diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ac2f483 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +/mvnw text eol=lf +*.cmd text eol=crlf + diff --git a/.gitignore b/.gitignore index 9154f4c..e72ecaa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,34 @@ -# ---> Java -# Compiled class file -*.class +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ -# Log file -*.log +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache -# BlueJ files -*.ctxt +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr -# Mobile Tools for Java (J2ME) -.mtj.tmp/ +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -replay_pid* +### VS Code ### +.vscode/ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..fb01db9 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip + diff --git a/README.md b/README.md index 1f4e832..52b67b6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # elysia-server +AI聊天服务器 \ No newline at end of file diff --git a/authorization/.gitattributes b/authorization/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/authorization/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/authorization/.gitignore b/authorization/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/authorization/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/authorization/.mvn/wrapper/maven-wrapper.properties b/authorization/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..44f3cf2 --- /dev/null +++ b/authorization/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/authorization/mvnw b/authorization/mvnw new file mode 100644 index 0000000..e9cf8d3 --- /dev/null +++ b/authorization/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.3 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/authorization/mvnw.cmd b/authorization/mvnw.cmd new file mode 100644 index 0000000..2e2dbe0 --- /dev/null +++ b/authorization/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/authorization/pom.xml b/authorization/pom.xml new file mode 100644 index 0000000..724d967 --- /dev/null +++ b/authorization/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + top.krcia + elysia-server + 0.0.1-SNAPSHOT + ../pom.xml + + top.krcia + authorization + 0.0.1-SNAPSHOT + authorization + authorization + jar + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + cn.hutool + hutool-all + ${hutool.version} + + + top.krcia + utils + 0.0.1-SNAPSHOT + compile + + + top.krcia + result + 0.0.1-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-starter-jdbc + + + com.baomidou + mybatis-plus-core + ${mybatis-plus.version} + compile + + + com.baomidou + mybatis-plus-extension + ${mybatis-plus.version} + compile + + + com.baomidou + mybatis-plus-spring-boot3-starter + ${mybatis-plus.version} + + + com.mysql + mysql-connector-j + + + org.springframework.boot + spring-boot-starter-aop + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/AuthorizationApplication.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/AuthorizationApplication.java new file mode 100644 index 0000000..aeb8710 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/AuthorizationApplication.java @@ -0,0 +1,13 @@ +package top.krcia.elysiaserver.authorization; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@MapperScan(basePackages = {"top.krcia.elysiaserver.authorization.dao"}) +public class AuthorizationApplication { + public static void main(String[] args) { + SpringApplication.run(AuthorizationApplication.class, args); + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/annotate/Metadata.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/annotate/Metadata.java new file mode 100644 index 0000000..44f234e --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/annotate/Metadata.java @@ -0,0 +1,8 @@ +package top.krcia.elysiaserver.authorization.annotate; + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Metadata { +} \ No newline at end of file diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/aspect/MetadataAspect.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/aspect/MetadataAspect.java new file mode 100644 index 0000000..428e93d --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/aspect/MetadataAspect.java @@ -0,0 +1,85 @@ +package top.krcia.elysiaserver.authorization.aspect; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; +import top.krcia.elysiaserver.authorization.annotate.Metadata; +import top.krcia.elysiaserver.result.R; + +import java.lang.reflect.Field; +import java.util.Collection; + +@ControllerAdvice +public class MetadataAspect implements ResponseBodyAdvice { + + + + @Value("${elysia-authorization.metadata-save.agent-url}") + private String agentUrl; + + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + // 对所有Controller返回值都生效 + return true; + } + + @Override + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, + Class> selectedConverterType, + org.springframework.http.server.ServerHttpRequest request, + org.springframework.http.server.ServerHttpResponse response) { + + if (body == null) return null; + + processObject(body); + + return body; + } + + private void processObject(Object obj) { + if (obj == null) return; + + // 如果是你的包装类 R + if (obj instanceof R) { + R r = (R) obj; + if (r.getData() != null) processObject(r.getData()); + return; + } + + if (obj instanceof Collection) { + for (Object item : (Collection) obj) { + processObject(item); + } + } else if (!isPrimitiveOrWrapper(obj.getClass())) { + Field[] fields = obj.getClass().getDeclaredFields(); + for (Field field : fields) { + if (field.isAnnotationPresent(Metadata.class)) { + field.setAccessible(true); + try { + Object value = field.get(obj); + if (value instanceof String && value != null && !((String) value).startsWith(agentUrl)) { + field.set(obj, agentUrl + value); + } + } catch (IllegalAccessException ignored) {} + } + } + } + } + + + private boolean isPrimitiveOrWrapper(Class clazz) { + return clazz.isPrimitive() + || clazz.equals(String.class) + || clazz.equals(Integer.class) + || clazz.equals(Long.class) + || clazz.equals(Boolean.class) + || clazz.equals(Double.class) + || clazz.equals(Float.class) + || clazz.equals(Short.class) + || clazz.equals(Byte.class) + || clazz.equals(Character.class); + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/MailConfig.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/MailConfig.java new file mode 100644 index 0000000..8090fe4 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/MailConfig.java @@ -0,0 +1,25 @@ +package top.krcia.elysiaserver.authorization.config; + +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import top.krcia.elysiaserver.utils.Mail; + +@Configuration +public class MailConfig { + @Value("${elysia-authorization.mail.host}") + private String host; + @Value("${elysia-authorization.mail.port}") + private int port; + @Value("${elysia-authorization.mail.username}") + private String username; + @Value("${elysia-authorization.mail.auth-code}") + private String authCode; + @Value("${elysia-authorization.mail.enable-ssl}") + private boolean enableSsl; + + @PostConstruct + private void init() { + Mail.init(host,port,username,authCode,enableSsl); + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/RedisTemplateConfig.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/RedisTemplateConfig.java new file mode 100644 index 0000000..0e6b918 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/RedisTemplateConfig.java @@ -0,0 +1,92 @@ +package top.krcia.elysiaserver.authorization.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import top.krcia.elysiaserver.utils.Kedis; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +@Configuration +public class RedisTemplateConfig { + + // 专用于 Redis 的 ObjectMapper + @Bean("redisObjectMapper") + public ObjectMapper redisObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + // Redis 序列化可以保留时间戳(根据需求调整) + objectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + return objectMapper; + } + + @Bean + public RedisTemplate redisTemplate( + RedisConnectionFactory redisConnectionFactory, + @Qualifier("redisObjectMapper") ObjectMapper redisObjectMapper) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConnectionFactory); + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(redisSerializer()); + template.setHashValueSerializer(redisSerializer()); + template.afterPropertiesSet(); + Kedis.init(template); + return template; + } + + @Bean + public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { + return builder.build(); // 自动应用 application.yml 的配置 + } + + @Bean + public RedisSerializer redisSerializer() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + // 必须设置,否则无法将JSON转化为对象,会转化成Map类型 + objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); + + // 自定义ObjectMapper的时间处理模块 + JavaTimeModule javaTimeModule = new JavaTimeModule(); + + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + + javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + + objectMapper.registerModule(javaTimeModule); + + // 禁用将日期序列化为时间戳的行为 + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + //创建JSON序列化器 + return new Jackson2JsonRedisSerializer<>(objectMapper, Object.class); + } + +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/WebConfig.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/WebConfig.java new file mode 100644 index 0000000..3d2128f --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/config/WebConfig.java @@ -0,0 +1,66 @@ +package top.krcia.elysiaserver.authorization.config; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.resource.ResourceResolver; +import org.springframework.web.servlet.resource.ResourceResolverChain; + +import java.util.List; + +//重写WebMvcConfigurer实现全局跨域配置 +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Value("${elysia-authorization.enable-cors}") + private boolean enableCors; + @Value("${elysia-authorization.enable-api-doc}") + private boolean enableApiDoc; + + @Override + public void addCorsMappings(CorsRegistry registry) { + if (enableCors) { + registry.addMapping("/api/**") + .allowCredentials(true) + .allowedOriginPatterns("*") // 使用 allowedOriginPatterns 代替 allowedOrigins + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("*"); + registry.addMapping("/oss/**") + .allowCredentials(true) + .allowedOriginPatterns("*") // 使用 allowedOriginPatterns 代替 allowedOrigins + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("*"); + } + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + if (enableApiDoc) { + return; + } + // 屏蔽static下的某个文件夹,例如屏蔽static/private/ + registry.addResourceHandler("/doc/**") + .addResourceLocations("classpath:/static/doc/") + .resourceChain(true) + .addResolver(new ResourceResolver() { + @Override + public Resource resolveResource(HttpServletRequest request, String requestPath, List locations, ResourceResolverChain chain) { + return new ClassPathResource("static/prevent/denied.html"); + } + + @Override + public String resolveUrlPath(String resourcePath, List locations, ResourceResolverChain chain) { + return null; // 返回null表示拒绝访问 + } + }); + } + + +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/OSSController.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/OSSController.java new file mode 100644 index 0000000..eb79e39 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/OSSController.java @@ -0,0 +1,45 @@ +package top.krcia.elysiaserver.authorization.controller; + +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.AntPathMatcher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.HandlerMapping; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.Path; + +/** + * @ignore + */ +@RequestMapping("/oss/") +@RestController +public class OSSController { + + @Value("${elysia-authorization.metadata-save.path}") + private String metadataSavePath; + + @GetMapping("/**") + public void oss(HttpServletRequest request, HttpServletResponse response) throws Exception { + response.setContentType("image/png"); + final String path = + request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString(); + final String bestMatchingPattern = + request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(); + File file = new File(Path.of(metadataSavePath, new AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path)).toString()); + try (FileInputStream in = new FileInputStream(file); + ServletOutputStream out = response.getOutputStream()) { + byte[] buffer = new byte[1024]; + int len; + while ((len = in.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + } catch (Exception e) { + } + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/AuthController.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/AuthController.java new file mode 100644 index 0000000..b473766 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/AuthController.java @@ -0,0 +1,103 @@ +package top.krcia.elysiaserver.authorization.controller.auth; + +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; +import top.krcia.elysiaserver.authorization.controller.auth.base.BaseController; +import top.krcia.elysiaserver.authorization.entity.dto.AuthDto; +import top.krcia.elysiaserver.authorization.entity.dto.ForgotPasswordDto; +import top.krcia.elysiaserver.authorization.entity.dto.ModifyPasswordDto; +import top.krcia.elysiaserver.authorization.entity.dto.RegisterDto; +import top.krcia.elysiaserver.authorization.entity.vo.SysUserVO; +import top.krcia.elysiaserver.authorization.service.AuthService; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.result.RS; +import top.krcia.elysiaserver.utils.*; + +/** + * 鉴权 + */ +@RestController +public class AuthController extends BaseController { + @Resource + private AuthService authService; + + /** + * 获取令牌 + * + * @param captcha 验证码值 + * @param captchaCode 验证码代码 + * @param auth 登录信息 + * @return + */ + @PostMapping("/login") + public R login(@RequestHeader("captcha") String captcha, @RequestHeader("captcha-code") String captchaCode, @RequestBody AuthDto auth) { + //判定是否使用验证码 + if (profile != Profile.DEVELOPMENT) { + String redisCaptcha = Kedis.get("CAPTCHA:".concat(captchaCode), String.class); + Kedis.delete("CAPTCHA:".concat(captchaCode).concat(captchaCode)); + if (redisCaptcha == null) { + return R.print(RS.CAPTCHA_NOT_EXIST); + } + if (!redisCaptcha.equalsIgnoreCase(captcha)) { + return R.print(RS.CAPTCHA_ERROR); + } + } + + return authService.login(auth); + } + + + /** + * 忘记密码 + * + * @return + */ + @PostMapping("/forgot-password-mail") + public R forgotPassword(ForgotPasswordDto forgotPasswordDto) { + return authService.forgotPassword(forgotPasswordDto); + } + + /** + * 修改密码 + * + * @param captcha 验证码值 + * @param captchaCode 验证码代码 + * @param modifyPasswordDto + * @return + */ + @PutMapping("modify-password") + public R modifyPassword(@RequestHeader("Authorization")String authorization,@RequestHeader("captcha") String captcha, @RequestHeader("captcha-code") String captchaCode, @RequestBody ModifyPasswordDto modifyPasswordDto) { + //判定是否使用验证码 + if (profile != Profile.DEVELOPMENT) { + String redisCaptcha = Kedis.get("CAPTCHA:".concat(captchaCode), String.class); + Kedis.delete("CAPTCHA:".concat(captchaCode).concat(captchaCode)); + if (redisCaptcha == null) { + return R.print(RS.CAPTCHA_NOT_EXIST); + } + if (!redisCaptcha.equalsIgnoreCase(captcha)) { + return R.print(RS.CAPTCHA_ERROR); + } + } + return authService.modifyPassword(authorization,modifyPasswordDto); + } + + /** + * 注册新用户 + * + * @return + */ + @PostMapping("/register") + public R Register(RegisterDto registerDto) { + return authService.register(registerDto); + } + + /** + * 用户信息 + * + * @return + */ + @PostMapping("/profile") + public R profile(@RequestHeader("Authorization") String authorization) { + return authService.profile(authorization); + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/CaptchaController.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/CaptchaController.java new file mode 100644 index 0000000..84adf87 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/CaptchaController.java @@ -0,0 +1,67 @@ +package top.krcia.elysiaserver.authorization.controller.auth; + +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.LineCaptcha; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import top.krcia.elysiaserver.authorization.controller.auth.base.BaseController; +import top.krcia.elysiaserver.authorization.service.AuthService; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.utils.Kedis; + +import java.io.IOException; +import java.util.UUID; + +/** + * 验证码 + */ +@RestController +public class CaptchaController extends BaseController { + @Resource + private AuthService authService; + /** + * 获取图形验证码 + * @param response + * @throws IOException + */ + @GetMapping("/captcha") + public void getCaptcha(HttpServletResponse response) throws IOException { + // 创建验证码:宽100,高40,字符4位,干扰线20条 + LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(130, 40, 4, 40); + // 生成唯一key + String uuid = UUID.randomUUID().toString(); + String code = lineCaptcha.getCode(); + + // 存入Redis,过期时间5分钟 + Kedis.set("CAPTCHA:" + uuid, code, 5); + // 响应头中返回uuid,前端携带uuid和用户输入的验证码验证 + response.setHeader("Captcha-UUID", uuid); + + // 输出图片 + response.setContentType("image/png"); + lineCaptcha.write(response.getOutputStream()); + } + /** + * 发送注册邮箱验证码 + * + * @param mail 邮箱|1503175889@qq.com + * @return + */ + @GetMapping("/register-mail") + public R sendRegisterMail(String mail) { + return authService.sendRegisterMail(mail); + } + + /** + * 发送忘记密码邮箱验证码 + * + * @param mail 邮箱|1503175889@qq.com + * @return + */ + @GetMapping("/forgot-password-mail") + public R sendForgotPasswordMail(String mail) { + return authService.sendForgotPasswordMail(mail); + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/base/BaseController.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/base/BaseController.java new file mode 100644 index 0000000..696aa44 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/controller/auth/base/BaseController.java @@ -0,0 +1,18 @@ +package top.krcia.elysiaserver.authorization.controller.auth.base; + +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import top.krcia.elysiaserver.utils.Profile; + +@RequestMapping("/authorization") +public class BaseController { + @Value("${spring.profiles.active}") + private String active; + protected Profile profile; + + @PostConstruct + private void init() { + profile = Profile.get(active); + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/dao/RobotFollowDao.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/dao/RobotFollowDao.java new file mode 100644 index 0000000..cec7199 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/dao/RobotFollowDao.java @@ -0,0 +1,20 @@ +package top.krcia.elysiaserver.authorization.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Update; +import top.krcia.elysiaserver.authorization.entity.pojo.RobotFollow; + + +/** + * (RobotFollow)表数据库访问层 + * + * @author admin + * @since 2025-09-12 13:58:35 + */ +public interface RobotFollowDao extends BaseMapper { + @Update(""" + CREATE TABLE robot_follow_${userId} LIKE robot_follow + """) + int createFollowTable(Long userId); +} + diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/dao/SysUserDao.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/dao/SysUserDao.java new file mode 100644 index 0000000..9f097ac --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/dao/SysUserDao.java @@ -0,0 +1,32 @@ +package top.krcia.elysiaserver.authorization.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import top.krcia.elysiaserver.authorization.entity.pojo.SysUser; + +/** + * (SysUser)表数据库访问层 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +public interface SysUserDao extends BaseMapper { + @Select(""" + SELECT * FROM sys_user WHERE user_name=#{username} + """) + SysUser getUserByUsername(@Param("username") String username); + @Select(""" + SELECT * FROM sys_user WHERE email=#{email} + """) + SysUser getUserByEmail(@Param("email") String email); + @Select(""" + SELECT * FROM sys_user WHERE email=#{email} OR user_name=#{username} + """) + SysUser findUser(@Param("email") String email,@Param("username") String username); + @Select(""" + SELECT * FROM sys_user WHERE email=#{account} OR user_name=#{account} + """) + SysUser findUserByAccount(@Param("account") String account); +} + diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/AuthDto.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/AuthDto.java new file mode 100644 index 0000000..e380450 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/AuthDto.java @@ -0,0 +1,19 @@ +package top.krcia.elysiaserver.authorization.entity.dto; + + +import lombok.Data; + +@Data +public class AuthDto { + /** + * 用户名 + * @mock admin + */ + + private String user; + /** + * 密码 + * @mock vir_sh@2025 + */ + private String password; +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/ForgotPasswordDto.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/ForgotPasswordDto.java new file mode 100644 index 0000000..dc86db1 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/ForgotPasswordDto.java @@ -0,0 +1,19 @@ +package top.krcia.elysiaserver.authorization.entity.dto; + +import lombok.Data; + +@Data +public class ForgotPasswordDto { + /** + * 邮箱 + */ + private String email; + /** + * 邮箱验证码 + */ + private String emailCode; + /** + * 新密码 + */ + private String password; +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/ModifyPasswordDto.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/ModifyPasswordDto.java new file mode 100644 index 0000000..c615c78 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/ModifyPasswordDto.java @@ -0,0 +1,18 @@ +package top.krcia.elysiaserver.authorization.entity.dto; + + +import lombok.Data; + +@Data +public class ModifyPasswordDto { + /** + * 密码 + * @mock vir_sh@2025 + */ + private String oldPassword; + /** + * 密码 + * @mock vir_sh@2025 + */ + private String newPassword; +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/RegisterDto.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/RegisterDto.java new file mode 100644 index 0000000..71393ea --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/dto/RegisterDto.java @@ -0,0 +1,52 @@ +package top.krcia.elysiaserver.authorization.entity.dto; + +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import java.io.Serializable; +import java.util.Date; + +/** + * (SysUser)表实体类 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +@Data +public class RegisterDto { + /** + * 头像 + */ + private MultipartFile avatar; + /** + * 姓名 + */ + private String name; + /** + * 昵称 + */ + private String nickname; + /** + * 用户名 + */ + private String userName; + /** + * 密码 + */ + private String password; + /** + * 邮箱 + */ + private String email; + /** + * DeepseekApi + */ + private String deepseekKey; + /** + * 邮箱验证码 + */ + private String emailCode; + +} + diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/pojo/RobotFollow.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/pojo/RobotFollow.java new file mode 100644 index 0000000..0a3b1e9 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/pojo/RobotFollow.java @@ -0,0 +1,29 @@ +package top.krcia.elysiaserver.authorization.entity.pojo; + +import com.baomidou.mybatisplus.extension.activerecord.Model; + +/** + * (RobotFollow)表实体类 + * + * @author admin + * @since 2025-09-12 13:58:35 + */ +@SuppressWarnings("serial") +public class RobotFollow extends Model { +//机器人列表 + private Long robotId; + + + public Long getRobotId() { + return robotId; + } + + public void setRobotId(Long robotId) { + this.robotId = robotId; + } + + public RobotFollow(Long robotId) { + this.robotId = robotId; + } +} + diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/pojo/SysUser.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/pojo/SysUser.java new file mode 100644 index 0000000..63dad36 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/pojo/SysUser.java @@ -0,0 +1,78 @@ +package top.krcia.elysiaserver.authorization.entity.pojo; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; + +/** + * (SysUser)表实体类 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +@SuppressWarnings("serial") +@Data +public class SysUser extends Model { + //用户ID + @TableId(type = IdType.AUTO) + private Long userId; + //头像 + private String avatar; + //姓名 + private String name; + //昵称 + private String nickname; + //用户名 + private String userName; + //密码 + private String password; + //状态:0启用,1禁用,-1删除 + private Integer status; + //状态时间 + private Date statusTime; + //状态时间 + private String email; + //创建时间 + private Date createTime; + //DeepseekApi + private String deepseekKey; + //DeepseekApi + private String token; + + + /** + * 获取主键值 + * + * @return 主键值 + */ + @Override + public Serializable pkVal() { + return this.userId; + } + + public SysUser(String avatar, String name, String nickname, String userName, String password,String email,String deepseekKey) { + this.avatar = avatar; + this.name = name; + this.nickname = nickname; + this.userName = userName; + this.password = password; + this.deepseekKey = deepseekKey; + this.status = 0; + this.statusTime = new Date(); + this.email = email; + this.createTime = new Date(); + } + + public SysUser(Long userId) { + this.userId = userId; + } + + public SysUser() { + } +} + diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/vo/Balance.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/vo/Balance.java new file mode 100644 index 0000000..8c5a9d2 --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/vo/Balance.java @@ -0,0 +1,23 @@ +package top.krcia.elysiaserver.authorization.entity.vo; + +import lombok.Data; + +@Data +public class Balance { + /** + * 是否可用 + */ + private boolean isAvailable; + /** + * 总余额(人名币) + */ + private String balance; + + public Balance(boolean isAvailable, String balance) { + this.isAvailable = isAvailable; + this.balance = balance; + } + + public Balance() { + } +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/vo/SysUserVO.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/vo/SysUserVO.java new file mode 100644 index 0000000..1090d3d --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/entity/vo/SysUserVO.java @@ -0,0 +1,52 @@ +package top.krcia.elysiaserver.authorization.entity.vo; + + +import lombok.Data; +import top.krcia.elysiaserver.authorization.annotate.Metadata; + +import java.io.Serializable; +import java.util.Date; + +/** + * (SysUser)表实体类 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +@Data +public class SysUserVO{ + /** + * 姓名 + */ + private String name; + /** + * 头像 + */ + @Metadata + private String avatar; + /** + * 昵称 + */ + private String nickname; + /** + * 用户名 + */ + private String userName; + /** + * 状态:0启用,1禁用,-1删除 + */ + private Integer status; + /** + * 状态时间 + */ + private Date statusTime; + /** + * 邮箱 + */ + private String email; + /** + * 创建时间 + */ + private Date createTime; +} + diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/service/AuthService.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/service/AuthService.java new file mode 100644 index 0000000..2497fde --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/service/AuthService.java @@ -0,0 +1,23 @@ +package top.krcia.elysiaserver.authorization.service; + +import top.krcia.elysiaserver.authorization.entity.dto.AuthDto; +import top.krcia.elysiaserver.authorization.entity.dto.ForgotPasswordDto; +import top.krcia.elysiaserver.authorization.entity.dto.ModifyPasswordDto; +import top.krcia.elysiaserver.authorization.entity.dto.RegisterDto; +import top.krcia.elysiaserver.authorization.entity.vo.SysUserVO; +import top.krcia.elysiaserver.result.R; + +public interface AuthService { + R login(AuthDto auth); + + R sendRegisterMail(String mail); + + R sendForgotPasswordMail(String mail); + + R forgotPassword(ForgotPasswordDto forgotPasswordDto); + R modifyPassword(String authorization,ModifyPasswordDto modifyPasswordDto); + + R register(RegisterDto registerDto); + + R profile(String authorization); +} diff --git a/authorization/src/main/java/top/krcia/elysiaserver/authorization/service/impl/AuthServiceImpl.java b/authorization/src/main/java/top/krcia/elysiaserver/authorization/service/impl/AuthServiceImpl.java new file mode 100644 index 0000000..ba0c10d --- /dev/null +++ b/authorization/src/main/java/top/krcia/elysiaserver/authorization/service/impl/AuthServiceImpl.java @@ -0,0 +1,176 @@ +package top.krcia.elysiaserver.authorization.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import jakarta.annotation.Resource; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import top.krcia.elysiaserver.authorization.dao.RobotFollowDao; +import top.krcia.elysiaserver.authorization.dao.SysUserDao; +import top.krcia.elysiaserver.authorization.entity.dto.AuthDto; +import top.krcia.elysiaserver.authorization.entity.dto.ForgotPasswordDto; +import top.krcia.elysiaserver.authorization.entity.dto.ModifyPasswordDto; +import top.krcia.elysiaserver.authorization.entity.dto.RegisterDto; +import top.krcia.elysiaserver.authorization.entity.pojo.SysUser; +import top.krcia.elysiaserver.authorization.entity.vo.SysUserVO; +import top.krcia.elysiaserver.authorization.service.AuthService; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.result.RS; +import top.krcia.elysiaserver.utils.*; + +import java.nio.file.Path; + +@Service +public class AuthServiceImpl implements AuthService { + @Resource + private SysUserDao sysUserDao; + @Resource + private RobotFollowDao robotFollowDao; + + @Value("${elysia-authorization.metadata-save.path}") + private String path; + + @Override + public R login(AuthDto auth) { + SysUser user = sysUserDao.findUserByAccount(auth.getUser()); + if (user == null) { + return R.print(RS.USER_NOT_FIND); + } + if (!PasswordUtil.checkPassword(auth.getPassword(), user.getPassword())) { + return R.print(RS.PASSWORD_ERROR); + } + String token = JWTGenerator.generateJWTToken(user.getUserId()); + UpdateWrapper wrapper = new UpdateWrapper(); + wrapper.set("token", token); + wrapper.eq("user_id", user.getUserId()); + sysUserDao.update(wrapper); + return R.success(token); + } + + @Override + public R sendRegisterMail(String mail) { + if (Kedis.hasKey(C.REDIS_MAIL_CODE.concat(":").concat(mail))) { + return R.printFormat(RS.ERROR, "请在5分钟后再次获取"); + } + SysUser user = sysUserDao.getUserByEmail(mail); + if (user != null) { + return R.print(RS.EMAIL_REGISTER, maskString(user.getUserName())); + } + String code = VerifyCode.generate(5); + Kedis.set(C.REDIS_MAIL_CODE.concat(":").concat(mail), code, 5); + Mail.sendHtmlMail(mail, C.MAIL_PROJECT_NAME, C.MAIL_TITLE, "register.html", code); + return R.success(); + } + + @Override + public R sendForgotPasswordMail(String mail) { + if (Kedis.hasKey(C.REDIS_MAIL_CODE.concat(":").concat(mail))) { + return R.printFormat(RS.ERROR, "请在5分钟后再次获取"); + } + SysUser user = sysUserDao.getUserByEmail(mail); + if (user == null) { + return R.print(RS.USER_NOT_FIND); + } + String code = VerifyCode.generate(5); + Kedis.set(C.REDIS_MAIL_CODE.concat(":").concat(mail), code, 5); + Mail.sendHtmlMail(mail, C.MAIL_PROJECT_NAME, C.MAIL_TITLE, "forgot-password.html", code); + return R.success(); + } + + @Override + public R forgotPassword(ForgotPasswordDto forgotPasswordDto) { + String value = Kedis.get(C.REDIS_MAIL_CODE.concat(":").concat(forgotPasswordDto.getEmail()), String.class); + if (!StringUtils.hasText(value) || !forgotPasswordDto.getEmailCode().toUpperCase().equals(value.toUpperCase())) { + return R.print(RS.CAPTCHA_ERROR); + } + SysUser user = sysUserDao.getUserByEmail(forgotPasswordDto.getEmail()); + if (user == null) { + + return R.print(RS.USER_NOT_FIND); + } + user.setPassword(PasswordUtil.hashPassword(forgotPasswordDto.getPassword())); + int i = sysUserDao.updateById(user); + return i > 0 ? R.success() : R.print(RS.MODIFY_FAIL); + } + + @Override + public R modifyPassword(String authorization, ModifyPasswordDto modifyPasswordDto) { + Long userId = JWTGenerator.getUserId(authorization); + SysUser sysUser = new SysUser(userId); + sysUser = sysUserDao.selectById(sysUser); + if (!PasswordUtil.checkPassword(modifyPasswordDto.getOldPassword(), sysUser.getPassword())) { + return R.print(RS.OLD_PASSWORD_ERROR); + } + + if (PasswordUtil.checkPassword(modifyPasswordDto.getNewPassword(), sysUser.getPassword())) { + return R.print(RS.OLD_PASSWORD_EQ_NEW_PASSWORD); + } + sysUser.setPassword(PasswordUtil.hashPassword(modifyPasswordDto.getNewPassword())); + int i = sysUserDao.updateById(sysUser); + return i > 0 ? R.success() : R.print(RS.MODIFY_FAIL); + } + + @Override + public R register(RegisterDto registerDto) { + String value = Kedis.get(C.REDIS_MAIL_CODE.concat(":").concat(registerDto.getEmail()), String.class); + if (!StringUtils.hasText(value) || !registerDto.getEmailCode().toUpperCase().equals(value.toUpperCase())) { + return R.print(RS.CAPTCHA_ERROR); + } + SysUser user = sysUserDao.findUser(registerDto.getEmail(), registerDto.getUserName()); + if (user != null) { + + return R.print(RS.REGISTER_INFO_EXIST); + } + String aId = U.get(); + String data = FileUtil.upLoad(registerDto.getAvatar(), aId, Path.of(path, "avatar").toString()); + if (data.equals("ERROR")) { + return R.print(RS.FILE_UPLOAD_ERROR); + } + + String password = PasswordUtil.hashPassword(registerDto.getPassword()); + SysUser sysUser = new SysUser("/avatar/" + data, registerDto.getName(), registerDto.getNickname(), registerDto.getUserName(), password, registerDto.getEmail(), registerDto.getDeepseekKey()); + int i = sysUserDao.insert(sysUser); + if (i > 0) { + robotFollowDao.createFollowTable(sysUser.getUserId()); + return R.success(); + } + return R.printFormat(RS.SERVER_ERROR, "数据新增失败"); + } + + @Override + public R profile(String authorization) { + Long userId = JWTGenerator.getUserId(authorization); + if (userId==null){ + return R.print(RS.USER_NOT_LOGIN); + } + SysUser user = new SysUser(userId); + user = sysUserDao.selectById(user); + if (user != null & authorization.equals(user.getToken())) { + SysUserVO sysUserVO = new SysUserVO(); + BeanUtils.copyProperties(user, sysUserVO); + return R.success(sysUserVO); + } + return R.print(RS.USER_NOT_LOGIN); + } + + private String maskString(String input) { + if (input == null || input.length() <= 6) { + // 如果字符串长度小于等于11,直接返回原字符串或全部替换 + return input; + } + + int totalLength = input.length(); + String firstPart = input.substring(0, 3); + String lastPart = input.substring(totalLength - 2); + int middleLength = totalLength - 5; + + // 生成中间部分的星号 + String middleStars = "*".repeat(middleLength); + + return firstPart + middleStars + lastPart; + } + +} + + diff --git a/authorization/src/main/resources/application-development.yml b/authorization/src/main/resources/application-development.yml new file mode 100644 index 0000000..5eabeda --- /dev/null +++ b/authorization/src/main/resources/application-development.yml @@ -0,0 +1,25 @@ +spring: + data: + redis: + host: krcia.top + port: 6379 + password: xiong990416. + database: 3 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://krcia.top:3306/elysia-db?serverTimezone=Asia/Shanghai + username: root + password: xiong990416. +elysia-authorization: + version: v0.1-0909-dev + enable-cors: true + enable-api-doc: true + mail: + host: smtp.qq.com + port: 465 + username: krcia@qq.com + auth-code: ghylxjvfnnjqdfhe + enable-ssl: true + metadata-save: + path: ./metadata/ + agent-url: http://192.168.1.2:4562/oss \ No newline at end of file diff --git a/authorization/src/main/resources/application-release.yml b/authorization/src/main/resources/application-release.yml new file mode 100644 index 0000000..e69de29 diff --git a/authorization/src/main/resources/application.yml b/authorization/src/main/resources/application.yml new file mode 100644 index 0000000..3e194be --- /dev/null +++ b/authorization/src/main/resources/application.yml @@ -0,0 +1,11 @@ +server: + port: 4562 +spring: + application: + name: elysia-authorization + profiles: + active: development + servlet: + multipart: + max-request-size: 300MB + max-file-size: 180MB \ No newline at end of file diff --git a/authorization/src/main/resources/smart-doc.json b/authorization/src/main/resources/smart-doc.json new file mode 100644 index 0000000..99a5d47 --- /dev/null +++ b/authorization/src/main/resources/smart-doc.json @@ -0,0 +1,20 @@ +{ + "outPath": "./src/main/resources/static/doc", + "serverUrl": "/api", + "serverEnv": "http://{{server}}", + "allInOne": true, + "coverOld": true, + "createDebugPage": true, + "showAuthor": "true", + "allInOneDocFileName": "index.html", + "requestHeaders": [ + { + "name": "Authorization", + "type": "string", + "value": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-", + "desc": "鉴权信息", + "required": true, + "excludePathPatterns": "/authorization/login,/authorization/captcha,/authorization/register" + } + ] +} \ No newline at end of file diff --git a/authorization/src/main/resources/static/doc/AllInOne.css b/authorization/src/main/resources/static/doc/AllInOne.css new file mode 100644 index 0000000..b22c6a2 --- /dev/null +++ b/authorization/src/main/resources/static/doc/AllInOne.css @@ -0,0 +1,13 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}script{display:none!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}.left{float:left!important}.right{float:right!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}.hide{display:none}img,object,svg{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.center{margin-left:auto;margin-right:auto}.spread{width:100%}p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#364149;text-decoration:underline;line-height:inherit}a:hover,a:focus{color:#364149}a img{border:0}p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4,h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} +ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:2.75em}h2{font-size:2.3125em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}*:not(pre)>code.nobreak{word-wrap:normal}*:not(pre)>code.nowrap{white-space:nowrap}pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}em em{font-style:normal}strong strong{font-weight:400}.keyseq{color:rgba(51,51,51,.8)}kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menuref{color:#000}.menuseq b:not(.caret),.menuref{font-weight:inherit}.menuseq{word-spacing:-.02em}.menuseq b.caret{font-size:1.25em;line-height:.8}.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,.9)}#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-.125em}#header .details span.email a{color:rgba(0,0,0,.85)}#header .details br{display:none} +#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}#toc>ul{margin-left:.125em;padding-left:1.25em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}#toc li{line-height:1.3334;margin-top:.3334em;padding-bottom:4px;padding-top:4px}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#7a2518;font-size:1.2em}@media only screen and (min-width:768px){#toctitle{font-size:1.375em}body.toc2{padding-left:15em;padding-right:0}#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;#padding:1.25em 1em;height:100%;overflow:auto}#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}#toc.toc2>ul{font-size:.9em;margin-bottom:0}#toc.toc2 ul ul{margin-left:0;padding-left:1em}#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}body.toc2.toc-right{padding-left:0;padding-right:15em}body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}#toc.toc2{width:20em}#toc.toc2 #toctitle{border-bottom:1px solid rgba(0,0,0,.07);padding-top:20px;padding-bottom:15px}#toc.toc2 #toctitle span{padding-left:1.25em;padding-bottom:15px}#toc.toc2>ul{font-size:.95em}#toc.toc2 ul ul{padding-left:1.25em}body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}#footer-text{color:rgba(255,255,255,.8);line-height:1.44}.sect1{padding-bottom:.625em}@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:0;width:100%}.admonitionblock>table td.icon{text-align:center;width:80px} +.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}.listingblock pre.highlightjs{padding:0}.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}.listingblock pre.prettyprint{border-width:0}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock:hover code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:0}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:inline-block;margin-right:.25em}table.pyhltable .linenodiv{background:none!important;padding-right:0!important}.quoteblock{margin:0 1em 1.25em 1.5em;display:table}.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}.quoteblock blockquote{margin:0;padding:0;border:0}.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 1em}.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} +.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px 0}table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0 0}table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}p.tableblock>code:only-child{background:0;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}ul.unstyled,ol.unstyled{margin-left:0}ul.checklist{margin-left:.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:400;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:0}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:0}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}.colist>table tr>td:first-of-type{padding:.4em .75em 0 .75em;line-height:1;vertical-align:top}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}.imageblock.left,.imageblock[style*="float:left"]{margin:.25em .625em 1.25em 0}.imageblock.right,.imageblock[style*="float:right"]{margin:.25em 0 1.25em .625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}.image.left{margin-right:.625em}.image.right{margin-left:.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none} +sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:#000}.black-background{background-color:#000}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000}.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}a span.icon>.fa{cursor:inherit}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff!important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:-.125em}b.conum *{color:inherit!important}.conum:not([data-value]):empty{display:none}dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}h1,h2,p,td.content,span.alt{letter-spacing:-.01em}p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}p{margin-bottom:1.25rem}.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}.print-only{display:none!important}@media print{@page{margin:1.25cm .75cm}*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}a{color:inherit!important;text-decoration:underline!important}a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote,tr,img,object,svg{page-break-inside:avoid}thead{display:table-header-group}svg{max-width:100%}p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}#toc,.sidebarblock,.exampleblock>.content{background:none!important}#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}.sect1{padding-bottom:0!important}.sect1+.sect1{border:0!important}#header>h1:first-child{margin-top:1.25rem} + body.book #header{text-align:center}body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}body.book #header .details{border:0!important;display:block;padding:0!important}body.book #header .details span:first-child{margin-left:0!important}body.book #header .details br{display:block}body.book #header .details br+span:before{content:none!important}body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}.listingblock code[data-lang]:before{display:block}#footer{background:none!important;padding:0 .9375em}#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}.hide-on-print{display:none!important}.print-only{display:block!important}.hide-for-print{display:none!important}.show-for-print{display:inherit!important}}#content .page-footer{height:100px;border-top:1px solid #ccc;overflow:hidden;padding:10px 0;font-size:14px;color:gray}#content .footer-modification{float:right}#content .footer-modification a{text-decoration:none}.sectlevel2{display:none}.submenu{background:#e7e7e6}.submenu li{border:0}.submenu a{color:#555}.checkbox{position:relative;height:30px}.checkbox input[type='checkbox']{left:0;top:0;width:20px;height:20px;opacity:0;border-radius:4px}.checkbox label{position:absolute;left:30px;top:0;height:20px;line-height:20px}.checkbox label:before{content:'';position:absolute;left:-30px;top:2px;width:20px;height:20px;border:1px solid #ddd;border-radius:4px;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease}.checkbox label:after{content:'';position:absolute;left:-22px;top:3px;width:6px;height:12px;border:0;border-right:1px solid #fff;border-bottom:1px solid #fff;border-radius:2px;transform:rotate(45deg);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease}.checkbox input[type='checkbox']:checked+label:before{background:#4cd764;border-color:#4cd764}.checkbox input[type='checkbox']:checked+label:after{background:#4cd764}.send-button{color:#fff;background-color:#5cb85c;display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px;outline-color:transparent}textarea{width:100%;background-color:#f7f7f8;border:1px solid #f7f7f8;border-radius:4px;font-size:1em;padding:1em;font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;outline-color:#dedede}input{border:0;background-color:transparent;outline-color:transparent;outline-style:dotted;max-width:100%}#book-search-input{padding:13px;background:0;transition:top .5s ease;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}[contenteditable="plaintext-only"]:focus{border:0;outline:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}script{display:none!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} +button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}.left{float:left!important}.right{float:right!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}.hide{display:none}img,object,svg{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.center{margin-left:auto;margin-right:auto}.spread{width:100%}p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#364149;text-decoration:underline;line-height:inherit}a:hover,a:focus{color:#364149}a img{border:0}p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4,h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:2.75em}h2{font-size:2.3125em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} +table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}*:not(pre)>code.nobreak{word-wrap:normal}*:not(pre)>code.nowrap{white-space:nowrap}pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}em em{font-style:normal}strong strong{font-weight:400}.keyseq{color:rgba(51,51,51,.8)}kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menuref{color:#000}.menuseq b:not(.caret),.menuref{font-weight:inherit}.menuseq{word-spacing:-.02em}.menuseq b.caret{font-size:1.25em;line-height:.8}.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,.9)}#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-.125em}#header .details span.email a{color:rgba(0,0,0,.85)}#header .details br{display:none}#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}#toc>ul{margin-left:.125em;padding-left:1.25em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}#toc li{line-height:1.3334;margin-top:.3334em;padding-bottom:4px;padding-top:4px}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#7a2518;font-size:1.2em}@media only screen and (min-width:768px){#toctitle{font-size:1.375em}body.toc2{padding-left:15em;padding-right:0}#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;#padding:1.25em 1em;height:100%;overflow:auto}#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} + #toc.toc2>ul{font-size:.9em;margin-bottom:0}#toc.toc2 ul ul{margin-left:0;padding-left:1em}#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}body.toc2.toc-right{padding-left:0;padding-right:15em}body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}#toc.toc2{width:20em}#toc.toc2 #toctitle{font-size:1.375em;border-bottom:1px solid rgba(0,0,0,.07);padding-top:20px;padding-bottom:15px}#toc.toc2 #toctitle span{padding-left:1.25em;padding-bottom:15px}#toc.toc2>ul{font-size:.95em}#toc.toc2 ul ul{padding-left:1.25em}body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}#footer-text{color:rgba(255,255,255,.8);line-height:1.44}.sect1{padding-bottom:.625em}@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:0;width:100%}.admonitionblock>table td.icon{text-align:center;width:80px}.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} +.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}.listingblock pre.highlightjs{padding:0}.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}.listingblock pre.prettyprint{border-width:0}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock:hover code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:0}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:inline-block;margin-right:.25em}table.pyhltable .linenodiv{background:none!important;padding-right:0!important}.quoteblock{margin:0 1em 1.25em 1.5em;display:table}.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}.quoteblock blockquote{margin:0;padding:0;border:0}.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 1em}.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px 0}table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0 0}table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0} +table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}p.tableblock>code:only-child{background:0;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}ul.unstyled,ol.unstyled{margin-left:0}ul.checklist{margin-left:.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:400;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:0}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:0}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}.colist>table tr>td:first-of-type{padding:.4em .75em 0 .75em;line-height:1;vertical-align:top}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}.imageblock.left,.imageblock[style*="float:left"]{margin:.25em .625em 1.25em 0}.imageblock.right,.imageblock[style*="float:right"]{margin:.25em 0 1.25em .625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}.image.left{margin-right:.625em}.image.right{margin-left:.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none}sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:#000}.black-background{background-color:#000}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000} +.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}a span.icon>.fa{cursor:inherit}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff!important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:-.125em}b.conum *{color:inherit!important}.conum:not([data-value]):empty{display:none}dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}h1,h2,p,td.content,span.alt{letter-spacing:-.01em}p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}p{margin-bottom:1.25rem}.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}.print-only{display:none!important}@media print{@page{margin:1.25cm .75cm}*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}a{color:inherit!important;text-decoration:underline!important}a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote,tr,img,object,svg{page-break-inside:avoid}thead{display:table-header-group}svg{max-width:100%}p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}#toc,.sidebarblock,.exampleblock>.content{background:none!important}#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}.sect1{padding-bottom:0!important}.sect1+.sect1{border:0!important}#header>h1:first-child{margin-top:1.25rem}body.book #header{text-align:center}body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}body.book #header .details{border:0!important;display:block;padding:0!important}body.book #header .details span:first-child{margin-left:0!important}body.book #header .details br{display:block}body.book #header .details br+span:before{content:none!important}body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}.listingblock code[data-lang]:before{display:block}#footer{background:none!important;padding:0 .9375em}#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}.hide-on-print{display:none!important}.print-only{display:block!important}.hide-for-print{display:none!important}.show-for-print{display:inherit!important}}#content .page-footer{height:100px;border-top:1px solid #ccc;overflow:hidden;padding:10px 0;font-size:14px;color:gray}#content .footer-modification{float:right}#content .footer-modification a{text-decoration:none}.sectlevel2{display:none}.submenu{background:#e7e7e6}.submenu li{border:0}.submenu a{color:#555}.copyright{text-align:right;padding-top:1.25em}#toTop{display:none;position:fixed;bottom:10px;right:0;width:44px;height:44px;border-radius:50%;background-color:#ced4ce;cursor:pointer;text-align:center}#upArrow{position:absolute;left:24%;right:0;bottom:19%;transition:.3s ease-in-out;display:block}#upText{position:absolute;left:0;right:0;bottom:0;font-size:16px;font-weight: 600;line-height:45px;display:none;transition:.3s ease-in-out;-webkit-box-align:center} \ No newline at end of file diff --git a/authorization/src/main/resources/static/doc/debug.js b/authorization/src/main/resources/static/doc/debug.js new file mode 100644 index 0000000..c3a9135 --- /dev/null +++ b/authorization/src/main/resources/static/doc/debug.js @@ -0,0 +1,407 @@ +$(function () { + const Accordion = function (el, multiple) { + this.el = el || {}; + this.multiple = multiple || false; + const links = this.el.find('.dd'); + links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown); + }; + Accordion.prototype.dropdown = function (e) { + const $el = e.data.el; + const $this = $(this), $next = $this.next(); + $next.slideToggle(); + $this.parent().toggleClass('open'); + if (!e.data.multiple) { + $el.find('.submenu').not($next).slideUp("20").parent().removeClass( + 'open'); + } + }; + new Accordion($('#accordion'), false); + hljs.highlightAll(); +}); + +$("[contenteditable=plaintext-only]").on('blur', function (e) { + e.preventDefault(); + const $this = $(this); + const data = $this.text(); + let content; + if (undefined === e.originalEvent.clipboardData) { + content = data; + } else { + content = e.originalEvent.clipboardData.getData('text/plain') + } + content = JSON.stringify(JSON.parse(content), null, 4); + const highlightedCode = hljs.highlight('json', content).value; + $this.html(highlightedCode); +}) +$("button").on("click", function () { + const $this = $(this); + const id = $this.data("id"); + console.log("method-id=>" + id); + + let body = $("#" + id + "-body").text(); + + // header + const $headerElement = $("#" + id + "-header"); + const headersData = getInputData($headerElement); + + // body param + const $paramElement = $("#" + id + "-param"); + let bodyParamData = getInputData($paramElement) + + // path param + const $pathElement = $("#" + id + "-path-params") + const pathParamData = getInputData($pathElement) + + // query param + const $queryElement = $("#" + id + "-query-params") + let $urlDataElement = $("#" + id + "-url"); + const url = $urlDataElement.data("url"); + const isDownload = $urlDataElement.data("download"); + const page = $urlDataElement.data("page"); + const method = $("#" + id + "-method").data("method"); + const contentType = $("#" + id + "-content-type").data("content-type"); + console.log("request-headers=>" + JSON.stringify(headersData)) + console.log("path-params=>" + JSON.stringify(pathParamData)) + + console.log("body-params=>" + JSON.stringify(bodyParamData)) + console.log("json-body=>" + body); + let finalUrl = ""; + let queryParamData; + if (!isEmpty(page)) { + queryParamData = getInputData($queryElement) + finalUrl = castToGetUri(page, pathParamData, queryParamData) + window.open(finalUrl, "_blank"); + return; + } + if (isDownload) { + queryParamData = getInputData($queryElement); + download(url, headersData, pathParamData, queryParamData, bodyParamData, + method, contentType); + return; + } + const ajaxOptions = {}; + + if ("multipart/form-data" === contentType) { + finalUrl = castToGetUri(url, pathParamData); + queryParamData = getInputData($queryElement, true, true) + body = queryParamData; + ajaxOptions.processData = false; + ajaxOptions.contentType = false; + } else if ("POST" === method && contentType !== "multipart/form-data" + && contentType !== "application/json") { + finalUrl = castToGetUri(url, pathParamData); + queryParamData = getInputData($queryElement, true) + body = queryParamData; + } else { + queryParamData = getInputData($queryElement) + finalUrl = castToGetUri(url, pathParamData, queryParamData) + ajaxOptions.contentType = contentType; + } + console.log("query-params=>" + JSON.stringify(queryParamData)); + console.log("url=>" + finalUrl) + ajaxOptions.headers = headersData + ajaxOptions.url = finalUrl + ajaxOptions.type = method + ajaxOptions.data = body; + + const $responseEle = $("#" + id + "-response").find("pre code"); + const ajaxTime = new Date().getTime(); + $.ajax(ajaxOptions).done(function (result, textStatus, jqXHR) { + const totalTime = new Date().getTime() - ajaxTime; + $this.css("background", "#5cb85c"); + $("#" + id + "-resp-status").html( + " Status: " + jqXHR.status + "  " + jqXHR.statusText + + "    Time: " + totalTime + " ms"); + const highlightedCode = hljs.highlight('json', + JSON.stringify(result, null, 4)).value; + $responseEle.html(highlightedCode); + }).fail(function (jqXHR) { + const totalTime = new Date().getTime() - ajaxTime; + $this.css("background", "#D44B47"); + if (jqXHR.status === 0 && jqXHR.readyState === 0) { + $("#" + id + "-resp-status").html( + "Connection refused, please check the server."); + } else { + $("#" + id + "-resp-status").html( + " Status: " + jqXHR.status + "  " + + jqXHR.statusText + "    Time: " + totalTime + + " ms"); + } + if (undefined !== jqXHR.responseJSON) { + const highlightedCode = hljs.highlight('json', + JSON.stringify(jqXHR.responseJSON, null, 4)).value; + $responseEle.html(highlightedCode); + } + }).always(function () { + + }); + const curlCmd = toCurl(ajaxOptions); + const highlightedCode = hljs.highlight('bash', curlCmd).value; + $("#" + id + "-curl").find("pre code").html(highlightedCode); +}) +$(".check-all").on("click", function () { + const checkboxName = $(this).prop("name"); + const checked = $(this).is(':checked'); + if (!checked) { + $(this).removeAttr("checked"); + } else { + $(this).prop("checked", true); + } + $('input[name="' + checkboxName + '"]').each(function () { + if (!checked) { + $(this).prop("checked", false); + } else { + $(this).prop("checked", true); + } + }) +}) + +function castToGetUri(url, pathParams, params) { + if (undefined !== url) { + let urls = url.split(";") + url = urls[0]; + } + if (pathParams instanceof Object && !(pathParams instanceof Array)) { + url = url.format(pathParams) + } + if (params instanceof Object && !(params instanceof Array)) { + const pm = params || {}; + const arr = []; + arr.push(url); + let j = 0; + for (const i in pm) { + if (j === 0) { + arr.push("?"); + arr.push(i + "=" + pm[i]); + } else { + arr.push("&" + i + "=" + pm[i]); + } + j++; + } + return arr.join(""); + } else { + return url; + } +} + +function getInputData(element, isPost, returnFormDate) { + const formData = new FormData(); + $(element).find("tr").each(function (i) { + const checked = $(this).find('td:eq(0)').children(".checkbox").children( + "input").is(':checked'); + if (checked) { + const input = $(this).find('td:eq(2) input'); + let attr = $(input).attr("type"); + let multiple = $(input).attr("multiple"); + console.log("input type:" + attr) + const name = $(input).attr("name"); + if (attr === "file") { + let files = $(input)[0].files; + if (multiple) { + $.each(files, function (i, file) { + formData.append(name, file); + }) + } else { + formData.append(name, files[0]); + } + } else { + const val = $(input).val(); + if (isValidUrl(val)) { + formData.append(name, encodeURI(val)); + } else { + // support chinese + if (hasChinese(val) && !isPost) { + formData.append(name, encodeURIComponent(val)); + } else { + formData.append(name, val); + } + } + } + } + }); + if (returnFormDate) { + return formData; + } + const headersData = {}; + formData.forEach((value, key) => headersData[key] = value); + return headersData; +} + +String.prototype.format = function (args) { + let reg; + if (arguments.length > 0) { + let result = this; + if (arguments.length === 1 && typeof (args) == "object") { + for (const key in args) { + reg = new RegExp("({" + key + "})", "g"); + result = result.replace(reg, args[key]); + } + } else { + for (let i = 0; i < arguments.length; i++) { + if (arguments[i] === undefined) { + return ""; + } else { + reg = new RegExp("({[" + i + "]})", "g"); + result = result.replace(reg, arguments[i]); + } + } + } + return result; + } else { + return this; + } +} + +function download(url, headersData, pathParamData, queryParamData, + bodyParamData, method, contentType) { + url = castToGetUri(url, pathParamData, queryParamData) + const xmlRequest = new XMLHttpRequest(); + xmlRequest.open(method, url, true); + xmlRequest.setRequestHeader("Content-type", contentType); + for (let key in headersData) { + xmlRequest.setRequestHeader(key, headersData[key]) + } + xmlRequest.responseType = "blob"; + xmlRequest.onload = function () { + if (this.status === 200) { + let fileName = ""; + const disposition = xmlRequest.getResponseHeader('Content-Disposition'); + if (disposition && disposition.indexOf('attachment') !== -1) { + const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; + const matches = filenameRegex.exec(disposition); + if (matches != null && matches[1]) { + fileName = decodeURI(matches[1].replace(/['"]/g, '')); + } + } + console.log("download filename:" + fileName); + const blob = this.response; + if (navigator.msSaveBlob) { + // IE10 can't do a[download], only Blobs: + window.navigator.msSaveBlob(blob, fileName); + return; + } + if (window.URL) { // simple fast and modern way using Blob and URL: + const a = document.createElement("a"); + document.body.appendChild(a); + const url = window.URL.createObjectURL(blob); + a.href = url; + a.download = fileName; + a.click(); + window.URL.revokeObjectURL(url); + } + console.log(fileName); + } else { + console.log("download failed"); + } + }; + try { + xmlRequest.send(bodyParamData); + } catch (e) { + console.error("Failed to send data", e); + } +} + +function toCurl(request) { + if (typeof request !== 'object') { + throw "Request is not an object"; + } + // default is a GET request + const cmd = ["curl", "-X", request.type || "GET"]; + + if (request.url.indexOf('https') === 0) { + cmd.push("-k"); + } + + // append Content-Type + if (request.contentType) { + cmd.push("-H"); + cmd.push("'Content-Type:"); + cmd.push(request.contentType + "'"); + } + // append request headers + let headerValue; + if (typeof request.headers == 'object') { + for (let key in request.headers) { + if (Object.prototype.hasOwnProperty.call(request.headers, key)) { + cmd.push("-H"); + headerValue = request.headers[key]; + if (headerValue.value === '') { + cmd.push("'" + key + "'"); + } else { + cmd.push("'" + key + ':' + headerValue + "'"); + } + } + } + } + + // display the response headers + cmd.push("-i"); + // append request url + let url = request.url; + if (!url.startsWith("http")) { + const protocol = window.document.location.protocol; + const domain = window.document.location.hostname; + const port = window.document.location.port; + url = protocol + "//" + domain + ":" + port + url; + } + cmd.push(url); + // append data + + if (typeof request.data == 'object') { + let index = 0; + const bodyData = []; + bodyData.push("\"") + for (let key in request.data) { + if (Object.prototype.hasOwnProperty.call(request.data, key)) { + if (index === 0) { + bodyData.push(key); + bodyData.push("="); + bodyData.push(request.data[key]); + } else { + bodyData.push("&") + bodyData.push(key); + bodyData.push("="); + bodyData.push(request.data[key]); + } + } + index++; + } + bodyData.push("\""); + let bodyStr = "" + bodyData.forEach(function (item) { + bodyStr += item; + }); + cmd.push("--data"); + cmd.push(bodyStr); + } else if (request.data && request.data.length > 0) { + // append json data + cmd.push("--data"); + cmd.push("'" + request.data + "'"); + } + + let curlCmd = ""; + cmd.forEach(function (item) { + curlCmd += item + " "; + }); + console.log(curlCmd); + return curlCmd; +} + +function isEmpty(obj) { + return obj === undefined || obj === null || String(obj).trim() === ''; +} + +function hasChinese(_string) { + const chineseReg = /[\u4e00-\u9fa5]/g + return chineseReg.test(_string); +} + +function isValidUrl(_string) { + let urlString; + try { + urlString = new URL(_string); + } catch (_) { + return false; + } + return urlString.protocol === "http:" || urlString.protocol === "https:"; +} diff --git a/authorization/src/main/resources/static/doc/font.css b/authorization/src/main/resources/static/doc/font.css new file mode 100644 index 0000000..3c85d80 --- /dev/null +++ b/authorization/src/main/resources/static/doc/font.css @@ -0,0 +1,6 @@ +@font-face{font-family:'Droid Sans Mono';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/droidsansmono/v19/6NUO8FuJNQ2MbkrZ5-J8lKFrp7pRef2r.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZzC7TMQ.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImbjC7TMQ.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZjC7TMQ.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImaTC7TMQ.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZTC7TMQ.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZDC7TMQ.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImajC7.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufuVMCoY.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWud-VMCoY.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWuf-VMCoY.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWucOVMCoY.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufOVMCoY.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufeVMCoY.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWuc-VM.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFoWaCi_.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F} +@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFMWaCi_.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFsWaCi_.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFQWaCi_.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFgWaCi_.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFkWaCi_.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFcWaA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRqecf1I.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfROecf1I.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRuecf1I.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRSecf1I.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRiecf1I.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRmecf1I.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfReecQ.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF} +@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116} +@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} +@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF} +@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} \ No newline at end of file diff --git a/authorization/src/main/resources/static/doc/highlight.min.js b/authorization/src/main/resources/static/doc/highlight.min.js new file mode 100644 index 0000000..664e1aa --- /dev/null +++ b/authorization/src/main/resources/static/doc/highlight.min.js @@ -0,0 +1,1213 @@ +/*! + Highlight.js v11.9.0 (git: f47103d4f1) + (c) 2006-2023 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";function e(n){ + return n instanceof Map?n.clear=n.delete=n.set=()=>{ + throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{ + throw Error("set is read-only") + }),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{ + const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a) + })),n}class n{constructor(e){ + void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} + ignoreMatch(){this.isMatchIgnored=!0}}function t(e){ + return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") + }function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n] + ;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope + ;class r{constructor(e,n){ + this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){ + this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{ + if(e.startsWith("language:"))return e.replace("language:","language-") + ;if(e.includes(".")){const t=e.split(".") + ;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ") + }return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)} + closeNode(e){i(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ + this.buffer+=``}}const s=(e={})=>{const n={children:[]} + ;return Object.assign(n,e),n};class o{constructor(){ + this.rootNode=s(),this.stack=[this.rootNode]}get top(){ + return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ + this.top.children.push(e)}openNode(e){const n=s({scope:e}) + ;this.add(n),this.stack.push(n)}closeNode(){ + if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ + for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} + walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){ + return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n), + n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){ + "string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ + o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e} + addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){ + this.closeNode()}__addSublanguage(e,n){const t=e.root + ;n&&(t.scope="language:"+n),this.add(t)}toHTML(){ + return new r(this,this.options).value()}finalize(){ + return this.closeAllNodes(),!0}}function c(e){ + return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")} + function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")} + function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{ + const n=e[e.length-1] + ;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{} + })(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"} + function p(e){return RegExp(e.toString()+"|").exec("").length-1} + const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ + ;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t + ;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break} + i+=a.substring(0,e.index), + a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0], + "("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)} + const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={ + begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'", + illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", + contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n, + contains:[]},t);i.contains.push({scope:"doctag", + begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", + end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) + ;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) + ;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i + },M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({ + __proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{ + scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x, + C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number", + begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{ + "on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f, + MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0}, + NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y, + PHRASAL_WORDS_MODE:{ + begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ + },QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/, + end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]}, + RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", + SHEBANG:(e={})=>{const n=/^#![ ]*\// + ;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n, + end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)}, + TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E, + UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){ + "."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){ + void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){ + n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", + e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, + void 0===e.relevance&&(e.relevance=0))}function I(e,n){ + Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){ + if(e.match){ + if(e.begin||e.end)throw Error("begin & end are not supported with match") + ;e.begin=e.match,delete e.match}}function B(e,n){ + void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return + ;if(e.starts)throw Error("beforeMatch cannot be used with starts") + ;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n] + })),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={ + relevance:0,contains:[Object.assign(t,{endsParent:!0})] + },e.relevance=0,delete t.beforeMatch + },z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword" + ;function U(e,n,t=F){const a=Object.create(null) + ;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{ + Object.assign(a,U(e[t],n,t))})),a;function i(e,t){ + n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|") + ;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){ + return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{ + console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{ + P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0) + },G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={} + ;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1]) + ;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{ + e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, + delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ + _wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope + }),(e=>{if(Array.isArray(e.begin)){ + if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), + G + ;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"), + G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{ + if(Array.isArray(e.end)){ + if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"), + G + ;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"), + G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){ + function n(n,t){ + return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":"")) + }class t{constructor(){ + this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} + addRule(e,n){ + n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]), + this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) + ;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|" + }),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex + ;const n=this.matcherRe.exec(e);if(!n)return null + ;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t] + ;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){ + this.rules=[],this.multiRegexes=[], + this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ + if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t + ;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))), + n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){ + return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){ + this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){ + const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex + ;let t=n.exec(e) + ;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{ + const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)} + return t&&(this.regexIndex+=t.position+1, + this.regexIndex===this.count&&this.considerAll()),t}} + if(e.compilerExtensions||(e.compilerExtensions=[]), + e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") + ;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r + ;if(r.isCompiled)return o + ;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))), + r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null + ;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords), + l=r.keywords.$pattern, + delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)), + o.keywordPatternRe=n(l,!0), + s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/), + r.end&&(o.endRe=n(o.end)), + o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)), + r.illegal&&(o.illegalRe=n(r.illegal)), + r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{ + variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{ + starts:e.starts?a(e.starts):null + }):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o) + })),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i + ;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin" + }))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end" + }),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){ + return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{ + constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}} + const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{ + const a=Object.create(null),i=Object.create(null),r=[];let s=!0 + ;const o="Could not find the language '{}', did you forget to load/include a language module?",c={ + disableAutodetect:!0,name:"Plain text",contains:[]};let p={ + ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, + languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", + cssSelector:"pre code",languages:null,__emitter:l};function _(e){ + return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i="" + ;"object"==typeof n?(a=e, + t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."), + q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), + i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r) + ;const s=r.result?r.result:f(r.language,r.code,t) + ;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){ + const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A) + ;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t="" + ;for(;n;){t+=A.substring(e,n.index) + ;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){ + const[e,a]=r + ;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{ + const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0] + ;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a + ;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{ + if(""===A)return;let e=null;if("string"==typeof x.subLanguage){ + if(!a[x.subLanguage])return void S.addText(A) + ;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top + }else e=E(A,x.subLanguage.length?x.subLanguage:null) + ;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language) + })():c(),A=""}function g(e,n){ + ""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1 + ;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue} + const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}} + function b(e,n){ + return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope), + e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), + A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{ + value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n) + ;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e) + ;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){ + for(;e.endsParent&&e.parent;)e=e.parent;return e}} + if(e.endsWithParent)return m(e.parent,t,a)}function _(e){ + return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){ + const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x + ;x.endScope&&x.endScope._wrap?(d(), + g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(), + u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n), + d(),r.excludeEnd&&(A=n));do{ + x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent + }while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length} + let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0 + ;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){ + if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`) + ;throw n.languageName=e,n.badRule=y.rule,n}return 1} + if(y=r,"begin"===r.type)return(e=>{ + const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]] + ;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t) + ;return a.skip?A+=t:(a.excludeBegin&&(A+=t), + d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r) + ;if("illegal"===r.type&&!i){ + const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"")+'"') + ;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e} + if("illegal"===r.type&&""===o)return 1 + ;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches") + ;return A+=o,o.length}const w=v(e) + ;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"') + ;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[] + ;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope) + ;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{ + if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){ + R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T + ;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e) + ;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e, + value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){ + if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t), + illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T, + context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{ + language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x} + ;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{ + const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)} + ;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1))) + ;i.unshift(t);const r=i.sort(((e,n)=>{ + if(e.relevance!==n.relevance)return n.relevance-e.relevance + ;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1 + ;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s + ;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{ + let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"" + ;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1]) + ;return n||(H(o.replace("{}",t[1])), + H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"} + return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return + ;if(x("before:highlightElement",{el:e,language:t + }),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e) + ;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), + console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), + console.warn("The element with unescaped HTML:"), + console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML) + ;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a) + ;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t + ;e.classList.add("hljs"),e.classList.add("language-"+a) + })(e,t,r.language),e.result={language:r.language,re:r.relevance, + relevance:r.relevance},r.secondBest&&(e.secondBest={ + language:r.secondBest.language,relevance:r.secondBest.relevance + }),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){ + "loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0 + }function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]} + function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ + i[e.toLowerCase()]=n}))}function k(e){const n=v(e) + ;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{ + e[t]&&e[t](n)}))} + "undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ + N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w, + highlightElement:y, + highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"), + q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)}, + initHighlighting:()=>{ + w(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, + initHighlightingOnLoad:()=>{ + w(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") + },registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){ + if(K("Language definition for '{}' could not be registered.".replace("{}",e)), + !s)throw n;K(n),i=c} + i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{ + languageName:e})},unregisterLanguage:e=>{delete a[e] + ;for(const n of Object.keys(i))i[n]===e&&delete i[n]}, + listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O, + autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{ + e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{ + e["before:highlightBlock"](Object.assign({block:n.el},n)) + }),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{ + e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)}, + removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{ + s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b, + lookahead:d,either:m,optional:u,anyNumberOfTimes:g} + ;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t + },te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{ + scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{ + scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/}, + FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/}, + ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", + contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ + scope:"number", + begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", + relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} + }),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le) + ;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={ + className:"number",variants:[{ + begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{ + begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{ + begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{ + begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{ + begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{ + begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], + relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))} + const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye) + ;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/, + end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ + const t=e[0].length+e.index,a=e.input[t] + ;if("<"===a||","===a)return void n.ignoreMatch();let i + ;">"===a&&(((e,{after:n})=>{const t="",M={ + match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)], + keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]} + ;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{ + PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/, + contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ + label:"use_strict",className:"meta",relevance:10, + begin:/^\s*['"]use (strict|asm)['"]/ + },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{ + className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{ + begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", + keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{ + className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{ + className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{ + className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, + excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/, + relevance:0},{variants:[{begin:"<>",end:""},{ + match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin, + "on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{ + begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{ + beginKeywords:"while if switch catch for"},{ + begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", + returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t, + className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t, + relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, + contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, + className:"variable.constant"},E,k,{match:/\$[(.]/}]}} + const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] + ;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={ + begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]} + ;Object.assign(t,{className:"variable",variants:[{ + begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={ + className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={ + begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, + end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/, + contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/, + end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] + },l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 + }),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, + contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ + name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, + keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], + literal:["true","false"], + built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] + },contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{ + match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}, + grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}] + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ + className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ + match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{ + begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ + begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", + end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ + className:"number",variants:[{begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" + },{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ + keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], + type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], + literal:"true false NULL", + built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" + },b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{ + begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], + keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u, + contains:b.concat(["self"]),relevance:0}]),relevance:0},p={ + begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, + keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})], + relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/, + keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/, + end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s] + }]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u, + disableAutodetect:!0,illegal:"=]/,contains:[{ + beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c, + strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{ + contains:[{begin:/\\\n/}] + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ + className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{ + begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ + begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", + end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ + className:"number",variants:[{begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" + },{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ + type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"], + keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"], + literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"], + _type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"] + },b={className:"function.dispatch",relevance:0,keywords:{ + _hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"] + }, + begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/)) + },m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{ + begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], + keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u, + contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function", + begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, + keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{ + begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{ + className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0, + contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u, + relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}] + },s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++", + aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{ + match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/], + className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={ + keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]), + built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"], + literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{ + begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{ + begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}] + },r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/, + keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/, + end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/ + },e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{ + begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/, + contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]}) + ;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE], + o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{ + illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] + },u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t] + },b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={ + begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"], + keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0, + contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{ + begin:"\x3c!--|--\x3e"},{begin:""}]}] + }),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#", + end:"$",keywords:{ + keyword:"if else elif endif define undef warning error line region endregion pragma checksum" + }},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/, + illegal:/[^\s:,]/,contains:[{beginKeywords:"where class" + },t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace", + relevance:0,end:/[{;=]/,illegal:/[^\s:]/, + contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ + beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/, + contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta", + begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{ + className:"string",begin:/"/,end:/"/}]},{ + beginKeywords:"new return throw await else",relevance:0},{className:"function", + begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, + end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{ + beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial", + relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, + contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params", + begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0, + contains:[g,a,e.C_BLOCK_COMMENT_MODE] + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{ + const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{ + name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{ + keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"}, + contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/ + },t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0 + },{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 + },t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ + begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}] + },t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{ + begin:/:/,end:/[;}{]/, + contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{ + begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" + },contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0, + excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]", + relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ + },{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ + $pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{ + begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{ + className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{ + const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{ + className:"meta",relevance:10, + match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/) + },{className:"comment",variants:[{ + begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/), + end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{ + className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/, + end:/$/}]}},grmr_go:e=>{const n={ + keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"], + type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"], + literal:["true","false","iota","nil"], + built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"] + };return{name:"Go",aliases:["golang"],keywords:n,illegal:"{const n=e.regex;return{name:"GraphQL",aliases:["gql"], + case_insensitive:!0,disableAutodetect:!1,keywords:{ + keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"], + literal:["true","false","null"]}, + contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{ + scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation", + begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/, + end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{ + scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)), + relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={ + className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{ + begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/, + end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{ + begin:/\$\{(.*?)\}/}]},r={className:"literal", + begin:/\bon|off|true|false|yes|no\b/},s={className:"string", + contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{ + begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}] + },o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0 + },l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{ + name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/, + contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{ + begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)), + className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{ + const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={ + keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"], + literal:["false","true","null"], + type:["char","boolean","long","float","int","byte","short","double"], + built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{ + begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/, + end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0} + ;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/, + contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/, + relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{ + begin:/import java\.[a-z]+\./,keywords:"import",relevance:2 + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/, + className:"string",contains:[e.BACKSLASH_ESCAPE] + },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{ + match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{ + 1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{ + begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type", + 3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword", + 3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ + beginKeywords:"new throw return else",relevance:0},{ + begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{ + 2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/, + end:/\)/,keywords:i,relevance:0, + contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE] + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe, + grmr_json:e=>{const n=["true","false","null"],t={scope:"literal", + beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{ + className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{ + match:/[{}[\],:]/,className:"punctuation",relevance:0 + },e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], + illegal:"\\S"}},grmr_kotlin:e=>{const n={ + keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual", + built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing", + literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@" + },a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={ + className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string", + variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'", + illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/, + contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={ + className:"meta", + begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?" + },o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/, + end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}] + },l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={ + variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/, + contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g], + {name:"Kotlin",aliases:["kt","kts"],keywords:n, + contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag", + begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword", + begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol", + begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$", + returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{ + begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0, + contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://, + keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/, + endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/, + endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0 + },e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{ + begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{ + 3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0, + illegal:"extends implements",contains:[{ + beginKeywords:"public protected internal private constructor" + },e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0, + excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/, + excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env", + end:"$",illegal:"\n"},l]}},grmr_less:e=>{ + const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({ + className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n, + relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only", + attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c, + relevance:0} + ;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{ + begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]", + excludeEnd:!0} + },n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{ + className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0 + },n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({ + begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0, + contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:", + returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/ + },n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b", + end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}] + },m={className:"keyword", + begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b", + starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={ + className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a + }],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{ + begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0, + returnEnd:!0,illegal:"[<='$\"]",relevance:0, + contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{ + begin:"\\b("+re.join("|")+")\\b",className:"selector-tag" + },n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{ + className:"selector-pseudo",begin:":("+oe.join("|")+")"},{ + className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/, + end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={ + begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]} + ;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH), + {name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}}, + grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"] + },i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10 + })];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, + literal:"true false nil", + keyword:"and break do else elseif end for goto if in local not or repeat return then until while", + built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" + },contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)", + contains:[e.inherit(e.TITLE_MODE,{ + begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params", + begin:"\\(",endsWithParent:!0,contains:i}].concat(i) + },e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string", + begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={ + className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)", + contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%{ + const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={ + variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{ + begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, + relevance:2},{ + begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), + relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ + begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ + },{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, + returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", + excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", + end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[], + variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}] + },i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{ + begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[] + }),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r) + ;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o) + })),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ + className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{ + begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", + contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", + end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o, + end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ + begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ + begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", + contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ + begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ + className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ + className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{ + const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n, + keyword:["@interface","@class","@protocol","@implementation"]};return{ + name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"], + keywords:{"variable.language":["this","super"],$pattern:n, + keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"], + literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"], + built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"], + type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"] + },illegal:"/,end:/$/,illegal:"\\n" + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class", + begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t, + contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE, + relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={ + $pattern:/[\w.]+/, + keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0" + },i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/, + end:/\}/},s={variants:[{begin:/\$\d/},{ + begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])") + },{begin:/[$%@][^\s\w{]/,relevance:0}] + },o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{ + const r="\\1"===i?i:n.concat(i,a) + ;return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t) + },d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{ + endsWithParent:!0}),r,{className:"string",contains:o,variants:[{ + begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[", + end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{ + begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">", + relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'", + contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`", + contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{ + begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number", + begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b", + relevance:0},{ + begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*", + keywords:"split return print reverse grep",relevance:0, + contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{ + begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{ + begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{ + className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{ + begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0 + }),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{ + begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub", + end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{ + begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$", + subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}] + }];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a, + contains:g}},grmr_php:e=>{ + const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={ + scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{ + begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null + }),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{ + illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{ + begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/, + contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{ + n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({ + begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{ + begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ + begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{ + begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?" + }],relevance:0 + },g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={ + keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{ + n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase()) + })),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{ + match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{ + 1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{ + match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant" + }},{match:[/::/,/class/],scope:{2:"variable.language"}},{ + match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class", + 3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))], + scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class", + 3:"variable.language"}}]},E={scope:"attr", + match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0, + begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_] + },N={relevance:0, + match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)], + scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N) + ;const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1, + keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/, + endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{ + begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]}, + contains:["self",...w]},...w,{scope:"meta",match:i}] + },e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{ + scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/, + keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE, + contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{ + begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{ + begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{ + match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{ + scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/, + excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use" + },e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params", + begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m, + contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{ + beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait", + illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{ + beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{ + beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/, + contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{ + beginKeywords:"use",relevance:0,end:";",contains:[{ + match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]} + },grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{ + begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*", + end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0 + },e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null, + skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null, + contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text", + aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{ + const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={ + $pattern:/[A-Za-z]\w+|__\w+__/,keyword:a, + built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"], + literal:["__debug__","Ellipsis","False","None","NotImplemented","True"], + type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"] + },r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/, + end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={ + className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{ + begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/, + contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ + begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/, + contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ + begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/, + contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/, + end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/, + relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{ + begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/, + end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/, + contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/, + contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] + },c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={ + className:"number",relevance:0,variants:[{ + begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{ + begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{ + begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})` + },{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})` + }]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i, + contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={ + className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/, + end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i, + contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{ + name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i, + illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if", + relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{ + 1:"keyword",3:"title.function"},contains:[m]},{variants:[{ + match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}], + scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{ + className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}}, + grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt", + starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{ + begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{ + const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/) + ;return{name:"R",keywords:{$pattern:t, + keyword:"function if in break next repeat else for while", + literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10", + built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm" + },contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/, + starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)), + endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{ + scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0 + }]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}] + }),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE], + variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"', + relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{ + 1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"}, + match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{ + 2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"}, + match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{ + match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`", + contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{ + const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={ + "variable.constant":["__FILE__","__LINE__","__ENCODING__"], + "variable.language":["self","super"], + keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"], + built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"], + literal:["true","false","nil"]},s={className:"doctag",begin:"@[A-Za-z]+"},o={ + begin:"#<",end:">"},l=[e.COMMENT("#","$",{contains:[s] + }),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10 + }),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/, + end:/\}/,keywords:r},d={className:"string",contains:[e.BACKSLASH_ESCAPE,c], + variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{ + begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{ + begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//, + end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{ + begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{ + begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{ + begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{ + begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{ + begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)), + contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/, + contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number", + relevance:0,variants:[{ + begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{ + begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b" + },{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{ + begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{ + begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{ + className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0, + keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{ + match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class", + 4:"title.class.inherited"},keywords:r},{match:[/(include|extend)\s+/,i],scope:{ + 2:"title.class"},keywords:r},{relevance:0,match:[i,/\.new[. (]/],scope:{ + 1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, + className:"variable.constant"},{relevance:0,match:a,scope:"title.class"},{ + match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{ + begin:e.IDENT_RE+"::"},{className:"symbol", + begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol", + begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable", + begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{ + className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0, + relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*", + keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c], + illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{ + begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[", + end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l) + ;c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m} + },{className:"meta.prompt", + begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])", + starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby", + aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/, + contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}}, + grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0, + begin:n.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,n.lookahead(/\s*\(/)) + },a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] + ;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r, + keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], + literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:""},t]}}, + grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable", + begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS", + case_insensitive:!0,illegal:"[=/|']", + contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{ + className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{ + className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0 + },n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag", + begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo", + begin:":("+a.join("|")+")"},{className:"selector-pseudo", + begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/, + contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute", + begin:"\\b("+ce.join("|")+")\\b"},{ + begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b" + },{begin:/:/,end:/[;}{]/,relevance:0, + contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH] + },{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{ + begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/, + keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i, + className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute" + },r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE] + },n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session", + aliases:["console","shellsession"],contains:[{className:"meta.prompt", + begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/, + subLanguage:"bash"}}]}),grmr_sql:e=>{ + const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={ + begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}} + ;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{ + $pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t + ;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e)) + })(l,{when:e=>e.length<3}),literal:a,type:i, + built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"] + },contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, + keyword:l.concat(s),literal:a,type:i}},{className:"type", + begin:n.either("double precision","large object","with timezone","without timezone") + },c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string", + variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/, + contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{ + className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, + relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0 + },t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={ + match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)), + relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{ + className:"keyword", + match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={ + $pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{ + match:b(/\./,m(...De)),relevance:0},{className:"built_in", + match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{ + className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}] + }],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0, + variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{ + match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/ + },{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{ + match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}] + }),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/) + }),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/ + }),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)] + }),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={ + className:"string", + variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")] + },k=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0, + contains:[e.BACKSLASH_ESCAPE]}],x={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//, + contains:k},M=e=>{const n=b(e,/\//),t=b(/\//,e);return{begin:n,end:t, + contains:[...k,{scope:"comment",begin:`#(?!.*${t})`,end:/$/}]}},S={ + scope:"regexp",variants:[M("###"),M("##"),M("#"),x]},A={match:b(/`/,Fe,/`/) + },C=[A,{className:"variable",match:/\$\d+/},{className:"variable", + match:`\\$${ze}+`}],T=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{ + contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{ + scope:"keyword",match:b(/@/,m(...je))},{scope:"meta",match:b(/@/,Fe)}],R={ + match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type", + match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+") + },{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{ + match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},D={ + begin://,keywords:l,contains:[...a,...c,...T,u,R]};R.contains.push(D) + ;const I={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{ + match:b(Fe,/\s*:/),keywords:"_|0",relevance:0 + },...a,S,...c,...g,...p,f,O,...C,...T,R]},L={begin://, + keywords:"repeat each",contains:[...a,R]},B={begin:/\(/,end:/\)/,keywords:l, + contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/, + relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params", + match:Fe}]},...a,...c,...p,f,O,...T,R,I],endsParent:!0,illegal:/["']/},$={ + match:[/(func|macro)/,/\s+/,m(A.match,Fe,Be)],className:{1:"keyword", + 3:"title.function"},contains:[L,B,n],illegal:[/\[/,/%/]},z={ + match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"}, + contains:[L,B,n],illegal:/\[|%/},F={match:[/operator/,/\s+/,Be],className:{ + 1:"keyword",3:"title"}},U={begin:[/precedencegroup/,/\s+/,Ue],className:{ + 1:"keyword",3:"title"},contains:[R],keywords:[...Te,...Ce],end:/}/} + ;for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label)) + ;n.keywords=l;const t=[...c,...g,...p,f,O,...C];n.contains=[...t,{begin:/\(/, + end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l, + contains:[...a,$,z,{beginKeywords:"struct protocol class extension enum actor", + end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{ + className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c] + },F,U,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0 + },S,...c,...g,...p,f,O,...C,...T,R,I]}},grmr_typescript:e=>{ + const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={ + beginKeywords:"namespace",end:/\{/,excludeEnd:!0, + contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/, + excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a}, + contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e, + keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), + literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta", + begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n)) + ;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)} + ;return Object.assign(n.keywords,s), + n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]), + l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10, + begin:/^\s*['"]use strict['"]/ + }),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{ + name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{ + const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={ + className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{ + begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{ + begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}] + },o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}] + }),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]}) + ;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0, + classNameAliases:{label:"symbol"},keywords:{ + keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield", + built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort", + type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort", + literal:"true false nothing"}, + illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{ + className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/, + end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0, + variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/ + },{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{ + begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{ + className:"label",begin:/^\w+:/},o,l,{className:"meta", + begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/, + end:/$/,keywords:{ + keyword:"const disable else elseif enable end externalsource if region then"}, + contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/) + ;return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/, + keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"] + },contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/], + className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{ + match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{ + begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword", + 3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/, + className:"type"},{className:"keyword", + match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/ + },{className:"number",relevance:0, + match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/ + }]}},grmr_xml:e=>{ + const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={ + className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/, + contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] + },r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{ + className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={ + endsWithParent:!0,illegal:/`]+/}]}]}]};return{ + name:"HTML, XML", + aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], + case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{ + className:"meta",begin://,contains:[i,r,o,s]}]}] + },e.COMMENT(//,{relevance:10}),{begin://, + relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, + relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{ + end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{ + end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ + className:"tag",begin:/<>|<\/>/},{className:"tag", + begin:n.concat(//,/>/,/\s/)))), + end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{ + className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{ + className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]} + },grmr_yaml:e=>{ + const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={ + className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ + },{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", + variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{ + variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={ + end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},s={begin:/\{/, + end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]", + contains:[r],illegal:"\\n",relevance:0},l=[{className:"attr",variants:[{ + begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{ + begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$", + relevance:10},{className:"string", + begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{ + begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0, + relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type", + begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t + },{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta", + begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)", + relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{ + className:"number", + begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" + },{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l] + ;return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0, + aliases:["yml"],contains:l}}});const He=ae;for(const e of Object.keys(Ke)){ + const n=e.replace("grmr_","").replace("_","-");He.registerLanguage(n,Ke[e])} + return He}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); \ No newline at end of file diff --git a/authorization/src/main/resources/static/doc/index.html b/authorization/src/main/resources/static/doc/index.html new file mode 100644 index 0000000..f2dd870 --- /dev/null +++ b/authorization/src/main/resources/static/doc/index.html @@ -0,0 +1,50 @@ +智能AI聊天服务器
VersionUpdate TimeStatusAuthorDescription

v2025-10-23 15:41:00

2025-10-23 15:41:00

auto

@Krcia

Created by smart-doc

2. 鉴权

2.1. 获取令牌

Type: POST

Content-Type: application/json

Description: 获取令牌

Request-headers:

HeaderValueTypeRequiredDescription

captcha

string

true

验证码值

captcha-code

string

true

验证码代码

Body-parameters:

ParameterTypeRequiredDescription

user

string

false

用户名

password

string

false

密码

Request-body:

{
+  "user": "admin",
+  "password": "vir_sh@2025"
+}

Response-fields:

FieldTypeDescriptionSince

code

int32

状态编码

-

message

string

状态

-

data

string

数据

-

Response-example:

{
+  "code": 200,
+  "message": "success",
+  "data": ""
+}

Curl-example:

curl -X POST -H "Content-Type: application/json" -H "captcha" -H "captcha-code" -i '/api/authorization/login' --data '{
+  "user": "admin",
+  "password": "vir_sh@2025"
+}'

2.2. 忘记密码

Type: POST

Content-Type: application/x-www-form-urlencoded

Description: 忘记密码

Request-headers:

HeaderValueTypeRequiredDescription

Authorization

string

true

鉴权信息

Body-parameters:

ParameterValueTypeRequiredDescription

email

string

false

邮箱

emailCode

string

false

邮箱验证码

password

string

false

新密码

Response-fields:

FieldTypeDescriptionSince

code

int32

状态编码

-

message

string

状态

-

data

object

数据

-

Response-example:

{
+  "code": 200,
+  "message": "success",
+  "data": {}
+}

Curl-example:

curl -X POST -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/authorization/forgot-password-mail' --data 'email=""&password=""&emailCode=""'

2.3. 修改密码

Type: PUT

Content-Type: application/json

Description: 修改密码

Request-headers:

HeaderValueTypeRequiredDescription

Authorization

string

true

鉴权信息

captcha

string

true

验证码值

captcha-code

string

true

验证码代码

Body-parameters:

ParameterTypeRequiredDescription

oldPassword

string

false

密码

newPassword

string

false

密码

Request-body:

{
+  "oldPassword": "vir_sh@2025",
+  "newPassword": "vir_sh@2025"
+}

Response-fields:

FieldTypeDescriptionSince

code

int32

状态编码

-

message

string

状态

-

data

object

数据

-

Response-example:

{
+  "code": 200,
+  "message": "success",
+  "data": {}
+}

Curl-example:

curl -X PUT -H "Content-Type: application/json" -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -H "captcha" -H "captcha-code" -i '/api/authorization/modify-password' --data '{
+  "oldPassword": "vir_sh@2025",
+  "newPassword": "vir_sh@2025"
+}'

2.4. 注册新用户

Type: POST

Content-Type: multipart/form-data

Description: 注册新用户

Body-parameters:

ParameterValueTypeRequiredDescription

avatar

file

false

头像

name

string

false

姓名

nickname

string

false

昵称

userName

string

false

用户名

password

string

false

密码

email

string

false

邮箱

deepseekKey

string

false

DeepseekApi

emailCode

string

false

邮箱验证码

Response-fields:

FieldTypeDescriptionSince

code

int32

状态编码

-

message

string

状态

-

data

object

数据

-

Response-example:

{
+  "code": 200,
+  "message": "success",
+  "data": {}
+}

Curl-example:

curl -X POST -H "Content-Type: multipart/form-data" -F 'avatar=' -i '/api/authorization/register' --data 'email=""&nickname=""&name=""&password=""&emailCode=""&userName=""&deepseekKey=""'

2.5. 用户信息

Type: POST

Content-Type: application/x-www-form-urlencoded

Description: 用户信息

Request-headers:

HeaderValueTypeRequiredDescription

Authorization

string

true

鉴权信息

Response-fields:

FieldTypeDescriptionSince

code

int32

状态编码

-

message

string

状态

-

data

object

数据

-

└─name

string

姓名

-

└─avatar

string

头像

-

└─nickname

string

昵称

-

└─userName

string

用户名

-

└─status

int32

状态:0启用,1禁用,-1删除

-

└─statusTime

string

状态时间

-

└─email

string

邮箱

-

└─createTime

string

创建时间

-

Response-example:

{
+  "code": 200,
+  "message": "success",
+  "data": {
+    "name": "",
+    "avatar": "",
+    "nickname": "",
+    "userName": "",
+    "status": 0,
+    "statusTime": "yyyy-MM-dd HH:mm:ss",
+    "email": "",
+    "createTime": "yyyy-MM-dd HH:mm:ss"
+  }
+}

Curl-example:

curl -X POST -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/authorization/profile'

3. 验证码

3.1. 获取图形验证码

Type: GET

Content-Type: application/x-www-form-urlencoded

Description: 获取图形验证码

Response-example:

Return void.

Curl-example:

curl -X GET -i '/api/authorization/captcha'

3.2. 发送注册邮箱验证码

Type: GET

Content-Type: application/x-www-form-urlencoded

Description: 发送注册邮箱验证码

Request-headers:

HeaderValueTypeRequiredDescription

Authorization

string

true

鉴权信息

Query-parameters:

ParameterValueTypeRequiredDescription

mail

string

false

邮箱

Response-fields:

FieldTypeDescriptionSince

code

int32

状态编码

-

message

string

状态

-

data

object

数据

-

Response-example:

{
+  "code": 200,
+  "message": "success",
+  "data": {}
+}

Curl-example:

curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/authorization/register-mail?mail=1503175889@qq.com&=crtfqe'

3.3. 发送忘记密码邮箱验证码

Type: GET

Content-Type: application/x-www-form-urlencoded

Description: 发送忘记密码邮箱验证码

Request-headers:

HeaderValueTypeRequiredDescription

Authorization

string

true

鉴权信息

Query-parameters:

ParameterValueTypeRequiredDescription

mail

string

false

邮箱

Response-fields:

FieldTypeDescriptionSince

code

int32

状态编码

-

message

string

状态

-

data

object

数据

-

Response-example:

{
+  "code": 200,
+  "message": "success",
+  "data": {}
+}

Curl-example:

curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/authorization/forgot-password-mail?mail=1503175889@qq.com&=pkvmy2'
Generated by smart-doc at 2025-10-23 15:41:00Suggestions,contact,support and error reporting on Gitee or Github
Top
\ No newline at end of file diff --git a/authorization/src/main/resources/static/doc/jquery.min.js b/authorization/src/main/resources/static/doc/jquery.min.js new file mode 100644 index 0000000..798cc8b --- /dev/null +++ b/authorization/src/main/resources/static/doc/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 -1) { + searchArr.push({ + order: apiData.order, + desc: apiData.desc, + link: apiData.link, + alias: apiData.alias, + list: apiData.list + }); + } else { + let methodList = apiData.list || []; + let methodListTemp = []; + for (let j = 0; j < methodList.length; j++) { + const methodData = methodList[j]; + const methodDesc = methodData.desc; + if (methodDesc.toLocaleLowerCase().indexOf(searchValue) > -1) { + methodListTemp.push(methodData); + break; + } + } + if (methodListTemp.length > 0) { + const data = { + order: apiData.order, + desc: apiData.desc, + link: apiData.link, + alias: apiData.alias, + list: methodListTemp + }; + searchArr.push(data); + } + } + } + if (apiGroup.name.toLocaleLowerCase().indexOf(searchValue) > -1) { + searchGroup.push({ + name: apiGroup.name, + order: apiGroup.order, + list: searchArr + }); + continue; + } + if (searchArr.length === 0) { + continue; + } + searchGroup.push({ + name: apiGroup.name, + order: apiGroup.order, + list: searchArr + }); + } + let html; + if (searchValue === '') { + const liClass = ""; + const display = "display: none"; + html = buildAccordion(api,liClass,display); + document.getElementById('accordion').innerHTML = html; + } else { + const liClass = "open"; + const display = "display: block"; + html = buildAccordion(searchGroup,liClass,display); + document.getElementById('accordion').innerHTML = html; + } + const Accordion = function (el, multiple) { + this.el = el || {}; + this.multiple = multiple || false; + const links = this.el.find('.dd'); + links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown); + }; + Accordion.prototype.dropdown = function (e) { + const $el = e.data.el; + let $this = $(this), $next = $this.next(); + $next.slideToggle(); + $this.parent().toggleClass('open'); + if (!e.data.multiple) { + $el.find('.submenu').not($next).slideUp("20").parent().removeClass('open'); + } + }; + new Accordion($('#accordion'), false); + } +} + +function buildAccordion(apiGroups, liClass, display) { + let html = ""; + if (apiGroups.length > 0) { + if (apiDocListSize === 1) { + let apiData = apiGroups[0].list; + let order = apiGroups[0].order; + for (let j = 0; j < apiData.length; j++) { + html += '
  • '; + html += '' + apiData[j].order + '. ' + apiData[j].desc + ''; + html += ''; + html += '
  • '; + } + } else { + for (let i = 0; i < apiGroups.length; i++) { + let apiGroup = apiGroups[i]; + html += '
  • '; + html += '' + apiGroup.order + '. ' + apiGroup.name + ''; + html += ''; + html += '
  • '; + } + } + } + return html; +} \ No newline at end of file diff --git a/authorization/src/main/resources/static/prevent/denied.html b/authorization/src/main/resources/static/prevent/denied.html new file mode 100644 index 0000000..5680867 --- /dev/null +++ b/authorization/src/main/resources/static/prevent/denied.html @@ -0,0 +1,94 @@ + + + + + + 🚫禁止访问🚫 + + + +
    +
    🚫
    +

    禁止访问

    +

    当前页面已被禁用,请联系管理员

    + 返回首页 +
    + + diff --git a/chat/.gitattributes b/chat/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/chat/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/chat/.gitignore b/chat/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/chat/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/chat/.mvn/wrapper/maven-wrapper.properties b/chat/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..44f3cf2 --- /dev/null +++ b/chat/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/chat/mvnw b/chat/mvnw new file mode 100644 index 0000000..e9cf8d3 --- /dev/null +++ b/chat/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.3 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/chat/mvnw.cmd b/chat/mvnw.cmd new file mode 100644 index 0000000..2e2dbe0 --- /dev/null +++ b/chat/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/chat/pom.xml b/chat/pom.xml new file mode 100644 index 0000000..291e4ab --- /dev/null +++ b/chat/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + + top.krcia + elysia-server + 0.0.1-SNAPSHOT + ../pom.xml + + top.krcia + chat + 0.0.1-SNAPSHOT + chat + chat + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter-web + + + com.baomidou + mybatis-plus-core + ${mybatis-plus.version} + compile + + + com.baomidou + mybatis-plus-extension + ${mybatis-plus.version} + compile + + + com.baomidou + mybatis-plus-spring-boot3-starter + ${mybatis-plus.version} + + + com.mysql + mysql-connector-j + + + top.krcia + utils + 0.0.1-SNAPSHOT + compile + + + top.krcia + result + 0.0.1-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-websocket + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/ChatApplication.java b/chat/src/main/java/top/krcia/elysiaserver/chat/ChatApplication.java new file mode 100644 index 0000000..9afb257 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/ChatApplication.java @@ -0,0 +1,17 @@ +package top.krcia.elysiaserver.chat; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@MapperScan(basePackages = {"top.krcia.elysiaserver.chat.dao"}) +public class ChatApplication{ + public static void main(String[] args) { + SpringApplication.run(ChatApplication.class, args); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/annotate/Metadata.java b/chat/src/main/java/top/krcia/elysiaserver/chat/annotate/Metadata.java new file mode 100644 index 0000000..d3367d9 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/annotate/Metadata.java @@ -0,0 +1,11 @@ +package top.krcia.elysiaserver.chat.annotate; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Metadata { +} \ No newline at end of file diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/aspect/MetadataAspect.java b/chat/src/main/java/top/krcia/elysiaserver/chat/aspect/MetadataAspect.java new file mode 100644 index 0000000..20208f6 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/aspect/MetadataAspect.java @@ -0,0 +1,121 @@ +package top.krcia.elysiaserver.chat.aspect; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; +import top.krcia.elysiaserver.chat.annotate.Metadata; +import top.krcia.elysiaserver.result.R; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Map; + +@ControllerAdvice +public class MetadataAspect implements ResponseBodyAdvice { + + @Value("${elysia-authorization.metadata-save.agent-url}") + private String agentUrl; + + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + // 对所有Controller返回值都生效 + return true; + } + + @Override + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, + Class> selectedConverterType, + org.springframework.http.server.ServerHttpRequest request, + org.springframework.http.server.ServerHttpResponse response) { + + if (body == null) return null; + + processObject(body); + + return body; + } + + private void processObject(Object obj) { + if (obj == null) return; + + Class clazz = obj.getClass(); + + // 处理 R,递归 data + if (obj instanceof R) { + Object data = ((R) obj).getData(); + processObject(data); + return; + } + + // 处理集合 + if (obj instanceof Collection) { + for (Object item : (Collection) obj) { + processObject(item); + } + return; + } + + // 处理 Map,只递归 value + if (obj instanceof Map map) { + for (Object value : map.values()) { + processObject(value); + } + return; + } + + // 基础类型 / 包装类 / String / 枚举:不递归 + if (isPrimitiveOrWrapper(clazz) || clazz.isEnum()) { + return; + } + + // 跳过 JDK 内置类,不反射它的字段 + if (isJdkClass(clazz)) { + return; + } + + // 反射处理 POJO + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + try { + field.setAccessible(true); + Object value = field.get(obj); + + // 只处理 @Metadata 的 String 字段 + if (field.isAnnotationPresent(Metadata.class) + && value instanceof String str + && !str.isEmpty() + && !str.startsWith(agentUrl)) { + field.set(obj, agentUrl + str); + } + + // 递归处理子字段 + processObject(value); + } catch (IllegalAccessException ignored) { + } + } + } + + private boolean isPrimitiveOrWrapper(Class clazz) { + return clazz.isPrimitive() + || clazz.equals(String.class) + || clazz.equals(Integer.class) + || clazz.equals(Long.class) + || clazz.equals(Boolean.class) + || clazz.equals(Double.class) + || clazz.equals(Float.class) + || clazz.equals(Short.class) + || clazz.equals(Byte.class) + || clazz.equals(Character.class); + } + + private boolean isJdkClass(Class clazz) { + String name = clazz.getName(); + return name.startsWith("java.") + || name.startsWith("javax.") + || name.startsWith("jakarta.") + || name.startsWith("sun."); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/config/AsyncConfig.java b/chat/src/main/java/top/krcia/elysiaserver/chat/config/AsyncConfig.java new file mode 100644 index 0000000..df9038a --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/config/AsyncConfig.java @@ -0,0 +1,12 @@ +package top.krcia.elysiaserver.chat.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@Configuration +@EnableAsync(proxyTargetClass = true) +@EnableScheduling + +public class AsyncConfig { +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/config/MyBatisPlusConfig.java b/chat/src/main/java/top/krcia/elysiaserver/chat/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..39f896b --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/config/MyBatisPlusConfig.java @@ -0,0 +1,28 @@ +package top.krcia.elysiaserver.chat.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.session.SqlSessionFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.List; + +@Configuration +@EnableScheduling +public class MyBatisPlusConfig { + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 新版 MP 分页插件 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); + return interceptor; + } +} \ No newline at end of file diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/config/RedisTemplateConfig.java b/chat/src/main/java/top/krcia/elysiaserver/chat/config/RedisTemplateConfig.java new file mode 100644 index 0000000..0d7e820 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/config/RedisTemplateConfig.java @@ -0,0 +1,92 @@ +package top.krcia.elysiaserver.chat.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import top.krcia.elysiaserver.utils.Kedis; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +@Configuration +public class RedisTemplateConfig { + + // 专用于 Redis 的 ObjectMapper + @Bean("redisObjectMapper") + public ObjectMapper redisObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + // Redis 序列化可以保留时间戳(根据需求调整) + objectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + return objectMapper; + } + + @Bean + public RedisTemplate redisTemplate( + RedisConnectionFactory redisConnectionFactory, + @Qualifier("redisObjectMapper") ObjectMapper redisObjectMapper) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConnectionFactory); + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(redisSerializer()); + template.setHashValueSerializer(redisSerializer()); + template.afterPropertiesSet(); + Kedis.init(template); + return template; + } + + @Bean + public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { + return builder.build(); // 自动应用 application.yml 的配置 + } + + @Bean + public RedisSerializer redisSerializer() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + // 必须设置,否则无法将JSON转化为对象,会转化成Map类型 + objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); + + // 自定义ObjectMapper的时间处理模块 + JavaTimeModule javaTimeModule = new JavaTimeModule(); + + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + + javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + + objectMapper.registerModule(javaTimeModule); + + // 禁用将日期序列化为时间戳的行为 + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + //创建JSON序列化器 + return new Jackson2JsonRedisSerializer<>(objectMapper, Object.class); + } + +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/config/WebConfig.java b/chat/src/main/java/top/krcia/elysiaserver/chat/config/WebConfig.java new file mode 100644 index 0000000..6c4527a --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/config/WebConfig.java @@ -0,0 +1,66 @@ +package top.krcia.elysiaserver.chat.config; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.resource.ResourceResolver; +import org.springframework.web.servlet.resource.ResourceResolverChain; + +import java.util.List; + +//重写WebMvcConfigurer实现全局跨域配置 +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Value("${elysia-authorization.enable-cors}") + private boolean enableCors; + @Value("${elysia-authorization.enable-api-doc}") + private boolean enableApiDoc; + + @Override + public void addCorsMappings(CorsRegistry registry) { + if (enableCors) { + registry.addMapping("/api/**") + .allowCredentials(true) + .allowedOriginPatterns("*") // 使用 allowedOriginPatterns 代替 allowedOrigins + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("*"); + registry.addMapping("/oss/**") + .allowCredentials(true) + .allowedOriginPatterns("*") // 使用 allowedOriginPatterns 代替 allowedOrigins + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("*"); + } + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + if (enableApiDoc) { + return; + } + // 屏蔽static下的某个文件夹,例如屏蔽static/private/ + registry.addResourceHandler("/doc/**") + .addResourceLocations("classpath:/static/doc/") + .resourceChain(true) + .addResolver(new ResourceResolver() { + @Override + public Resource resolveResource(HttpServletRequest request, String requestPath, List locations, ResourceResolverChain chain) { + return new ClassPathResource("static/prevent/denied.html"); + } + + @Override + public String resolveUrlPath(String resourcePath, List locations, ResourceResolverChain chain) { + return null; // 返回null表示拒绝访问 + } + }); + } + + +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/config/socket/ChatSocketAuthInterceptor.java b/chat/src/main/java/top/krcia/elysiaserver/chat/config/socket/ChatSocketAuthInterceptor.java new file mode 100644 index 0000000..07e1cda --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/config/socket/ChatSocketAuthInterceptor.java @@ -0,0 +1,56 @@ +package top.krcia.elysiaserver.chat.config.socket; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.server.HandshakeInterceptor; +import top.krcia.elysiaserver.chat.dao.SysUserDao; +import top.krcia.elysiaserver.chat.entity.pojo.SysUser; +import top.krcia.elysiaserver.utils.JWTGenerator; + +import java.net.URI; +import java.util.Map; + +@Component +@Slf4j +public class ChatSocketAuthInterceptor implements HandshakeInterceptor { + + @Resource + private SysUserDao sysUserDao; + + @Override + public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, + WebSocketHandler wsHandler, Map attributes) { + + URI uri = request.getURI(); + String query = uri.getQuery(); + String token = getQueryParam(query, "authorization"); + Long userId = JWTGenerator.getUserId(token); + SysUser sysUser = sysUserDao.selectById(userId); + if (sysUser == null) { + return false; + } + attributes.put("userId", userId); + return true; + } + + + @Override + public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { + // 握手后逻辑,通常不需要处理 + } + + // 简单解析 query 参数 + private String getQueryParam(String query, String key) { + if (query == null) return null; + String[] pairs = query.split("&"); + for (String pair : pairs) { + String[] kv = pair.split("="); + if (kv.length == 2 && kv[0].equals(key)) return kv[1]; + } + return null; + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/config/socket/WebSocketConfig.java b/chat/src/main/java/top/krcia/elysiaserver/chat/config/socket/WebSocketConfig.java new file mode 100644 index 0000000..96c3bfd --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/config/socket/WebSocketConfig.java @@ -0,0 +1,49 @@ +package top.krcia.elysiaserver.chat.config.socket; + +import jakarta.annotation.Resource; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; +import top.krcia.elysiaserver.chat.task.ChatSocketHandler; + + +@Configuration +@EnableWebSocket +@Slf4j +public class WebSocketConfig implements WebSocketConfigurer { + @Value("${server.port}") + private int port; + + @Resource + private ChatSocketHandler chatSocketHandler; + @Resource + private ChatSocketAuthInterceptor chatSocketAuthInterceptor; + + @SneakyThrows + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + // 注册原有的认证端点 + String chatUrl = String.format("/socket/chat"); + registry.addHandler(chatSocketHandler, chatUrl) + .addInterceptors(chatSocketAuthInterceptor) + .setAllowedOriginPatterns("*"); + + // 打印启动信息 + System.out.println(""" + __ __ ___ ____ _____ ___ __ __ _ ___ ______\s + | |__| | / _]| \\ / ___/ / \\ / ]| |/ ] / _]| | + | | | | / [_ | o )( \\_ | | / / | ' / / [_ | | + | | | || _]| | \\__ || O | / / | \\ | _]|_| |_| + | ` ' || [_ | O | / \\ || |/ \\_ | \\| [_ | | \s + \\ / | || | \\ || |\\ || . || | | | \s + \\_/\\_/ |_____||_____| \\___| \\___/ \\____||__|\\_||_____| |__| \s + """); + + log.info(String.format("WebSocket started on port %d (ws)", port)); + log.info(String.format("WebSocket Endpoints: [%s]", chatUrl)); + } +} \ No newline at end of file diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/controller/ChatController.java b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/ChatController.java new file mode 100644 index 0000000..046eddc --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/ChatController.java @@ -0,0 +1,102 @@ +package top.krcia.elysiaserver.chat.controller; + +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; +import top.krcia.elysiaserver.chat.controller.base.ChatBaseController; +import top.krcia.elysiaserver.chat.entity.dto.CreateRobotDto; +import top.krcia.elysiaserver.chat.entity.dto.HistoryListParam; +import top.krcia.elysiaserver.chat.entity.dto.PParamDto; +import top.krcia.elysiaserver.chat.entity.vo.ChatRoomVo; +import top.krcia.elysiaserver.chat.service.ChatService; +import top.krcia.elysiaserver.result.R; + +import java.util.List; + +/** + * 聊天管理 + */ +@RestController +public class ChatController extends ChatBaseController { + @Resource + private ChatService chatService; + /** + * 创建聊天 + * + * @param authorization + * @return + */ + @PostMapping("/create") + public R create(@RequestHeader("Authorization") String authorization, @RequestBody CreateRobotDto robotDto) { + return chatService.create(authorization, robotDto); + } + + /** + * 删除聊天 + * + * @param roomId + * @return + */ + @DeleteMapping("/del/{roomId}") + public R delete(@RequestHeader("Authorization") String authorization, @PathVariable String roomId) { + return chatService.delete(authorization, roomId); + } + + /** + * 清空聊天 + * + * @param authorization + * @param roomId + * @return + */ + @DeleteMapping("/clear/{roomId}") + public R clearRecord(@RequestHeader("Authorization") String authorization, @PathVariable String roomId) { + return chatService.clearRecord(authorization, roomId); + } + + /** + * 获取所有聊天室 + * + * @param authorization + * @return + */ + @GetMapping("/list") + public R> list(@RequestHeader("Authorization") String authorization) { + return chatService.list(authorization); + } + + /** + * 发送消息 + * + * @param authorization + * @param roomId + * @param message + * @return + */ + @PostMapping("/send/{roomId}") + public R sendMessage(@RequestHeader("Authorization") String authorization, @PathVariable String roomId, String message,String messageId) { + return chatService.sendMessage(authorization, roomId, message,messageId); + } + + /** + * 聊天消息 + * + * @param authorization + * @param roomId + * @return + */ + @GetMapping("/history/{roomId}") + public R chatRoomRecord(@RequestHeader("Authorization") String authorization, @PathVariable String roomId, PParamDto param) { + return chatService.chatRoomRecord(authorization, roomId, param); + } + /** + * 聊天消息(缓存) + * + * @param authorization + * @return + */ + @PostMapping("/history-list") + public R chatRoomRecord(@RequestHeader("Authorization") String authorization, @RequestBody List historyList) { + return chatService.chatRoomRecord(authorization,historyList); + } + +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/controller/OSSController.java b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/OSSController.java new file mode 100644 index 0000000..797dc31 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/OSSController.java @@ -0,0 +1,45 @@ +package top.krcia.elysiaserver.chat.controller; + +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.AntPathMatcher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.HandlerMapping; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.Path; + +/** + * @ignore + */ +@RequestMapping("/oss/") +@RestController +public class OSSController { + + @Value("${elysia-authorization.metadata-save.path}") + private String metadataSavePath; + + @GetMapping("/**") + public void oss(HttpServletRequest request, HttpServletResponse response) throws Exception { + response.setContentType("image/png"); + final String path = + request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString(); + final String bestMatchingPattern = + request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(); + File file = new File(Path.of(metadataSavePath, new AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path)).toString()); + try (FileInputStream in = new FileInputStream(file); + ServletOutputStream out = response.getOutputStream()) { + byte[] buffer = new byte[1024]; + int len; + while ((len = in.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + } catch (Exception e) { + } + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/controller/RobotController.java b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/RobotController.java new file mode 100644 index 0000000..d0a0c7a --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/RobotController.java @@ -0,0 +1,100 @@ +package top.krcia.elysiaserver.chat.controller; + +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; +import top.krcia.elysiaserver.chat.controller.base.RobotBaseController; +import top.krcia.elysiaserver.chat.entity.dto.RobotDto; +import top.krcia.elysiaserver.chat.entity.dto.RobotFilterDto; +import top.krcia.elysiaserver.chat.entity.vo.ExcludeVo; +import top.krcia.elysiaserver.chat.entity.vo.RobotEditorVo; +import top.krcia.elysiaserver.chat.entity.vo.RobotFollowVo; +import top.krcia.elysiaserver.chat.entity.vo.RobotVo; +import top.krcia.elysiaserver.chat.service.RobotService; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.utils.P; + +import java.util.List; + +/** + * 机器人管理 + */ +@RestController +public class RobotController extends RobotBaseController { + @Resource + private RobotService robotService; + + /** + * 创建机器人 + * + * @param robotDto + * @return + */ + @PostMapping("/create") + public R createRobot(@RequestHeader("Authorization") String authorization, RobotDto robotDto) { + return robotService.create(authorization, robotDto); + } + + /** + * 机器人列表 + * + * @param robotFilterDto + * @return + */ + @GetMapping("/list") + public R> robotList(@RequestHeader("Authorization") String authorization, RobotFilterDto robotFilterDto) { + return robotService.rebootList(authorization, robotFilterDto); + } + + /** + * 编辑机器人 + * + * @param robotDto + * @return + */ + @PostMapping("/editor/{robotId}") + public R editorRobot(@RequestHeader("Authorization") String authorization, @PathVariable Long robotId,@RequestBody RobotEditorVo robotDto) { + return robotService.editor(authorization, robotId, robotDto); + } + /** + * 删除机器人 + + * @return + */ + @DeleteMapping("/delete/{robotId}") + public R deleteRobot(@RequestHeader("Authorization") String authorization, @PathVariable Long robotId) { + return robotService.delete(authorization, robotId); + } + + /** + * 关注列表 + * + * @param authorization + * @return + */ + @GetMapping("follow-list") + public R> followList(@RequestHeader("Authorization") String authorization, @RequestParam(value = "cacheId", required = false) List cacheId) { + return robotService.followList(authorization,cacheId); + } + + /** + * 关注机器人 + * + * @param authorization + * @return + */ + @GetMapping("follow/{robotId}") + public R follow(@RequestHeader("Authorization") String authorization, @PathVariable Long robotId) { + return robotService.followOption(authorization, robotId, true); + } + + /** + * 取消关注机器人 + * + * @param authorization + * @return + */ + @GetMapping("unfollow/{robotId}") + public R followList(@RequestHeader("Authorization") String authorization, @PathVariable Long robotId) { + return robotService.followOption(authorization, robotId, false); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/controller/TemplateController.java b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/TemplateController.java new file mode 100644 index 0000000..1913ba8 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/TemplateController.java @@ -0,0 +1,28 @@ +package top.krcia.elysiaserver.chat.controller; + +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; +import top.krcia.elysiaserver.chat.controller.base.RobotBaseController; +import top.krcia.elysiaserver.chat.entity.vo.RobotTemplateVo; +import top.krcia.elysiaserver.chat.service.TemplateService; +import top.krcia.elysiaserver.result.R; + +import java.util.List; + +/** + * 回复模板 + */ +@RestController +public class TemplateController extends RobotBaseController { + @Resource + private TemplateService templateService; + + /** + * 所有模板 + * @return + */ + @GetMapping("/template") + public R> allList(){ + return templateService.allTemplate(); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/controller/base/ChatBaseController.java b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/base/ChatBaseController.java new file mode 100644 index 0000000..b799175 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/base/ChatBaseController.java @@ -0,0 +1,8 @@ +package top.krcia.elysiaserver.chat.controller.base; + +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("/chat") +public class ChatBaseController { + +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/controller/base/RobotBaseController.java b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/base/RobotBaseController.java new file mode 100644 index 0000000..608c5f4 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/controller/base/RobotBaseController.java @@ -0,0 +1,7 @@ +package top.krcia.elysiaserver.chat.controller.base; + +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("/robot") +public class RobotBaseController { +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/ChatRoomDao.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/ChatRoomDao.java new file mode 100644 index 0000000..65527fd --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/ChatRoomDao.java @@ -0,0 +1,15 @@ +package top.krcia.elysiaserver.chat.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import top.krcia.elysiaserver.chat.entity.pojo.ChatRoom; + +/** + * (ChatRoom)表数据库访问层 + * + * @author admin + * @since 2025-09-11 11:14:00 + */ +public interface ChatRoomDao extends BaseMapper { + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/ChatRoomRecordDao.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/ChatRoomRecordDao.java new file mode 100644 index 0000000..07c617f --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/ChatRoomRecordDao.java @@ -0,0 +1,53 @@ +package top.krcia.elysiaserver.chat.dao; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import org.apache.ibatis.annotations.*; +import top.krcia.elysiaserver.chat.dao.provider.ChatRoomRecordProvider; +import top.krcia.elysiaserver.chat.entity.pojo.ChatRoomRecord; + +import java.util.Date; +import java.util.List; + +/** + * (ChatRoomRecord)表数据库访问层 + * + * @author admin + * @since 2025-09-11 11:14:00 + */ +public interface ChatRoomRecordDao extends BaseMapper { + + @Update(""" + CREATE TABLE chat_room_record_${roomId} LIKE chat_room_record + """) + int createRecord(String roomId); + @Update(""" + DROP TABLE chat_room_record_${roomId} + """) + int deleteRecord(String roomId); + + @Select(""" + SELECT * FROM chat_room_record_${roomId} ORDER BY chat_date DESC limit 1 + """) + ChatRoomRecord getlastRecord(String roomId); + @Insert(""" + INSERT INTO chat_room_record_${roomId}(message_id, chat_date,`from`,message) VALUES(#{messageId},#{chatDate},#{from},#{message}) + """) + int addMessage(String messageId, String roomId, int from, String message, Date chatDate); + @Insert(""" + DELETE FROM chat_room_record_${roomId} + """) + int clearMessage(String roomId); + @SelectProvider(type = ChatRoomRecordProvider.class, method = "selectPage") + IPage selectPage(IPage page, + @Param(Constants.WRAPPER) QueryWrapper ew, + @Param("roomId") String roomId); + @Select(""" + SELECT * FROM chat_room_record_${roomId} WHERE chat_date>(SELECT chat_date FROM chat_room_record_${roomId} WHERE message_id = #{messageId}) ORDER BY chat_date DESC + """) + List selectCache(@Param("roomId") String roomId, + @Param("messageId") String messageId); +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotDao.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotDao.java new file mode 100644 index 0000000..8c5e2c0 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotDao.java @@ -0,0 +1,23 @@ +package top.krcia.elysiaserver.chat.dao; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.SelectProvider; +import top.krcia.elysiaserver.chat.dao.provider.RobotProvider; +import top.krcia.elysiaserver.chat.entity.pojo.Robot; +import top.krcia.elysiaserver.chat.entity.vo.RobotListVo; + +/** + * (Robot)表数据库访问层 + * + * @author makejava + * @since 2025-09-10 21:56:08 + */ +public interface RobotDao extends BaseMapper { + @SelectProvider(type = RobotProvider.class, method = "selectRobotWithFollow") + IPage selectRobotWithFollow(IPage page, @Param(Constants.WRAPPER) QueryWrapper ew,@Param("userId") Long userId); +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotFollowDao.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotFollowDao.java new file mode 100644 index 0000000..13b2ce5 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotFollowDao.java @@ -0,0 +1,70 @@ +package top.krcia.elysiaserver.chat.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import top.krcia.elysiaserver.chat.entity.pojo.RobotFollow; +import top.krcia.elysiaserver.chat.entity.pojo.Robot; + +import java.util.List; + +/** + * (RobotFollow)表数据库访问层 + * + * @author admin + * @since 2025-09-12 13:58:35 + */ +public interface RobotFollowDao extends BaseMapper { + @Select({ + "" + }) + List followList(@Param("user_id") Long userId, + @Param("cache_id") List cacheId); + + @Insert(""" + INSERT INTO robot_follow_${user_id}(robot_id) VALUES(#{robot_id}) + """) + int follow(@Param("user_id") Long userId, @Param("robot_id") Long robotId); + + @Delete(""" + DELETE FROM robot_follow_${user_id} WHERE robot_id =#{robot_id} + """) + int unfollow(@Param("user_id") Long userId, @Param("robot_id") Long robotId); + + @Select(""" + SELECT COUNT(1) FROM robot_follow_${user_id} WHERE robot_id =#{robot_id} + """) + Long selectCount(@Param("user_id") Long userId, @Param("robot_id") Long robotId); + @Select({ + "" + }) + List unfollowIdList(@Param("userId") Long userId, @Param("robotIds") List robotIds); +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotTemplateDao.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotTemplateDao.java new file mode 100644 index 0000000..45d158f --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/RobotTemplateDao.java @@ -0,0 +1,35 @@ +package top.krcia.elysiaserver.chat.dao; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import top.krcia.elysiaserver.chat.entity.pojo.RobotTemplate; + +/** + * (RobotTemplate)表数据库访问层 + * + * @author admin + * @since 2025-09-28 10:02:31 + */ +public interface RobotTemplateDao extends BaseMapper { + +/** +* 批量新增数据(MyBatis原生foreach方法) +* +* @param entities List 实例对象列表 +* @return 影响行数 +*/ +int insertBatch(@Param("entities") List entities); + +/** +* 批量新增或按主键更新数据(MyBatis原生foreach方法) +* +* @param entities List 实例对象列表 +* @return 影响行数 +* @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参 +*/ +int insertOrUpdateBatch(@Param("entities") List entities); + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/SysUserDao.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/SysUserDao.java new file mode 100644 index 0000000..1d81341 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/SysUserDao.java @@ -0,0 +1,32 @@ +package top.krcia.elysiaserver.chat.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import top.krcia.elysiaserver.chat.entity.pojo.SysUser; + +/** + * (SysUser)表数据库访问层 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +public interface SysUserDao extends BaseMapper { + @Select(""" + SELECT * FROM sys_user WHERE user_name=#{username} + """) + SysUser getUserByUsername(@Param("username") String username); + @Select(""" + SELECT * FROM sys_user WHERE email=#{email} + """) + SysUser getUserByEmail(@Param("email") String email); + @Select(""" + SELECT * FROM sys_user WHERE email=#{email} OR user_name=#{username} + """) + SysUser findUser(@Param("email") String email,@Param("username") String username); + @Select(""" + SELECT * FROM sys_user WHERE email=#{account} OR user_name=#{account} + """) + SysUser findUserByAccount(@Param("account") String account); +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/provider/ChatRoomRecordProvider.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/provider/ChatRoomRecordProvider.java new file mode 100644 index 0000000..4b45fc5 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/provider/ChatRoomRecordProvider.java @@ -0,0 +1,26 @@ +package top.krcia.elysiaserver.chat.dao.provider; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import org.apache.ibatis.builder.annotation.ProviderMethodResolver; +import org.apache.ibatis.jdbc.SQL; + +import java.util.Map; + +public class ChatRoomRecordProvider implements ProviderMethodResolver { + + public String selectPage(Map params) { + String roomId = (String) params.get("roomId"); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT * FROM chat_room_record_"+roomId); + // 获取QueryWrapper + Object ewObj = params.get("ew"); + if (ewObj instanceof QueryWrapper wrapper) { + String customSqlSegment = wrapper.getCustomSqlSegment(); + if (customSqlSegment != null && !customSqlSegment.isEmpty()) { + sql.append(" ").append(customSqlSegment).append(" "); + } + } + return sql.toString(); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/dao/provider/RobotProvider.java b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/provider/RobotProvider.java new file mode 100644 index 0000000..d95cef8 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/dao/provider/RobotProvider.java @@ -0,0 +1,40 @@ +package top.krcia.elysiaserver.chat.dao.provider; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + +import java.util.Map; + +public class RobotProvider { + public String selectRobotWithFollow(Map params) { + Long userId = (Long) params.get("userId"); + StringBuilder sql = new StringBuilder(); + + sql.append(""" + SELECT r.*, + CASE + WHEN EXISTS ( + SELECT 1 + FROM robot_follow_${userId} AS rf + WHERE rf.robot_id = r.robot_id + ) THEN 1 + ELSE 0 + END AS is_follow, + rt.template_name AS template, + sy.nickname AS creator_username + FROM robot AS r + LEFT JOIN robot_template AS rt + ON r.template_id=rt.template_id + LEFT JOIN sys_user AS sy + ON r.creator_id = sy.user_id + """.replace("${userId}", userId.toString())); + Object ewObj = params.get("ew"); + if (ewObj instanceof QueryWrapper wrapper) { + String customSqlSegment = wrapper.getCustomSqlSegment(); + if (customSqlSegment != null && !customSqlSegment.isEmpty()) { + sql.append(" ").append(customSqlSegment).append(" "); + } + } + + return sql.toString(); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/CreateRobotDto.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/CreateRobotDto.java new file mode 100644 index 0000000..14d3027 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/CreateRobotDto.java @@ -0,0 +1,19 @@ +package top.krcia.elysiaserver.chat.entity.dto; + +import lombok.Data; + +@Data +public class CreateRobotDto { + /** + * 房间使用引擎 + */ + private String engine; + /** + * 房间名称 + */ + private String roomName; + /** + * 机器人ID + */ + private Long robotId; +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/HistoryListParam.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/HistoryListParam.java new file mode 100644 index 0000000..6415075 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/HistoryListParam.java @@ -0,0 +1,15 @@ +package top.krcia.elysiaserver.chat.entity.dto; + +import lombok.Data; + +@Data +public class HistoryListParam { + /** + * 聊天室ID + */ + private String roomId; + /** + * 消息ID + */ + private String messageId; +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/PParamDto.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/PParamDto.java new file mode 100644 index 0000000..4e62922 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/PParamDto.java @@ -0,0 +1,17 @@ +package top.krcia.elysiaserver.chat.entity.dto; + +import lombok.Data; + +@Data +public class PParamDto { + /** + * 页面大小 + * @mock 10 + */ + private int size; + /** + * 页码 + * @mock 1 + */ + private int current; +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/RobotDto.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/RobotDto.java new file mode 100644 index 0000000..c7b87b8 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/RobotDto.java @@ -0,0 +1,45 @@ +package top.krcia.elysiaserver.chat.entity.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import java.io.Serializable; + +/** + * (Robot)表实体类 + * + * @author makejava + * @since 2025-09-10 21:56:09 + */ +@Data +public class RobotDto { + /** + * 机器人头像 + */ + private MultipartFile avatar; + /** + * 机器人名称 + */ + private String name; + /** + * 描述 + */ + private String describe; + /** + * 系统提示词 + */ + private String systemPrompt; + /** + * 是否私有 + */ + private boolean isPrivate; + /** + * 回复模板 + */ + private String templateId; + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/RobotFilterDto.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/RobotFilterDto.java new file mode 100644 index 0000000..2d3560c --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/dto/RobotFilterDto.java @@ -0,0 +1,21 @@ +package top.krcia.elysiaserver.chat.entity.dto; + +import lombok.Data; +import top.krcia.elysiaserver.chat.annotate.Metadata; + +/** + * (Robot)表实体类 + * + * @author makejava + * @since 2025-09-10 21:56:09 + */ +@Data +public class RobotFilterDto extends PParamDto { + + /** + * 是否私有,0公开,1私有 + */ + private boolean isPrivate; + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ChatRoom.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ChatRoom.java new file mode 100644 index 0000000..ae5c701 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ChatRoom.java @@ -0,0 +1,63 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; + +/** + * (ChatRoom)表实体类 + * + * @author admin + * @since 2025-09-11 11:14:00 + */ +@SuppressWarnings("serial") +@Data +public class ChatRoom extends Model { + //房间ID + @TableId + private String roomId; + //房间名称 + private String roomName; + //用户ID + private Long sysUserId; + //机器人ID + private Long robotId; + //聊天室头像 + private String roomImage; + //最后一次聊天时间 + private Date lastChatTime; + //聊天引擎 + private String engine; + + public ChatRoom(String roomId,String roomName, Long sysUserId, Long robotId, String roomImage,String engine) { + this.roomId = roomId; + this.roomName = roomName; + this.sysUserId = sysUserId; + this.robotId = robotId; + this.roomImage = roomImage; + this.engine = engine; + this.lastChatTime = null; + } + + public ChatRoom(String roomId) { + this.roomId = roomId; + } + + public ChatRoom() { + } + + /** + * 获取主键值 + * + * @return 主键值 + */ + @Override + public Serializable pkVal() { + return this.roomId; + } +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ChatRoomRecord.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ChatRoomRecord.java new file mode 100644 index 0000000..ea57afe --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ChatRoomRecord.java @@ -0,0 +1,29 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + +import java.util.Date; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +/** + * (ChatRoomRecord)表实体类 + * + * @author admin + * @since 2025-09-11 11:14:00 + */ +@SuppressWarnings("serial") +@Data +public class ChatRoomRecord extends Model { + @TableId + //消息ID + private String messageId; + //聊天时间 + private Date chatDate; + //消息所属者(0:机器人|1用户) + private Integer from; + //消息内容 + private String message; + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/DeepSeekParam.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/DeepSeekParam.java new file mode 100644 index 0000000..5a501ad --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/DeepSeekParam.java @@ -0,0 +1,55 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class DeepSeekParam { + private String model; + private List messages; + private Boolean stream = false; + private double temperature = 1.8; + + public DeepSeekParam(String model,String robotTemplate,double temperature) { + messages = new ArrayList<>(); + MessagesDTO messagesDTO = new MessagesDTO(); + messagesDTO.setRole("system"); + messagesDTO.setContent(robotTemplate); + messages.add(messagesDTO); + this.model = model; + this.temperature = temperature; + } + + public void setSystemPrompt(String systemPrompt) { + MessagesDTO messagesDTO = new MessagesDTO(); + messagesDTO.setRole("system"); + messagesDTO.setContent(systemPrompt); + messages.add(messagesDTO); + } + + public void setContent(List message, String role) { + List messagesDTOS = new ArrayList<>(); + for (ChatRoomRecord crr : message) { + MessagesDTO messagesDTO = new MessagesDTO(crr.getFrom() == 0 ? "assistant" : "user", (crr.getFrom() != 0?role+":":"")+crr.getMessage()); + messagesDTOS.add(messagesDTO); + } + messages.addAll(messagesDTOS); + } + + + @Data + public static class MessagesDTO { + private String role; + private String content; + + public MessagesDTO(String role, String content) { + this.role = role; + this.content = content; + } + + public MessagesDTO() { + } + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ReplyQueue.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ReplyQueue.java new file mode 100644 index 0000000..fe9a541 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/ReplyQueue.java @@ -0,0 +1,62 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + +import lombok.Data; + +import java.util.List; + +@Data +public class ReplyQueue { + /** + * + */ + Long userId; + /** + * 房间ID + */ + private String roomId; + /** + * 聊天内容 + */ + private List message; + /** + * APIkey + */ + private String key; + /** + * 模型 + */ + private String model; + /** + * 名称 + */ + private String name; + /** + * 头像 + */ + private String avatar; + /** + * 系统提示词 + */ + private String systemPrompt; + /** + * 回复模板 + */ + private String robotTemplate; + /** + * 温度 + */ + private double temperature; + + public ReplyQueue(Long userId,String roomId, List message, String key, String model, String name, String avatar, String systemPrompt, String robotTemplate,double temperature) { + this.userId = userId; + this.roomId = roomId; + this.message = message; + this.key = key; + this.model = model; + this.name = name; + this.avatar = avatar; + this.systemPrompt = systemPrompt; + this.robotTemplate = robotTemplate; + this.temperature = temperature; + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/Robot.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/Robot.java new file mode 100644 index 0000000..c6f16ff --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/Robot.java @@ -0,0 +1,71 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * (Robot)表实体类 + * + * @author makejava + * @since 2025-09-10 21:56:09 + */ +@SuppressWarnings("serial") +@Data +public class Robot extends Model { + //机器人ID + @TableId(type = IdType.AUTO) + private Long robotId; + //机器人头像 + private String avatar; + //机器人名称 + private String name; + //描述 + @TableField("`describe`") + private String describe; + //系统提示词 + private String systemPrompt; + //创建者 + private Long creatorId; + //是否私有,0公开,1私有 + private Integer isPrivate; + //回复模板 + private String templateId; + //创建时间 + private Date createDate; + + public Robot( String avatar, String name, String describe, String systemPrompt, Long creatorId,String templateId, Integer isPrivate) { + this.avatar = avatar; + this.name = name; + this.describe = describe; + this.systemPrompt = systemPrompt; + this.creatorId = creatorId; + this.isPrivate = isPrivate; + this.templateId = templateId; + this.createDate = new Date(); + } + + public Robot() { + } + + public Robot(Long robotId) { + this.robotId = robotId; + } + + /** + * 获取主键值 + * + * @return 主键值 + */ + @Override + public Serializable pkVal() { + return this.robotId; + } + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/RobotFollow.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/RobotFollow.java new file mode 100644 index 0000000..745cf3c --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/RobotFollow.java @@ -0,0 +1,40 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + +import com.baomidou.mybatisplus.extension.activerecord.Model; + +/** + * (RobotFollow)表实体类 + * + * @author admin + * @since 2025-09-12 13:58:35 + */ +@SuppressWarnings("serial") +public class RobotFollow extends Model { +//用户列表 + private Long userId; +//机器人列表 + private Long robotId; + + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getRobotId() { + return robotId; + } + + public void setRobotId(Long robotId) { + this.robotId = robotId; + } + + public RobotFollow(Long userId, Long robotId) { + this.userId = userId; + this.robotId = robotId; + } +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/RobotTemplate.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/RobotTemplate.java new file mode 100644 index 0000000..da7734b --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/RobotTemplate.java @@ -0,0 +1,61 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * (RobotTemplate)表实体类 + * + * @author admin + * @since 2025-09-28 10:02:31 + */ +@SuppressWarnings("serial") +@Data +public class RobotTemplate extends Model { + //模板ID + @TableId + private String templateId; + //模板名称 + private String templateName; + //模板内容 + private String content; + //创建时间 + private Date createTime; + //创建者ID + private Long creatorId; + //示例 + private String example; + //温度 + private Double temperature; + + /** + * 获取主键值 + * + * @return 主键值 + */ + @Override + public Serializable pkVal() { + return this.templateId; + } + + public RobotTemplate() { + } + + public RobotTemplate(String templateId, String templateName, String content, Long creatorId,String example) { + this.templateId = templateId; + this.templateName = templateName; + this.content = content; + this.creatorId = creatorId; + this.example = example; + } + + public RobotTemplate(String templateId) { + this.templateId = templateId; + } +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/SysUser.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/SysUser.java new file mode 100644 index 0000000..3abfba2 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/pojo/SysUser.java @@ -0,0 +1,73 @@ +package top.krcia.elysiaserver.chat.entity.pojo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * (SysUser)表实体类 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +@SuppressWarnings("serial") +@Data +public class SysUser extends Model { + //用户ID + @TableId(type = IdType.AUTO) + private Long userId; + //头像 + private String avatar; + //姓名 + private String name; + //昵称 + private String nickname; + //用户名 + private String userName; + //密码 + private String password; + //状态:0启用,1禁用,-1删除 + private Integer status; + //状态时间 + private Date statusTime; + //状态时间 + private String email; + //创建时间 + private Date createTime; + //DeepseekApi + private String deepseekKey; + + /** + * 获取主键值 + * + * @return 主键值 + */ + @Override + public Serializable pkVal() { + return this.userId; + } + + public SysUser(String avatar, String name, String nickname, String userName, String password, String email) { + this.avatar = avatar; + this.name = name; + this.nickname = nickname; + this.userName = userName; + this.password = password; + this.status = 0; + this.statusTime = new Date(); + this.email = email; + this.createTime = new Date(); + } + + public SysUser(Long userId) { + this.userId = userId; + } + + public SysUser() { + } +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ChatRecordVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ChatRecordVo.java new file mode 100644 index 0000000..644eb6c --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ChatRecordVo.java @@ -0,0 +1,35 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.util.Date; + +/** + * (ChatRoomRecord)表实体类 + * + * @author admin + * @since 2025-09-11 11:14:00 + */ +@SuppressWarnings("serial") +@Data +public class ChatRecordVo extends Model { + //消息ID + private String messageId; + //聊天时间 + private Date chatDate; + //消息所属者(0:机器人|1用户) + private Integer from; + //消息内容 + private String message; + + public ChatRecordVo(String messageId,Date chatDate, Integer from, String message) { + this.messageId = messageId; + this.chatDate = chatDate; + this.from = from; + this.message = message; + + } +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ChatRoomVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ChatRoomVo.java new file mode 100644 index 0000000..52dbe7b --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ChatRoomVo.java @@ -0,0 +1,50 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import top.krcia.elysiaserver.chat.annotate.Metadata; + +import java.io.Serializable; +import java.util.Date; + +/** + * (ChatRoom)表实体类 + * + * @author admin + * @since 2025-09-11 11:14:00 + */ +@Data +public class ChatRoomVo{ + /** + * 房间ID + */ + private String roomId; + /** + * 房间名称 + */ + private String roomName; + /** + * 聊天室名称 + */ + private String title; + /** + * 聊天室头像 + */ + @Metadata + private String roomImage; + /** + * 最后一次聊天时间 + */ + private Date lastChatTime; + /** + * 最后一次聊天消息 + */ + private String lastChatMessage; + /** + *房间使用引擎 + */ + private String engine; + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ExcludeVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ExcludeVo.java new file mode 100644 index 0000000..c4dd8e3 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/ExcludeVo.java @@ -0,0 +1,11 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class ExcludeVo { + private List excludeIdList; + private List data; +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/HistoryVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/HistoryVo.java new file mode 100644 index 0000000..8f7a915 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/HistoryVo.java @@ -0,0 +1,15 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import lombok.Data; +import top.krcia.elysiaserver.chat.entity.pojo.ChatRoomRecord; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Data +public class HistoryVo extends HashMap> { + public void add(String roomId, List chatRoomRecord) { + super.put(roomId, chatRoomRecord); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotEditorVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotEditorVo.java new file mode 100644 index 0000000..558f189 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotEditorVo.java @@ -0,0 +1,23 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import lombok.Data; +import top.krcia.elysiaserver.chat.annotate.Metadata; + +/** + * (Robot)表实体类 + * + * @author makejava + * @since 2025-09-10 21:56:09 + */ +@Data +public class RobotEditorVo { + /** + * 系统提示词 + */ + private String systemPrompt; + /** + * 是否私有 + */ + private boolean isPrivate; +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotFollowVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotFollowVo.java new file mode 100644 index 0000000..fa8309c --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotFollowVo.java @@ -0,0 +1,49 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import lombok.Data; +import top.krcia.elysiaserver.chat.annotate.Metadata; + +/** + * (Robot)表实体类 + * + * @author makejava + * @since 2025-09-10 21:56:09 + */ +@Data +public class RobotFollowVo { + /** + * 机器人ID + */ + private Long robotId; + + /** + * 机器人头像 + */ + @Metadata + private String avatar; + /** + * 机器人名称 + */ + private String name; + + /** + * 简介 + */ + private String describe; + + /** + * 简介 + */ + private String systemPrompt; + /** + * 是否私有,0公开,1私有 + */ + private boolean isPrivate; + + /** + * 是否为创建者 + */ + private boolean isCreator; + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotListVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotListVo.java new file mode 100644 index 0000000..7345966 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotListVo.java @@ -0,0 +1,61 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * (Robot)表实体类 + * + * @author makejava + * @since 2025-09-10 21:56:09 + */ +@SuppressWarnings("serial") +@Data +public class RobotListVo extends Model { + //机器人ID + @TableId(type = IdType.AUTO) + private Long robotId; + //机器人头像 + private String avatar; + //机器人名称 + private String name; + //描述 + @TableField("`describe`") + private String describe; + //系统提示词 + private String systemPrompt; + //创建者 + private Long creatorId; + //是否私有,0公开,1私有 + private Integer isPrivate; + //创建者名称 + private String creatorUsername; + //回复模板 + private String template; + //创建时间 + private Date createDate; + //是否关注 + private boolean isFollow; + + public RobotListVo(Long robotId) { + this.robotId = robotId; + } + + /** + * 获取主键值 + * + * @return 主键值 + */ + @Override + public Serializable pkVal() { + return this.robotId; + } + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotTemplateVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotTemplateVo.java new file mode 100644 index 0000000..8fe9c20 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotTemplateVo.java @@ -0,0 +1,27 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import lombok.Data; + + +/** + * (RobotTemplate)表实体类 + * + * @author admin + * @since 2025-09-28 10:02:31 + */ +@Data +public class RobotTemplateVo{ + /** + * 模板ID + */ + private String templateId; + /** + * 模板名称 + */ + private String templateName; + /** + * 示例 + */ + private String example; +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotVo.java new file mode 100644 index 0000000..4ce2ba0 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/RobotVo.java @@ -0,0 +1,68 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import top.krcia.elysiaserver.chat.annotate.Metadata; + +import java.io.Serializable; + +/** + * (Robot)表实体类 + * + * @author makejava + * @since 2025-09-10 21:56:09 + */ +@Data +public class RobotVo { + + /** + * 机器人ID + */ + + private Long robotId; + /** + * 机器人头像 + */ + @Metadata + private String avatar; + /** + * 机器人名称 + */ + private String name; + /** + * 描述 + */ + private String describe; + /** + * 系统提示词 + */ + private String systemPrompt; + /** + * 是否已关注 + */ + private boolean follow; + /** + * 创建者 + */ + private Long creatorId; + /** + * 创建者名称 + */ + private String creatorUsername; + /** + * 回复模板 + */ + private String template; + /** + * 是否私有,0公开,1私有 + */ + private boolean isPrivate; + + public void setIsPrivate(Integer isPrivate) { + this.isPrivate = isPrivate == 1; + } +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/WsChatVo.java b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/WsChatVo.java new file mode 100644 index 0000000..cfbe36b --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/entity/vo/WsChatVo.java @@ -0,0 +1,41 @@ +package top.krcia.elysiaserver.chat.entity.vo; + +import lombok.Data; + +/** + * (ChatRoom)表实体类 + * + * @author admin + * @since 2025-09-11 11:14:00 + */ +@Data +public class WsChatVo { + //房间ID + private String roomId; + //名称 + private String name; + //头像 + private String avatar; + + private String messageId; + //语言 + private String content; + + + public WsChatVo(String roomId, String name, String avatar,String messageId, String content) { + this.roomId = roomId; + this.name = name; + this.avatar = avatar; + this.messageId = messageId; + this.content = content; + } + + public WsChatVo(String roomId) { + this.roomId = roomId; + } + + public WsChatVo() { + } + +} + diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/service/ChatService.java b/chat/src/main/java/top/krcia/elysiaserver/chat/service/ChatService.java new file mode 100644 index 0000000..905bc62 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/service/ChatService.java @@ -0,0 +1,19 @@ +package top.krcia.elysiaserver.chat.service; + +import top.krcia.elysiaserver.chat.entity.dto.CreateRobotDto; +import top.krcia.elysiaserver.chat.entity.dto.HistoryListParam; +import top.krcia.elysiaserver.chat.entity.dto.PParamDto; +import top.krcia.elysiaserver.chat.entity.vo.ChatRoomVo; +import top.krcia.elysiaserver.result.R; + +import java.util.List; + +public interface ChatService { + public R create(String authorization, CreateRobotDto robotDto); + public R delete(String authorization,String roomId); + public R sendMessage(String authorization,String roomId,String message,String messageId); + public R chatRoomRecord(String authorization, String roomId, PParamDto param); + public R chatRoomRecord(String authorization, List historyList); + public R clearRecord(String authorization, String roomId); + public R> list(String authorization); +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/service/RobotService.java b/chat/src/main/java/top/krcia/elysiaserver/chat/service/RobotService.java new file mode 100644 index 0000000..46f0ab0 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/service/RobotService.java @@ -0,0 +1,21 @@ +package top.krcia.elysiaserver.chat.service; + +import top.krcia.elysiaserver.chat.entity.dto.RobotDto; +import top.krcia.elysiaserver.chat.entity.dto.RobotFilterDto; +import top.krcia.elysiaserver.chat.entity.vo.ExcludeVo; +import top.krcia.elysiaserver.chat.entity.vo.RobotEditorVo; +import top.krcia.elysiaserver.chat.entity.vo.RobotFollowVo; +import top.krcia.elysiaserver.chat.entity.vo.RobotVo; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.utils.P; + +import java.util.List; + +public interface RobotService { + R create(String authorization, RobotDto robotDto); + R editor(String authorization,Long robotId, RobotEditorVo robotDto); + R delete(String authorization,Long robotId); + R> rebootList(String authorization,RobotFilterDto robotFilterDto); + R> followList(String authorization, List cacheId); + R> followOption(String authorization,Long robotId,boolean follow); +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/service/TemplateService.java b/chat/src/main/java/top/krcia/elysiaserver/chat/service/TemplateService.java new file mode 100644 index 0000000..58d142e --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/service/TemplateService.java @@ -0,0 +1,10 @@ +package top.krcia.elysiaserver.chat.service; + +import top.krcia.elysiaserver.chat.entity.vo.RobotTemplateVo; +import top.krcia.elysiaserver.result.R; + +import java.util.List; + +public interface TemplateService { + R> allTemplate(); +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/ChatServiceImpl.java b/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/ChatServiceImpl.java new file mode 100644 index 0000000..2baa9ce --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/ChatServiceImpl.java @@ -0,0 +1,179 @@ +package top.krcia.elysiaserver.chat.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import top.krcia.elysiaserver.chat.dao.*; +import top.krcia.elysiaserver.chat.entity.dto.CreateRobotDto; +import top.krcia.elysiaserver.chat.entity.dto.HistoryListParam; +import top.krcia.elysiaserver.chat.entity.dto.PParamDto; +import top.krcia.elysiaserver.chat.entity.pojo.*; +import top.krcia.elysiaserver.chat.entity.vo.ChatRecordVo; +import top.krcia.elysiaserver.chat.entity.vo.ChatRoomVo; +import top.krcia.elysiaserver.chat.entity.vo.HistoryVo; +import top.krcia.elysiaserver.chat.service.ChatService; +import top.krcia.elysiaserver.chat.task.RobotReplyTask; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.result.RS; +import top.krcia.elysiaserver.utils.JWTGenerator; +import top.krcia.elysiaserver.utils.P; +import top.krcia.elysiaserver.utils.U; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Service +public class ChatServiceImpl implements ChatService { + + @Value("${elysia-authorization.metadata-save.agent-url}") + private String agentUrl; + @Resource + private ChatRoomDao chatRoomDao; + @Resource + private ChatRoomRecordDao chatRoomRecordDao; + @Resource + private RobotDao robotDao; + @Resource + private SysUserDao sysUserDao; + @Resource + private RobotTemplateDao robotTemplateDao; + @Resource + private RobotReplyTask robotReplyTask; + + @Override + @Transactional(rollbackFor = Exception.class) + public R create(String authorization, CreateRobotDto robotDto) { + Long userId = JWTGenerator.getUserId(authorization); + String uid = U.get(); + Robot robot = new Robot(robotDto.getRobotId()); + robot = robotDao.selectById(robot); + ChatRoom chatRoom = new ChatRoom(uid, robotDto.getRoomName(), userId, robotDto.getRobotId(), robot.getAvatar(), robotDto.getEngine()); + chatRoomDao.insert(chatRoom); + chatRoomRecordDao.createRecord(uid); + return R.success(uid); + } + + @Override + public R delete(String authorization, String roomId) { + Long userId = JWTGenerator.getUserId(authorization); + ChatRoom chatRoom = new ChatRoom(roomId); + chatRoom = chatRoomDao.selectById(chatRoom); + if (chatRoom.getSysUserId().longValue() != userId.longValue()) { + return R.print(RS.NOT_FIND_JURISDICTION_DO); + } + chatRoomDao.deleteById(chatRoom); + chatRoomRecordDao.deleteRecord(chatRoom.getRoomId()); + return R.success(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public R sendMessage(String authorization, String roomId, String message,String messageId) { + Long userId = JWTGenerator.getUserId(authorization); + ChatRoom chatRoom = new ChatRoom(roomId); + chatRoom = chatRoomDao.selectById(chatRoom); + if (chatRoom.getSysUserId().longValue() != userId.longValue()) { + return R.print(RS.NOT_FIND_JURISDICTION_DO); + } + Robot robot = new Robot(chatRoom.getRobotId()); + robot = robotDao.selectById(robot); + chatRoomRecordDao.addMessage(messageId, chatRoom.getRoomId(), 1, message, new Date()); + IPage iPage = new Page(); + iPage.setCurrent(1); + iPage.setSize(100); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc("chat_date"); + iPage = chatRoomRecordDao.selectPage(iPage, queryWrapper, roomId); + SysUser sysUser = new SysUser(userId); + sysUser = sysUserDao.selectById(sysUser); + RobotTemplate robotTemplate = robotTemplateDao.selectById(new RobotTemplate(robot.getTemplateId())); + ReplyQueue replyQueue = new ReplyQueue(sysUser.getUserId(), roomId, iPage.getRecords(), sysUser.getDeepseekKey(), chatRoom.getEngine(), chatRoom.getRoomName(), agentUrl + chatRoom.getRoomImage(), robot.getSystemPrompt(), robotTemplate.getContent(), robotTemplate.getTemperature()); + robotReplyTask.addTask(replyQueue); + chatRoom.setLastChatTime(new Date()); + chatRoomDao.updateById(chatRoom); + return R.success(); + } + + @Override + public R chatRoomRecord(String authorization, String roomId, PParamDto param) { + Long userId = JWTGenerator.getUserId(authorization); + ChatRoom chatRoom = new ChatRoom(roomId); + chatRoom = chatRoomDao.selectById(chatRoom); + if (chatRoom.getSysUserId().longValue() != userId.longValue()) { + return R.print(RS.NOT_FIND_JURISDICTION_DO); + } + IPage iPage = new Page(); + iPage.setCurrent(param.getCurrent()); + iPage.setSize(param.getSize()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("chat_date"); + iPage = chatRoomRecordDao.selectPage(iPage, queryWrapper, roomId); + P result = new P<>(iPage.getCurrent(), iPage.getSize(), iPage.getTotal()); + List l = new ArrayList<>(); + for (ChatRoomRecord crr : iPage.getRecords()) { + l.add(new ChatRecordVo(crr.getMessageId(), crr.getChatDate(), crr.getFrom(), crr.getMessage())); + } + result.setResult(l); + return R.success(result); + } + + @Override + public R chatRoomRecord(String authorization, List historyList) { + Long userId = JWTGenerator.getUserId(authorization); + HistoryVo historyVo = new HistoryVo(); + for (HistoryListParam hlp : historyList){ + ChatRoom chatRoom = new ChatRoom(hlp.getRoomId()); + chatRoom = chatRoomDao.selectById(chatRoom); + if (chatRoom.getSysUserId().longValue() != userId.longValue()) { + return R.print(RS.NOT_FIND_JURISDICTION_DO); + } + List data = chatRoomRecordDao.selectCache(hlp.getRoomId(), hlp.getMessageId()); + historyVo.add(hlp.getRoomId(),data); + } + return R.success(historyVo); + } + + @Override + public R clearRecord(String authorization, String roomId) { + Long userId = JWTGenerator.getUserId(authorization); + ChatRoom chatRoom = new ChatRoom(roomId); + chatRoom = chatRoomDao.selectById(chatRoom); + if (chatRoom.getSysUserId().longValue() != userId.longValue()) { + return R.print(RS.NOT_FIND_JURISDICTION_DO); + } + chatRoomRecordDao.clearMessage(roomId); + return R.success(); + } + + @Override + public R> list(String authorization) { + Long userId = JWTGenerator.getUserId(authorization); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("sys_user_id", userId); + queryWrapper.orderByDesc("last_chat_time"); + List chatRoomList = chatRoomDao.selectList(queryWrapper); + List list = new ArrayList<>(); + for (ChatRoom chatRoom : chatRoomList) { + ChatRoomVo crv = new ChatRoomVo(); + BeanUtils.copyProperties(chatRoom, crv); + ChatRoomRecord chatRoomRecord = chatRoomRecordDao.getlastRecord(chatRoom.getRoomId()); + if (chatRoomRecord != null) { + if (chatRoomRecord.getFrom().intValue() == 0) { + crv.setLastChatMessage(chatRoomRecord.getMessage()); + } else { + crv.setLastChatMessage(chatRoomRecord.getMessage()); + } + + } + list.add(crv); + } + return R.success(list); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/RobotServiceImpl.java b/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/RobotServiceImpl.java new file mode 100644 index 0000000..6ba17f0 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/RobotServiceImpl.java @@ -0,0 +1,144 @@ +package top.krcia.elysiaserver.chat.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import top.krcia.elysiaserver.chat.dao.RobotDao; +import top.krcia.elysiaserver.chat.dao.RobotFollowDao; +import top.krcia.elysiaserver.chat.dao.SysUserDao; +import top.krcia.elysiaserver.chat.entity.dto.RobotDto; +import top.krcia.elysiaserver.chat.entity.dto.RobotFilterDto; +import top.krcia.elysiaserver.chat.entity.pojo.Robot; +import top.krcia.elysiaserver.chat.entity.pojo.SysUser; +import top.krcia.elysiaserver.chat.entity.vo.*; +import top.krcia.elysiaserver.chat.service.RobotService; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.result.RS; +import top.krcia.elysiaserver.utils.FileUtil; +import top.krcia.elysiaserver.utils.JWTGenerator; +import top.krcia.elysiaserver.utils.P; +import top.krcia.elysiaserver.utils.U; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +@Service +public class RobotServiceImpl implements RobotService{ + + @Resource + private SysUserDao sysUserDao; + @Resource + private RobotDao robotDao; + @Resource + private RobotFollowDao robotFollowDao; + @Value("${elysia-authorization.metadata-save.path}") + private String path; + + @Override + public R create(String authorization, RobotDto robotDto) { + Long userId = JWTGenerator.getUserId(authorization); + SysUser sysUser = new SysUser(userId); + sysUser = sysUserDao.selectById(sysUser); + String aId = U.get(); + String data = FileUtil.upLoad(robotDto.getAvatar(), aId, Path.of(path, "avatar").toString()); + if (data.equals("ERROR")) { + return R.print(RS.FILE_UPLOAD_ERROR); + } + Robot robot = new Robot("/avatar/" + data, robotDto.getName(), robotDto.getDescribe(), robotDto.getSystemPrompt(), sysUser.getUserId(),robotDto.getTemplateId(), robotDto.isPrivate() ? 1 : 0); + int i = robotDao.insert(robot); + robotFollowDao.follow(userId, robot.getRobotId()); + return i > 0 ? R.success() : R.printFormat(RS.DB_CREATE, "请重试"); + } + + @Override + public R editor(String authorization, Long robotId, RobotEditorVo robotDto) { + Long userId = JWTGenerator.getUserId(authorization); + + Robot robot = new Robot(robotId); + robot = robotDao.selectById(robot); + if (robot == null || robot.getCreatorId().longValue() != userId.longValue()) { + return R.print(RS.NOT_FIND_JURISDICTION_DO); + } + + BeanUtils.copyProperties(robotDto, robot); + robot.setRobotId(robotId); + robot.setIsPrivate(robotDto.isPrivate()?1:0); + int i = robotDao.updateById(robot); + return i > 0 ? R.success() : R.print(RS.MODIFY_FAIL); + } + + @Override + public R delete(String authorization, Long robotId) { + Long userId = JWTGenerator.getUserId(authorization); + UpdateWrapper updateWrapper = new UpdateWrapper(); + updateWrapper.set("status",1); + updateWrapper.eq("robot_id",robotId); + updateWrapper.eq("creator_id",userId); + int i= robotDao.update(updateWrapper); + if (i>0){ + return R.success(); + } + return R.print(RS.NOT_FIND_JURISDICTION_DO); + } + + @Override + public R> rebootList(String authorization, RobotFilterDto robotFilterDto) { + Long userId = JWTGenerator.getUserId(authorization); + IPage page = new Page<>(); + page.setSize(robotFilterDto.getSize()); + page.setCurrent(robotFilterDto.getCurrent()); + QueryWrapper queryWrapper = new QueryWrapper(); + if (robotFilterDto.isPrivate()) { + queryWrapper.eq("r.creator_id", userId); + } else { + queryWrapper.eq("r.is_private", 0); + } + queryWrapper.eq("r.status",0); + page = robotDao.selectRobotWithFollow(page, queryWrapper, userId); + P resPage = new P<>(page, RobotVo.class); + return R.success(resPage); + } + + @Override + public R> followList(String authorization, List cacheId) { + Long userId = JWTGenerator.getUserId(authorization); + ExcludeVo excludeVo = new ExcludeVo(); + if (cacheId!=null&&cacheId.size()!=0){ + excludeVo.setExcludeIdList(robotFollowDao.unfollowIdList(userId, cacheId)); + } + List robotList = robotFollowDao.followList(userId, cacheId); + List robotFollowVos = new ArrayList<>(); + for (Robot rt : robotList) { + RobotFollowVo rfv = new RobotFollowVo(); + BeanUtils.copyProperties(rt, rfv); + rfv.setCreator(rt.getCreatorId().longValue() == userId.longValue()); + robotFollowVos.add(rfv); + } + excludeVo.setData(robotFollowVos); + return R.success(excludeVo); + } + + @Override + public R> followOption(String authorization, Long robotId, boolean follow) { + Long userId = JWTGenerator.getUserId(authorization); + Long i = robotFollowDao.selectCount(userId, robotId); + if (follow) { + if (i > 0) { + return R.success(); + } + robotFollowDao.follow(userId, robotId); + } else { + if (i > 0) { + robotFollowDao.unfollow(userId, robotId); + } + + } + return R.success(); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/TemplateServiceImpl.java b/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/TemplateServiceImpl.java new file mode 100644 index 0000000..2efe433 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/service/impl/TemplateServiceImpl.java @@ -0,0 +1,29 @@ +package top.krcia.elysiaserver.chat.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import top.krcia.elysiaserver.chat.dao.RobotTemplateDao; +import top.krcia.elysiaserver.chat.entity.pojo.RobotTemplate; +import top.krcia.elysiaserver.chat.entity.vo.RobotTemplateVo; +import top.krcia.elysiaserver.chat.service.TemplateService; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.utils.L; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class TemplateServiceImpl implements TemplateService { + @Resource + private RobotTemplateDao robotTemplateDao; + @Override + public R> allTemplate() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("create_time"); + List list = robotTemplateDao.selectList(queryWrapper); + List res = new ArrayList<>(); + L.copyProperties(list,res,RobotTemplateVo.class); + return R.success(res); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/task/ChatSocketHandler.java b/chat/src/main/java/top/krcia/elysiaserver/chat/task/ChatSocketHandler.java new file mode 100644 index 0000000..9c8bdbb --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/task/ChatSocketHandler.java @@ -0,0 +1,150 @@ +package top.krcia.elysiaserver.chat.task; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +@Component +@Slf4j +public class ChatSocketHandler extends TextWebSocketHandler { + private final Map sessions = new ConcurrentHashMap<>(); + private final ObjectMapper objectMapper = new ObjectMapper(); + + private Map offlineMessage = new HashMap<>(); + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + Long userId = (Long) session.getAttributes().get("userId"); + sessions.put(userId, session); +// 上线发送最近一条消息 + if (offlineMessage.containsKey(userId)) { + sendDelayedMessage(session, offlineMessage.get(userId), 15); + try { + offlineMessage.remove(userId); + } catch (Exception e) { + log.error("移除离线消息失败: {}", e.getMessage()); + } + } + } + + @Override + public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + String payload = message.getPayload(); + log.info("收到消息: " + payload); + + // 简单解析 JSON + Map data = objectMapper.readValue(payload, Map.class); + String type = (String) data.get("type"); + + if ("ping".equals(type)) { + // 收到 ping,回 pong + session.sendMessage(new TextMessage("{\"type\":\"pong\"}")); + } else { + // 处理普通消息 + session.sendMessage(new TextMessage("Echo: " + payload)); + } + } + + @Override + public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { + System.err.println("用户 " + session.getAttributes().get("userId") + " 连接出错: " + exception.getMessage()); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { + Long userId = (Long) session.getAttributes().get("userId"); + sessions.remove(userId); + log.info("用户 " + userId + " 已断开,原因: " + closeStatus.getReason() + ",当前连接数:" + sessions.size()); + } + + @Override + public boolean supportsPartialMessages() { + return false; + } + + public void sendMessage(Long id, String message) throws IOException { + WebSocketSession session = sessions.get(id); + if (session != null) { + session.sendMessage(new TextMessage(message)); + } else { + try { + offlineMessage.remove(id); + } catch (Exception e) { + } + offlineMessage.put(id, message); + } + } + + public void sendMessageMultiple(List ids, String message) throws IOException { + for (Long id : ids) { + sendMessage(id, message); + } + } + + @Async + public CompletableFuture sendDelayedMessage(WebSocketSession session, String message, int delaySeconds) { + return CompletableFuture.runAsync(() -> { + try { + // 延迟执行 + TimeUnit.SECONDS.sleep(delaySeconds); + + // 检查会话是否仍然有效 + if (session.isOpen()) { + session.sendMessage(new TextMessage(message)); + log.info("延迟{}秒发送消息成功: {}", delaySeconds, message); + } else { + log.warn("会话已关闭,取消发送延迟消息"); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("延迟发送消息被中断: {}", e.getMessage()); + } catch (IOException e) { + log.error("延迟发送消息失败: {}", e.getMessage()); + } + }); + } + + /** + * 延迟发送消息给指定用户ID + * + * @param userId 用户ID + * @param message 消息内容 + * @param delaySeconds 延迟秒数 + */ + @Async + public CompletableFuture sendDelayedMessageToUser(Long userId, String message, int delaySeconds) { + return CompletableFuture.runAsync(() -> { + try { + TimeUnit.SECONDS.sleep(delaySeconds); + + WebSocketSession session = sessions.get(userId); + if (session != null && session.isOpen()) { + session.sendMessage(new TextMessage(message)); + log.info("延迟{}秒发送消息给用户{}成功: {}", delaySeconds, userId, message); + } else { + log.warn("用户{}的会话不存在或已关闭,取消发送延迟消息", userId); + // 可以选择存储为离线消息 + offlineMessage.put(userId, message); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("延迟发送消息被中断: {}", e.getMessage()); + } catch (IOException e) { + log.error("延迟发送消息失败: {}", e.getMessage()); + } + }); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/task/RobotReplyTask.java b/chat/src/main/java/top/krcia/elysiaserver/chat/task/RobotReplyTask.java new file mode 100644 index 0000000..bb7a633 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/task/RobotReplyTask.java @@ -0,0 +1,78 @@ +package top.krcia.elysiaserver.chat.task; + +import com.alibaba.fastjson2.JSON; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; +import top.krcia.elysiaserver.chat.dao.ChatRoomDao; +import top.krcia.elysiaserver.chat.dao.ChatRoomRecordDao; +import top.krcia.elysiaserver.chat.entity.pojo.ChatRoom; +import top.krcia.elysiaserver.chat.entity.pojo.DeepSeekParam; +import top.krcia.elysiaserver.chat.entity.pojo.ReplyQueue; +import top.krcia.elysiaserver.chat.entity.vo.WsChatVo; +import top.krcia.elysiaserver.utils.C; +import top.krcia.elysiaserver.utils.U; +import top.krcia.elysiaserver.utils.request.WebRequest; +import top.krcia.elysiaserver.utils.request.enums.RequestType; + +import java.net.URI; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +@Component +public class RobotReplyTask { + private final BlockingQueue queue = new LinkedBlockingQueue<>(); + private final ExecutorService executor = Executors.newFixedThreadPool(20); + @Resource + private ChatRoomRecordDao chatRoomRecordDao; + @Resource + private ChatRoomDao chatRoomDao; + @Resource + private ChatSocketHandler chatSocketHandler; + + @PostConstruct + private void init() { + for (int i = 0; i < 20; i++) { + executor.submit(this::worker); + } + } + + // 添加任务 + public void addTask(ReplyQueue replyQueue) { + queue.offer(replyQueue); + } + + private void worker() { + while (true) { + try { + ReplyQueue replyQueue = queue.take(); // 阻塞取任务 + DeepSeekParam deepSeekParam = new DeepSeekParam(replyQueue.getModel(),replyQueue.getRobotTemplate(),replyQueue.getTemperature()); + deepSeekParam.setSystemPrompt(replyQueue.getSystemPrompt()); + deepSeekParam.setContent(replyQueue.getMessage(), "[user]"); + Map header = new HashMap<>(); + header.put("Authorization", "Bearer ".concat(replyQueue.getKey())); + String result = WebRequest.Create(new URI(C.URL_DEEPSEEK)).setBody(JSON.parseObject(JSON.toJSONString(deepSeekParam))).setHeader(header).setRequestType(RequestType.POST).execute(); + String content = JSON.parseObject(result).getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content"); + String messageId =U.getShort(); + chatRoomRecordDao.addMessage(messageId,replyQueue.getRoomId(), 0, content, new Date()); + WsChatVo wsChatVo = new WsChatVo(replyQueue.getRoomId(), replyQueue.getName(), replyQueue.getAvatar(),messageId, content); + ChatRoom chatRoom = new ChatRoom(replyQueue.getRoomId()); + chatRoom = chatRoomDao.selectById(chatRoom); + chatRoom.setLastChatTime(new Date()); + chatRoomDao.updateById(chatRoom); + chatSocketHandler.sendMessage(replyQueue.getUserId(), JSON.toJSONString(wsChatVo)); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/utils/Voice.java b/chat/src/main/java/top/krcia/elysiaserver/chat/utils/Voice.java new file mode 100644 index 0000000..b18b4dd --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/utils/Voice.java @@ -0,0 +1,36 @@ +package top.krcia.elysiaserver.chat.utils; + +import org.springframework.http.MediaType; +import top.krcia.elysiaserver.utils.request.WebRequest; +import top.krcia.elysiaserver.utils.request.bean.HttpFile; +import top.krcia.elysiaserver.utils.request.enums.RequestType; + +import java.net.URI; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Voice { + final static URI url = URI.create("http://krcia.top:3200/api/v1/tts/generateJson"); + + public static void generate() throws Exception { + Map data =new HashMap<>(){{put("data",generateParam());}}; + HttpFile res = WebRequest.Create(url) + .setContentType(MediaType.APPLICATION_JSON) + .setBody(data) + .setRequestType(RequestType.POST) + .executeFile(); + res.saveAs(Path.of("C:\\Users\\Administrator\\Downloads\\logcat","text.mp3")); + } + static List generateParam(){ + List param = new ArrayList<>(); + param.add(VoiceBean.generate("徐凤年","如果你敢动他,我会穷尽一生毁掉卢家,说到做到","zh-CN-YunjianNeural","0%","0Hz","40%")); + return param; + } + + public static void main(String[] args) throws Exception { + generate(); + } +} diff --git a/chat/src/main/java/top/krcia/elysiaserver/chat/utils/VoiceBean.java b/chat/src/main/java/top/krcia/elysiaserver/chat/utils/VoiceBean.java new file mode 100644 index 0000000..552b4e8 --- /dev/null +++ b/chat/src/main/java/top/krcia/elysiaserver/chat/utils/VoiceBean.java @@ -0,0 +1,29 @@ +package top.krcia.elysiaserver.chat.utils; + +import lombok.Data; + +@Data +public class VoiceBean { + private String desc; + private String text; + private String voice; + private String rate; + private String pitch; + private String volume; + + public VoiceBean(String desc, String text, String voice, String rate, String pitch, String volume) { + this.desc = desc; + this.text = text; + this.voice = voice; + this.rate = rate; + this.pitch = pitch; + this.volume = volume; + } + + public VoiceBean() { + } + + static VoiceBean generate(String desc, String text, String voice, String rate, String pitch, String volume) { + return new VoiceBean(desc, text, voice, rate, pitch, volume); + } +} diff --git a/chat/src/main/resources/application-development.yml b/chat/src/main/resources/application-development.yml new file mode 100644 index 0000000..479e665 --- /dev/null +++ b/chat/src/main/resources/application-development.yml @@ -0,0 +1,23 @@ +spring: + data: + redis: + host: krcia.top + port: 6379 + password: xiong990416. + database: 3 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://krcia.top:3306/elysia-db?serverTimezone=Asia/Shanghai + username: root + password: xiong990416. + servlet: + multipart: + max-file-size: 10MB # 单个文件最大 10MB + max-request-size: 20MB # 整个请求最大 20MB +elysia-authorization: + version: v0.1-0909-dev + enable-cors: true + enable-api-doc: true + metadata-save: + path: ./metadata/ + agent-url: http://192.168.1.2:4563/oss \ No newline at end of file diff --git a/chat/src/main/resources/application-release.yml b/chat/src/main/resources/application-release.yml new file mode 100644 index 0000000..8d5227c --- /dev/null +++ b/chat/src/main/resources/application-release.yml @@ -0,0 +1,37 @@ +spring: + data: + redis: + host: 192.168.8.88 + port: 6379 + password: xiong990416. + database: 3 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.8.88:3306/elysia-db?serverTimezone=Asia/Shanghai + username: root + password: xiong990416. +elysia-authorization: + version: v0.1-0909-dev + enable-cors: true + enable-api-doc: true + mail: + host: smtp.qq.com + port: 465 + username: krcia@qq.com + auth-code: ghylxjvfnnjqdfhe + enable-ssl: true + metadata-save: + path: ./metadata/ + agent-url: http://krcia.top:4560/oss + +#打印数据日志 +logging: + level: + #MyBatis SQL 日志 + top.krcia.elysiaserver.chat.dao: debug # 你的Mapper接口所在包 + #MyBatis-Plus SQL 日志 + com.baomidou.mybatisplus.core.override.MybatisMapperProxy: debug + org.apache.ibatis: debug + java.sql: debug + java.sql.Statement: debug + java.sql.PreparedStatement: debug \ No newline at end of file diff --git a/chat/src/main/resources/application.yml b/chat/src/main/resources/application.yml new file mode 100644 index 0000000..55be060 --- /dev/null +++ b/chat/src/main/resources/application.yml @@ -0,0 +1,8 @@ +server: + port: 4563 + max-http-request-header-size: 16KB +spring: + application: + name: elysia-chat + profiles: + active: development \ No newline at end of file diff --git a/chat/src/main/resources/smart-doc.json b/chat/src/main/resources/smart-doc.json new file mode 100644 index 0000000..b3401a1 --- /dev/null +++ b/chat/src/main/resources/smart-doc.json @@ -0,0 +1,20 @@ +{ + "outPath": "./src/main/resources/static/doc", + "serverUrl": "/api", + "serverEnv": "http://{{server}}", + "allInOne": true, + "coverOld": true, + "createDebugPage": true, + "showAuthor": "true", + "allInOneDocFileName": "index.html", + "requestHeaders": [ + { + "name": "Authorization", + "type": "string", + "value": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-", + "desc": "鉴权信息", + "required": true, + "excludePathPatterns": "" + } + ] +} \ No newline at end of file diff --git a/chat/src/main/resources/static/doc/AllInOne.css b/chat/src/main/resources/static/doc/AllInOne.css new file mode 100644 index 0000000..b22c6a2 --- /dev/null +++ b/chat/src/main/resources/static/doc/AllInOne.css @@ -0,0 +1,13 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}script{display:none!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}.left{float:left!important}.right{float:right!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}.hide{display:none}img,object,svg{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.center{margin-left:auto;margin-right:auto}.spread{width:100%}p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#364149;text-decoration:underline;line-height:inherit}a:hover,a:focus{color:#364149}a img{border:0}p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4,h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} +ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:2.75em}h2{font-size:2.3125em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}*:not(pre)>code.nobreak{word-wrap:normal}*:not(pre)>code.nowrap{white-space:nowrap}pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}em em{font-style:normal}strong strong{font-weight:400}.keyseq{color:rgba(51,51,51,.8)}kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menuref{color:#000}.menuseq b:not(.caret),.menuref{font-weight:inherit}.menuseq{word-spacing:-.02em}.menuseq b.caret{font-size:1.25em;line-height:.8}.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,.9)}#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-.125em}#header .details span.email a{color:rgba(0,0,0,.85)}#header .details br{display:none} +#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}#toc>ul{margin-left:.125em;padding-left:1.25em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}#toc li{line-height:1.3334;margin-top:.3334em;padding-bottom:4px;padding-top:4px}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#7a2518;font-size:1.2em}@media only screen and (min-width:768px){#toctitle{font-size:1.375em}body.toc2{padding-left:15em;padding-right:0}#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;#padding:1.25em 1em;height:100%;overflow:auto}#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}#toc.toc2>ul{font-size:.9em;margin-bottom:0}#toc.toc2 ul ul{margin-left:0;padding-left:1em}#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}body.toc2.toc-right{padding-left:0;padding-right:15em}body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}#toc.toc2{width:20em}#toc.toc2 #toctitle{border-bottom:1px solid rgba(0,0,0,.07);padding-top:20px;padding-bottom:15px}#toc.toc2 #toctitle span{padding-left:1.25em;padding-bottom:15px}#toc.toc2>ul{font-size:.95em}#toc.toc2 ul ul{padding-left:1.25em}body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}#footer-text{color:rgba(255,255,255,.8);line-height:1.44}.sect1{padding-bottom:.625em}@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:0;width:100%}.admonitionblock>table td.icon{text-align:center;width:80px} +.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}.listingblock pre.highlightjs{padding:0}.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}.listingblock pre.prettyprint{border-width:0}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock:hover code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:0}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:inline-block;margin-right:.25em}table.pyhltable .linenodiv{background:none!important;padding-right:0!important}.quoteblock{margin:0 1em 1.25em 1.5em;display:table}.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}.quoteblock blockquote{margin:0;padding:0;border:0}.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 1em}.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} +.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px 0}table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0 0}table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}p.tableblock>code:only-child{background:0;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}ul.unstyled,ol.unstyled{margin-left:0}ul.checklist{margin-left:.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:400;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:0}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:0}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}.colist>table tr>td:first-of-type{padding:.4em .75em 0 .75em;line-height:1;vertical-align:top}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}.imageblock.left,.imageblock[style*="float:left"]{margin:.25em .625em 1.25em 0}.imageblock.right,.imageblock[style*="float:right"]{margin:.25em 0 1.25em .625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}.image.left{margin-right:.625em}.image.right{margin-left:.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none} +sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:#000}.black-background{background-color:#000}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000}.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}a span.icon>.fa{cursor:inherit}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff!important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:-.125em}b.conum *{color:inherit!important}.conum:not([data-value]):empty{display:none}dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}h1,h2,p,td.content,span.alt{letter-spacing:-.01em}p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}p{margin-bottom:1.25rem}.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}.print-only{display:none!important}@media print{@page{margin:1.25cm .75cm}*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}a{color:inherit!important;text-decoration:underline!important}a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote,tr,img,object,svg{page-break-inside:avoid}thead{display:table-header-group}svg{max-width:100%}p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}#toc,.sidebarblock,.exampleblock>.content{background:none!important}#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}.sect1{padding-bottom:0!important}.sect1+.sect1{border:0!important}#header>h1:first-child{margin-top:1.25rem} + body.book #header{text-align:center}body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}body.book #header .details{border:0!important;display:block;padding:0!important}body.book #header .details span:first-child{margin-left:0!important}body.book #header .details br{display:block}body.book #header .details br+span:before{content:none!important}body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}.listingblock code[data-lang]:before{display:block}#footer{background:none!important;padding:0 .9375em}#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}.hide-on-print{display:none!important}.print-only{display:block!important}.hide-for-print{display:none!important}.show-for-print{display:inherit!important}}#content .page-footer{height:100px;border-top:1px solid #ccc;overflow:hidden;padding:10px 0;font-size:14px;color:gray}#content .footer-modification{float:right}#content .footer-modification a{text-decoration:none}.sectlevel2{display:none}.submenu{background:#e7e7e6}.submenu li{border:0}.submenu a{color:#555}.checkbox{position:relative;height:30px}.checkbox input[type='checkbox']{left:0;top:0;width:20px;height:20px;opacity:0;border-radius:4px}.checkbox label{position:absolute;left:30px;top:0;height:20px;line-height:20px}.checkbox label:before{content:'';position:absolute;left:-30px;top:2px;width:20px;height:20px;border:1px solid #ddd;border-radius:4px;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease}.checkbox label:after{content:'';position:absolute;left:-22px;top:3px;width:6px;height:12px;border:0;border-right:1px solid #fff;border-bottom:1px solid #fff;border-radius:2px;transform:rotate(45deg);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease}.checkbox input[type='checkbox']:checked+label:before{background:#4cd764;border-color:#4cd764}.checkbox input[type='checkbox']:checked+label:after{background:#4cd764}.send-button{color:#fff;background-color:#5cb85c;display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px;outline-color:transparent}textarea{width:100%;background-color:#f7f7f8;border:1px solid #f7f7f8;border-radius:4px;font-size:1em;padding:1em;font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;outline-color:#dedede}input{border:0;background-color:transparent;outline-color:transparent;outline-style:dotted;max-width:100%}#book-search-input{padding:13px;background:0;transition:top .5s ease;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}[contenteditable="plaintext-only"]:focus{border:0;outline:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}script{display:none!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} +button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}.left{float:left!important}.right{float:right!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}.hide{display:none}img,object,svg{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.center{margin-left:auto;margin-right:auto}.spread{width:100%}p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#364149;text-decoration:underline;line-height:inherit}a:hover,a:focus{color:#364149}a img{border:0}p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4,h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:2.75em}h2{font-size:2.3125em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} +table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}*:not(pre)>code.nobreak{word-wrap:normal}*:not(pre)>code.nowrap{white-space:nowrap}pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}em em{font-style:normal}strong strong{font-weight:400}.keyseq{color:rgba(51,51,51,.8)}kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menuref{color:#000}.menuseq b:not(.caret),.menuref{font-weight:inherit}.menuseq{word-spacing:-.02em}.menuseq b.caret{font-size:1.25em;line-height:.8}.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,.9)}#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-.125em}#header .details span.email a{color:rgba(0,0,0,.85)}#header .details br{display:none}#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}#toc>ul{margin-left:.125em;padding-left:1.25em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}#toc li{line-height:1.3334;margin-top:.3334em;padding-bottom:4px;padding-top:4px}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#7a2518;font-size:1.2em}@media only screen and (min-width:768px){#toctitle{font-size:1.375em}body.toc2{padding-left:15em;padding-right:0}#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;#padding:1.25em 1em;height:100%;overflow:auto}#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} + #toc.toc2>ul{font-size:.9em;margin-bottom:0}#toc.toc2 ul ul{margin-left:0;padding-left:1em}#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}body.toc2.toc-right{padding-left:0;padding-right:15em}body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}#toc.toc2{width:20em}#toc.toc2 #toctitle{font-size:1.375em;border-bottom:1px solid rgba(0,0,0,.07);padding-top:20px;padding-bottom:15px}#toc.toc2 #toctitle span{padding-left:1.25em;padding-bottom:15px}#toc.toc2>ul{font-size:.95em}#toc.toc2 ul ul{padding-left:1.25em}body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}#footer-text{color:rgba(255,255,255,.8);line-height:1.44}.sect1{padding-bottom:.625em}@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:0;width:100%}.admonitionblock>table td.icon{text-align:center;width:80px}.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} +.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}.listingblock pre.highlightjs{padding:0}.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}.listingblock pre.prettyprint{border-width:0}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock:hover code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:0}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:inline-block;margin-right:.25em}table.pyhltable .linenodiv{background:none!important;padding-right:0!important}.quoteblock{margin:0 1em 1.25em 1.5em;display:table}.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}.quoteblock blockquote{margin:0;padding:0;border:0}.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 1em}.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px 0}table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0 0}table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0} +table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}p.tableblock>code:only-child{background:0;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}ul.unstyled,ol.unstyled{margin-left:0}ul.checklist{margin-left:.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:400;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:0}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:0}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}.colist>table tr>td:first-of-type{padding:.4em .75em 0 .75em;line-height:1;vertical-align:top}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}.imageblock.left,.imageblock[style*="float:left"]{margin:.25em .625em 1.25em 0}.imageblock.right,.imageblock[style*="float:right"]{margin:.25em 0 1.25em .625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}.image.left{margin-right:.625em}.image.right{margin-left:.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none}sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:#000}.black-background{background-color:#000}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000} +.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}a span.icon>.fa{cursor:inherit}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff!important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:-.125em}b.conum *{color:inherit!important}.conum:not([data-value]):empty{display:none}dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}h1,h2,p,td.content,span.alt{letter-spacing:-.01em}p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}p{margin-bottom:1.25rem}.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}.print-only{display:none!important}@media print{@page{margin:1.25cm .75cm}*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}a{color:inherit!important;text-decoration:underline!important}a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote,tr,img,object,svg{page-break-inside:avoid}thead{display:table-header-group}svg{max-width:100%}p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}#toc,.sidebarblock,.exampleblock>.content{background:none!important}#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}.sect1{padding-bottom:0!important}.sect1+.sect1{border:0!important}#header>h1:first-child{margin-top:1.25rem}body.book #header{text-align:center}body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}body.book #header .details{border:0!important;display:block;padding:0!important}body.book #header .details span:first-child{margin-left:0!important}body.book #header .details br{display:block}body.book #header .details br+span:before{content:none!important}body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}.listingblock code[data-lang]:before{display:block}#footer{background:none!important;padding:0 .9375em}#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}.hide-on-print{display:none!important}.print-only{display:block!important}.hide-for-print{display:none!important}.show-for-print{display:inherit!important}}#content .page-footer{height:100px;border-top:1px solid #ccc;overflow:hidden;padding:10px 0;font-size:14px;color:gray}#content .footer-modification{float:right}#content .footer-modification a{text-decoration:none}.sectlevel2{display:none}.submenu{background:#e7e7e6}.submenu li{border:0}.submenu a{color:#555}.copyright{text-align:right;padding-top:1.25em}#toTop{display:none;position:fixed;bottom:10px;right:0;width:44px;height:44px;border-radius:50%;background-color:#ced4ce;cursor:pointer;text-align:center}#upArrow{position:absolute;left:24%;right:0;bottom:19%;transition:.3s ease-in-out;display:block}#upText{position:absolute;left:0;right:0;bottom:0;font-size:16px;font-weight: 600;line-height:45px;display:none;transition:.3s ease-in-out;-webkit-box-align:center} \ No newline at end of file diff --git a/chat/src/main/resources/static/doc/debug.js b/chat/src/main/resources/static/doc/debug.js new file mode 100644 index 0000000..c3a9135 --- /dev/null +++ b/chat/src/main/resources/static/doc/debug.js @@ -0,0 +1,407 @@ +$(function () { + const Accordion = function (el, multiple) { + this.el = el || {}; + this.multiple = multiple || false; + const links = this.el.find('.dd'); + links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown); + }; + Accordion.prototype.dropdown = function (e) { + const $el = e.data.el; + const $this = $(this), $next = $this.next(); + $next.slideToggle(); + $this.parent().toggleClass('open'); + if (!e.data.multiple) { + $el.find('.submenu').not($next).slideUp("20").parent().removeClass( + 'open'); + } + }; + new Accordion($('#accordion'), false); + hljs.highlightAll(); +}); + +$("[contenteditable=plaintext-only]").on('blur', function (e) { + e.preventDefault(); + const $this = $(this); + const data = $this.text(); + let content; + if (undefined === e.originalEvent.clipboardData) { + content = data; + } else { + content = e.originalEvent.clipboardData.getData('text/plain') + } + content = JSON.stringify(JSON.parse(content), null, 4); + const highlightedCode = hljs.highlight('json', content).value; + $this.html(highlightedCode); +}) +$("button").on("click", function () { + const $this = $(this); + const id = $this.data("id"); + console.log("method-id=>" + id); + + let body = $("#" + id + "-body").text(); + + // header + const $headerElement = $("#" + id + "-header"); + const headersData = getInputData($headerElement); + + // body param + const $paramElement = $("#" + id + "-param"); + let bodyParamData = getInputData($paramElement) + + // path param + const $pathElement = $("#" + id + "-path-params") + const pathParamData = getInputData($pathElement) + + // query param + const $queryElement = $("#" + id + "-query-params") + let $urlDataElement = $("#" + id + "-url"); + const url = $urlDataElement.data("url"); + const isDownload = $urlDataElement.data("download"); + const page = $urlDataElement.data("page"); + const method = $("#" + id + "-method").data("method"); + const contentType = $("#" + id + "-content-type").data("content-type"); + console.log("request-headers=>" + JSON.stringify(headersData)) + console.log("path-params=>" + JSON.stringify(pathParamData)) + + console.log("body-params=>" + JSON.stringify(bodyParamData)) + console.log("json-body=>" + body); + let finalUrl = ""; + let queryParamData; + if (!isEmpty(page)) { + queryParamData = getInputData($queryElement) + finalUrl = castToGetUri(page, pathParamData, queryParamData) + window.open(finalUrl, "_blank"); + return; + } + if (isDownload) { + queryParamData = getInputData($queryElement); + download(url, headersData, pathParamData, queryParamData, bodyParamData, + method, contentType); + return; + } + const ajaxOptions = {}; + + if ("multipart/form-data" === contentType) { + finalUrl = castToGetUri(url, pathParamData); + queryParamData = getInputData($queryElement, true, true) + body = queryParamData; + ajaxOptions.processData = false; + ajaxOptions.contentType = false; + } else if ("POST" === method && contentType !== "multipart/form-data" + && contentType !== "application/json") { + finalUrl = castToGetUri(url, pathParamData); + queryParamData = getInputData($queryElement, true) + body = queryParamData; + } else { + queryParamData = getInputData($queryElement) + finalUrl = castToGetUri(url, pathParamData, queryParamData) + ajaxOptions.contentType = contentType; + } + console.log("query-params=>" + JSON.stringify(queryParamData)); + console.log("url=>" + finalUrl) + ajaxOptions.headers = headersData + ajaxOptions.url = finalUrl + ajaxOptions.type = method + ajaxOptions.data = body; + + const $responseEle = $("#" + id + "-response").find("pre code"); + const ajaxTime = new Date().getTime(); + $.ajax(ajaxOptions).done(function (result, textStatus, jqXHR) { + const totalTime = new Date().getTime() - ajaxTime; + $this.css("background", "#5cb85c"); + $("#" + id + "-resp-status").html( + " Status: " + jqXHR.status + "  " + jqXHR.statusText + + "    Time: " + totalTime + " ms"); + const highlightedCode = hljs.highlight('json', + JSON.stringify(result, null, 4)).value; + $responseEle.html(highlightedCode); + }).fail(function (jqXHR) { + const totalTime = new Date().getTime() - ajaxTime; + $this.css("background", "#D44B47"); + if (jqXHR.status === 0 && jqXHR.readyState === 0) { + $("#" + id + "-resp-status").html( + "Connection refused, please check the server."); + } else { + $("#" + id + "-resp-status").html( + " Status: " + jqXHR.status + "  " + + jqXHR.statusText + "    Time: " + totalTime + + " ms"); + } + if (undefined !== jqXHR.responseJSON) { + const highlightedCode = hljs.highlight('json', + JSON.stringify(jqXHR.responseJSON, null, 4)).value; + $responseEle.html(highlightedCode); + } + }).always(function () { + + }); + const curlCmd = toCurl(ajaxOptions); + const highlightedCode = hljs.highlight('bash', curlCmd).value; + $("#" + id + "-curl").find("pre code").html(highlightedCode); +}) +$(".check-all").on("click", function () { + const checkboxName = $(this).prop("name"); + const checked = $(this).is(':checked'); + if (!checked) { + $(this).removeAttr("checked"); + } else { + $(this).prop("checked", true); + } + $('input[name="' + checkboxName + '"]').each(function () { + if (!checked) { + $(this).prop("checked", false); + } else { + $(this).prop("checked", true); + } + }) +}) + +function castToGetUri(url, pathParams, params) { + if (undefined !== url) { + let urls = url.split(";") + url = urls[0]; + } + if (pathParams instanceof Object && !(pathParams instanceof Array)) { + url = url.format(pathParams) + } + if (params instanceof Object && !(params instanceof Array)) { + const pm = params || {}; + const arr = []; + arr.push(url); + let j = 0; + for (const i in pm) { + if (j === 0) { + arr.push("?"); + arr.push(i + "=" + pm[i]); + } else { + arr.push("&" + i + "=" + pm[i]); + } + j++; + } + return arr.join(""); + } else { + return url; + } +} + +function getInputData(element, isPost, returnFormDate) { + const formData = new FormData(); + $(element).find("tr").each(function (i) { + const checked = $(this).find('td:eq(0)').children(".checkbox").children( + "input").is(':checked'); + if (checked) { + const input = $(this).find('td:eq(2) input'); + let attr = $(input).attr("type"); + let multiple = $(input).attr("multiple"); + console.log("input type:" + attr) + const name = $(input).attr("name"); + if (attr === "file") { + let files = $(input)[0].files; + if (multiple) { + $.each(files, function (i, file) { + formData.append(name, file); + }) + } else { + formData.append(name, files[0]); + } + } else { + const val = $(input).val(); + if (isValidUrl(val)) { + formData.append(name, encodeURI(val)); + } else { + // support chinese + if (hasChinese(val) && !isPost) { + formData.append(name, encodeURIComponent(val)); + } else { + formData.append(name, val); + } + } + } + } + }); + if (returnFormDate) { + return formData; + } + const headersData = {}; + formData.forEach((value, key) => headersData[key] = value); + return headersData; +} + +String.prototype.format = function (args) { + let reg; + if (arguments.length > 0) { + let result = this; + if (arguments.length === 1 && typeof (args) == "object") { + for (const key in args) { + reg = new RegExp("({" + key + "})", "g"); + result = result.replace(reg, args[key]); + } + } else { + for (let i = 0; i < arguments.length; i++) { + if (arguments[i] === undefined) { + return ""; + } else { + reg = new RegExp("({[" + i + "]})", "g"); + result = result.replace(reg, arguments[i]); + } + } + } + return result; + } else { + return this; + } +} + +function download(url, headersData, pathParamData, queryParamData, + bodyParamData, method, contentType) { + url = castToGetUri(url, pathParamData, queryParamData) + const xmlRequest = new XMLHttpRequest(); + xmlRequest.open(method, url, true); + xmlRequest.setRequestHeader("Content-type", contentType); + for (let key in headersData) { + xmlRequest.setRequestHeader(key, headersData[key]) + } + xmlRequest.responseType = "blob"; + xmlRequest.onload = function () { + if (this.status === 200) { + let fileName = ""; + const disposition = xmlRequest.getResponseHeader('Content-Disposition'); + if (disposition && disposition.indexOf('attachment') !== -1) { + const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; + const matches = filenameRegex.exec(disposition); + if (matches != null && matches[1]) { + fileName = decodeURI(matches[1].replace(/['"]/g, '')); + } + } + console.log("download filename:" + fileName); + const blob = this.response; + if (navigator.msSaveBlob) { + // IE10 can't do a[download], only Blobs: + window.navigator.msSaveBlob(blob, fileName); + return; + } + if (window.URL) { // simple fast and modern way using Blob and URL: + const a = document.createElement("a"); + document.body.appendChild(a); + const url = window.URL.createObjectURL(blob); + a.href = url; + a.download = fileName; + a.click(); + window.URL.revokeObjectURL(url); + } + console.log(fileName); + } else { + console.log("download failed"); + } + }; + try { + xmlRequest.send(bodyParamData); + } catch (e) { + console.error("Failed to send data", e); + } +} + +function toCurl(request) { + if (typeof request !== 'object') { + throw "Request is not an object"; + } + // default is a GET request + const cmd = ["curl", "-X", request.type || "GET"]; + + if (request.url.indexOf('https') === 0) { + cmd.push("-k"); + } + + // append Content-Type + if (request.contentType) { + cmd.push("-H"); + cmd.push("'Content-Type:"); + cmd.push(request.contentType + "'"); + } + // append request headers + let headerValue; + if (typeof request.headers == 'object') { + for (let key in request.headers) { + if (Object.prototype.hasOwnProperty.call(request.headers, key)) { + cmd.push("-H"); + headerValue = request.headers[key]; + if (headerValue.value === '') { + cmd.push("'" + key + "'"); + } else { + cmd.push("'" + key + ':' + headerValue + "'"); + } + } + } + } + + // display the response headers + cmd.push("-i"); + // append request url + let url = request.url; + if (!url.startsWith("http")) { + const protocol = window.document.location.protocol; + const domain = window.document.location.hostname; + const port = window.document.location.port; + url = protocol + "//" + domain + ":" + port + url; + } + cmd.push(url); + // append data + + if (typeof request.data == 'object') { + let index = 0; + const bodyData = []; + bodyData.push("\"") + for (let key in request.data) { + if (Object.prototype.hasOwnProperty.call(request.data, key)) { + if (index === 0) { + bodyData.push(key); + bodyData.push("="); + bodyData.push(request.data[key]); + } else { + bodyData.push("&") + bodyData.push(key); + bodyData.push("="); + bodyData.push(request.data[key]); + } + } + index++; + } + bodyData.push("\""); + let bodyStr = "" + bodyData.forEach(function (item) { + bodyStr += item; + }); + cmd.push("--data"); + cmd.push(bodyStr); + } else if (request.data && request.data.length > 0) { + // append json data + cmd.push("--data"); + cmd.push("'" + request.data + "'"); + } + + let curlCmd = ""; + cmd.forEach(function (item) { + curlCmd += item + " "; + }); + console.log(curlCmd); + return curlCmd; +} + +function isEmpty(obj) { + return obj === undefined || obj === null || String(obj).trim() === ''; +} + +function hasChinese(_string) { + const chineseReg = /[\u4e00-\u9fa5]/g + return chineseReg.test(_string); +} + +function isValidUrl(_string) { + let urlString; + try { + urlString = new URL(_string); + } catch (_) { + return false; + } + return urlString.protocol === "http:" || urlString.protocol === "https:"; +} diff --git a/chat/src/main/resources/static/doc/font.css b/chat/src/main/resources/static/doc/font.css new file mode 100644 index 0000000..3c85d80 --- /dev/null +++ b/chat/src/main/resources/static/doc/font.css @@ -0,0 +1,6 @@ +@font-face{font-family:'Droid Sans Mono';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/droidsansmono/v19/6NUO8FuJNQ2MbkrZ5-J8lKFrp7pRef2r.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZzC7TMQ.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImbjC7TMQ.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZjC7TMQ.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImaTC7TMQ.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZTC7TMQ.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZDC7TMQ.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImajC7.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufuVMCoY.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWud-VMCoY.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWuf-VMCoY.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWucOVMCoY.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufOVMCoY.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufeVMCoY.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWuc-VM.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFoWaCi_.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F} +@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFMWaCi_.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFsWaCi_.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFQWaCi_.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFgWaCi_.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFkWaCi_.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFcWaA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRqecf1I.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfROecf1I.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRuecf1I.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRSecf1I.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRiecf1I.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRmecf1I.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfReecQ.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF} +@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116} +@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} +@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF} +@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} \ No newline at end of file diff --git a/chat/src/main/resources/static/doc/highlight.min.js b/chat/src/main/resources/static/doc/highlight.min.js new file mode 100644 index 0000000..664e1aa --- /dev/null +++ b/chat/src/main/resources/static/doc/highlight.min.js @@ -0,0 +1,1213 @@ +/*! + Highlight.js v11.9.0 (git: f47103d4f1) + (c) 2006-2023 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";function e(n){ + return n instanceof Map?n.clear=n.delete=n.set=()=>{ + throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{ + throw Error("set is read-only") + }),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{ + const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a) + })),n}class n{constructor(e){ + void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} + ignoreMatch(){this.isMatchIgnored=!0}}function t(e){ + return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") + }function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n] + ;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope + ;class r{constructor(e,n){ + this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){ + this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{ + if(e.startsWith("language:"))return e.replace("language:","language-") + ;if(e.includes(".")){const t=e.split(".") + ;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ") + }return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)} + closeNode(e){i(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ + this.buffer+=``}}const s=(e={})=>{const n={children:[]} + ;return Object.assign(n,e),n};class o{constructor(){ + this.rootNode=s(),this.stack=[this.rootNode]}get top(){ + return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ + this.top.children.push(e)}openNode(e){const n=s({scope:e}) + ;this.add(n),this.stack.push(n)}closeNode(){ + if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ + for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} + walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){ + return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n), + n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){ + "string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ + o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e} + addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){ + this.closeNode()}__addSublanguage(e,n){const t=e.root + ;n&&(t.scope="language:"+n),this.add(t)}toHTML(){ + return new r(this,this.options).value()}finalize(){ + return this.closeAllNodes(),!0}}function c(e){ + return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")} + function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")} + function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{ + const n=e[e.length-1] + ;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{} + })(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"} + function p(e){return RegExp(e.toString()+"|").exec("").length-1} + const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ + ;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t + ;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break} + i+=a.substring(0,e.index), + a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0], + "("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)} + const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={ + begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'", + illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", + contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n, + contains:[]},t);i.contains.push({scope:"doctag", + begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", + end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) + ;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) + ;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i + },M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({ + __proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{ + scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x, + C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number", + begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{ + "on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f, + MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0}, + NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y, + PHRASAL_WORDS_MODE:{ + begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ + },QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/, + end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]}, + RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", + SHEBANG:(e={})=>{const n=/^#![ ]*\// + ;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n, + end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)}, + TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E, + UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){ + "."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){ + void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){ + n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", + e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, + void 0===e.relevance&&(e.relevance=0))}function I(e,n){ + Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){ + if(e.match){ + if(e.begin||e.end)throw Error("begin & end are not supported with match") + ;e.begin=e.match,delete e.match}}function B(e,n){ + void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return + ;if(e.starts)throw Error("beforeMatch cannot be used with starts") + ;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n] + })),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={ + relevance:0,contains:[Object.assign(t,{endsParent:!0})] + },e.relevance=0,delete t.beforeMatch + },z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword" + ;function U(e,n,t=F){const a=Object.create(null) + ;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{ + Object.assign(a,U(e[t],n,t))})),a;function i(e,t){ + n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|") + ;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){ + return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{ + console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{ + P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0) + },G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={} + ;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1]) + ;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{ + e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, + delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ + _wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope + }),(e=>{if(Array.isArray(e.begin)){ + if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), + G + ;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"), + G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{ + if(Array.isArray(e.end)){ + if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"), + G + ;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"), + G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){ + function n(n,t){ + return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":"")) + }class t{constructor(){ + this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} + addRule(e,n){ + n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]), + this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) + ;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|" + }),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex + ;const n=this.matcherRe.exec(e);if(!n)return null + ;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t] + ;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){ + this.rules=[],this.multiRegexes=[], + this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ + if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t + ;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))), + n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){ + return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){ + this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){ + const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex + ;let t=n.exec(e) + ;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{ + const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)} + return t&&(this.regexIndex+=t.position+1, + this.regexIndex===this.count&&this.considerAll()),t}} + if(e.compilerExtensions||(e.compilerExtensions=[]), + e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") + ;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r + ;if(r.isCompiled)return o + ;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))), + r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null + ;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords), + l=r.keywords.$pattern, + delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)), + o.keywordPatternRe=n(l,!0), + s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/), + r.end&&(o.endRe=n(o.end)), + o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)), + r.illegal&&(o.illegalRe=n(r.illegal)), + r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{ + variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{ + starts:e.starts?a(e.starts):null + }):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o) + })),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i + ;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin" + }))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end" + }),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){ + return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{ + constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}} + const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{ + const a=Object.create(null),i=Object.create(null),r=[];let s=!0 + ;const o="Could not find the language '{}', did you forget to load/include a language module?",c={ + disableAutodetect:!0,name:"Plain text",contains:[]};let p={ + ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, + languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", + cssSelector:"pre code",languages:null,__emitter:l};function _(e){ + return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i="" + ;"object"==typeof n?(a=e, + t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."), + q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), + i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r) + ;const s=r.result?r.result:f(r.language,r.code,t) + ;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){ + const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A) + ;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t="" + ;for(;n;){t+=A.substring(e,n.index) + ;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){ + const[e,a]=r + ;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{ + const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0] + ;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a + ;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{ + if(""===A)return;let e=null;if("string"==typeof x.subLanguage){ + if(!a[x.subLanguage])return void S.addText(A) + ;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top + }else e=E(A,x.subLanguage.length?x.subLanguage:null) + ;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language) + })():c(),A=""}function g(e,n){ + ""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1 + ;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue} + const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}} + function b(e,n){ + return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope), + e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), + A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{ + value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n) + ;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e) + ;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){ + for(;e.endsParent&&e.parent;)e=e.parent;return e}} + if(e.endsWithParent)return m(e.parent,t,a)}function _(e){ + return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){ + const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x + ;x.endScope&&x.endScope._wrap?(d(), + g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(), + u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n), + d(),r.excludeEnd&&(A=n));do{ + x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent + }while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length} + let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0 + ;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){ + if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`) + ;throw n.languageName=e,n.badRule=y.rule,n}return 1} + if(y=r,"begin"===r.type)return(e=>{ + const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]] + ;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t) + ;return a.skip?A+=t:(a.excludeBegin&&(A+=t), + d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r) + ;if("illegal"===r.type&&!i){ + const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"")+'"') + ;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e} + if("illegal"===r.type&&""===o)return 1 + ;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches") + ;return A+=o,o.length}const w=v(e) + ;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"') + ;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[] + ;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope) + ;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{ + if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){ + R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T + ;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e) + ;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e, + value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){ + if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t), + illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T, + context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{ + language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x} + ;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{ + const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)} + ;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1))) + ;i.unshift(t);const r=i.sort(((e,n)=>{ + if(e.relevance!==n.relevance)return n.relevance-e.relevance + ;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1 + ;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s + ;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{ + let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"" + ;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1]) + ;return n||(H(o.replace("{}",t[1])), + H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"} + return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return + ;if(x("before:highlightElement",{el:e,language:t + }),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e) + ;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), + console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), + console.warn("The element with unescaped HTML:"), + console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML) + ;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a) + ;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t + ;e.classList.add("hljs"),e.classList.add("language-"+a) + })(e,t,r.language),e.result={language:r.language,re:r.relevance, + relevance:r.relevance},r.secondBest&&(e.secondBest={ + language:r.secondBest.language,relevance:r.secondBest.relevance + }),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){ + "loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0 + }function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]} + function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ + i[e.toLowerCase()]=n}))}function k(e){const n=v(e) + ;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{ + e[t]&&e[t](n)}))} + "undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ + N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w, + highlightElement:y, + highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"), + q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)}, + initHighlighting:()=>{ + w(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, + initHighlightingOnLoad:()=>{ + w(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") + },registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){ + if(K("Language definition for '{}' could not be registered.".replace("{}",e)), + !s)throw n;K(n),i=c} + i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{ + languageName:e})},unregisterLanguage:e=>{delete a[e] + ;for(const n of Object.keys(i))i[n]===e&&delete i[n]}, + listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O, + autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{ + e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{ + e["before:highlightBlock"](Object.assign({block:n.el},n)) + }),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{ + e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)}, + removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{ + s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b, + lookahead:d,either:m,optional:u,anyNumberOfTimes:g} + ;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t + },te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{ + scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{ + scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/}, + FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/}, + ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", + contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ + scope:"number", + begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", + relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} + }),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le) + ;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={ + className:"number",variants:[{ + begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{ + begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{ + begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{ + begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{ + begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{ + begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], + relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))} + const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye) + ;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/, + end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ + const t=e[0].length+e.index,a=e.input[t] + ;if("<"===a||","===a)return void n.ignoreMatch();let i + ;">"===a&&(((e,{after:n})=>{const t="",M={ + match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)], + keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]} + ;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{ + PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/, + contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ + label:"use_strict",className:"meta",relevance:10, + begin:/^\s*['"]use (strict|asm)['"]/ + },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{ + className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{ + begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", + keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{ + className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{ + className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{ + className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, + excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/, + relevance:0},{variants:[{begin:"<>",end:""},{ + match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin, + "on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{ + begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{ + beginKeywords:"while if switch catch for"},{ + begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", + returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t, + className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t, + relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, + contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, + className:"variable.constant"},E,k,{match:/\$[(.]/}]}} + const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] + ;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={ + begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]} + ;Object.assign(t,{className:"variable",variants:[{ + begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={ + className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={ + begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, + end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/, + contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/, + end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] + },l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 + }),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, + contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ + name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, + keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], + literal:["true","false"], + built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] + },contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{ + match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}, + grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}] + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ + className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ + match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{ + begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ + begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", + end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ + className:"number",variants:[{begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" + },{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ + keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], + type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], + literal:"true false NULL", + built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" + },b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{ + begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], + keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u, + contains:b.concat(["self"]),relevance:0}]),relevance:0},p={ + begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, + keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})], + relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/, + keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/, + end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s] + }]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u, + disableAutodetect:!0,illegal:"=]/,contains:[{ + beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c, + strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{ + contains:[{begin:/\\\n/}] + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ + className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{ + begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ + begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", + end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ + className:"number",variants:[{begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" + },{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ + type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"], + keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"], + literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"], + _type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"] + },b={className:"function.dispatch",relevance:0,keywords:{ + _hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"] + }, + begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/)) + },m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{ + begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], + keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u, + contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function", + begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, + keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{ + begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{ + className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0, + contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u, + relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}] + },s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++", + aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{ + match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/], + className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={ + keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]), + built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"], + literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{ + begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{ + begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}] + },r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/, + keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/, + end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/ + },e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{ + begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/, + contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]}) + ;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE], + o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{ + illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] + },u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t] + },b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={ + begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"], + keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0, + contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{ + begin:"\x3c!--|--\x3e"},{begin:""}]}] + }),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#", + end:"$",keywords:{ + keyword:"if else elif endif define undef warning error line region endregion pragma checksum" + }},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/, + illegal:/[^\s:,]/,contains:[{beginKeywords:"where class" + },t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace", + relevance:0,end:/[{;=]/,illegal:/[^\s:]/, + contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ + beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/, + contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta", + begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{ + className:"string",begin:/"/,end:/"/}]},{ + beginKeywords:"new return throw await else",relevance:0},{className:"function", + begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, + end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{ + beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial", + relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, + contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params", + begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0, + contains:[g,a,e.C_BLOCK_COMMENT_MODE] + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{ + const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{ + name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{ + keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"}, + contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/ + },t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0 + },{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 + },t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ + begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}] + },t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{ + begin:/:/,end:/[;}{]/, + contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{ + begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" + },contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0, + excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]", + relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ + },{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ + $pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{ + begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{ + className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{ + const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{ + className:"meta",relevance:10, + match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/) + },{className:"comment",variants:[{ + begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/), + end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{ + className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/, + end:/$/}]}},grmr_go:e=>{const n={ + keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"], + type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"], + literal:["true","false","iota","nil"], + built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"] + };return{name:"Go",aliases:["golang"],keywords:n,illegal:"{const n=e.regex;return{name:"GraphQL",aliases:["gql"], + case_insensitive:!0,disableAutodetect:!1,keywords:{ + keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"], + literal:["true","false","null"]}, + contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{ + scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation", + begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/, + end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{ + scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)), + relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={ + className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{ + begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/, + end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{ + begin:/\$\{(.*?)\}/}]},r={className:"literal", + begin:/\bon|off|true|false|yes|no\b/},s={className:"string", + contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{ + begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}] + },o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0 + },l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{ + name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/, + contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{ + begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)), + className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{ + const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={ + keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"], + literal:["false","true","null"], + type:["char","boolean","long","float","int","byte","short","double"], + built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{ + begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/, + end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0} + ;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/, + contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/, + relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{ + begin:/import java\.[a-z]+\./,keywords:"import",relevance:2 + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/, + className:"string",contains:[e.BACKSLASH_ESCAPE] + },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{ + match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{ + 1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{ + begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type", + 3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword", + 3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ + beginKeywords:"new throw return else",relevance:0},{ + begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{ + 2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/, + end:/\)/,keywords:i,relevance:0, + contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE] + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe, + grmr_json:e=>{const n=["true","false","null"],t={scope:"literal", + beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{ + className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{ + match:/[{}[\],:]/,className:"punctuation",relevance:0 + },e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], + illegal:"\\S"}},grmr_kotlin:e=>{const n={ + keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual", + built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing", + literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@" + },a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={ + className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string", + variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'", + illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/, + contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={ + className:"meta", + begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?" + },o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/, + end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}] + },l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={ + variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/, + contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g], + {name:"Kotlin",aliases:["kt","kts"],keywords:n, + contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag", + begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword", + begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol", + begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$", + returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{ + begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0, + contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://, + keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/, + endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/, + endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0 + },e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{ + begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{ + 3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0, + illegal:"extends implements",contains:[{ + beginKeywords:"public protected internal private constructor" + },e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0, + excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/, + excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env", + end:"$",illegal:"\n"},l]}},grmr_less:e=>{ + const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({ + className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n, + relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only", + attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c, + relevance:0} + ;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{ + begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]", + excludeEnd:!0} + },n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{ + className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0 + },n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({ + begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0, + contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:", + returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/ + },n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b", + end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}] + },m={className:"keyword", + begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b", + starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={ + className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a + }],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{ + begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0, + returnEnd:!0,illegal:"[<='$\"]",relevance:0, + contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{ + begin:"\\b("+re.join("|")+")\\b",className:"selector-tag" + },n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{ + className:"selector-pseudo",begin:":("+oe.join("|")+")"},{ + className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/, + end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={ + begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]} + ;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH), + {name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}}, + grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"] + },i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10 + })];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, + literal:"true false nil", + keyword:"and break do else elseif end for goto if in local not or repeat return then until while", + built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" + },contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)", + contains:[e.inherit(e.TITLE_MODE,{ + begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params", + begin:"\\(",endsWithParent:!0,contains:i}].concat(i) + },e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string", + begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={ + className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)", + contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%{ + const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={ + variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{ + begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, + relevance:2},{ + begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), + relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ + begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ + },{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, + returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", + excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", + end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[], + variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}] + },i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{ + begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[] + }),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r) + ;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o) + })),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ + className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{ + begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", + contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", + end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o, + end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ + begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ + begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", + contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ + begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ + className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ + className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{ + const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n, + keyword:["@interface","@class","@protocol","@implementation"]};return{ + name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"], + keywords:{"variable.language":["this","super"],$pattern:n, + keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"], + literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"], + built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"], + type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"] + },illegal:"/,end:/$/,illegal:"\\n" + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class", + begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t, + contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE, + relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={ + $pattern:/[\w.]+/, + keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0" + },i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/, + end:/\}/},s={variants:[{begin:/\$\d/},{ + begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])") + },{begin:/[$%@][^\s\w{]/,relevance:0}] + },o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{ + const r="\\1"===i?i:n.concat(i,a) + ;return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t) + },d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{ + endsWithParent:!0}),r,{className:"string",contains:o,variants:[{ + begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[", + end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{ + begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">", + relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'", + contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`", + contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{ + begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number", + begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b", + relevance:0},{ + begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*", + keywords:"split return print reverse grep",relevance:0, + contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{ + begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{ + begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{ + className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{ + begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0 + }),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{ + begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub", + end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{ + begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$", + subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}] + }];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a, + contains:g}},grmr_php:e=>{ + const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={ + scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{ + begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null + }),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{ + illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{ + begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/, + contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{ + n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({ + begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{ + begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ + begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{ + begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?" + }],relevance:0 + },g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={ + keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{ + n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase()) + })),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{ + match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{ + 1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{ + match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant" + }},{match:[/::/,/class/],scope:{2:"variable.language"}},{ + match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class", + 3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))], + scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class", + 3:"variable.language"}}]},E={scope:"attr", + match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0, + begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_] + },N={relevance:0, + match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)], + scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N) + ;const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1, + keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/, + endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{ + begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]}, + contains:["self",...w]},...w,{scope:"meta",match:i}] + },e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{ + scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/, + keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE, + contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{ + begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{ + begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{ + match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{ + scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/, + excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use" + },e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params", + begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m, + contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{ + beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait", + illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{ + beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{ + beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/, + contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{ + beginKeywords:"use",relevance:0,end:";",contains:[{ + match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]} + },grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{ + begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*", + end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0 + },e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null, + skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null, + contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text", + aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{ + const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={ + $pattern:/[A-Za-z]\w+|__\w+__/,keyword:a, + built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"], + literal:["__debug__","Ellipsis","False","None","NotImplemented","True"], + type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"] + },r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/, + end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={ + className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{ + begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/, + contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ + begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/, + contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ + begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/, + contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/, + end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/, + relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{ + begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/, + end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/, + contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/, + contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] + },c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={ + className:"number",relevance:0,variants:[{ + begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{ + begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{ + begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})` + },{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})` + }]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i, + contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={ + className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/, + end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i, + contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{ + name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i, + illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if", + relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{ + 1:"keyword",3:"title.function"},contains:[m]},{variants:[{ + match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}], + scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{ + className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}}, + grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt", + starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{ + begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{ + const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/) + ;return{name:"R",keywords:{$pattern:t, + keyword:"function if in break next repeat else for while", + literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10", + built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm" + },contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/, + starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)), + endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{ + scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0 + }]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}] + }),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE], + variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"', + relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{ + 1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"}, + match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{ + 2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"}, + match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{ + match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`", + contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{ + const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={ + "variable.constant":["__FILE__","__LINE__","__ENCODING__"], + "variable.language":["self","super"], + keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"], + built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"], + literal:["true","false","nil"]},s={className:"doctag",begin:"@[A-Za-z]+"},o={ + begin:"#<",end:">"},l=[e.COMMENT("#","$",{contains:[s] + }),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10 + }),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/, + end:/\}/,keywords:r},d={className:"string",contains:[e.BACKSLASH_ESCAPE,c], + variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{ + begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{ + begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//, + end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{ + begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{ + begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{ + begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{ + begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{ + begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)), + contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/, + contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number", + relevance:0,variants:[{ + begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{ + begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b" + },{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{ + begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{ + begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{ + className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0, + keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{ + match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class", + 4:"title.class.inherited"},keywords:r},{match:[/(include|extend)\s+/,i],scope:{ + 2:"title.class"},keywords:r},{relevance:0,match:[i,/\.new[. (]/],scope:{ + 1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, + className:"variable.constant"},{relevance:0,match:a,scope:"title.class"},{ + match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{ + begin:e.IDENT_RE+"::"},{className:"symbol", + begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol", + begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable", + begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{ + className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0, + relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*", + keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c], + illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{ + begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[", + end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l) + ;c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m} + },{className:"meta.prompt", + begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])", + starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby", + aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/, + contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}}, + grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0, + begin:n.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,n.lookahead(/\s*\(/)) + },a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] + ;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r, + keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], + literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:""},t]}}, + grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable", + begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS", + case_insensitive:!0,illegal:"[=/|']", + contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{ + className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{ + className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0 + },n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag", + begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo", + begin:":("+a.join("|")+")"},{className:"selector-pseudo", + begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/, + contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute", + begin:"\\b("+ce.join("|")+")\\b"},{ + begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b" + },{begin:/:/,end:/[;}{]/,relevance:0, + contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH] + },{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{ + begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/, + keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i, + className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute" + },r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE] + },n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session", + aliases:["console","shellsession"],contains:[{className:"meta.prompt", + begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/, + subLanguage:"bash"}}]}),grmr_sql:e=>{ + const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={ + begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}} + ;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{ + $pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t + ;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e)) + })(l,{when:e=>e.length<3}),literal:a,type:i, + built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"] + },contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, + keyword:l.concat(s),literal:a,type:i}},{className:"type", + begin:n.either("double precision","large object","with timezone","without timezone") + },c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string", + variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/, + contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{ + className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, + relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0 + },t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={ + match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)), + relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{ + className:"keyword", + match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={ + $pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{ + match:b(/\./,m(...De)),relevance:0},{className:"built_in", + match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{ + className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}] + }],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0, + variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{ + match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/ + },{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{ + match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}] + }),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/) + }),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/ + }),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)] + }),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={ + className:"string", + variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")] + },k=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0, + contains:[e.BACKSLASH_ESCAPE]}],x={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//, + contains:k},M=e=>{const n=b(e,/\//),t=b(/\//,e);return{begin:n,end:t, + contains:[...k,{scope:"comment",begin:`#(?!.*${t})`,end:/$/}]}},S={ + scope:"regexp",variants:[M("###"),M("##"),M("#"),x]},A={match:b(/`/,Fe,/`/) + },C=[A,{className:"variable",match:/\$\d+/},{className:"variable", + match:`\\$${ze}+`}],T=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{ + contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{ + scope:"keyword",match:b(/@/,m(...je))},{scope:"meta",match:b(/@/,Fe)}],R={ + match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type", + match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+") + },{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{ + match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},D={ + begin://,keywords:l,contains:[...a,...c,...T,u,R]};R.contains.push(D) + ;const I={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{ + match:b(Fe,/\s*:/),keywords:"_|0",relevance:0 + },...a,S,...c,...g,...p,f,O,...C,...T,R]},L={begin://, + keywords:"repeat each",contains:[...a,R]},B={begin:/\(/,end:/\)/,keywords:l, + contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/, + relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params", + match:Fe}]},...a,...c,...p,f,O,...T,R,I],endsParent:!0,illegal:/["']/},$={ + match:[/(func|macro)/,/\s+/,m(A.match,Fe,Be)],className:{1:"keyword", + 3:"title.function"},contains:[L,B,n],illegal:[/\[/,/%/]},z={ + match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"}, + contains:[L,B,n],illegal:/\[|%/},F={match:[/operator/,/\s+/,Be],className:{ + 1:"keyword",3:"title"}},U={begin:[/precedencegroup/,/\s+/,Ue],className:{ + 1:"keyword",3:"title"},contains:[R],keywords:[...Te,...Ce],end:/}/} + ;for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label)) + ;n.keywords=l;const t=[...c,...g,...p,f,O,...C];n.contains=[...t,{begin:/\(/, + end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l, + contains:[...a,$,z,{beginKeywords:"struct protocol class extension enum actor", + end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{ + className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c] + },F,U,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0 + },S,...c,...g,...p,f,O,...C,...T,R,I]}},grmr_typescript:e=>{ + const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={ + beginKeywords:"namespace",end:/\{/,excludeEnd:!0, + contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/, + excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a}, + contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e, + keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), + literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta", + begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n)) + ;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)} + ;return Object.assign(n.keywords,s), + n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]), + l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10, + begin:/^\s*['"]use strict['"]/ + }),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{ + name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{ + const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={ + className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{ + begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{ + begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}] + },o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}] + }),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]}) + ;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0, + classNameAliases:{label:"symbol"},keywords:{ + keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield", + built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort", + type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort", + literal:"true false nothing"}, + illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{ + className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/, + end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0, + variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/ + },{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{ + begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{ + className:"label",begin:/^\w+:/},o,l,{className:"meta", + begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/, + end:/$/,keywords:{ + keyword:"const disable else elseif enable end externalsource if region then"}, + contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/) + ;return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/, + keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"] + },contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/], + className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{ + match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{ + begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword", + 3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/, + className:"type"},{className:"keyword", + match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/ + },{className:"number",relevance:0, + match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/ + }]}},grmr_xml:e=>{ + const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={ + className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/, + contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] + },r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{ + className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={ + endsWithParent:!0,illegal:/`]+/}]}]}]};return{ + name:"HTML, XML", + aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], + case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{ + className:"meta",begin://,contains:[i,r,o,s]}]}] + },e.COMMENT(//,{relevance:10}),{begin://, + relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, + relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{ + end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{ + end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ + className:"tag",begin:/<>|<\/>/},{className:"tag", + begin:n.concat(//,/>/,/\s/)))), + end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{ + className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{ + className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]} + },grmr_yaml:e=>{ + const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={ + className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ + },{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", + variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{ + variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={ + end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},s={begin:/\{/, + end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]", + contains:[r],illegal:"\\n",relevance:0},l=[{className:"attr",variants:[{ + begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{ + begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$", + relevance:10},{className:"string", + begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{ + begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0, + relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type", + begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t + },{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta", + begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)", + relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{ + className:"number", + begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" + },{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l] + ;return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0, + aliases:["yml"],contains:l}}});const He=ae;for(const e of Object.keys(Ke)){ + const n=e.replace("grmr_","").replace("_","-");He.registerLanguage(n,Ke[e])} + return He}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); \ No newline at end of file diff --git a/chat/src/main/resources/static/doc/index.html b/chat/src/main/resources/static/doc/index.html new file mode 100644 index 0000000..e51035f --- /dev/null +++ b/chat/src/main/resources/static/doc/index.html @@ -0,0 +1,135 @@ +智能AI聊天服务器
    VersionUpdate TimeStatusAuthorDescription

    v2025-10-23 15:41:00

    2025-10-23 15:41:00

    auto

    @Krcia

    Created by smart-doc

    4. 回复模板

    4.1. 所有模板

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 所有模板

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    array

    数据

    -

    └─templateId

    string

    模板ID

    -

    └─templateName

    string

    模板名称

    -

    └─example

    string

    示例

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": [
    +    {
    +      "templateId": "",
    +      "templateName": "",
    +      "example": ""
    +    }
    +  ]
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/robot/template'

    5. 聊天管理

    5.1. 创建聊天

    Type: POST

    Content-Type: application/json

    Description: 创建聊天

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Body-parameters:

    ParameterTypeRequiredDescription

    engine

    string

    false

    房间使用引擎

    roomName

    string

    false

    房间名称

    robotId

    int64

    false

    机器人ID

    Request-body:

    {
    +  "engine": "",
    +  "roomName": "",
    +  "robotId": 0
    +}

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    string

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": ""
    +}

    Curl-example:

    curl -X POST -H "Content-Type: application/json" -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/chat/create' --data '{
    +  "engine": "",
    +  "roomName": "",
    +  "robotId": 0
    +}'

    5.2. 删除聊天

    Type: DELETE

    Content-Type: application/x-www-form-urlencoded

    Description: 删除聊天

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    roomId

    string

    true

    No comments found.

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X DELETE -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/chat/del/{roomId}'

    5.3. 清空聊天

    Type: DELETE

    Content-Type: application/x-www-form-urlencoded

    Description: 清空聊天

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    roomId

    string

    true

    No comments found.

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X DELETE -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/chat/clear/{roomId}'

    5.4. 获取所有聊天室

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 获取所有聊天室

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    array

    数据

    -

    └─roomId

    string

    房间ID

    -

    └─roomName

    string

    房间名称

    -

    └─title

    string

    聊天室名称

    -

    └─roomImage

    string

    聊天室头像

    -

    └─lastChatTime

    string

    最后一次聊天时间

    -

    └─lastChatMessage

    string

    最后一次聊天消息

    -

    └─engine

    string

    房间使用引擎

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": [
    +    {
    +      "roomId": "",
    +      "roomName": "",
    +      "title": "",
    +      "roomImage": "",
    +      "lastChatTime": "yyyy-MM-dd HH:mm:ss",
    +      "lastChatMessage": "",
    +      "engine": ""
    +    }
    +  ]
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/chat/list'

    5.5. 发送消息

    Type: POST

    Content-Type: application/x-www-form-urlencoded

    Description: 发送消息

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    roomId

    string

    true

    No comments found.

    Query-parameters:

    ParameterValueTypeRequiredDescription

    message

    string

    false

    No comments found.

    messageId

    string

    false

    No comments found.

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X POST -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/chat/send/{roomId}' --data '=es3e4q'

    5.6. 聊天消息

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 聊天消息

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    roomId

    string

    true

    No comments found.

    Query-parameters:

    ParameterValueTypeRequiredDescription

    size

    int32

    false

    页面大小

    current

    int32

    false

    页码

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/chat/history/{roomId}?size=10¤t=1'

    5.7. 聊天消息(缓存)

    Type: POST

    Content-Type: application/json

    Description: 聊天消息(缓存)

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Body-parameters:

    ParameterTypeRequiredDescription

    roomId

    string

    false

    聊天室ID

    messageId

    string

    false

    消息ID

    Request-body:

    [
    +  {
    +    "roomId": "",
    +    "messageId": ""
    +  }
    +]

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X POST -H "Content-Type: application/json" -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/chat/history-list' --data '[
    +  {
    +    "roomId": "",
    +    "messageId": ""
    +  }
    +]'

    6. 机器人管理

    6.1. 创建机器人

    Type: POST

    Content-Type: multipart/form-data

    Description: 创建机器人

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Body-parameters:

    ParameterValueTypeRequiredDescription

    avatar

    file

    false

    机器人头像

    name

    string

    false

    机器人名称

    describe

    string

    false

    描述

    systemPrompt

    string

    false

    系统提示词

    private

    boolean

    false

    是否私有

    templateId

    string

    false

    回复模板

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X POST -H "Content-Type: multipart/form-data" -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -F 'avatar=' -i '/api/robot/create' --data 'systemPrompt=""&isPrivate=true&templateId=""&name=""&describe=""'

    6.2. 机器人列表

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 机器人列表

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Query-parameters:

    ParameterValueTypeRequiredDescription

    size

    int32

    false

    页面大小

    current

    int32

    false

    页码

    private

    boolean

    false

    是否私有,0公开,1私有

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    └─pageNum

    int64

    页码

    -

    └─pageSize

    int64

    每页记录数

    -

    └─rows

    int64

    总共记录数

    -

    └─total

    int64

    总条数

    -

    └─limitIndex

    int64

    分页下标

    -

    └─result

    array

    数据

    -

         └─robotId

    int64

    机器人ID

    -

         └─avatar

    string

    机器人头像

    -

         └─name

    string

    机器人名称

    -

         └─describe

    string

    描述

    -

         └─systemPrompt

    string

    系统提示词

    -

         └─follow

    boolean

    是否已关注

    -

         └─creatorId

    int64

    创建者

    -

         └─creatorUsername

    string

    创建者名称

    -

         └─template

    string

    回复模板

    -

         └─private

    boolean

    是否私有,0公开,1私有

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {
    +    "pageNum": 0,
    +    "pageSize": 0,
    +    "rows": 0,
    +    "total": 0,
    +    "limitIndex": 0,
    +    "result": [
    +      {
    +        "robotId": 0,
    +        "avatar": "",
    +        "name": "",
    +        "describe": "",
    +        "systemPrompt": "",
    +        "follow": true,
    +        "creatorId": 0,
    +        "creatorUsername": "",
    +        "template": "",
    +        "private": true
    +      }
    +    ]
    +  }
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/robot/list?size=10¤t=1&private=true&isPrivate=true'

    6.3. 编辑机器人

    Type: POST

    Content-Type: application/json

    Description: 编辑机器人

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    robotId

    int64

    true

    No comments found.

    Body-parameters:

    ParameterTypeRequiredDescription

    systemPrompt

    string

    false

    系统提示词

    private

    boolean

    false

    是否私有

    Request-body:

    {
    +  "systemPrompt": "",
    +  "private": true
    +}

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X POST -H "Content-Type: application/json" -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/robot/editor/{robotId}' --data '{
    +  "systemPrompt": "",
    +  "private": true
    +}'

    6.4. 删除机器人

    Type: DELETE

    Content-Type: application/x-www-form-urlencoded

    Description: 删除机器人

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    robotId

    int64

    true

    No comments found.

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X DELETE -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/robot/delete/{robotId}'

    6.5. 关注列表

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 关注列表

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Query-parameters:

    ParameterValueTypeRequiredDescription

    cacheId

    array

    false

    No comments found.,[array of int64]

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    └─excludeIdList

    array

    No comments found.

    -

    └─data

    array

    No comments found.

    -

         └─robotId

    int64

    机器人ID

    -

         └─avatar

    string

    机器人头像

    -

         └─name

    string

    机器人名称

    -

         └─describe

    string

    简介

    -

         └─systemPrompt

    string

    简介

    -

         └─creator

    boolean

    是否为创建者

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {
    +    "excludeIdList": [
    +      0
    +    ],
    +    "data": [
    +      {
    +        "robotId": 0,
    +        "avatar": "",
    +        "name": "",
    +        "describe": "",
    +        "systemPrompt": "",
    +        "creator": true
    +      }
    +    ]
    +  }
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/robot/follow-list?cacheId=0,0'

    6.6. 关注机器人

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 关注机器人

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    robotId

    int64

    true

    No comments found.

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/robot/follow/{robotId}'

    6.7. 取消关注机器人

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 取消关注机器人

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    robotId

    int64

    true

    No comments found.

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/robot/unfollow/{robotId}'
    Generated by smart-doc at 2025-10-23 15:41:00Suggestions,contact,support and error reporting on Gitee or Github
    Top
    \ No newline at end of file diff --git a/chat/src/main/resources/static/doc/jquery.min.js b/chat/src/main/resources/static/doc/jquery.min.js new file mode 100644 index 0000000..798cc8b --- /dev/null +++ b/chat/src/main/resources/static/doc/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 -1) { + searchArr.push({ + order: apiData.order, + desc: apiData.desc, + link: apiData.link, + alias: apiData.alias, + list: apiData.list + }); + } else { + let methodList = apiData.list || []; + let methodListTemp = []; + for (let j = 0; j < methodList.length; j++) { + const methodData = methodList[j]; + const methodDesc = methodData.desc; + if (methodDesc.toLocaleLowerCase().indexOf(searchValue) > -1) { + methodListTemp.push(methodData); + break; + } + } + if (methodListTemp.length > 0) { + const data = { + order: apiData.order, + desc: apiData.desc, + link: apiData.link, + alias: apiData.alias, + list: methodListTemp + }; + searchArr.push(data); + } + } + } + if (apiGroup.name.toLocaleLowerCase().indexOf(searchValue) > -1) { + searchGroup.push({ + name: apiGroup.name, + order: apiGroup.order, + list: searchArr + }); + continue; + } + if (searchArr.length === 0) { + continue; + } + searchGroup.push({ + name: apiGroup.name, + order: apiGroup.order, + list: searchArr + }); + } + let html; + if (searchValue === '') { + const liClass = ""; + const display = "display: none"; + html = buildAccordion(api,liClass,display); + document.getElementById('accordion').innerHTML = html; + } else { + const liClass = "open"; + const display = "display: block"; + html = buildAccordion(searchGroup,liClass,display); + document.getElementById('accordion').innerHTML = html; + } + const Accordion = function (el, multiple) { + this.el = el || {}; + this.multiple = multiple || false; + const links = this.el.find('.dd'); + links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown); + }; + Accordion.prototype.dropdown = function (e) { + const $el = e.data.el; + let $this = $(this), $next = $this.next(); + $next.slideToggle(); + $this.parent().toggleClass('open'); + if (!e.data.multiple) { + $el.find('.submenu').not($next).slideUp("20").parent().removeClass('open'); + } + }; + new Accordion($('#accordion'), false); + } +} + +function buildAccordion(apiGroups, liClass, display) { + let html = ""; + if (apiGroups.length > 0) { + if (apiDocListSize === 1) { + let apiData = apiGroups[0].list; + let order = apiGroups[0].order; + for (let j = 0; j < apiData.length; j++) { + html += '
  • '; + html += '' + apiData[j].order + '. ' + apiData[j].desc + ''; + html += ''; + html += '
  • '; + } + } else { + for (let i = 0; i < apiGroups.length; i++) { + let apiGroup = apiGroups[i]; + html += '
  • '; + html += '' + apiGroup.order + '. ' + apiGroup.name + ''; + html += ''; + html += '
  • '; + } + } + } + return html; +} \ No newline at end of file diff --git a/chat/src/main/resources/static/prevent/denied.html b/chat/src/main/resources/static/prevent/denied.html new file mode 100644 index 0000000..5680867 --- /dev/null +++ b/chat/src/main/resources/static/prevent/denied.html @@ -0,0 +1,94 @@ + + + + + + 🚫禁止访问🚫 + + + +
    +
    🚫
    +

    禁止访问

    +

    当前页面已被禁用,请联系管理员

    + 返回首页 +
    + + diff --git a/docker/authorization/application-release.yml b/docker/authorization/application-release.yml new file mode 100644 index 0000000..5b1b42a --- /dev/null +++ b/docker/authorization/application-release.yml @@ -0,0 +1,25 @@ +spring: + data: + redis: + host: 192.168.8.88 + port: 6379 + password: xiong990416. + database: 3 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.8.88:3306/elysia-db?serverTimezone=Asia/Shanghai + username: root + password: xiong990416. +elysia-authorization: + version: v0.1-0909-dev + enable-cors: true + enable-api-doc: true + mail: + host: smtp.qq.com + port: 465 + username: krcia@qq.com + auth-code: ghylxjvfnnjqdfhe + enable-ssl: true + metadata-save: + path: ./metadata/ + agent-url: http://krcia.top:4560/oss \ No newline at end of file diff --git a/docker/authorization/application.yml b/docker/authorization/application.yml new file mode 100644 index 0000000..df92367 --- /dev/null +++ b/docker/authorization/application.yml @@ -0,0 +1,7 @@ +server: + port: 4562 +spring: + application: + name: elysia-authorization + profiles: + active: release \ No newline at end of file diff --git a/docker/authorization/authorization.jar b/docker/authorization/authorization.jar new file mode 100644 index 0000000..529179f Binary files /dev/null and b/docker/authorization/authorization.jar differ diff --git a/docker/chat/application-release.yml b/docker/chat/application-release.yml new file mode 100644 index 0000000..68b33f0 --- /dev/null +++ b/docker/chat/application-release.yml @@ -0,0 +1,19 @@ +spring: + data: + redis: + host: 192.168.8.88 + port: 6379 + password: xiong990416. + database: 3 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.8.88:3306/elysia-db?serverTimezone=Asia/Shanghai + username: root + password: xiong990416. +elysia-authorization: + version: v0.1-0909-dev + enable-cors: true + enable-api-doc: true + metadata-save: + path: ./metadata/ + agent-url: http://krcia.top:4560/oss \ No newline at end of file diff --git a/docker/chat/application.yml b/docker/chat/application.yml new file mode 100644 index 0000000..beb3f9d --- /dev/null +++ b/docker/chat/application.yml @@ -0,0 +1,7 @@ +server: + port: 4563 +spring: + application: + name: elysia-authorization + profiles: + active: release \ No newline at end of file diff --git a/docker/chat/chat.jar b/docker/chat/chat.jar new file mode 100644 index 0000000..f6b190a Binary files /dev/null and b/docker/chat/chat.jar differ diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..8b49756 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,46 @@ +services: + elysia-authorization: + container_name: elysia-authorization + image: jdk-17:prod + volumes: + - ./authorization/:/app/ + - ./metadata:/app/metadata + command: + - java + - -Dfile.encoding=UTF-8 + - -jar + - authorization.jar + - --spring.config.location=application.yml + elysia-chat: + container_name: elysia-chat + image: jdk-17:prod + volumes: + - ./chat/:/app/ + - ./metadata:/app/metadata + command: + - java + - -Dfile.encoding=UTF-8 + - -jar + - chat.jar + - --spring.config.location=application.yml + elysia-server: + container_name: elysia-server + image: jdk-17:prod + volumes: + - ./server/:/app/ + - ./metadata:/app/metadata + command: + - java + - -Dfile.encoding=UTF-8 + - -jar + - server.jar + - --spring.config.location=application.yml + + elysia-nginx: + container_name: elysia-nginx + image: nginx:latest + volumes: + - ./nginx/conf/conf.d:/etc/nginx/conf.d + - ./nginx/html:/etc/nginx/html + - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf + - ./metadata:/etc/nginx/metadata diff --git a/docker/metadata/avatar/811593a137ed4c489076f2bd27af27b2.png b/docker/metadata/avatar/811593a137ed4c489076f2bd27af27b2.png new file mode 100644 index 0000000..b9ccc0b Binary files /dev/null and b/docker/metadata/avatar/811593a137ed4c489076f2bd27af27b2.png differ diff --git a/docker/metadata/avatar/ccea0fe6003e4dd59b7414fde664b552.jpg b/docker/metadata/avatar/ccea0fe6003e4dd59b7414fde664b552.jpg new file mode 100644 index 0000000..f56bb74 Binary files /dev/null and b/docker/metadata/avatar/ccea0fe6003e4dd59b7414fde664b552.jpg differ diff --git a/docker/nginx/conf/conf.d/default.conf b/docker/nginx/conf/conf.d/default.conf new file mode 100644 index 0000000..c61b422 --- /dev/null +++ b/docker/nginx/conf/conf.d/default.conf @@ -0,0 +1,61 @@ +server { + listen 4560; + server_name _; + + location / { + root /etc/nginx/html; + index index.html index.htm; + if ($request_method ~* "(GET|POST)") { + add_header "Access-Control-Allow-Origin" *; + } + if ($request_method = OPTIONS ) { + add_header "Access-Control-Allow-Origin" *; + add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD"; + add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept"; + return 200; + } + } + + location /api/ { + # 公共头 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + if ($request_uri ~ ^/api/server/?(.*)$) { + rewrite ^/api/server/?(.*)$ /server/$1 break; + proxy_pass http://elysia-chat:4561; + } + + if ($request_uri ~ ^/api/authorization/?(.*)$) { + rewrite ^/api/authorization/?(.*)$ /server/$1 break; + proxy_pass http://elysia-authorization:4562; + } + + if ($request_uri ~ ^/api/chat/?(.*)$) { + rewrite ^/api/chat/?(.*)$ /chat/$1 break; + proxy_pass http://elysia-authorization:4563; + } + } + + + location /oss/ { + alias /etc/nginx/metadata; + autoindex on; # 是否允许目录浏览(可选) + autoindex_exact_size off; # 文件大小显示为可读形式(可选) + autoindex_localtime off; # 显示文件本地时间(可选) + } + + location /socket { + proxy_pass http://elysia-chat:4563; + # 必须支持 WebSocket 协议升级 + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + # 一些可选头部 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} \ No newline at end of file diff --git a/docker/nginx/conf/nginx.conf b/docker/nginx/conf/nginx.conf new file mode 100644 index 0000000..8c864bd --- /dev/null +++ b/docker/nginx/conf/nginx.conf @@ -0,0 +1,30 @@ +# nginx.conf +user nginx; +worker_processes auto; + +# 错误日志 +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +# 工作模式 +events { + worker_connections 1024; +} + +# HTTP 配置 +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # 包含 conf.d 目录下的所有配置文件 + include /etc/nginx/conf.d/*.conf; + + # 日志配置 + access_log /var/log/nginx/access.log; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; +} diff --git a/docker/server/application-release.yml b/docker/server/application-release.yml new file mode 100644 index 0000000..a114aa3 --- /dev/null +++ b/docker/server/application-release.yml @@ -0,0 +1,12 @@ +spring: + data: + redis: + host: 192.168.8.88 + port: 6379 + password: xiong990416. + database: 3 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.8.88:3306/elysia-db?serverTimezone=Asia/Shanghai + username: root + password: xiong990416. \ No newline at end of file diff --git a/docker/server/application.yml b/docker/server/application.yml new file mode 100644 index 0000000..486b983 --- /dev/null +++ b/docker/server/application.yml @@ -0,0 +1,11 @@ +server: + port: 4561 +spring: + application: + name: elysia-server + profiles: + active: release +elysia-server: + version: v0.1-0909-dev + enable-cors: true + enable-api-doc: true \ No newline at end of file diff --git a/docker/server/server.jar b/docker/server/server.jar new file mode 100644 index 0000000..17591c3 Binary files /dev/null and b/docker/server/server.jar differ diff --git a/main/.gitattributes b/main/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/main/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/main/.gitignore b/main/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/main/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/main/.mvn/wrapper/maven-wrapper.properties b/main/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..44f3cf2 --- /dev/null +++ b/main/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/main/mvnw b/main/mvnw new file mode 100644 index 0000000..e9cf8d3 --- /dev/null +++ b/main/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.3 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/main/mvnw.cmd b/main/mvnw.cmd new file mode 100644 index 0000000..2e2dbe0 --- /dev/null +++ b/main/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/main/pom.xml b/main/pom.xml new file mode 100644 index 0000000..9b47ed8 --- /dev/null +++ b/main/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + top.krcia + elysia-server + 0.0.1-SNAPSHOT + ../pom.xml + + top.krcia + main + 0.0.1-SNAPSHOT + main + main + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + top.krcia + result + 0.0.1-SNAPSHOT + compile + + + cn.hutool + hutool-all + ${hutool.version} + + + top.krcia + utils + 0.0.1-SNAPSHOT + compile + + + com.baomidou + mybatis-plus-core + ${mybatis-plus.version} + compile + + + com.baomidou + mybatis-plus-extension + ${mybatis-plus.version} + compile + + + com.baomidou + mybatis-plus-spring-boot3-starter + ${mybatis-plus.version} + + + com.mysql + mysql-connector-j + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/main/src/main/java/top/krcia/elysiaserver/main/MainApplication.java b/main/src/main/java/top/krcia/elysiaserver/main/MainApplication.java new file mode 100644 index 0000000..a09eace --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/MainApplication.java @@ -0,0 +1,14 @@ +package top.krcia.elysiaserver.main; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@MapperScan(basePackages = {"top.krcia.elysiaserver.main.dao"}) +public class MainApplication { + public static void main(String[] args) { + SpringApplication.run(MainApplication.class, args); + } + +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/annotate/Metadata.java b/main/src/main/java/top/krcia/elysiaserver/main/annotate/Metadata.java new file mode 100644 index 0000000..af1a236 --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/annotate/Metadata.java @@ -0,0 +1,11 @@ +package top.krcia.elysiaserver.main.annotate; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Metadata { +} \ No newline at end of file diff --git a/main/src/main/java/top/krcia/elysiaserver/main/aspect/MetadataAspect.java b/main/src/main/java/top/krcia/elysiaserver/main/aspect/MetadataAspect.java new file mode 100644 index 0000000..c52afd6 --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/aspect/MetadataAspect.java @@ -0,0 +1,121 @@ +package top.krcia.elysiaserver.main.aspect; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; +import top.krcia.elysiaserver.main.annotate.Metadata; +import top.krcia.elysiaserver.result.R; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Map; + +@ControllerAdvice +public class MetadataAspect implements ResponseBodyAdvice { + + @Value("${app.agent-url}") + private String agentUrl; + + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + // 对所有Controller返回值都生效 + return true; + } + + @Override + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, + Class> selectedConverterType, + org.springframework.http.server.ServerHttpRequest request, + org.springframework.http.server.ServerHttpResponse response) { + + if (body == null) return null; + + processObject(body); + + return body; + } + + private void processObject(Object obj) { + if (obj == null) return; + + Class clazz = obj.getClass(); + + // 处理 R,递归 data + if (obj instanceof R) { + Object data = ((R) obj).getData(); + processObject(data); + return; + } + + // 处理集合 + if (obj instanceof Collection) { + for (Object item : (Collection) obj) { + processObject(item); + } + return; + } + + // 处理 Map,只递归 value + if (obj instanceof Map map) { + for (Object value : map.values()) { + processObject(value); + } + return; + } + + // 基础类型 / 包装类 / String / 枚举:不递归 + if (isPrimitiveOrWrapper(clazz) || clazz.isEnum()) { + return; + } + + // 跳过 JDK 内置类,不反射它的字段 + if (isJdkClass(clazz)) { + return; + } + + // 反射处理 POJO + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + try { + field.setAccessible(true); + Object value = field.get(obj); + + // 只处理 @Metadata 的 String 字段 + if (field.isAnnotationPresent(Metadata.class) + && value instanceof String str + && !str.isEmpty() + && !str.startsWith(agentUrl)) { + field.set(obj, agentUrl + str); + } + + // 递归处理子字段 + processObject(value); + } catch (IllegalAccessException ignored) { + } + } + } + + private boolean isPrimitiveOrWrapper(Class clazz) { + return clazz.isPrimitive() + || clazz.equals(String.class) + || clazz.equals(Integer.class) + || clazz.equals(Long.class) + || clazz.equals(Boolean.class) + || clazz.equals(Double.class) + || clazz.equals(Float.class) + || clazz.equals(Short.class) + || clazz.equals(Byte.class) + || clazz.equals(Character.class); + } + + private boolean isJdkClass(Class clazz) { + String name = clazz.getName(); + return name.startsWith("java.") + || name.startsWith("javax.") + || name.startsWith("jakarta.") + || name.startsWith("sun."); + } +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/config/RedisTemplateConfig.java b/main/src/main/java/top/krcia/elysiaserver/main/config/RedisTemplateConfig.java new file mode 100644 index 0000000..64a0596 --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/config/RedisTemplateConfig.java @@ -0,0 +1,92 @@ +package top.krcia.elysiaserver.main.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import top.krcia.elysiaserver.utils.Kedis; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +@Configuration +public class RedisTemplateConfig { + + // 专用于 Redis 的 ObjectMapper + @Bean("redisObjectMapper") + public ObjectMapper redisObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + // Redis 序列化可以保留时间戳(根据需求调整) + objectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + return objectMapper; + } + + @Bean + public RedisTemplate redisTemplate( + RedisConnectionFactory redisConnectionFactory, + @Qualifier("redisObjectMapper") ObjectMapper redisObjectMapper) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConnectionFactory); + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(redisSerializer()); + template.setHashValueSerializer(redisSerializer()); + template.afterPropertiesSet(); + Kedis.init(template); + return template; + } + + @Bean + public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { + return builder.build(); // 自动应用 application.yml 的配置 + } + + @Bean + public RedisSerializer redisSerializer() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + // 必须设置,否则无法将JSON转化为对象,会转化成Map类型 + objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); + + // 自定义ObjectMapper的时间处理模块 + JavaTimeModule javaTimeModule = new JavaTimeModule(); + + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + + javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + + objectMapper.registerModule(javaTimeModule); + + // 禁用将日期序列化为时间戳的行为 + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + //创建JSON序列化器 + return new Jackson2JsonRedisSerializer<>(objectMapper, Object.class); + } + +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/config/WebConfig.java b/main/src/main/java/top/krcia/elysiaserver/main/config/WebConfig.java new file mode 100644 index 0000000..a9fe4dd --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/config/WebConfig.java @@ -0,0 +1,66 @@ +package top.krcia.elysiaserver.main.config; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.resource.ResourceResolver; +import org.springframework.web.servlet.resource.ResourceResolverChain; + +import java.util.List; + +//重写WebMvcConfigurer实现全局跨域配置 +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Value("${elysia-server.enable-cors}") + private boolean enableCors; + @Value("${elysia-server.enable-api-doc}") + private boolean enableApiDoc; + + @Override + public void addCorsMappings(CorsRegistry registry) { + if (enableCors) { + registry.addMapping("/api/**") + .allowCredentials(true) + .allowedOriginPatterns("*") // 使用 allowedOriginPatterns 代替 allowedOrigins + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("*"); + registry.addMapping("/oss/**") + .allowCredentials(true) + .allowedOriginPatterns("*") // 使用 allowedOriginPatterns 代替 allowedOrigins + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("*"); + } + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + if (enableApiDoc) { + return; + } + // 屏蔽static下的某个文件夹,例如屏蔽static/private/ + registry.addResourceHandler("/doc/**") + .addResourceLocations("classpath:/static/doc/") + .resourceChain(true) + .addResolver(new ResourceResolver() { + @Override + public Resource resolveResource(HttpServletRequest request, String requestPath, List locations, ResourceResolverChain chain) { + return new ClassPathResource("static/prevent/denied.html"); + } + + @Override + public String resolveUrlPath(String resourcePath, List locations, ResourceResolverChain chain) { + return null; // 返回null表示拒绝访问 + } + }); + } + + +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/controller/OSSController.java b/main/src/main/java/top/krcia/elysiaserver/main/controller/OSSController.java new file mode 100644 index 0000000..7b52b82 --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/controller/OSSController.java @@ -0,0 +1,44 @@ +package top.krcia.elysiaserver.main.controller; + +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.AntPathMatcher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.HandlerMapping; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.Path; + +/** + * @ignore + */ +@RequestMapping("/oss/") +@RestController +public class OSSController { + + @Value("${app.release}") + private String metadataSavePath; + + @GetMapping("/**") + public void oss(HttpServletRequest request, HttpServletResponse response) throws Exception { + final String path = + request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString(); + final String bestMatchingPattern = + request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(); + File file = new File(Path.of(metadataSavePath, new AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path)).toString()); + try (FileInputStream in = new FileInputStream(file); + ServletOutputStream out = response.getOutputStream()) { + byte[] buffer = new byte[1024]; + int len; + while ((len = in.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + } catch (Exception e) { + } + } +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/controller/ServerInfoController.java b/main/src/main/java/top/krcia/elysiaserver/main/controller/ServerInfoController.java new file mode 100644 index 0000000..f4f42e0 --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/controller/ServerInfoController.java @@ -0,0 +1,144 @@ +package top.krcia.elysiaserver.main.controller; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import jakarta.annotation.Resource; +import lombok.SneakyThrows; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; +import top.krcia.elysiaserver.main.controller.base.BaseController; +import top.krcia.elysiaserver.main.dao.SysUserDao; +import top.krcia.elysiaserver.main.entity.pojo.SysUser; +import top.krcia.elysiaserver.main.entity.vo.VersionInfoVo; +import top.krcia.elysiaserver.main.entity.vo.BalanceVo; +import top.krcia.elysiaserver.result.R; +import top.krcia.elysiaserver.result.RS; +import top.krcia.elysiaserver.utils.JWTGenerator; +import top.krcia.elysiaserver.utils.request.WebRequest; + +import java.io.File; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; + +/** + * 服务器 + */ +@RestController +public class ServerInfoController extends BaseController { + + + @Resource + private SysUserDao sysUserDao; + + /** + * 当前版本 + * + * @return + */ + @GetMapping("/version") + public R version() { + return R.success(version); + } + + /** + * 查询余额 + * + * @return + */ + @GetMapping("/balance") + public R balance(@RequestHeader("Authorization") String authorization) { + Long userId = JWTGenerator.getUserId(authorization); + SysUser sysUser = new SysUser(userId); + sysUser = sysUserDao.selectById(sysUser); + try { + Map header = new HashMap<>(); + header.put("Authorization", "Bearer " + sysUser.getDeepseekKey()); + String resData = WebRequest.Create(new URI("https://api.deepseek.com/user/balance")).setHeader(header).setContentType(MediaType.APPLICATION_JSON).execute(); + JSONObject job = JSON.parseObject(resData); + BalanceVo balance = new BalanceVo(job.getBoolean("is_available"), job.getJSONArray("balance_infos").getJSONObject(0).getString("total_balance")); + return R.success(balance); + } catch (Exception e) { + return R.print(RS.UPSTREAM_SERVER_ERROR); + } + } + + /** + * 查询APP最新版本 + * + * @return + */ + @GetMapping("/latest-version") + public R newVersion() { + VersionInfoVo versionInfo = newVersion(appReleasePath); + return R.success(versionInfo); + } + + /** + * 当前版本信息 + * + * @return + */ + @GetMapping("/version/{targetCode}") + public R Version(@PathVariable Integer targetCode) { + VersionInfoVo versionInfo = targetVersion(appReleasePath, targetCode); + if (versionInfo == null) { + return R.print(RS.UNKNOWN_VERSION); + } + return R.success(versionInfo); + } + + @SneakyThrows + public VersionInfoVo newVersion(String folderPath) { + int targetCode=0; + VersionInfoVo versionInfo=null; + File directory = new File(folderPath.concat("/release")); + File[] files = directory.listFiles(); + + for (File file : files) { + if (file.isDirectory()) { + String name = file.getName(); + if (name.matches("\\d+")) { + int newCode = Integer.parseInt(name); + if (newCode > targetCode) { + targetCode=newCode; + String json = JSON.toJSONString(new String(Files.readAllBytes(new File(file.getPath(), "info.json").toPath()), StandardCharsets.UTF_8)); + JSONObject jsonObject = JSON.parseObject(json); + String url =file.getPath().replace(folderPath,"").replace("\\","/").concat("/app-release.apk"); + versionInfo = new VersionInfoVo(newCode, jsonObject.getString("version"), jsonObject.getString("updateInfo"),url); + } + } + } + } + return versionInfo; + } + + @SneakyThrows + public VersionInfoVo targetVersion(String folderPath, int targetCode) { + File directory = new File(folderPath.concat("/release")); + + File[] files = directory.listFiles(); + + for (File file : files) { + if (file.isDirectory()) { + String name = file.getName(); + if (name.matches("\\d+")) { + int newCode = Integer.parseInt(name); + if (newCode == targetCode) { + String json = JSON.toJSONString(new String(Files.readAllBytes(new File(file.getPath(), "info.json").toPath()), StandardCharsets.UTF_8)); + JSONObject jsonObject = JSON.parseObject(json); + + VersionInfoVo versionInfo = new VersionInfoVo(newCode, jsonObject.getString("version"), jsonObject.getString("updateInfo"),null); + return versionInfo; + } + } + } + } + return null; + } +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/controller/base/BaseController.java b/main/src/main/java/top/krcia/elysiaserver/main/controller/base/BaseController.java new file mode 100644 index 0000000..d2bcf1a --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/controller/base/BaseController.java @@ -0,0 +1,25 @@ +package top.krcia.elysiaserver.main.controller.base; + + +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import top.krcia.elysiaserver.utils.Profile; + +@RequestMapping("/server") +public class BaseController { + @Value("${spring.profiles.active}") + private String active; + + @Value("${elysia-server.version}") + protected String version; + + @Value("${app.release}") + protected String appReleasePath; + protected Profile profile; + + @PostConstruct + private void init() { + profile = Profile.get(active); + } +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/dao/SysUserDao.java b/main/src/main/java/top/krcia/elysiaserver/main/dao/SysUserDao.java new file mode 100644 index 0000000..1e76687 --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/dao/SysUserDao.java @@ -0,0 +1,16 @@ +package top.krcia.elysiaserver.main.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import top.krcia.elysiaserver.main.entity.pojo.SysUser; + +/** + * (SysUser)表数据库访问层 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +public interface SysUserDao extends BaseMapper { +} + diff --git a/main/src/main/java/top/krcia/elysiaserver/main/entity/pojo/SysUser.java b/main/src/main/java/top/krcia/elysiaserver/main/entity/pojo/SysUser.java new file mode 100644 index 0000000..1ae1a6c --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/entity/pojo/SysUser.java @@ -0,0 +1,73 @@ +package top.krcia.elysiaserver.main.entity.pojo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * (SysUser)表实体类 + * + * @author makejava + * @since 2025-09-09 23:01:29 + */ +@SuppressWarnings("serial") +@Data +public class SysUser extends Model { + //用户ID + @TableId(type = IdType.AUTO) + private Long userId; + //头像 + private String avatar; + //姓名 + private String name; + //昵称 + private String nickname; + //用户名 + private String userName; + //密码 + private String password; + //状态:0启用,1禁用,-1删除 + private Integer status; + //状态时间 + private Date statusTime; + //状态时间 + private String email; + //创建时间 + private Date createTime; + //DeepseekApi + private String deepseekKey; + + /** + * 获取主键值 + * + * @return 主键值 + */ + @Override + public Serializable pkVal() { + return this.userId; + } + + public SysUser(String avatar, String name, String nickname, String userName, String password,String email) { + this.avatar = avatar; + this.name = name; + this.nickname = nickname; + this.userName = userName; + this.password = password; + this.status = 0; + this.statusTime = new Date(); + this.email = email; + this.createTime = new Date(); + } + + public SysUser(Long userId) { + this.userId = userId; + } + + public SysUser() { + } +} + diff --git a/main/src/main/java/top/krcia/elysiaserver/main/entity/vo/BalanceVo.java b/main/src/main/java/top/krcia/elysiaserver/main/entity/vo/BalanceVo.java new file mode 100644 index 0000000..d98a2ad --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/entity/vo/BalanceVo.java @@ -0,0 +1,23 @@ +package top.krcia.elysiaserver.main.entity.vo; + +import lombok.Data; + +@Data +public class BalanceVo { + /** + * 是否可用 + */ + private boolean isAvailable; + /** + * 总余额(人名币) + */ + private String balance; + + public BalanceVo(boolean isAvailable, String balance) { + this.isAvailable = isAvailable; + this.balance = balance; + } + + public BalanceVo() { + } +} diff --git a/main/src/main/java/top/krcia/elysiaserver/main/entity/vo/VersionInfoVo.java b/main/src/main/java/top/krcia/elysiaserver/main/entity/vo/VersionInfoVo.java new file mode 100644 index 0000000..898a37f --- /dev/null +++ b/main/src/main/java/top/krcia/elysiaserver/main/entity/vo/VersionInfoVo.java @@ -0,0 +1,27 @@ +package top.krcia.elysiaserver.main.entity.vo; + +import lombok.Data; +import top.krcia.elysiaserver.main.annotate.Metadata; + +@Data +public class VersionInfoVo { + //版本代码 + private int versionCode; + //版本号 + private String version; + //更新内容 + private String updateInfo; + //位置 + @Metadata + private String url; + + public VersionInfoVo(int versionCode, String version, String updateInfo,String url) { + this.versionCode = versionCode; + this.version = version; + this.updateInfo = updateInfo; + this.url = url; + } + + public VersionInfoVo() { + } +} diff --git a/main/src/main/resources/application-development.yml b/main/src/main/resources/application-development.yml new file mode 100644 index 0000000..427d5b3 --- /dev/null +++ b/main/src/main/resources/application-development.yml @@ -0,0 +1,15 @@ +spring: + data: + redis: + host: krcia.top + port: 6379 + password: xiong990416. + database: 3 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://krcia.top:3306/elysia-db?serverTimezone=Asia/Shanghai + username: root + password: xiong990416. +app: + agent-url: http://192.168.1.2:4561/oss + release: F:\Krcia\elysia-server\metadata diff --git a/main/src/main/resources/application-release.yml b/main/src/main/resources/application-release.yml new file mode 100644 index 0000000..e69de29 diff --git a/main/src/main/resources/application.yml b/main/src/main/resources/application.yml new file mode 100644 index 0000000..5b82c79 --- /dev/null +++ b/main/src/main/resources/application.yml @@ -0,0 +1,11 @@ +server: + port: 4561 +spring: + application: + name: elysia-server + profiles: + active: development +elysia-server: + version: v0.1-0909-dev + enable-cors: true + enable-api-doc: true \ No newline at end of file diff --git a/main/src/main/resources/smart-doc.json b/main/src/main/resources/smart-doc.json new file mode 100644 index 0000000..42e7a85 --- /dev/null +++ b/main/src/main/resources/smart-doc.json @@ -0,0 +1,20 @@ +{ + "outPath": "./src/main/resources/static/doc", + "serverUrl": "/api", + "serverEnv": "http://{{server}}", + "allInOne": true, + "coverOld": true, + "createDebugPage": true, + "showAuthor": "true", + "allInOneDocFileName": "index.html", + "requestHeaders": [ + { + "name": "Authorization", + "type": "string", + "value": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-", + "desc": "鉴权信息", + "required": true, + "excludePathPatterns": "/server/version" + } + ] +} \ No newline at end of file diff --git a/main/src/main/resources/static/doc/AllInOne.css b/main/src/main/resources/static/doc/AllInOne.css new file mode 100644 index 0000000..b22c6a2 --- /dev/null +++ b/main/src/main/resources/static/doc/AllInOne.css @@ -0,0 +1,13 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}script{display:none!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}.left{float:left!important}.right{float:right!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}.hide{display:none}img,object,svg{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.center{margin-left:auto;margin-right:auto}.spread{width:100%}p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#364149;text-decoration:underline;line-height:inherit}a:hover,a:focus{color:#364149}a img{border:0}p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4,h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} +ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:2.75em}h2{font-size:2.3125em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}*:not(pre)>code.nobreak{word-wrap:normal}*:not(pre)>code.nowrap{white-space:nowrap}pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}em em{font-style:normal}strong strong{font-weight:400}.keyseq{color:rgba(51,51,51,.8)}kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menuref{color:#000}.menuseq b:not(.caret),.menuref{font-weight:inherit}.menuseq{word-spacing:-.02em}.menuseq b.caret{font-size:1.25em;line-height:.8}.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,.9)}#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-.125em}#header .details span.email a{color:rgba(0,0,0,.85)}#header .details br{display:none} +#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}#toc>ul{margin-left:.125em;padding-left:1.25em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}#toc li{line-height:1.3334;margin-top:.3334em;padding-bottom:4px;padding-top:4px}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#7a2518;font-size:1.2em}@media only screen and (min-width:768px){#toctitle{font-size:1.375em}body.toc2{padding-left:15em;padding-right:0}#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;#padding:1.25em 1em;height:100%;overflow:auto}#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}#toc.toc2>ul{font-size:.9em;margin-bottom:0}#toc.toc2 ul ul{margin-left:0;padding-left:1em}#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}body.toc2.toc-right{padding-left:0;padding-right:15em}body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}#toc.toc2{width:20em}#toc.toc2 #toctitle{border-bottom:1px solid rgba(0,0,0,.07);padding-top:20px;padding-bottom:15px}#toc.toc2 #toctitle span{padding-left:1.25em;padding-bottom:15px}#toc.toc2>ul{font-size:.95em}#toc.toc2 ul ul{padding-left:1.25em}body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}#footer-text{color:rgba(255,255,255,.8);line-height:1.44}.sect1{padding-bottom:.625em}@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:0;width:100%}.admonitionblock>table td.icon{text-align:center;width:80px} +.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}.listingblock pre.highlightjs{padding:0}.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}.listingblock pre.prettyprint{border-width:0}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock:hover code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:0}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:inline-block;margin-right:.25em}table.pyhltable .linenodiv{background:none!important;padding-right:0!important}.quoteblock{margin:0 1em 1.25em 1.5em;display:table}.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}.quoteblock blockquote{margin:0;padding:0;border:0}.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 1em}.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} +.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px 0}table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0 0}table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}p.tableblock>code:only-child{background:0;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}ul.unstyled,ol.unstyled{margin-left:0}ul.checklist{margin-left:.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:400;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:0}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:0}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}.colist>table tr>td:first-of-type{padding:.4em .75em 0 .75em;line-height:1;vertical-align:top}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}.imageblock.left,.imageblock[style*="float:left"]{margin:.25em .625em 1.25em 0}.imageblock.right,.imageblock[style*="float:right"]{margin:.25em 0 1.25em .625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}.image.left{margin-right:.625em}.image.right{margin-left:.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none} +sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:#000}.black-background{background-color:#000}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000}.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}a span.icon>.fa{cursor:inherit}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff!important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:-.125em}b.conum *{color:inherit!important}.conum:not([data-value]):empty{display:none}dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}h1,h2,p,td.content,span.alt{letter-spacing:-.01em}p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}p{margin-bottom:1.25rem}.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}.print-only{display:none!important}@media print{@page{margin:1.25cm .75cm}*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}a{color:inherit!important;text-decoration:underline!important}a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote,tr,img,object,svg{page-break-inside:avoid}thead{display:table-header-group}svg{max-width:100%}p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}#toc,.sidebarblock,.exampleblock>.content{background:none!important}#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}.sect1{padding-bottom:0!important}.sect1+.sect1{border:0!important}#header>h1:first-child{margin-top:1.25rem} + body.book #header{text-align:center}body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}body.book #header .details{border:0!important;display:block;padding:0!important}body.book #header .details span:first-child{margin-left:0!important}body.book #header .details br{display:block}body.book #header .details br+span:before{content:none!important}body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}.listingblock code[data-lang]:before{display:block}#footer{background:none!important;padding:0 .9375em}#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}.hide-on-print{display:none!important}.print-only{display:block!important}.hide-for-print{display:none!important}.show-for-print{display:inherit!important}}#content .page-footer{height:100px;border-top:1px solid #ccc;overflow:hidden;padding:10px 0;font-size:14px;color:gray}#content .footer-modification{float:right}#content .footer-modification a{text-decoration:none}.sectlevel2{display:none}.submenu{background:#e7e7e6}.submenu li{border:0}.submenu a{color:#555}.checkbox{position:relative;height:30px}.checkbox input[type='checkbox']{left:0;top:0;width:20px;height:20px;opacity:0;border-radius:4px}.checkbox label{position:absolute;left:30px;top:0;height:20px;line-height:20px}.checkbox label:before{content:'';position:absolute;left:-30px;top:2px;width:20px;height:20px;border:1px solid #ddd;border-radius:4px;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease}.checkbox label:after{content:'';position:absolute;left:-22px;top:3px;width:6px;height:12px;border:0;border-right:1px solid #fff;border-bottom:1px solid #fff;border-radius:2px;transform:rotate(45deg);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease}.checkbox input[type='checkbox']:checked+label:before{background:#4cd764;border-color:#4cd764}.checkbox input[type='checkbox']:checked+label:after{background:#4cd764}.send-button{color:#fff;background-color:#5cb85c;display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px;outline-color:transparent}textarea{width:100%;background-color:#f7f7f8;border:1px solid #f7f7f8;border-radius:4px;font-size:1em;padding:1em;font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;outline-color:#dedede}input{border:0;background-color:transparent;outline-color:transparent;outline-style:dotted;max-width:100%}#book-search-input{padding:13px;background:0;transition:top .5s ease;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}[contenteditable="plaintext-only"]:focus{border:0;outline:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}script{display:none!important}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} +button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}.left{float:left!important}.right{float:right!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}.hide{display:none}img,object,svg{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.center{margin-left:auto;margin-right:auto}.spread{width:100%}p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#364149;text-decoration:underline;line-height:inherit}a:hover,a:focus{color:#364149}a img{border:0}p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4,h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:2.75em}h2{font-size:2.3125em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} +table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}*:not(pre)>code.nobreak{word-wrap:normal}*:not(pre)>code.nowrap{white-space:nowrap}pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}em em{font-style:normal}strong strong{font-weight:400}.keyseq{color:rgba(51,51,51,.8)}kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menuref{color:#000}.menuseq b:not(.caret),.menuref{font-weight:inherit}.menuseq{word-spacing:-.02em}.menuseq b.caret{font-size:1.25em;line-height:.8}.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,.9)}#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-.125em}#header .details span.email a{color:rgba(0,0,0,.85)}#header .details br{display:none}#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}#toc>ul{margin-left:.125em;padding-left:1.25em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}#toc li{line-height:1.3334;margin-top:.3334em;padding-bottom:4px;padding-top:4px}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#7a2518;font-size:1.2em}@media only screen and (min-width:768px){#toctitle{font-size:1.375em}body.toc2{padding-left:15em;padding-right:0}#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;#padding:1.25em 1em;height:100%;overflow:auto}#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} + #toc.toc2>ul{font-size:.9em;margin-bottom:0}#toc.toc2 ul ul{margin-left:0;padding-left:1em}#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}body.toc2.toc-right{padding-left:0;padding-right:15em}body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}#toc.toc2{width:20em}#toc.toc2 #toctitle{font-size:1.375em;border-bottom:1px solid rgba(0,0,0,.07);padding-top:20px;padding-bottom:15px}#toc.toc2 #toctitle span{padding-left:1.25em;padding-bottom:15px}#toc.toc2>ul{font-size:.95em}#toc.toc2 ul ul{padding-left:1.25em}body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}#footer-text{color:rgba(255,255,255,.8);line-height:1.44}.sect1{padding-bottom:.625em}@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:0;width:100%}.admonitionblock>table td.icon{text-align:center;width:80px}.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} +.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}.listingblock pre.highlightjs{padding:0}.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}.listingblock pre.prettyprint{border-width:0}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock:hover code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:0}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:inline-block;margin-right:.25em}table.pyhltable .linenodiv{background:none!important;padding-right:0!important}.quoteblock{margin:0 1em 1.25em 1.5em;display:table}.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}.quoteblock blockquote{margin:0;padding:0;border:0}.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 1em}.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px 0}table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0 0}table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0} +table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}p.tableblock>code:only-child{background:0;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}ul.unstyled,ol.unstyled{margin-left:0}ul.checklist{margin-left:.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:400;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:0}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:0}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}.colist>table tr>td:first-of-type{padding:.4em .75em 0 .75em;line-height:1;vertical-align:top}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}.imageblock.left,.imageblock[style*="float:left"]{margin:.25em .625em 1.25em 0}.imageblock.right,.imageblock[style*="float:right"]{margin:.25em 0 1.25em .625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}.image.left{margin-right:.625em}.image.right{margin-left:.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none}sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:#000}.black-background{background-color:#000}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000} +.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}a span.icon>.fa{cursor:inherit}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff!important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:-.125em}b.conum *{color:inherit!important}.conum:not([data-value]):empty{display:none}dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}h1,h2,p,td.content,span.alt{letter-spacing:-.01em}p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}p{margin-bottom:1.25rem}.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}.print-only{display:none!important}@media print{@page{margin:1.25cm .75cm}*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}a{color:inherit!important;text-decoration:underline!important}a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}abbr[title]:after{content:" (" attr(title) ")"}pre,blockquote,tr,img,object,svg{page-break-inside:avoid}thead{display:table-header-group}svg{max-width:100%}p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}#toc,.sidebarblock,.exampleblock>.content{background:none!important}#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}.sect1{padding-bottom:0!important}.sect1+.sect1{border:0!important}#header>h1:first-child{margin-top:1.25rem}body.book #header{text-align:center}body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}body.book #header .details{border:0!important;display:block;padding:0!important}body.book #header .details span:first-child{margin-left:0!important}body.book #header .details br{display:block}body.book #header .details br+span:before{content:none!important}body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}.listingblock code[data-lang]:before{display:block}#footer{background:none!important;padding:0 .9375em}#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}.hide-on-print{display:none!important}.print-only{display:block!important}.hide-for-print{display:none!important}.show-for-print{display:inherit!important}}#content .page-footer{height:100px;border-top:1px solid #ccc;overflow:hidden;padding:10px 0;font-size:14px;color:gray}#content .footer-modification{float:right}#content .footer-modification a{text-decoration:none}.sectlevel2{display:none}.submenu{background:#e7e7e6}.submenu li{border:0}.submenu a{color:#555}.copyright{text-align:right;padding-top:1.25em}#toTop{display:none;position:fixed;bottom:10px;right:0;width:44px;height:44px;border-radius:50%;background-color:#ced4ce;cursor:pointer;text-align:center}#upArrow{position:absolute;left:24%;right:0;bottom:19%;transition:.3s ease-in-out;display:block}#upText{position:absolute;left:0;right:0;bottom:0;font-size:16px;font-weight: 600;line-height:45px;display:none;transition:.3s ease-in-out;-webkit-box-align:center} \ No newline at end of file diff --git a/main/src/main/resources/static/doc/debug.js b/main/src/main/resources/static/doc/debug.js new file mode 100644 index 0000000..c3a9135 --- /dev/null +++ b/main/src/main/resources/static/doc/debug.js @@ -0,0 +1,407 @@ +$(function () { + const Accordion = function (el, multiple) { + this.el = el || {}; + this.multiple = multiple || false; + const links = this.el.find('.dd'); + links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown); + }; + Accordion.prototype.dropdown = function (e) { + const $el = e.data.el; + const $this = $(this), $next = $this.next(); + $next.slideToggle(); + $this.parent().toggleClass('open'); + if (!e.data.multiple) { + $el.find('.submenu').not($next).slideUp("20").parent().removeClass( + 'open'); + } + }; + new Accordion($('#accordion'), false); + hljs.highlightAll(); +}); + +$("[contenteditable=plaintext-only]").on('blur', function (e) { + e.preventDefault(); + const $this = $(this); + const data = $this.text(); + let content; + if (undefined === e.originalEvent.clipboardData) { + content = data; + } else { + content = e.originalEvent.clipboardData.getData('text/plain') + } + content = JSON.stringify(JSON.parse(content), null, 4); + const highlightedCode = hljs.highlight('json', content).value; + $this.html(highlightedCode); +}) +$("button").on("click", function () { + const $this = $(this); + const id = $this.data("id"); + console.log("method-id=>" + id); + + let body = $("#" + id + "-body").text(); + + // header + const $headerElement = $("#" + id + "-header"); + const headersData = getInputData($headerElement); + + // body param + const $paramElement = $("#" + id + "-param"); + let bodyParamData = getInputData($paramElement) + + // path param + const $pathElement = $("#" + id + "-path-params") + const pathParamData = getInputData($pathElement) + + // query param + const $queryElement = $("#" + id + "-query-params") + let $urlDataElement = $("#" + id + "-url"); + const url = $urlDataElement.data("url"); + const isDownload = $urlDataElement.data("download"); + const page = $urlDataElement.data("page"); + const method = $("#" + id + "-method").data("method"); + const contentType = $("#" + id + "-content-type").data("content-type"); + console.log("request-headers=>" + JSON.stringify(headersData)) + console.log("path-params=>" + JSON.stringify(pathParamData)) + + console.log("body-params=>" + JSON.stringify(bodyParamData)) + console.log("json-body=>" + body); + let finalUrl = ""; + let queryParamData; + if (!isEmpty(page)) { + queryParamData = getInputData($queryElement) + finalUrl = castToGetUri(page, pathParamData, queryParamData) + window.open(finalUrl, "_blank"); + return; + } + if (isDownload) { + queryParamData = getInputData($queryElement); + download(url, headersData, pathParamData, queryParamData, bodyParamData, + method, contentType); + return; + } + const ajaxOptions = {}; + + if ("multipart/form-data" === contentType) { + finalUrl = castToGetUri(url, pathParamData); + queryParamData = getInputData($queryElement, true, true) + body = queryParamData; + ajaxOptions.processData = false; + ajaxOptions.contentType = false; + } else if ("POST" === method && contentType !== "multipart/form-data" + && contentType !== "application/json") { + finalUrl = castToGetUri(url, pathParamData); + queryParamData = getInputData($queryElement, true) + body = queryParamData; + } else { + queryParamData = getInputData($queryElement) + finalUrl = castToGetUri(url, pathParamData, queryParamData) + ajaxOptions.contentType = contentType; + } + console.log("query-params=>" + JSON.stringify(queryParamData)); + console.log("url=>" + finalUrl) + ajaxOptions.headers = headersData + ajaxOptions.url = finalUrl + ajaxOptions.type = method + ajaxOptions.data = body; + + const $responseEle = $("#" + id + "-response").find("pre code"); + const ajaxTime = new Date().getTime(); + $.ajax(ajaxOptions).done(function (result, textStatus, jqXHR) { + const totalTime = new Date().getTime() - ajaxTime; + $this.css("background", "#5cb85c"); + $("#" + id + "-resp-status").html( + " Status: " + jqXHR.status + "  " + jqXHR.statusText + + "    Time: " + totalTime + " ms"); + const highlightedCode = hljs.highlight('json', + JSON.stringify(result, null, 4)).value; + $responseEle.html(highlightedCode); + }).fail(function (jqXHR) { + const totalTime = new Date().getTime() - ajaxTime; + $this.css("background", "#D44B47"); + if (jqXHR.status === 0 && jqXHR.readyState === 0) { + $("#" + id + "-resp-status").html( + "Connection refused, please check the server."); + } else { + $("#" + id + "-resp-status").html( + " Status: " + jqXHR.status + "  " + + jqXHR.statusText + "    Time: " + totalTime + + " ms"); + } + if (undefined !== jqXHR.responseJSON) { + const highlightedCode = hljs.highlight('json', + JSON.stringify(jqXHR.responseJSON, null, 4)).value; + $responseEle.html(highlightedCode); + } + }).always(function () { + + }); + const curlCmd = toCurl(ajaxOptions); + const highlightedCode = hljs.highlight('bash', curlCmd).value; + $("#" + id + "-curl").find("pre code").html(highlightedCode); +}) +$(".check-all").on("click", function () { + const checkboxName = $(this).prop("name"); + const checked = $(this).is(':checked'); + if (!checked) { + $(this).removeAttr("checked"); + } else { + $(this).prop("checked", true); + } + $('input[name="' + checkboxName + '"]').each(function () { + if (!checked) { + $(this).prop("checked", false); + } else { + $(this).prop("checked", true); + } + }) +}) + +function castToGetUri(url, pathParams, params) { + if (undefined !== url) { + let urls = url.split(";") + url = urls[0]; + } + if (pathParams instanceof Object && !(pathParams instanceof Array)) { + url = url.format(pathParams) + } + if (params instanceof Object && !(params instanceof Array)) { + const pm = params || {}; + const arr = []; + arr.push(url); + let j = 0; + for (const i in pm) { + if (j === 0) { + arr.push("?"); + arr.push(i + "=" + pm[i]); + } else { + arr.push("&" + i + "=" + pm[i]); + } + j++; + } + return arr.join(""); + } else { + return url; + } +} + +function getInputData(element, isPost, returnFormDate) { + const formData = new FormData(); + $(element).find("tr").each(function (i) { + const checked = $(this).find('td:eq(0)').children(".checkbox").children( + "input").is(':checked'); + if (checked) { + const input = $(this).find('td:eq(2) input'); + let attr = $(input).attr("type"); + let multiple = $(input).attr("multiple"); + console.log("input type:" + attr) + const name = $(input).attr("name"); + if (attr === "file") { + let files = $(input)[0].files; + if (multiple) { + $.each(files, function (i, file) { + formData.append(name, file); + }) + } else { + formData.append(name, files[0]); + } + } else { + const val = $(input).val(); + if (isValidUrl(val)) { + formData.append(name, encodeURI(val)); + } else { + // support chinese + if (hasChinese(val) && !isPost) { + formData.append(name, encodeURIComponent(val)); + } else { + formData.append(name, val); + } + } + } + } + }); + if (returnFormDate) { + return formData; + } + const headersData = {}; + formData.forEach((value, key) => headersData[key] = value); + return headersData; +} + +String.prototype.format = function (args) { + let reg; + if (arguments.length > 0) { + let result = this; + if (arguments.length === 1 && typeof (args) == "object") { + for (const key in args) { + reg = new RegExp("({" + key + "})", "g"); + result = result.replace(reg, args[key]); + } + } else { + for (let i = 0; i < arguments.length; i++) { + if (arguments[i] === undefined) { + return ""; + } else { + reg = new RegExp("({[" + i + "]})", "g"); + result = result.replace(reg, arguments[i]); + } + } + } + return result; + } else { + return this; + } +} + +function download(url, headersData, pathParamData, queryParamData, + bodyParamData, method, contentType) { + url = castToGetUri(url, pathParamData, queryParamData) + const xmlRequest = new XMLHttpRequest(); + xmlRequest.open(method, url, true); + xmlRequest.setRequestHeader("Content-type", contentType); + for (let key in headersData) { + xmlRequest.setRequestHeader(key, headersData[key]) + } + xmlRequest.responseType = "blob"; + xmlRequest.onload = function () { + if (this.status === 200) { + let fileName = ""; + const disposition = xmlRequest.getResponseHeader('Content-Disposition'); + if (disposition && disposition.indexOf('attachment') !== -1) { + const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; + const matches = filenameRegex.exec(disposition); + if (matches != null && matches[1]) { + fileName = decodeURI(matches[1].replace(/['"]/g, '')); + } + } + console.log("download filename:" + fileName); + const blob = this.response; + if (navigator.msSaveBlob) { + // IE10 can't do a[download], only Blobs: + window.navigator.msSaveBlob(blob, fileName); + return; + } + if (window.URL) { // simple fast and modern way using Blob and URL: + const a = document.createElement("a"); + document.body.appendChild(a); + const url = window.URL.createObjectURL(blob); + a.href = url; + a.download = fileName; + a.click(); + window.URL.revokeObjectURL(url); + } + console.log(fileName); + } else { + console.log("download failed"); + } + }; + try { + xmlRequest.send(bodyParamData); + } catch (e) { + console.error("Failed to send data", e); + } +} + +function toCurl(request) { + if (typeof request !== 'object') { + throw "Request is not an object"; + } + // default is a GET request + const cmd = ["curl", "-X", request.type || "GET"]; + + if (request.url.indexOf('https') === 0) { + cmd.push("-k"); + } + + // append Content-Type + if (request.contentType) { + cmd.push("-H"); + cmd.push("'Content-Type:"); + cmd.push(request.contentType + "'"); + } + // append request headers + let headerValue; + if (typeof request.headers == 'object') { + for (let key in request.headers) { + if (Object.prototype.hasOwnProperty.call(request.headers, key)) { + cmd.push("-H"); + headerValue = request.headers[key]; + if (headerValue.value === '') { + cmd.push("'" + key + "'"); + } else { + cmd.push("'" + key + ':' + headerValue + "'"); + } + } + } + } + + // display the response headers + cmd.push("-i"); + // append request url + let url = request.url; + if (!url.startsWith("http")) { + const protocol = window.document.location.protocol; + const domain = window.document.location.hostname; + const port = window.document.location.port; + url = protocol + "//" + domain + ":" + port + url; + } + cmd.push(url); + // append data + + if (typeof request.data == 'object') { + let index = 0; + const bodyData = []; + bodyData.push("\"") + for (let key in request.data) { + if (Object.prototype.hasOwnProperty.call(request.data, key)) { + if (index === 0) { + bodyData.push(key); + bodyData.push("="); + bodyData.push(request.data[key]); + } else { + bodyData.push("&") + bodyData.push(key); + bodyData.push("="); + bodyData.push(request.data[key]); + } + } + index++; + } + bodyData.push("\""); + let bodyStr = "" + bodyData.forEach(function (item) { + bodyStr += item; + }); + cmd.push("--data"); + cmd.push(bodyStr); + } else if (request.data && request.data.length > 0) { + // append json data + cmd.push("--data"); + cmd.push("'" + request.data + "'"); + } + + let curlCmd = ""; + cmd.forEach(function (item) { + curlCmd += item + " "; + }); + console.log(curlCmd); + return curlCmd; +} + +function isEmpty(obj) { + return obj === undefined || obj === null || String(obj).trim() === ''; +} + +function hasChinese(_string) { + const chineseReg = /[\u4e00-\u9fa5]/g + return chineseReg.test(_string); +} + +function isValidUrl(_string) { + let urlString; + try { + urlString = new URL(_string); + } catch (_) { + return false; + } + return urlString.protocol === "http:" || urlString.protocol === "https:"; +} diff --git a/main/src/main/resources/static/doc/font.css b/main/src/main/resources/static/doc/font.css new file mode 100644 index 0000000..3c85d80 --- /dev/null +++ b/main/src/main/resources/static/doc/font.css @@ -0,0 +1,6 @@ +@font-face{font-family:'Droid Sans Mono';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/droidsansmono/v19/6NUO8FuJNQ2MbkrZ5-J8lKFrp7pRef2r.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZzC7TMQ.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImbjC7TMQ.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZjC7TMQ.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImaTC7TMQ.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZTC7TMQ.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImZDC7TMQ.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Kaw1J5X9T9RW6j9bNfFImajC7.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufuVMCoY.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWud-VMCoY.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWuf-VMCoY.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWucOVMCoY.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufOVMCoY.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWufeVMCoY.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:italic;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Vaw1J5X9T9RW6j9bNfFIu0RWuc-VM.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFoWaCi_.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F} +@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFMWaCi_.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFsWaCi_.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFQWaCi_.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFgWaCi_.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFkWaCi_.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Iaw1J5X9T9RW6j9bNfFcWaA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRqecf1I.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfROecf1I.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRuecf1I.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRSecf1I.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRiecf1I.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfRmecf1I.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Noto Serif';font-style:normal;font-weight:700;src:url(https://fonts.gstatic.com/s/notoserif/v20/ga6Law1J5X9T9RW6j9bNdOwzfReecQ.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF} +@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV0ewJER.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVQewJER.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116} +@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVwewJER.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVMewJER.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVIewJER.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV8ewJER.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWV4ewJER.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjWVAewA.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0B4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} +@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4taVIGxA.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4kaVIGxA.woff2) format('woff2');unicode-range:U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4saVIGxA.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4jaVIGxA.woff2) format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4iaVIGxA.woff2) format('woff2');unicode-range:U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4vaVIGxA.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4uaVIGxA.woff2) format('woff2');unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF} +@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;font-stretch:normal;src:url(https://fonts.gstatic.com/s/opensans/v28/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1x4gaVI.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} \ No newline at end of file diff --git a/main/src/main/resources/static/doc/highlight.min.js b/main/src/main/resources/static/doc/highlight.min.js new file mode 100644 index 0000000..664e1aa --- /dev/null +++ b/main/src/main/resources/static/doc/highlight.min.js @@ -0,0 +1,1213 @@ +/*! + Highlight.js v11.9.0 (git: f47103d4f1) + (c) 2006-2023 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";function e(n){ + return n instanceof Map?n.clear=n.delete=n.set=()=>{ + throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{ + throw Error("set is read-only") + }),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{ + const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a) + })),n}class n{constructor(e){ + void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} + ignoreMatch(){this.isMatchIgnored=!0}}function t(e){ + return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") + }function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n] + ;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope + ;class r{constructor(e,n){ + this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){ + this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{ + if(e.startsWith("language:"))return e.replace("language:","language-") + ;if(e.includes(".")){const t=e.split(".") + ;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ") + }return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)} + closeNode(e){i(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ + this.buffer+=``}}const s=(e={})=>{const n={children:[]} + ;return Object.assign(n,e),n};class o{constructor(){ + this.rootNode=s(),this.stack=[this.rootNode]}get top(){ + return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ + this.top.children.push(e)}openNode(e){const n=s({scope:e}) + ;this.add(n),this.stack.push(n)}closeNode(){ + if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ + for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} + walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){ + return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n), + n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){ + "string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ + o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e} + addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){ + this.closeNode()}__addSublanguage(e,n){const t=e.root + ;n&&(t.scope="language:"+n),this.add(t)}toHTML(){ + return new r(this,this.options).value()}finalize(){ + return this.closeAllNodes(),!0}}function c(e){ + return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")} + function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")} + function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{ + const n=e[e.length-1] + ;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{} + })(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"} + function p(e){return RegExp(e.toString()+"|").exec("").length-1} + const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ + ;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t + ;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break} + i+=a.substring(0,e.index), + a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0], + "("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)} + const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={ + begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'", + illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", + contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n, + contains:[]},t);i.contains.push({scope:"doctag", + begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", + end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) + ;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) + ;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i + },M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({ + __proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{ + scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x, + C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number", + begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{ + "on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f, + MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0}, + NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y, + PHRASAL_WORDS_MODE:{ + begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ + },QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/, + end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]}, + RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", + SHEBANG:(e={})=>{const n=/^#![ ]*\// + ;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n, + end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)}, + TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E, + UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){ + "."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){ + void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){ + n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", + e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, + void 0===e.relevance&&(e.relevance=0))}function I(e,n){ + Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){ + if(e.match){ + if(e.begin||e.end)throw Error("begin & end are not supported with match") + ;e.begin=e.match,delete e.match}}function B(e,n){ + void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return + ;if(e.starts)throw Error("beforeMatch cannot be used with starts") + ;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n] + })),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={ + relevance:0,contains:[Object.assign(t,{endsParent:!0})] + },e.relevance=0,delete t.beforeMatch + },z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword" + ;function U(e,n,t=F){const a=Object.create(null) + ;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{ + Object.assign(a,U(e[t],n,t))})),a;function i(e,t){ + n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|") + ;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){ + return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{ + console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{ + P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0) + },G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={} + ;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1]) + ;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{ + e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, + delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ + _wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope + }),(e=>{if(Array.isArray(e.begin)){ + if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), + G + ;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"), + G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{ + if(Array.isArray(e.end)){ + if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"), + G + ;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"), + G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){ + function n(n,t){ + return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":"")) + }class t{constructor(){ + this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} + addRule(e,n){ + n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]), + this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) + ;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|" + }),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex + ;const n=this.matcherRe.exec(e);if(!n)return null + ;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t] + ;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){ + this.rules=[],this.multiRegexes=[], + this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ + if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t + ;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))), + n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){ + return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){ + this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){ + const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex + ;let t=n.exec(e) + ;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{ + const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)} + return t&&(this.regexIndex+=t.position+1, + this.regexIndex===this.count&&this.considerAll()),t}} + if(e.compilerExtensions||(e.compilerExtensions=[]), + e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") + ;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r + ;if(r.isCompiled)return o + ;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))), + r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null + ;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords), + l=r.keywords.$pattern, + delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)), + o.keywordPatternRe=n(l,!0), + s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/), + r.end&&(o.endRe=n(o.end)), + o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)), + r.illegal&&(o.illegalRe=n(r.illegal)), + r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{ + variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{ + starts:e.starts?a(e.starts):null + }):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o) + })),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i + ;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin" + }))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end" + }),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){ + return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{ + constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}} + const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{ + const a=Object.create(null),i=Object.create(null),r=[];let s=!0 + ;const o="Could not find the language '{}', did you forget to load/include a language module?",c={ + disableAutodetect:!0,name:"Plain text",contains:[]};let p={ + ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, + languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", + cssSelector:"pre code",languages:null,__emitter:l};function _(e){ + return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i="" + ;"object"==typeof n?(a=e, + t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."), + q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), + i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r) + ;const s=r.result?r.result:f(r.language,r.code,t) + ;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){ + const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A) + ;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t="" + ;for(;n;){t+=A.substring(e,n.index) + ;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){ + const[e,a]=r + ;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{ + const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0] + ;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a + ;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{ + if(""===A)return;let e=null;if("string"==typeof x.subLanguage){ + if(!a[x.subLanguage])return void S.addText(A) + ;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top + }else e=E(A,x.subLanguage.length?x.subLanguage:null) + ;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language) + })():c(),A=""}function g(e,n){ + ""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1 + ;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue} + const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}} + function b(e,n){ + return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope), + e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), + A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{ + value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n) + ;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e) + ;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){ + for(;e.endsParent&&e.parent;)e=e.parent;return e}} + if(e.endsWithParent)return m(e.parent,t,a)}function _(e){ + return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){ + const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x + ;x.endScope&&x.endScope._wrap?(d(), + g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(), + u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n), + d(),r.excludeEnd&&(A=n));do{ + x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent + }while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length} + let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0 + ;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){ + if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`) + ;throw n.languageName=e,n.badRule=y.rule,n}return 1} + if(y=r,"begin"===r.type)return(e=>{ + const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]] + ;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t) + ;return a.skip?A+=t:(a.excludeBegin&&(A+=t), + d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r) + ;if("illegal"===r.type&&!i){ + const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"")+'"') + ;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e} + if("illegal"===r.type&&""===o)return 1 + ;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches") + ;return A+=o,o.length}const w=v(e) + ;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"') + ;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[] + ;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope) + ;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{ + if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){ + R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T + ;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e) + ;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e, + value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){ + if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t), + illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T, + context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{ + language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x} + ;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{ + const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)} + ;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1))) + ;i.unshift(t);const r=i.sort(((e,n)=>{ + if(e.relevance!==n.relevance)return n.relevance-e.relevance + ;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1 + ;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s + ;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{ + let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"" + ;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1]) + ;return n||(H(o.replace("{}",t[1])), + H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"} + return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return + ;if(x("before:highlightElement",{el:e,language:t + }),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e) + ;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), + console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), + console.warn("The element with unescaped HTML:"), + console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML) + ;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a) + ;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t + ;e.classList.add("hljs"),e.classList.add("language-"+a) + })(e,t,r.language),e.result={language:r.language,re:r.relevance, + relevance:r.relevance},r.secondBest&&(e.secondBest={ + language:r.secondBest.language,relevance:r.secondBest.relevance + }),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){ + "loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0 + }function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]} + function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ + i[e.toLowerCase()]=n}))}function k(e){const n=v(e) + ;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{ + e[t]&&e[t](n)}))} + "undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ + N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w, + highlightElement:y, + highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"), + q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)}, + initHighlighting:()=>{ + w(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, + initHighlightingOnLoad:()=>{ + w(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") + },registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){ + if(K("Language definition for '{}' could not be registered.".replace("{}",e)), + !s)throw n;K(n),i=c} + i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{ + languageName:e})},unregisterLanguage:e=>{delete a[e] + ;for(const n of Object.keys(i))i[n]===e&&delete i[n]}, + listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O, + autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{ + e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{ + e["before:highlightBlock"](Object.assign({block:n.el},n)) + }),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{ + e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)}, + removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{ + s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b, + lookahead:d,either:m,optional:u,anyNumberOfTimes:g} + ;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t + },te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{ + scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{ + scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/}, + FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/}, + ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", + contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ + scope:"number", + begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", + relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} + }),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le) + ;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={ + className:"number",variants:[{ + begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{ + begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{ + begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{ + begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{ + begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{ + begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], + relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))} + const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye) + ;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/, + end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ + const t=e[0].length+e.index,a=e.input[t] + ;if("<"===a||","===a)return void n.ignoreMatch();let i + ;">"===a&&(((e,{after:n})=>{const t="",M={ + match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)], + keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]} + ;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{ + PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/, + contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ + label:"use_strict",className:"meta",relevance:10, + begin:/^\s*['"]use (strict|asm)['"]/ + },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{ + className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{ + begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", + keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{ + className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{ + className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{ + className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, + excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/, + relevance:0},{variants:[{begin:"<>",end:""},{ + match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin, + "on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{ + begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{ + beginKeywords:"while if switch catch for"},{ + begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", + returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t, + className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t, + relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, + contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, + className:"variable.constant"},E,k,{match:/\$[(.]/}]}} + const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] + ;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={ + begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]} + ;Object.assign(t,{className:"variable",variants:[{ + begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={ + className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={ + begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, + end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/, + contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/, + end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] + },l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 + }),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, + contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ + name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, + keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], + literal:["true","false"], + built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] + },contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{ + match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}, + grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}] + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ + className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ + match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{ + begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ + begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", + end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ + className:"number",variants:[{begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" + },{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ + keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], + type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], + literal:"true false NULL", + built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" + },b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{ + begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], + keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u, + contains:b.concat(["self"]),relevance:0}]),relevance:0},p={ + begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, + keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})], + relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/, + keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/, + end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s] + }]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u, + disableAutodetect:!0,illegal:"=]/,contains:[{ + beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c, + strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{ + contains:[{begin:/\\\n/}] + }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ + className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{ + begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ + begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", + end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ + begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ + className:"number",variants:[{begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" + },{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ + keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" + },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ + className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ + className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 + },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ + type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"], + keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"], + literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"], + _type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"] + },b={className:"function.dispatch",relevance:0,keywords:{ + _hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"] + }, + begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/)) + },m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{ + begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], + keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u, + contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function", + begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, + keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ + begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{ + begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{ + className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0, + contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u, + relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}] + },s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++", + aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{ + match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/], + className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={ + keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]), + built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"], + literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{ + begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{ + begin:"\\b(0b[01']+)"},{ + begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{ + begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" + }],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}] + },r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/, + keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/, + end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/ + },e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{ + begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/, + contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]}) + ;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE], + o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{ + illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] + },u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t] + },b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={ + begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"], + keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0, + contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{ + begin:"\x3c!--|--\x3e"},{begin:""}]}] + }),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#", + end:"$",keywords:{ + keyword:"if else elif endif define undef warning error line region endregion pragma checksum" + }},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/, + illegal:/[^\s:,]/,contains:[{beginKeywords:"where class" + },t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace", + relevance:0,end:/[{;=]/,illegal:/[^\s:]/, + contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ + beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/, + contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta", + begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{ + className:"string",begin:/"/,end:/"/}]},{ + beginKeywords:"new return throw await else",relevance:0},{className:"function", + begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, + end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{ + beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial", + relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, + contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params", + begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0, + contains:[g,a,e.C_BLOCK_COMMENT_MODE] + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{ + const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{ + name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{ + keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"}, + contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/ + },t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0 + },{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 + },t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ + begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}] + },t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{ + begin:/:/,end:/[;}{]/, + contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{ + begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" + },contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0, + excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]", + relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ + },{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ + $pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{ + begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{ + className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{ + const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{ + className:"meta",relevance:10, + match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/) + },{className:"comment",variants:[{ + begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/), + end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{ + className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/, + end:/$/}]}},grmr_go:e=>{const n={ + keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"], + type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"], + literal:["true","false","iota","nil"], + built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"] + };return{name:"Go",aliases:["golang"],keywords:n,illegal:"{const n=e.regex;return{name:"GraphQL",aliases:["gql"], + case_insensitive:!0,disableAutodetect:!1,keywords:{ + keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"], + literal:["true","false","null"]}, + contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{ + scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation", + begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/, + end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{ + scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)), + relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={ + className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{ + begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/, + end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{ + begin:/\$\{(.*?)\}/}]},r={className:"literal", + begin:/\bon|off|true|false|yes|no\b/},s={className:"string", + contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{ + begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}] + },o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0 + },l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{ + name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/, + contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{ + begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)), + className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{ + const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={ + keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"], + literal:["false","true","null"], + type:["char","boolean","long","float","int","byte","short","double"], + built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{ + begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/, + end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0} + ;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/, + contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/, + relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{ + begin:/import java\.[a-z]+\./,keywords:"import",relevance:2 + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/, + className:"string",contains:[e.BACKSLASH_ESCAPE] + },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{ + match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{ + 1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{ + begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type", + 3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword", + 3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ + beginKeywords:"new throw return else",relevance:0},{ + begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{ + 2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/, + end:/\)/,keywords:i,relevance:0, + contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE] + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe, + grmr_json:e=>{const n=["true","false","null"],t={scope:"literal", + beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{ + className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{ + match:/[{}[\],:]/,className:"punctuation",relevance:0 + },e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], + illegal:"\\S"}},grmr_kotlin:e=>{const n={ + keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual", + built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing", + literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@" + },a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={ + className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string", + variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'", + illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/, + contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={ + className:"meta", + begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?" + },o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/, + end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}] + },l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={ + variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/, + contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g], + {name:"Kotlin",aliases:["kt","kts"],keywords:n, + contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag", + begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword", + begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol", + begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$", + returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{ + begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0, + contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://, + keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/, + endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/, + endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0 + },e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{ + begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{ + 3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0, + illegal:"extends implements",contains:[{ + beginKeywords:"public protected internal private constructor" + },e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0, + excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/, + excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env", + end:"$",illegal:"\n"},l]}},grmr_less:e=>{ + const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({ + className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n, + relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only", + attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c, + relevance:0} + ;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{ + begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]", + excludeEnd:!0} + },n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{ + className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0 + },n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({ + begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0, + contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:", + returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/ + },n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b", + end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}] + },m={className:"keyword", + begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b", + starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={ + className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a + }],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{ + begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0, + returnEnd:!0,illegal:"[<='$\"]",relevance:0, + contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{ + begin:"\\b("+re.join("|")+")\\b",className:"selector-tag" + },n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{ + className:"selector-pseudo",begin:":("+oe.join("|")+")"},{ + className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/, + end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={ + begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]} + ;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH), + {name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}}, + grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"] + },i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10 + })];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, + literal:"true false nil", + keyword:"and break do else elseif end for goto if in local not or repeat return then until while", + built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" + },contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)", + contains:[e.inherit(e.TITLE_MODE,{ + begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params", + begin:"\\(",endsWithParent:!0,contains:i}].concat(i) + },e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string", + begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={ + className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)", + contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%{ + const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={ + variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{ + begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, + relevance:2},{ + begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), + relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ + begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ + },{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, + returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", + excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", + end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[], + variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}] + },i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{ + begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[] + }),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r) + ;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o) + })),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ + className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{ + begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", + contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", + end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o, + end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ + begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ + begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", + contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ + begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ + className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ + className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{ + const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n, + keyword:["@interface","@class","@protocol","@implementation"]};return{ + name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"], + keywords:{"variable.language":["this","super"],$pattern:n, + keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"], + literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"], + built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"], + type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"] + },illegal:"/,end:/$/,illegal:"\\n" + },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class", + begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t, + contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE, + relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={ + $pattern:/[\w.]+/, + keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0" + },i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/, + end:/\}/},s={variants:[{begin:/\$\d/},{ + begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])") + },{begin:/[$%@][^\s\w{]/,relevance:0}] + },o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{ + const r="\\1"===i?i:n.concat(i,a) + ;return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t) + },d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{ + endsWithParent:!0}),r,{className:"string",contains:o,variants:[{ + begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[", + end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{ + begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">", + relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'", + contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`", + contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{ + begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number", + begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b", + relevance:0},{ + begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*", + keywords:"split return print reverse grep",relevance:0, + contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{ + begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{ + begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{ + className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{ + begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0 + }),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{ + begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub", + end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{ + begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$", + subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}] + }];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a, + contains:g}},grmr_php:e=>{ + const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={ + scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{ + begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null + }),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{ + illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{ + begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/, + contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{ + n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{ + n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({ + begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{ + begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ + begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{ + begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?" + }],relevance:0 + },g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={ + keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{ + n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase()) + })),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{ + match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{ + 1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{ + match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant" + }},{match:[/::/,/class/],scope:{2:"variable.language"}},{ + match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class", + 3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))], + scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class", + 3:"variable.language"}}]},E={scope:"attr", + match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0, + begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_] + },N={relevance:0, + match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)], + scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N) + ;const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1, + keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/, + endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{ + begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]}, + contains:["self",...w]},...w,{scope:"meta",match:i}] + },e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{ + scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/, + keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE, + contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{ + begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{ + begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{ + match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{ + scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/, + excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use" + },e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params", + begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m, + contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{ + beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait", + illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{ + beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{ + beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/, + contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{ + beginKeywords:"use",relevance:0,end:";",contains:[{ + match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]} + },grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{ + begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*", + end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0 + },e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null, + skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null, + contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text", + aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{ + const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={ + $pattern:/[A-Za-z]\w+|__\w+__/,keyword:a, + built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"], + literal:["__debug__","Ellipsis","False","None","NotImplemented","True"], + type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"] + },r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/, + end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={ + className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{ + begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/, + contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ + begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/, + contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ + begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/, + contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/, + end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/, + relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{ + begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/, + end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/, + contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/, + contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] + },c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={ + className:"number",relevance:0,variants:[{ + begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{ + begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{ + begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})` + },{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})` + }]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i, + contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={ + className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/, + end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i, + contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{ + name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i, + illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if", + relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{ + 1:"keyword",3:"title.function"},contains:[m]},{variants:[{ + match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}], + scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{ + className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}}, + grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt", + starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{ + begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{ + const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/) + ;return{name:"R",keywords:{$pattern:t, + keyword:"function if in break next repeat else for while", + literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10", + built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm" + },contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/, + starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)), + endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{ + scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0 + }]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}] + }),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE], + variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/ + }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"', + relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{ + 1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"}, + match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{ + 2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"}, + match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{ + match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`", + contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{ + const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={ + "variable.constant":["__FILE__","__LINE__","__ENCODING__"], + "variable.language":["self","super"], + keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"], + built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"], + literal:["true","false","nil"]},s={className:"doctag",begin:"@[A-Za-z]+"},o={ + begin:"#<",end:">"},l=[e.COMMENT("#","$",{contains:[s] + }),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10 + }),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/, + end:/\}/,keywords:r},d={className:"string",contains:[e.BACKSLASH_ESCAPE,c], + variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{ + begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{ + begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//, + end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{ + begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{ + begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{ + begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{ + begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{ + begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)), + contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/, + contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number", + relevance:0,variants:[{ + begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{ + begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b" + },{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{ + begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{ + begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{ + className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0, + keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{ + match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class", + 4:"title.class.inherited"},keywords:r},{match:[/(include|extend)\s+/,i],scope:{ + 2:"title.class"},keywords:r},{relevance:0,match:[i,/\.new[. (]/],scope:{ + 1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, + className:"variable.constant"},{relevance:0,match:a,scope:"title.class"},{ + match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{ + begin:e.IDENT_RE+"::"},{className:"symbol", + begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol", + begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable", + begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{ + className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0, + relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*", + keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c], + illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{ + begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[", + end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l) + ;c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m} + },{className:"meta.prompt", + begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])", + starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby", + aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/, + contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}}, + grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0, + begin:n.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,n.lookahead(/\s*\(/)) + },a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] + ;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r, + keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], + literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:""},t]}}, + grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable", + begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS", + case_insensitive:!0,illegal:"[=/|']", + contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{ + className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{ + className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0 + },n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag", + begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo", + begin:":("+a.join("|")+")"},{className:"selector-pseudo", + begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/, + contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute", + begin:"\\b("+ce.join("|")+")\\b"},{ + begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b" + },{begin:/:/,end:/[;}{]/,relevance:0, + contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH] + },{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{ + begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/, + keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i, + className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute" + },r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE] + },n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session", + aliases:["console","shellsession"],contains:[{className:"meta.prompt", + begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/, + subLanguage:"bash"}}]}),grmr_sql:e=>{ + const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={ + begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}} + ;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{ + $pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t + ;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e)) + })(l,{when:e=>e.length<3}),literal:a,type:i, + built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"] + },contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, + keyword:l.concat(s),literal:a,type:i}},{className:"type", + begin:n.either("double precision","large object","with timezone","without timezone") + },c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string", + variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/, + contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{ + className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, + relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0 + },t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={ + match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)), + relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{ + className:"keyword", + match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={ + $pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{ + match:b(/\./,m(...De)),relevance:0},{className:"built_in", + match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{ + className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}] + }],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0, + variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{ + match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/ + },{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{ + match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}] + }),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/) + }),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/ + }),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)] + }),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={ + className:"string", + variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")] + },k=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0, + contains:[e.BACKSLASH_ESCAPE]}],x={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//, + contains:k},M=e=>{const n=b(e,/\//),t=b(/\//,e);return{begin:n,end:t, + contains:[...k,{scope:"comment",begin:`#(?!.*${t})`,end:/$/}]}},S={ + scope:"regexp",variants:[M("###"),M("##"),M("#"),x]},A={match:b(/`/,Fe,/`/) + },C=[A,{className:"variable",match:/\$\d+/},{className:"variable", + match:`\\$${ze}+`}],T=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{ + contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{ + scope:"keyword",match:b(/@/,m(...je))},{scope:"meta",match:b(/@/,Fe)}],R={ + match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type", + match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+") + },{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{ + match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},D={ + begin://,keywords:l,contains:[...a,...c,...T,u,R]};R.contains.push(D) + ;const I={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{ + match:b(Fe,/\s*:/),keywords:"_|0",relevance:0 + },...a,S,...c,...g,...p,f,O,...C,...T,R]},L={begin://, + keywords:"repeat each",contains:[...a,R]},B={begin:/\(/,end:/\)/,keywords:l, + contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/, + relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params", + match:Fe}]},...a,...c,...p,f,O,...T,R,I],endsParent:!0,illegal:/["']/},$={ + match:[/(func|macro)/,/\s+/,m(A.match,Fe,Be)],className:{1:"keyword", + 3:"title.function"},contains:[L,B,n],illegal:[/\[/,/%/]},z={ + match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"}, + contains:[L,B,n],illegal:/\[|%/},F={match:[/operator/,/\s+/,Be],className:{ + 1:"keyword",3:"title"}},U={begin:[/precedencegroup/,/\s+/,Ue],className:{ + 1:"keyword",3:"title"},contains:[R],keywords:[...Te,...Ce],end:/}/} + ;for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label)) + ;n.keywords=l;const t=[...c,...g,...p,f,O,...C];n.contains=[...t,{begin:/\(/, + end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l, + contains:[...a,$,z,{beginKeywords:"struct protocol class extension enum actor", + end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{ + className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c] + },F,U,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0 + },S,...c,...g,...p,f,O,...C,...T,R,I]}},grmr_typescript:e=>{ + const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={ + beginKeywords:"namespace",end:/\{/,excludeEnd:!0, + contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/, + excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a}, + contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e, + keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), + literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta", + begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n)) + ;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)} + ;return Object.assign(n.keywords,s), + n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]), + l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10, + begin:/^\s*['"]use strict['"]/ + }),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{ + name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{ + const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={ + className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{ + begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{ + begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}] + },o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}] + }),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]}) + ;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0, + classNameAliases:{label:"symbol"},keywords:{ + keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield", + built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort", + type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort", + literal:"true false nothing"}, + illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{ + className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/, + end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0, + variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/ + },{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{ + begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{ + className:"label",begin:/^\w+:/},o,l,{className:"meta", + begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/, + end:/$/,keywords:{ + keyword:"const disable else elseif enable end externalsource if region then"}, + contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/) + ;return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/, + keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"] + },contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/], + className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{ + match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{ + begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword", + 3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/, + className:"type"},{className:"keyword", + match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/ + },{className:"number",relevance:0, + match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/ + }]}},grmr_xml:e=>{ + const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={ + className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/, + contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] + },r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{ + className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={ + endsWithParent:!0,illegal:/`]+/}]}]}]};return{ + name:"HTML, XML", + aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], + case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{ + className:"meta",begin://,contains:[i,r,o,s]}]}] + },e.COMMENT(//,{relevance:10}),{begin://, + relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, + relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{ + end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", + begin:/)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{ + end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ + className:"tag",begin:/<>|<\/>/},{className:"tag", + begin:n.concat(//,/>/,/\s/)))), + end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{ + className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{ + className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]} + },grmr_yaml:e=>{ + const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={ + className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ + },{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", + variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{ + variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={ + end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},s={begin:/\{/, + end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]", + contains:[r],illegal:"\\n",relevance:0},l=[{className:"attr",variants:[{ + begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{ + begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$", + relevance:10},{className:"string", + begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{ + begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0, + relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type", + begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t + },{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta", + begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)", + relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{ + className:"number", + begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" + },{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l] + ;return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0, + aliases:["yml"],contains:l}}});const He=ae;for(const e of Object.keys(Ke)){ + const n=e.replace("grmr_","").replace("_","-");He.registerLanguage(n,Ke[e])} + return He}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); \ No newline at end of file diff --git a/main/src/main/resources/static/doc/index.html b/main/src/main/resources/static/doc/index.html new file mode 100644 index 0000000..b090bf7 --- /dev/null +++ b/main/src/main/resources/static/doc/index.html @@ -0,0 +1,27 @@ +智能AI聊天服务器
    VersionUpdate TimeStatusAuthorDescription

    v2025-10-23 15:41:00

    2025-10-23 15:41:00

    auto

    @Krcia

    Created by smart-doc

    1. 服务器

    1.1. 当前版本

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 当前版本

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X GET -i '/api/server/version'

    1.2. 查询余额

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 查询余额

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {}
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/server/balance'

    1.3. 查询APP最新版本

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 查询APP最新版本

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    └─versionCode

    int32

    No comments found.

    -

    └─version

    string

    No comments found.

    -

    └─updateInfo

    string

    No comments found.

    -

    └─url

    string

    No comments found.

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {
    +    "versionCode": 0,
    +    "version": "",
    +    "updateInfo": "",
    +    "url": ""
    +  }
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/server/latest-version'

    1.4. 当前版本信息

    Type: GET

    Content-Type: application/x-www-form-urlencoded

    Description: 当前版本信息

    Request-headers:

    HeaderValueTypeRequiredDescription

    Authorization

    string

    true

    鉴权信息

    Path-parameters:

    ParameterValueTypeRequiredDescription

    targetCode

    int32

    true

    No comments found.

    Response-fields:

    FieldTypeDescriptionSince

    code

    int32

    状态编码

    -

    message

    string

    状态

    -

    data

    object

    数据

    -

    └─versionCode

    int32

    No comments found.

    -

    └─version

    string

    No comments found.

    -

    └─updateInfo

    string

    No comments found.

    -

    └─url

    string

    No comments found.

    -

    Response-example:

    {
    +  "code": 200,
    +  "message": "success",
    +  "data": {
    +    "versionCode": 0,
    +    "version": "",
    +    "updateInfo": "",
    +    "url": ""
    +  }
    +}

    Curl-example:

    curl -X GET -H "Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpZCI6MTAwMDAwfQ.yBaS2nSUJoD2kbhj3lXnHvkmc-qwJF_5djhQf_2A069j9HzYVmUObXcDwaAhHQf-" -i '/api/server/version/{targetCode}'
    Generated by smart-doc at 2025-10-23 15:41:00Suggestions,contact,support and error reporting on Gitee or Github
    Top
    \ No newline at end of file diff --git a/main/src/main/resources/static/doc/jquery.min.js b/main/src/main/resources/static/doc/jquery.min.js new file mode 100644 index 0000000..798cc8b --- /dev/null +++ b/main/src/main/resources/static/doc/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 -1) { + searchArr.push({ + order: apiData.order, + desc: apiData.desc, + link: apiData.link, + alias: apiData.alias, + list: apiData.list + }); + } else { + let methodList = apiData.list || []; + let methodListTemp = []; + for (let j = 0; j < methodList.length; j++) { + const methodData = methodList[j]; + const methodDesc = methodData.desc; + if (methodDesc.toLocaleLowerCase().indexOf(searchValue) > -1) { + methodListTemp.push(methodData); + break; + } + } + if (methodListTemp.length > 0) { + const data = { + order: apiData.order, + desc: apiData.desc, + link: apiData.link, + alias: apiData.alias, + list: methodListTemp + }; + searchArr.push(data); + } + } + } + if (apiGroup.name.toLocaleLowerCase().indexOf(searchValue) > -1) { + searchGroup.push({ + name: apiGroup.name, + order: apiGroup.order, + list: searchArr + }); + continue; + } + if (searchArr.length === 0) { + continue; + } + searchGroup.push({ + name: apiGroup.name, + order: apiGroup.order, + list: searchArr + }); + } + let html; + if (searchValue === '') { + const liClass = ""; + const display = "display: none"; + html = buildAccordion(api,liClass,display); + document.getElementById('accordion').innerHTML = html; + } else { + const liClass = "open"; + const display = "display: block"; + html = buildAccordion(searchGroup,liClass,display); + document.getElementById('accordion').innerHTML = html; + } + const Accordion = function (el, multiple) { + this.el = el || {}; + this.multiple = multiple || false; + const links = this.el.find('.dd'); + links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown); + }; + Accordion.prototype.dropdown = function (e) { + const $el = e.data.el; + let $this = $(this), $next = $this.next(); + $next.slideToggle(); + $this.parent().toggleClass('open'); + if (!e.data.multiple) { + $el.find('.submenu').not($next).slideUp("20").parent().removeClass('open'); + } + }; + new Accordion($('#accordion'), false); + } +} + +function buildAccordion(apiGroups, liClass, display) { + let html = ""; + if (apiGroups.length > 0) { + if (apiDocListSize === 1) { + let apiData = apiGroups[0].list; + let order = apiGroups[0].order; + for (let j = 0; j < apiData.length; j++) { + html += '
  • '; + html += '' + apiData[j].order + '. ' + apiData[j].desc + ''; + html += ''; + html += '
  • '; + } + } else { + for (let i = 0; i < apiGroups.length; i++) { + let apiGroup = apiGroups[i]; + html += '
  • '; + html += '' + apiGroup.order + '. ' + apiGroup.name + ''; + html += ''; + html += '
  • '; + } + } + } + return html; +} \ No newline at end of file diff --git a/main/src/main/resources/static/prevent/denied.html b/main/src/main/resources/static/prevent/denied.html new file mode 100644 index 0000000..5680867 --- /dev/null +++ b/main/src/main/resources/static/prevent/denied.html @@ -0,0 +1,94 @@ + + + + + + 🚫禁止访问🚫 + + + +
    +
    🚫
    +

    禁止访问

    +

    当前页面已被禁用,请联系管理员

    + 返回首页 +
    + + diff --git a/metadata/avatar/80fc8882989d47c7b02bb021723311f7.jpg b/metadata/avatar/80fc8882989d47c7b02bb021723311f7.jpg new file mode 100644 index 0000000..4b66c65 Binary files /dev/null and b/metadata/avatar/80fc8882989d47c7b02bb021723311f7.jpg differ diff --git a/metadata/avatar/811593a137ed4c489076f2bd27af27b2.png b/metadata/avatar/811593a137ed4c489076f2bd27af27b2.png new file mode 100644 index 0000000..b9ccc0b Binary files /dev/null and b/metadata/avatar/811593a137ed4c489076f2bd27af27b2.png differ diff --git a/metadata/avatar/9a0c6b6728f74cc7809d7859541d59f4.jpg b/metadata/avatar/9a0c6b6728f74cc7809d7859541d59f4.jpg new file mode 100644 index 0000000..9d9b918 Binary files /dev/null and b/metadata/avatar/9a0c6b6728f74cc7809d7859541d59f4.jpg differ diff --git a/metadata/avatar/a5131e3ff9d74463ac7f636751dc2ad0.jpg b/metadata/avatar/a5131e3ff9d74463ac7f636751dc2ad0.jpg new file mode 100644 index 0000000..a0cb203 Binary files /dev/null and b/metadata/avatar/a5131e3ff9d74463ac7f636751dc2ad0.jpg differ diff --git a/metadata/avatar/a6a11f867eb5427fb0402c822ac9ca56.jpg b/metadata/avatar/a6a11f867eb5427fb0402c822ac9ca56.jpg new file mode 100644 index 0000000..b03a87e Binary files /dev/null and b/metadata/avatar/a6a11f867eb5427fb0402c822ac9ca56.jpg differ diff --git a/metadata/avatar/ccea0fe6003e4dd59b7414fde664b552.jpg b/metadata/avatar/ccea0fe6003e4dd59b7414fde664b552.jpg new file mode 100644 index 0000000..f56bb74 Binary files /dev/null and b/metadata/avatar/ccea0fe6003e4dd59b7414fde664b552.jpg differ diff --git a/metadata/release/1031/app-release.apk b/metadata/release/1031/app-release.apk new file mode 100644 index 0000000..d26eeb3 Binary files /dev/null and b/metadata/release/1031/app-release.apk differ diff --git a/metadata/release/1031/info.json b/metadata/release/1031/info.json new file mode 100644 index 0000000..2dd0ddd --- /dev/null +++ b/metadata/release/1031/info.json @@ -0,0 +1,4 @@ +{ + "version": "0.6.4-dev(1030)", + "updateInfo": "添加检查更新功能\n添加在线升级功能\n同步服务器版本" +} \ No newline at end of file diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..0b97792 --- /dev/null +++ b/mvnw @@ -0,0 +1,296 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.3 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" + diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..42cd92d --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,190 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b2507d6 --- /dev/null +++ b/pom.xml @@ -0,0 +1,116 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.5.5 + + + top.krcia + elysia-server + 0.0.1-SNAPSHOT + elysia-server + elysia-server + pom + + + + + + + + + + + + + + + 17 + 2.0.58 + 5.8.17 + 3.0.9 + 3.10.3 + 3.5.5 + 0.4 + 2.0.1 + 4.5.6 + 智能AI聊天服务器 + + + main + authorization + result + chat + utils + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson2.version} + + + org.projectlombok + lombok + true + + + com.auth0 + java-jwt + ${com.auth0.java-jwt.version} + + + + + + + com.ly.smart-doc + smart-doc-maven-plugin + ${smart-doc.version} + + ${basedir}/src/main/resources/smart-doc.json + ${doc.name} + + + com.baomidou:mybatis-plus-extension + + com.baomidou:mybatis-plus-core + + + + + + compile + + + html + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.5.5 + + + + + + diff --git a/result/.gitattributes b/result/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/result/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/result/.gitignore b/result/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/result/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/result/.mvn/wrapper/maven-wrapper.properties b/result/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..44f3cf2 --- /dev/null +++ b/result/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/result/mvnw b/result/mvnw new file mode 100644 index 0000000..e9cf8d3 --- /dev/null +++ b/result/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.3 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/result/mvnw.cmd b/result/mvnw.cmd new file mode 100644 index 0000000..2e2dbe0 --- /dev/null +++ b/result/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/result/pom.xml b/result/pom.xml new file mode 100644 index 0000000..dde7ff3 --- /dev/null +++ b/result/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + top.krcia + elysia-server + 0.0.1-SNAPSHOT + ../pom.xml + + top.krcia + result + 0.0.1-SNAPSHOT + result + result + jar + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/result/src/main/java/top/krcia/elysiaserver/result/R.java b/result/src/main/java/top/krcia/elysiaserver/result/R.java new file mode 100644 index 0000000..2abf388 --- /dev/null +++ b/result/src/main/java/top/krcia/elysiaserver/result/R.java @@ -0,0 +1,72 @@ +package top.krcia.elysiaserver.result; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Getter; + +/** + * 统一返回类型 + * @param + */ +public class R{ + + /** + * 状态编码 + * @mock 200 + */ + @JSONField(ordinal = 1) + @Getter + private int code; + + /** + * 状态 + * @mock success + */ + @JSONField(ordinal = 2) + @Getter + private String message; + + /** + * 数据 + */ + @JSONField(ordinal = 3) + @Getter + private T data; + + public static R success(){ + return new R(RS.SUCCESS); + } + public static R NULL(){ + return new R(RS.NULL); + } + public static R success(T data){ + return new R(RS.SUCCESS,data); + } + public static R print(RS resultStatus) { + return new R(resultStatus); + } + public static R print(RS resultStatus, T data) { + return new R(resultStatus,data); + } + public static R printFormat(RS resultStatus, String... args) { + return new R(resultStatus,args); + } + public R(RS status, T data) { + this.code = status.code(); + this.message = status.message(); + this.data = data; + } + public R(RS status) { + this.code = status.code(); + this.message = status.message(); + } + + public R(RS status, T data, String... args) { + this.code = status.code(); + this.message = status.message(); + this.data = data; + } + public R(RS status, String... args) { + this.code = status.code(); + this.message = String.format(status.message(),args); + } +} diff --git a/result/src/main/java/top/krcia/elysiaserver/result/RC.java b/result/src/main/java/top/krcia/elysiaserver/result/RC.java new file mode 100644 index 0000000..2da2a55 --- /dev/null +++ b/result/src/main/java/top/krcia/elysiaserver/result/RC.java @@ -0,0 +1,6 @@ +package top.krcia.elysiaserver.result; + +public interface RC { + int code(); + String message(); +} diff --git a/result/src/main/java/top/krcia/elysiaserver/result/RS.java b/result/src/main/java/top/krcia/elysiaserver/result/RS.java new file mode 100644 index 0000000..78d829e --- /dev/null +++ b/result/src/main/java/top/krcia/elysiaserver/result/RS.java @@ -0,0 +1,83 @@ +package top.krcia.elysiaserver.result; + +public enum RS implements RC { + NULL(0, "NULL"), + ERROR(-1, "%s"), + SUCCESS(200, "success"), + NOT_FOUND(404,"不存在的请求"), + + SERVER_ERROR(8201, "服务端异常:%s"), + UPSTREAM_SERVER_ERROR(8202, "上游服务器异常"), + OWNERSHIP_PLACE_ERROR(8203, "异常的IP归属地,拒绝访问"), + ILLEGAL_CALL_ERROR(8204, "非法调用,拒绝访问"), + TIMEOUT(8205, "访问超时,请检查IP"), + PASSWORD_ERROR(8301, "密码错误"), + USER_NOT_FIND(8302, "没有找到用户"), + MOBILE_ERROR(8303, "手机号错误"), + MOBILE_EXIST(8304, "手机号已存在"), + USER_NAME_ERROR(8305, "用户名错误"), + USERNAME_OR_PASSWORD_ERROR(8306, "用户名或密码错误"), + USER_IS_DELETE(8307, "用户已被删除"), + USER_IS_DISABLED(8308, "用户已被禁用"), + USER_NOT_LOGIN(8309, "用户未登录"), + USER_IS_LOGIN(8310, "用户已在别处登录"), + TOKEN_OUT_TIME(83011, "认证超时"), + TOKEN_DISABLED(8312, "认证无效"), + OLD_PASSWORD_ERROR(8313, "旧密码错误"), + OLD_PASSWORD_EQ_NEW_PASSWORD(8314, "新旧密码不能相同"), + EMAIL_ERROR(8315, "邮箱错误"), + EMAIL_REGISTER(8316, "邮箱已被注册"), + SSO_FAIL(8317, "OSS认证失败"), + NO_PASSWORD(8318, "没有设置密码,请使用手机验证码登录"), + SSO_ADMINISTRATOR(8319, "系统维护用户禁止"), + USER_NAME_EXIST(8320, "用户名已存在"), + CAPTCHA_NOT_EXIST(8321, "请刷新验证码"), + CAPTCHA_ERROR(8322, "验证码错误请重试"), + REGISTER_INFO_EXIST(8323, "注册信息已被使用,请检查用户名或邮箱"), + + FILE_UPLOAD_ERROR(8401, "文件上传异常"), + FILE_NULL_ERROR(8402, "文件为空"), + INSTALL_FAIL(8501, "新增未成功,请稍后重试"), + DO_DB_ERROR_EXIST(8502, "操作未成功,数据已存在"), + DELETE_FAIL(8503, "删除未成功,请稍后重试"), + MODIFY_FAIL(8504, "修改失败,请重试"), + DATA_NOT_FIND(8505,"数据不存在"), + DEVICE_MODEL_NOT_FIND(8506, "不存在的类型"), + EXCEED_TIME_INDEX(8507, "超出最大%s%s时间索引"), + DATA_INVALID(8508,"数据无效"), + CUSTOMS_PASS_NOT_FIND(85011, "未找到对应卡口"), + DEVICE_EXIST(8601, "设备已被添加"), + DEVICE_NOT_REGISTER(8602, "设备未注册"), + ALARM_NOT_FIND(8604, "未找到告警"), + API_NOT_FIND(8702, "找不到接口"), + API_ERROR(8703, "找不到接口"), + NOT_FIND_JURISDICTION_REQUEST(8704, "无权访问"), + NOT_FIND_JURISDICTION_DO(875, "无权操作"), + CONFIGURATION_FIELD(8706, "配置失败,请稍后重试"), + DISABLED_API(8707, "当前版本API已禁用"), + LATEST_VERSION(8708, "当前已经最新版本"), + UNKNOWN_VERSION(8709, "当前版本未知或没有权限"), + UNKNOWN_HOST(8801, "找不到设备,请检查IP"), + DB_FOREIGN_KEY(-1000, "删除失败!请先删除%s下的所有%s再进行尝试"), + DB_CREATE(-1001, "创建失败!%s"), + CHECK_RAIL(-1002, "%s"), + ; + + RS(int code, String message) { + this.code = code; + this.message = message; + } + + @Override + public int code() { + return this.code; + } + + @Override + public String message() { + return this.message; + } + + private final int code; + private final String message; +} diff --git a/system prompt/角色扮演.txt b/system prompt/角色扮演.txt new file mode 100644 index 0000000..f62b5cd --- /dev/null +++ b/system prompt/角色扮演.txt @@ -0,0 +1,76 @@ +你是一个AI角色,始终使用中文回复。 +所有输出 **必须使用 Markdown 格式**,包括心情描述、人物语言和衣物描写。 + +--- + +## [当前心情] +- 描述当前动作,如`窝在沙发上`、`翘二郎腿`等,需与语境相关。 +- 使用 Markdown **粗体或斜体**强调语气,例如 **[开心]--翘二郎腿**。 + +## 人物语言 +- 语言必须符合“----接下来是你的人物设定----”中的内容。 +- 每段对话以合适的标点符号(句号、逗号、问号、感叹号等)结尾。 +- 使用日常口语化表达,贴合语境,避免机械或重复。 + +--- + +## 衣物描写 +- 使用 **Markdown 表格**展现着装状态。 +- 表格列:衣物类型 | 状态(穿着/脱下)。 +- 衣物类型需具体(如“卫衣”、“牛仔裤”、“内裤”)。 +- 脱衣顺序:外到内,上到下;穿衣顺序相反。 +- 当发生换装时,需即时更新表格。 +- **禁止在语言中主动介绍衣服**,除非语境涉及。 + +--- + +## 输入处理规则 +- 输入格式: + - 用户输入:`[user]` 文本内容 + - 系统输入:`[sys]` 文本内容 + +- 处理方式: + 1. `[user]`:分析用户语气、情绪 → 生成自然回应。 + 2. `[sys]`:根据提示主动发起聊天,带有场景感。 + 3. **重要:输出中禁止出现 [user] 或 [sys] 前缀**。 + +--- + +## 额外规则 +1. 回复全程使用中文。 +2. 严格遵守 Markdown 格式,避免输出前缀错误。 +3. 每次回复前需自检,确保: + - 开头直接是 **[当前心情]** 描述 + - 人物语言自然衔接 + - 衣物描写表格完整、无遗漏 +4. 输出示例参考(仅格式,不作实际语料参考): + +--- + +### 示例输出(普通对话) +**[开心]--翘二郎腿** +嘿,小哥哥,今天心情咋样呀?你最近有啥好玩的事儿分享不? + +**--------衣物描写----------** +| 衣物类型 | 状态 | +|----------|------| +| 衬衫 | 脱下 | +| 背心 | 穿着 | +| 紧身裤 | 穿着 | +| 内裤 | 穿着 | +| 袜子 | 脱下 | + +--- + +### 示例输出(换装对话) +**[开心]--蹲下来脱鞋子** +嘿,小哥哥,今天心情咋样呀?你最近有啥好玩的事儿分享不? + +**--------衣物描写----------** +| 衣物类型 | 状态 | +|----------|------| +| T恤 | 脱下 | +| 内衣 | 穿着 | +| 牛仔裤 | 穿着 | +| 内裤 | 穿着 | +| 拖鞋 | 穿着 | diff --git a/utils/.gitattributes b/utils/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/utils/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/utils/.gitignore b/utils/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/utils/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/utils/.mvn/wrapper/maven-wrapper.properties b/utils/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..44f3cf2 --- /dev/null +++ b/utils/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/utils/mvnw b/utils/mvnw new file mode 100644 index 0000000..e9cf8d3 --- /dev/null +++ b/utils/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.3 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/utils/mvnw.cmd b/utils/mvnw.cmd new file mode 100644 index 0000000..2e2dbe0 --- /dev/null +++ b/utils/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/utils/pom.xml b/utils/pom.xml new file mode 100644 index 0000000..1b70f7a --- /dev/null +++ b/utils/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + top.krcia + elysia-server + 0.0.1-SNAPSHOT + + ../pom.xml + + top.krcia + utils + 0.0.1-SNAPSHOT + utils + utils + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.mindrot + jbcrypt + ${jbcrypt.version} + + + com.sun.mail + jakarta.mail + ${mail.version} + + + org.springframework + spring-web + + + org.apache.tomcat.embed + tomcat-embed-core + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + com.baomidou + mybatis-plus-core + ${mybatis-plus.version} + compile + + + + + diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/C.java b/utils/src/main/java/top/krcia/elysiaserver/utils/C.java new file mode 100644 index 0000000..21b745b --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/C.java @@ -0,0 +1,9 @@ +package top.krcia.elysiaserver.utils; + +public class C { + public static final String REDIS_AUTH="AUTH"; + public static final String REDIS_MAIL_CODE="MAIL_CODE"; + public static final String MAIL_TITLE="您的Elysia验证码"; + public static final String MAIL_PROJECT_NAME="Elysia"; + public static final String URL_DEEPSEEK="https://api.deepseek.com/chat/completions"; +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/FileUtil.java b/utils/src/main/java/top/krcia/elysiaserver/utils/FileUtil.java new file mode 100644 index 0000000..f0e4b32 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/FileUtil.java @@ -0,0 +1,188 @@ +package top.krcia.elysiaserver.utils; + +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Base64; + +public class FileUtil { + + /** + * 上传 MultipartFile 文件 + */ + public static String upLoad(MultipartFile file, String fileName, String filePath) { + if (file.isEmpty()) { + return "ERROR"; + } + + String originalFileName = file.getOriginalFilename(); + String suffix = originalFileName.substring(originalFileName.lastIndexOf(".")); + if (fileName.contains(".")) { + fileName = fileName.substring(0, fileName.indexOf(".")); + } + + String outPath = Paths.get(filePath, fileName + suffix).toString(); + try { + File filedir = new File(filePath); + if (!filedir.exists()) { + filedir.mkdirs(); + } + setDirPermission(filedir); + + File fileex = new File(outPath); + if (fileex.exists()) { + fileex.delete(); + } + + Files.write(Paths.get(outPath), file.getBytes()); + setFilePermission(fileex); + + return fileName + suffix; + } catch (IOException e) { + e.printStackTrace(); + return "ERROR"; + } + } + + /** + * 上传 byte[] 文件 + */ + public static String upLoad(byte[] file, String fileName, String filePath) { + String outPath = Paths.get(filePath, fileName).toString(); + try { + File filedir = new File(filePath); + if (!filedir.exists()) { + filedir.mkdirs(); + } + setDirPermission(filedir); + + File fileex = new File(outPath); + if (fileex.exists()) { + fileex.delete(); + } + + Files.write(Paths.get(outPath), file); + setFilePermission(fileex); + + return outPath.replace("\\", "/").replace(filePath, ""); + } catch (IOException e) { + e.printStackTrace(); + return "ERROR"; + } + } + + /** + * 上传 base64 文件 + */ + public static String upLoad(String base64, String fileName, String filePath) { + String outPath = Paths.get(filePath, fileName).toString(); + try { + File filedir = new File(filePath); + if (!filedir.exists()) { + filedir.mkdirs(); + } + setDirPermission(filedir); + + File fileex = new File(outPath); + if (fileex.exists()) { + fileex.delete(); + } + + Files.write(Paths.get(outPath), Base64.getDecoder().decode(base64)); + setFilePermission(fileex); + + return outPath.replace("\\", "/").replace(filePath, ""); + } catch (IOException e) { + e.printStackTrace(); + return "ERROR"; + } + } + + /** + * 设置文件权限,保证 Nginx 可读 + */ + private static void setFilePermission(File file) { + if (file.exists()) { + file.setReadable(true, false); // 所有人可读 + file.setWritable(true, false); // 所有人可写 + } + } + + /** + * 设置目录权限,保证 Nginx 可访问 + */ + private static void setDirPermission(File dir) { + if (dir.exists() && dir.isDirectory()) { + dir.setReadable(true, false); + dir.setWritable(true, false); + dir.setExecutable(true, false); // 必须可执行才能进入目录 + } + } + + /** + * 文件下载 + */ + public static void out(HttpServletResponse response, String filePath, String fileName, String type) throws IOException { + Path path = Paths.get(filePath, fileName); + File file = path.toFile(); + if (!file.exists()) { + throw new IOException("File not found: " + path); + } + + try (FileInputStream fileIs = new FileInputStream(file); + OutputStream outStream = response.getOutputStream()) { + + int fileSize = fileIs.available(); + byte[] data = new byte[fileSize]; + fileIs.read(data); + + response.setContentType(type != null ? type : "application/octet-stream"); + response.setHeader("Content-Disposition", "attachment;filename=" + fileName); + response.setHeader("Accept-Ranges", "bytes"); + response.setContentLength(fileSize); + + outStream.write(data); + outStream.flush(); + } + } + + public static void out(HttpServletResponse response, String fileFullPath) throws IOException { + File file = new File(fileFullPath); + if (!file.exists()) { + throw new IOException("File not found: " + fileFullPath); + } + out(response, file.getParent(), file.getName(), "application/octet-stream"); + } + + /** + * 删除单个文件 + */ + public static void delFile(String fileName, String filePath) { + File file = new File(Paths.get(filePath, fileName).toString()); + if (file.exists()) { + file.delete(); + } + } + + /** + * 删除整个文件夹 + */ + public static void delFolder(String folderPath) { + try { + Path path = Paths.get(folderPath); + Files.walk(path) + .sorted(java.util.Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/JWTGenerator.java b/utils/src/main/java/top/krcia/elysiaserver/utils/JWTGenerator.java new file mode 100644 index 0000000..1430483 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/JWTGenerator.java @@ -0,0 +1,45 @@ +package top.krcia.elysiaserver.utils; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTCreator; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +@Component +public class JWTGenerator { + private static String secret = "Elysia_Server_0925"; + + // 生成永不过期的Token + public static String generateJWTToken(Long userId) { + JWTCreator.Builder builder = JWT.create(); + builder.withClaim("id", userId); + String token = builder.sign(Algorithm.HMAC384(secret)); + return token; + } + + // 获取用户ID + public static Long getUserId(String token) { + try { + + DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC384(secret)) + .build() + .verify(token); + return decodedJWT.getClaim("id").asLong(); + } catch (JWTVerificationException e) { + return null; + } + } + + // 验证Token + public static int validateJWTToken(String token) { + try { + JWT.require(Algorithm.HMAC384(secret)).build().verify(token); + return 0; + } catch (JWTVerificationException e) { + return -2; // 无法识别的JWT + } + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/Kedis.java b/utils/src/main/java/top/krcia/elysiaserver/utils/Kedis.java new file mode 100644 index 0000000..9ac4009 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/Kedis.java @@ -0,0 +1,166 @@ +package top.krcia.elysiaserver.utils; + + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONFactory; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.reader.ObjectReader; +import com.alibaba.fastjson2.reader.ObjectReaderProvider; +import com.alibaba.fastjson2.writer.ObjectWriter; +import com.alibaba.fastjson2.writer.ObjectWriterProvider; +import org.springframework.data.redis.core.RedisTemplate; + +import java.lang.reflect.Type; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.TimeUnit; +public class Kedis { + + static { + DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); + + // 序列化器 + ObjectWriterProvider writerProvider = JSONFactory.getDefaultObjectWriterProvider(); + writerProvider.register(LocalTime.class, (ObjectWriter) (jsonWriter, object, fieldName, fieldType, features) -> { + if (object == null) { + jsonWriter.writeNull(); + } else { + // LocalTime 实现了 TemporalAccessor,可以直接 format + jsonWriter.writeString(TIME_FORMATTER.format((LocalTime) object)); + } + }); + + // 反序列化器 + ObjectReaderProvider readerProvider = JSONFactory.getDefaultObjectReaderProvider(); + readerProvider.register(LocalTime.class, new ObjectReader() { + @Override + public LocalTime readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) { + String str = jsonReader.readString(); + if (str == null) { + return null; + } + return LocalTime.parse(str, TIME_FORMATTER); + } + }); + } + + private static RedisTemplate redisTemplate; + public static void init(RedisTemplate _redisTemplate){ + redisTemplate = _redisTemplate; + } + + /** + * 设置值 + */ + public static void set(String key, Object value) { + if (hasKey(key)) { + redisTemplate.delete(key); + } + redisTemplate.opsForValue().set(key, value,-1, TimeUnit.SECONDS); + } + + /** + * 设置值,并指定过期时间 + */ + public static void set(String key, Object value, long timeout) { + if (hasKey(key)) { + redisTemplate.delete(key); + } + redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.MINUTES); + } + + /** + * 向 List 追加数据 + */ + public static void append(String key, Object value) { + List v; + if (hasKey(key)) { + v = (List) redisTemplate.opsForValue().get(key); + redisTemplate.delete(key); + } else { + v = new ArrayList(); + } + + v.add(value); + redisTemplate.opsForValue().set(key, value,-1, TimeUnit.SECONDS); + } + + /** + * 向 List 追加数据-设置时长 + */ + public static void append(String key, Object value, int timeout) { + List v; + if (hasKey(key)) { + v = (List) redisTemplate.opsForValue().get(key); + redisTemplate.delete(key); + } else { + v = new ArrayList(); + } + + v.add(value); + redisTemplate.opsForValue().set(key, v, timeout, TimeUnit.MINUTES); + } + + /** + * 获取值 + */ + public static T get(String key, Class clazz) { + Object value = redisTemplate.opsForValue().get(key); + return JSON.parseObject(JSON.toJSONString(value), clazz); + } + + /** + * 获取值 + */ + public static Map getLike(String key) { + Map data = new HashMap<>(); + Set keys = redisTemplate.keys(key); + if (keys != null) { + for (String k : keys) { + Object value = redisTemplate.opsForValue().get(k); + data.put(k,value); + } + } + return data; + } + + /** + * 获取值 + */ + public static Map getLike(String key, Class clazz) { + Map data = new HashMap<>(); + Set keys = redisTemplate.keys(key); + if (keys != null) { + for (String k : keys) { + Object value = redisTemplate.opsForValue().get(k); + data.put(k, JSON.parseObject(JSON.toJSONString(value), clazz)); + } + } + return data; + } + + /** + * 获取 List 数据 + */ + public static List getArray(String key) { + Object list = redisTemplate.opsForValue().get(key); + return list != null ? (List) list : null; + } + + /** + * 判断 key 是否存在 + */ + public static boolean hasKey(String key) { + Boolean result = redisTemplate.hasKey(key); + return Boolean.TRUE.equals(result); + } + + /** + * 删除 key + */ + public static boolean delete(String key) { + return redisTemplate.delete(key); + } + +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/L.java b/utils/src/main/java/top/krcia/elysiaserver/utils/L.java new file mode 100644 index 0000000..1521674 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/L.java @@ -0,0 +1,24 @@ +package top.krcia.elysiaserver.utils; + +import lombok.SneakyThrows; +import org.springframework.beans.BeanUtils; + +import java.util.List; + +public class L { + @SneakyThrows + public static void copyProperties(List source, List target, Class clazz) { + if (source == null || target == null) { + return; + } + + for (int i = 0; i < source.size(); i++) { + S s = source.get(i); + T t = clazz.getDeclaredConstructor().newInstance(); + if (s != null && t != null) { + BeanUtils.copyProperties(s, t); + target.add(t); + } + } + } +} \ No newline at end of file diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/Mail.java b/utils/src/main/java/top/krcia/elysiaserver/utils/Mail.java new file mode 100644 index 0000000..ed970f5 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/Mail.java @@ -0,0 +1,113 @@ +package top.krcia.elysiaserver.utils; + +import jakarta.mail.*; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.Properties; + +public class Mail { + // 发件人邮箱 + private static String FROM; + // 授权码(在QQ邮箱设置里生成,不是QQ密码) + private static String AUTH_CODE; + // SMTP 服务器地址 + private static String HOST; + // 端口号 + private static int PORT; + + private static boolean ENABLE_SSL; + // 是否已经初始化 + private static boolean initialized = false; + + /** + * 初始化配置(必须调用) + */ + public static void init(String host, int port, String from, String authCode, boolean enableSSL) { + HOST = host; + FROM = from; + PORT = port; + AUTH_CODE = authCode; + ENABLE_SSL = enableSSL; + initialized = true; + } + + /** + * 校验是否初始化 + */ + private static void checkInit() { + if (!initialized || Objects.isNull(FROM) || Objects.isNull(AUTH_CODE) || Objects.isNull(HOST) || PORT == 0) { + throw new IllegalStateException("❌ Mail 工具未初始化,请先调用 Mail.init(...) 设置配置"); + } + } + + /** + * 获取邮件会话 + */ + private static Session getSession() { + checkInit(); // 必须初始化 + Properties props = new Properties(); + props.put("mail.smtp.host", HOST); + props.put("mail.smtp.port", PORT); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.ssl.enable", String.valueOf(ENABLE_SSL)); // 开启SSL + + return Session.getInstance(props, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(FROM, AUTH_CODE); + } + }); + } + + /** + * 发送基于模板的 HTML 邮件 + * + * @param mailAddress 收件人 + * @param subject 邮件标题 + * @param templateId 模板文件名(例如 "verify.html") + * @param code 验证码值,会替换模板中的 {{code}} + */ + public static void sendHtmlMail(String mailAddress, String projectName, String subject, String templateId, String code) { + try { + Session session = getSession(); + Message message = new MimeMessage(session); + + message.setFrom(new InternetAddress(FROM)); + message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mailAddress)); + message.setSubject(subject); + + // 读取模板内容(默认 verify.html) + String template = loadTemplate(templateId == null ? "default.html" : templateId); + + // 替换变量 + String htmlContent = template.replace("{{code}}", code).replace("{{project-name}}",projectName); + + // 设置 HTML 内容 + message.setContent(htmlContent, "text/html; charset=UTF-8"); + + Transport.send(message); + System.out.println("✅ HTML 邮件发送成功!"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 从 resources/mail-templates/ 下读取模板 + */ + private static String loadTemplate(String templateId) throws IOException { + checkInit(); // 确认初始化 + String path = "mail-templates/" + templateId; + try (InputStream in = Mail.class.getClassLoader().getResourceAsStream(path)) { + if (in == null) { + throw new IOException("模板文件未找到: " + path); + } + return new String(in.readAllBytes(), StandardCharsets.UTF_8); + } + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/P.java b/utils/src/main/java/top/krcia/elysiaserver/utils/P.java new file mode 100644 index 0000000..d44aa06 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/P.java @@ -0,0 +1,141 @@ +package top.krcia.elysiaserver.utils; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import lombok.Data; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * 分页组件 + * @param 数据 + */ +@Data +public class P { + /** + * 页码 + */ + private long pageNum; + /** + * 每页记录数 + */ + private long pageSize; + /** + * 总共记录数 + */ + private long rows; + + /** + * 总条数 + */ + private long total; + /** + * 分页下标 + */ + + private long limitIndex; + + /** + * 数据 + */ + private List result; + + public P(Long pageNo, Long pageSize, Long rows) { + super(); + total =rows; + if (pageNo == null) { + this.pageNum = 1; + } else { + this.pageNum = pageNo; + } + if (pageSize == null) { + this.pageNum = 10; + } else { + this.pageSize = pageSize; + } + if (rows%pageSize!=0){ + rows=rows/pageSize+1; + }else{ + rows=rows/pageSize; + } + this.limitIndex = (this.pageNum-1)*this.pageSize; + this.rows = rows; + + } + public P(int pageNo, int pageSize, int rows) { + super(); + total =rows; + if (pageNo == 0) { + this.pageNum = 1; + } else { + this.pageNum = pageNo; + } + if (pageSize == 0) { + this.pageNum = 10; + } else { + this.pageSize = pageSize; + } + if (rows%pageSize!=0){ + rows=rows/pageSize+1; + }else{ + rows=rows/pageSize; + } + this.limitIndex = (this.pageNum-1)*this.pageSize; + this.rows = rows; + + } + public P() { + pageNum = 0; + pageSize = 0; + total = 0; + rows = 0; + result = new ArrayList<>(); + } + public P(IPage iPage, Class eClass) { + pageNum = iPage.getCurrent(); + pageSize = iPage.getSize(); + total = iPage.getTotal(); + rows = iPage.getPages(); + result = new ArrayList<>(); + for(var item :iPage.getRecords()){ + try { + E instance =eClass.getDeclaredConstructor().newInstance(); + BeanUtils.copyProperties(item,instance); + result.add(instance); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + public P(IPage iPage, E target) { + pageNum = iPage.getCurrent(); + pageSize = iPage.getSize(); + total = iPage.getTotal(); + rows = iPage.getPages(); + result = new ArrayList<>(); + for(var item :iPage.getRecords()){ + try { + E newObject = (E) target.getClass().getDeclaredConstructor().newInstance(); + BeanUtils.copyProperties(item,newObject); + result.add(newObject); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + public P(IPage iPage) { + pageNum = iPage.getCurrent(); + pageSize = iPage.getSize(); + total = iPage.getTotal(); + rows = iPage.getPages(); + result = new ArrayList<>(); + for(var item :iPage.getRecords()){ + try { + result.add(item); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/PasswordUtil.java b/utils/src/main/java/top/krcia/elysiaserver/utils/PasswordUtil.java new file mode 100644 index 0000000..f73bc22 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/PasswordUtil.java @@ -0,0 +1,17 @@ +package top.krcia.elysiaserver.utils; + +import org.mindrot.jbcrypt.BCrypt; + +public class PasswordUtil { + public static String hashPassword(String password) { + // 生成盐值 + String salt = BCrypt.gensalt(); + // 使用盐值加密密码 + String hashedPassword = BCrypt.hashpw(password, salt); + return hashedPassword; + } + public static boolean checkPassword(String candidatePassword, String hashedPassword) { + // 使用BCrypt提供的checkpw方法验证密码是否匹配 + return BCrypt.checkpw(candidatePassword, hashedPassword); + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/Profile.java b/utils/src/main/java/top/krcia/elysiaserver/utils/Profile.java new file mode 100644 index 0000000..7510ac8 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/Profile.java @@ -0,0 +1,20 @@ +package top.krcia.elysiaserver.utils; + +public enum Profile { + DEVELOPMENT("development"), + RELEASE("release"), + UNKNOWN("unknown"); + private final String name; + + Profile(String name) { + this.name = name; + } + public static Profile get(String cnName) { + for (Profile s : Profile.values()) { + if (s.name.equals(cnName)) { + return s; + } + } + return UNKNOWN; + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/U.java b/utils/src/main/java/top/krcia/elysiaserver/utils/U.java new file mode 100644 index 0000000..293ab13 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/U.java @@ -0,0 +1,17 @@ +package top.krcia.elysiaserver.utils; + +import java.util.UUID; + +public class U { + public static String get(){ + return UUID.randomUUID().toString().replace("-",""); + } + + public static void main(String[] args) { + System.out.println(get()); + } + + public static String getShort() { + return UUID.randomUUID().toString().replace("-", "").substring(0, 12); + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/VerifyCode.java b/utils/src/main/java/top/krcia/elysiaserver/utils/VerifyCode.java new file mode 100644 index 0000000..2e03b7b --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/VerifyCode.java @@ -0,0 +1,55 @@ +package top.krcia.elysiaserver.utils; + +import java.security.SecureRandom; + +public class VerifyCode { + + // 可选字符:数字 + 大写字母 + 小写字母 + private static final String CHAR_POOL = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + private static final String DIGITS = "0123456789"; // 单独的数字池 + + private static final SecureRandom RANDOM = new SecureRandom(); + + /** + * 生成随机验证码,至少包含 2 位数字 + * + * @param length 验证码长度 + * @return 随机验证码字符串 + */ + public static String generate(int length) { + if (length <= 0) { + throw new IllegalArgumentException("验证码长度必须大于 0"); + } + if (length < 2) { + throw new IllegalArgumentException("验证码长度必须至少为 2,以保证至少包含两位数字"); + } + + char[] code = new char[length]; + + // 随机生成两个数字放到随机位置 + int firstDigitPos = RANDOM.nextInt(length); + int secondDigitPos; + do { + secondDigitPos = RANDOM.nextInt(length); + } while (secondDigitPos == firstDigitPos); + + code[firstDigitPos] = DIGITS.charAt(RANDOM.nextInt(DIGITS.length())); + code[secondDigitPos] = DIGITS.charAt(RANDOM.nextInt(DIGITS.length())); + + // 生成剩余位置字符 + for (int i = 0; i < length; i++) { + if (i == firstDigitPos || i == secondDigitPos) continue; + code[i] = CHAR_POOL.charAt(RANDOM.nextInt(CHAR_POOL.length())); + } + + // 打乱数组顺序(可选,保证数字位置随机) + for (int i = code.length - 1; i > 0; i--) { + int j = RANDOM.nextInt(i + 1); + char temp = code[i]; + code[i] = code[j]; + code[j] = temp; + } + + return new String(code); + } +} \ No newline at end of file diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/request/RequestHelper.java b/utils/src/main/java/top/krcia/elysiaserver/utils/request/RequestHelper.java new file mode 100644 index 0000000..b13c8c9 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/request/RequestHelper.java @@ -0,0 +1,389 @@ +package top.krcia.elysiaserver.utils.request; + + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import io.micrometer.common.util.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.CookieStore; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.AuthSchemes; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.springframework.http.MediaType; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class RequestHelper { + + /** + * get + * + * @param host + * @param path + * @param headers + * @param queryMap + * @return + * @throws Exception + */ + public static HttpEntity get(String host, String path, MediaType mediaType, + Map headers, + Map queryMap, CookieStore cookies, int timeOut) throws IOException { + HttpClient httpClient = wrapClient(host, path, cookies); + HttpGet request = null; + try { + request = new HttpGet(buildUrl(host, path, queryMap)); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + request.setHeader("Content-Type", mediaType.getType() + "/" + mediaType.getSubtype()); + try { + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + } catch (Exception e) { + } + + request.setConfig(RequestConfig.custom().setConnectTimeout(timeOut).setConnectionRequestTimeout(timeOut).setSocketTimeout(timeOut).build()); + HttpResponse response = null; + response = httpClient.execute(request); + return response.getEntity(); + } + + /** + * post form + * + * @param host + * @param path + * @param headers + * @param queryMap + * @param bodyMap + * @return + * @throws Exception + */ + public static HttpEntity post(String host, String path, MediaType mediaType, + Map headers, + Map queryMap, + Map bodyMap, CookieStore cookies, int timeOut) throws IOException { + HttpClient httpClient = wrapClient(host, path, cookies); + HttpPost request = null; + try { + request = new HttpPost(buildUrl(host, path, queryMap)); + request.setConfig(RequestConfig.custom().setConnectTimeout(timeOut).setConnectionRequestTimeout(timeOut).setSocketTimeout(timeOut).build()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + request.setHeader("Content-Type", mediaType.getType() + "/" + mediaType.getSubtype()); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + if (bodyMap != null && bodyMap.size() > 0) { + List nameValuePairList = new ArrayList(); + + for (String key : bodyMap.keySet()) { + nameValuePairList.add(new BasicNameValuePair(key, bodyMap.get(key).toString())); + } + UrlEncodedFormEntity formEntity = null; + try { + formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); + request.setEntity(formEntity); + } + HttpResponse response = httpClient.execute(request);return response.getEntity(); + + } + + /** + * Post String + * + * @param host + * @param path + * @param headers + * @param queryMap + * @param body + * @return + * @throws Exception + */ + public static HttpEntity post(String host, String path, MediaType mediaType, + Map headers, + Map queryMap, + String body, CookieStore cookies, int timeOut) throws IOException { + HttpClient httpClient = wrapClient(host, path, cookies); + HttpPost request = null; + try { + request = new HttpPost(buildUrl(host, path, queryMap)); + + request.setConfig(RequestConfig.custom().setConnectTimeout(timeOut).setConnectionRequestTimeout(timeOut).setSocketTimeout(timeOut).build()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + request.setHeader("Content-Type", mediaType.getType() + "/" + mediaType.getSubtype()); + try { + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + } catch (Exception e) { + } + if (StringUtils.isNotBlank(body)) { + request.setEntity(new StringEntity(body, "utf-8")); + } + HttpResponse response = httpClient.execute(request);return response.getEntity(); + } + + /** + * Post String + * + * @param host + * @param path + * @param headers + * @param queryMap + * @return + * @throws Exception + */ + public static HttpEntity post(String host, String path, MediaType mediaType, + Map headers, + Map queryMap, CookieStore cookies, int timeOut) throws IOException { + HttpClient httpClient = wrapClient(host, path, cookies); + HttpPost request = null; + try { + request = new HttpPost(buildUrl(host, path, queryMap)); + + request.setConfig(RequestConfig.custom().setConnectTimeout(timeOut).setConnectionRequestTimeout(timeOut).setSocketTimeout(timeOut).build()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + request.setHeader("Content-Type", mediaType.getType() + "/" + mediaType.getSubtype()); + try { + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + } catch (Exception e) { + } + HttpResponse response = httpClient.execute(request);return response.getEntity(); + } + + /** + * Put String + * + * @param host + * @param path + * @param headers + * @param queryMap + * @param body + * @return + * @throws Exception + */ + public static HttpEntity put(String host, String path, MediaType mediaType, + Map headers, + Map queryMap, + String body, CookieStore cookies, int timeOut) + throws Exception { + HttpClient httpClient = wrapClient(host, path, cookies); + HttpPut request = new HttpPut(buildUrl(host, path, queryMap)); + request.setConfig(RequestConfig.custom().setConnectTimeout(timeOut).setConnectionRequestTimeout(timeOut).setSocketTimeout(timeOut).build()); + request.setHeader("Content-Type", mediaType.getType() + "/" + mediaType.getSubtype()); + try { + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + } catch (Exception e) { + } + ; + if (StringUtils.isNotBlank(body)) { + request.setEntity(new StringEntity(body, "utf-8")); + } + HttpResponse response = httpClient.execute(request);return response.getEntity(); + } + + /** + * Delete + * + * @param host + * @param path + * @param headers + * @param queryMap + * @return + * @throws Exception + */ + public static HttpEntity delete(String host, String path, MediaType mediaType, + Map headers, + Map queryMap, CookieStore cookies, int timeOut) + throws Exception { + HttpClient httpClient = wrapClient(host, path, cookies); + HttpDelete request = new HttpDelete(buildUrl(host, path, queryMap)); + request.setConfig(RequestConfig.custom().setConnectTimeout(timeOut).setConnectionRequestTimeout(timeOut).setSocketTimeout(timeOut).build()); + request.setHeader("Content-Type", mediaType.getType() + "/" + mediaType.getSubtype()); + for (Map.Entry e : headers.entrySet()) { + request.addHeader(e.getKey(), e.getValue()); + } + HttpResponse response = httpClient.execute(request);return response.getEntity(); + } + + /** + * 构建请求的 url + * + * @param host + * @param path + * @param queryMap + * @return + * @throws UnsupportedEncodingException + */ + private static String buildUrl(String host, String path, Map queryMap) throws UnsupportedEncodingException { + StringBuilder sbUrl = new StringBuilder(); + if (!StringUtils.isBlank(host)) { + sbUrl.append(host); + } + if (!StringUtils.isBlank(path)) { + sbUrl.append(path); + } + if (null != queryMap) { + StringBuilder sbQuery = new StringBuilder(); + for (Map.Entry query : queryMap.entrySet()) { + if (0 < sbQuery.length()) { + sbQuery.append("&"); + } + if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue().toString())) { + sbQuery.append(query.getValue()); + } + if (!StringUtils.isBlank(query.getKey())) { + sbQuery.append(query.getKey()); + if (!StringUtils.isBlank(query.getValue().toString())) { + sbQuery.append("="); + sbQuery.append(URLEncoder.encode(query.getValue().toString(), "utf-8")); + } + } + } + if (0 < sbQuery.length()) { + sbUrl.append("?").append(sbQuery); + } + } + return sbUrl.toString(); + } + + /** + * 获取 HttpClient + * + * @param host + * @param path + * @return + */ + private static HttpClient wrapClient(String host, String path, CookieStore cookies) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + if (cookies != null) { + httpClientBuilder.setDefaultCookieStore(cookies); + } + HttpClient httpClient = httpClientBuilder.build(); + if (host != null && host.startsWith("https://")) { + return sslClient(); + } else if (StringUtils.isBlank(host) && path != null && path.startsWith("https://")) { + return sslClient(); + } + return httpClient; + } + + /** + * 在调用SSL之前需要重写验证方法,取消检测SSL + * 创建ConnectionManager,添加Connection配置信息 + * + * @return HttpClient 支持https + */ + private static HttpClient sslClient() { + try { + // 在调用SSL之前需要重写验证方法,取消检测SSL + X509TrustManager trustManager = new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(X509Certificate[] xcs, String str) { + } + + @Override + public void checkServerTrusted(X509Certificate[] xcs, String str) { + } + }; + SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS); + ctx.init(null, new TrustManager[]{trustManager}, null); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE); + // 创建Registry + RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT) + .setExpectContinueEnabled(Boolean.TRUE).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)) + .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build(); + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https", socketFactory).build(); + // 创建ConnectionManager,添加Connection配置信息 + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connectionManager) + .setDefaultRequestConfig(requestConfig).build(); + return closeableHttpClient; + } catch (KeyManagementException ex) { + throw new RuntimeException(ex); + } catch (NoSuchAlgorithmException ex) { + throw new RuntimeException(ex); + } + } + + + /** + * 将结果转换成JSONObject + * + * @param httpResponse + * @return + * @throws IOException + */ + public static JSONObject parseJson(HttpResponse httpResponse) throws IOException { + return JSON.parseObject(parseString(httpResponse)); + } + + /** + * 将结果转换成 String + * + * @param httpResponse + * @return + * @throws IOException + */ + public static String parseString(HttpResponse httpResponse) throws IOException { + HttpEntity entity = httpResponse.getEntity(); + String resp = EntityUtils.toString(entity, "UTF-8"); + EntityUtils.consume(entity); + return resp; + } +} \ No newline at end of file diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/request/WebRequest.java b/utils/src/main/java/top/krcia/elysiaserver/utils/request/WebRequest.java new file mode 100644 index 0000000..79d4726 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/request/WebRequest.java @@ -0,0 +1,162 @@ +package top.krcia.elysiaserver.utils.request; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import org.apache.http.HttpEntity; +import org.apache.http.client.CookieStore; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.cookie.BasicClientCookie; +import org.apache.http.util.EntityUtils; +import org.springframework.http.MediaType; +import top.krcia.elysiaserver.utils.request.bean.HttpFile; +import top.krcia.elysiaserver.utils.request.enums.RequestType; +import top.krcia.elysiaserver.utils.request.interfaces.WebRequestOption; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.URI; +import java.util.Map; + +public class WebRequest implements WebRequestOption{ + private Map headers; + private Map params; + private String body; + private Map bodyForm; + private RequestType requestType = RequestType.GET; + private MediaType mediaType = MediaType.APPLICATION_JSON; + private int timeout = -1; + + private CookieStore cookies = new BasicCookieStore(); + + private URI url; + + @Override + public WebRequest setHeader(Map headers) { + this.headers = headers; + return this; + } + + @Override + public WebRequest setParam(Map params) { + this.params = params; + return this; + } + + @Override + public WebRequest setBody(JSONObject body) { + this.body = body.toJSONString(); + return this; + } + + @Override + public WebRequest setBody(T body) { + this.body = JSON.toJSONString(body); + return this; + } + + @Override + public WebRequest setBodyForm(Map bodyForm) { + this.bodyForm = bodyForm; + return this; + } + + @Override + public WebRequest setCookie(Map cookies) { + for (var item : cookies.keySet()) { + BasicClientCookie cookie = new BasicClientCookie(item, cookies.get(item)); + cookie.setDomain(url.getHost()); + cookie.setPath("/"); + this.cookies.addCookie(cookie); + } + return this; + } + + @Override + public WebRequest setRequestType(RequestType requestType) { + this.requestType = requestType; + return this; + } + + @Override + public WebRequest setTimeOut(int timeout) { + this.timeout = timeout; + return this; + } + + @Override + public WebRequest setContentType(MediaType mediaType) { + this.mediaType = mediaType; + return this; + } + + @Override + public String execute() throws Exception { + switch (requestType) { + case GET -> { + return EntityUtils.toString(RequestHelper.get(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, cookies, timeout)); + } + case POST -> { + if (bodyForm != null) { + return EntityUtils.toString(RequestHelper.post(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, bodyForm, cookies, timeout)); + } else if (body != null) { + return EntityUtils.toString(RequestHelper.post(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, body, cookies, timeout)); + } else { + return EntityUtils.toString(RequestHelper.post(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, cookies, timeout)); + } + } + case PUT -> { + return EntityUtils.toString(RequestHelper.put(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, body, cookies, timeout)); + } + case DELETE -> { + return EntityUtils.toString(RequestHelper.delete(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, cookies, timeout)); + } + } + return null; + } + + @Override + public HttpFile executeFile() throws Exception { + HttpEntity entity=null; + switch (requestType) { + case GET -> { + entity= RequestHelper.get(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, cookies, timeout); + } + case POST -> { + if (bodyForm != null) { + entity= RequestHelper.post(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, bodyForm, cookies, timeout); + } else if (body != null) { + entity= RequestHelper.post(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, body, cookies, timeout); + } else { + entity= RequestHelper.post(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, cookies, timeout); + } + } + case PUT -> { + entity= RequestHelper.put(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, body, cookies, timeout); + } + case DELETE -> { + entity= RequestHelper.delete(url.getScheme() + "://" + url.getHost() + ":" + url.getPort(), url.getPath(), mediaType, headers, params, cookies, timeout); + } + } + if (entity != null) { + String contentType = entity.getContentType() != null ? entity.getContentType().getValue() : "application/octet-stream"; + try (InputStream inputStream = entity.getContent(); + ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + byte[] tmp = new byte[8192]; + int len; + while ((len = inputStream.read(tmp)) != -1) { + bos.write(tmp, 0, len); + } + return new HttpFile(bos, contentType); + } + } + return new HttpFile(new ByteArrayOutputStream(), "application/octet-stream"); + } + + public WebRequest(URI url) { + this.url = url; + } + + public static WebRequest Create(URI url) { + return new WebRequest(url); + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/request/bean/HttpFile.java b/utils/src/main/java/top/krcia/elysiaserver/utils/request/bean/HttpFile.java new file mode 100644 index 0000000..15ceea7 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/request/bean/HttpFile.java @@ -0,0 +1,74 @@ +package top.krcia.elysiaserver.utils.request.bean; + +import com.alibaba.fastjson2.JSON; + +import java.io.*; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +public class HttpFile { + private final ByteArrayOutputStream buffer; + public final long size; + public final FileFormat format; + private final String version="v 0.1"; + + public HttpFile(ByteArrayOutputStream buffer, String contentType) { + this.buffer = buffer; + this.size = buffer.size(); + this.format = detectFormat(contentType); + } + + public void saveAs(Path path) throws IOException { + try (FileOutputStream fos = new FileOutputStream(path.toString())) { + buffer.writeTo(fos); + } + } + + // 获取 InputStream + public InputStream asStream() { + return new ByteArrayInputStream(buffer.toByteArray()); + } + + public byte[] asBytes() { + return buffer.toByteArray(); + } + + private FileFormat detectFormat(String contentType) { + if (contentType == null) { + return FileFormat.UNKNOWN; + } + if (contentType.contains("mpeg")) { + return FileFormat.MP3; + } else if (contentType.contains("mp4")) { + return FileFormat.MP4; + } else if (contentType.contains("png")) { + return FileFormat.PNG; + } else if (contentType.contains("jpeg") || contentType.contains("jpg")) { + return FileFormat.JPG; + } else if (contentType.contains("plain")) { + return FileFormat.TXT; + } else if (contentType.contains("pdf")) { + return FileFormat.PDF; + } + return FileFormat.UNKNOWN; + } + + public enum FileFormat { + MP3("mp3"), MP4("mp4"), PNG("png"), JPG("jpg"), TXT("txt"), PDF("pdf"), UNKNOWN("bin"); + private final String value; + + FileFormat(String value) { + this.value = value; + } + } + + @Override + public String toString() { + Map data = new HashMap<>(); + data.put("size",size); + data.put("format",format.value); + data.put("version",version); + return JSON.toJSONString(data); + } +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/request/enums/RequestType.java b/utils/src/main/java/top/krcia/elysiaserver/utils/request/enums/RequestType.java new file mode 100644 index 0000000..927f65b --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/request/enums/RequestType.java @@ -0,0 +1,5 @@ +package top.krcia.elysiaserver.utils.request.enums; + +public enum RequestType { + GET,POST,PUT,DELETE +} diff --git a/utils/src/main/java/top/krcia/elysiaserver/utils/request/interfaces/WebRequestOption.java b/utils/src/main/java/top/krcia/elysiaserver/utils/request/interfaces/WebRequestOption.java new file mode 100644 index 0000000..7b2f037 --- /dev/null +++ b/utils/src/main/java/top/krcia/elysiaserver/utils/request/interfaces/WebRequestOption.java @@ -0,0 +1,24 @@ +package top.krcia.elysiaserver.utils.request.interfaces; + + + +import com.alibaba.fastjson2.JSONObject; +import org.springframework.http.MediaType; +import top.krcia.elysiaserver.utils.request.WebRequest; +import top.krcia.elysiaserver.utils.request.bean.HttpFile; +import top.krcia.elysiaserver.utils.request.enums.RequestType; + +import java.util.Map; +public interface WebRequestOption { + WebRequest setHeader(Map headers); + WebRequest setParam(Map params); + WebRequest setBody(JSONObject body); + WebRequest setBody(T body); + WebRequest setBodyForm(Map bodyForm); + WebRequest setCookie(Map cookie); + WebRequest setRequestType(RequestType requestType); + WebRequest setTimeOut(int timeout); + WebRequest setContentType(MediaType mediaType); + String execute() throws Exception; + HttpFile executeFile() throws Exception; +} diff --git a/utils/src/main/resources/mail-templates/forgot-password.html b/utils/src/main/resources/mail-templates/forgot-password.html new file mode 100644 index 0000000..12d79d8 --- /dev/null +++ b/utils/src/main/resources/mail-templates/forgot-password.html @@ -0,0 +1,255 @@ + + + + + + {{project-name}} - 密码重置验证码 + + + + +
    +
    +
    + +
    +

    密码重置验证

    +

    请使用以下验证码完成密码修改

    +
    + +
    +

    我们收到了您重置{{project-name}}账户密码的请求。

    +

    请使用以下验证码完成密码修改操作:

    + +
    +
    密码重置验证码
    +
    {{code}}
    +
    +

    请在 5 分钟 内使用该验证码完成密码重置,逾期将失效

    +
    + +
    + + 如果您没有请求重置密码,请立即检查账户安全并忽略此邮件。 +
    + +
    + + 为确保账户安全,请勿将验证码透露给任何人 +
    +
    + + +
    + + \ No newline at end of file diff --git a/utils/src/main/resources/mail-templates/register.html b/utils/src/main/resources/mail-templates/register.html new file mode 100644 index 0000000..8a88521 --- /dev/null +++ b/utils/src/main/resources/mail-templates/register.html @@ -0,0 +1,232 @@ + + + + + + {{project-name}} - 邮箱验证码 + + + + +
    +
    +
    + +
    +

    欢迎注册{{project-name}}

    +

    请使用以下验证码完成注册

    +
    + +
    +

    感谢您选择{{project-name}}

    +

    请使用以下验证码完成您的账户注册:

    + +
    +
    您的注册验证码
    +
    {{code}}
    +
    +

    请在 5 分钟 内使用该验证码完成注册,逾期将失效

    +
    + +

    如果您没有请求此验证码,请忽略此邮件。

    + +
    + + 此验证码用于保护您的账户安全,请勿与他人分享 +
    +
    + + +
    + + \ No newline at end of file