fix
This commit is contained in:
commit
dcd3e0a386
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/mvnw text eol=lf
|
||||||
|
*.cmd text eol=crlf
|
||||||
35
.gitignore
vendored
Normal file
35
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
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/
|
||||||
|
|
||||||
|
out/
|
||||||
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# 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.
|
||||||
|
wrapperVersion=3.3.2
|
||||||
|
distributionType=only-script
|
||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip
|
||||||
259
mvnw
vendored
Normal file
259
mvnw
vendored
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
#!/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.2
|
||||||
|
#
|
||||||
|
# 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:]'
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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 <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.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${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||||
|
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||||
|
[ -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
|
||||||
|
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
|
||||||
|
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||||
|
|
||||||
|
clean || :
|
||||||
|
exec_maven "$@"
|
||||||
149
mvnw.cmd
vendored
Normal file
149
mvnw.cmd
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
<# : 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.2
|
||||||
|
@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-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||||
|
if ($env:MVNW_REPOURL) {
|
||||||
|
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/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_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
|
||||||
|
if ($env:MAVEN_USER_HOME) {
|
||||||
|
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
|
||||||
|
}
|
||||||
|
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::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
|
||||||
|
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -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"
|
||||||
121
pom.xml
Normal file
121
pom.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.5.3</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.linearpast</groupId>
|
||||||
|
<artifactId>MinecraftManager</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
<name>MinecraftManager</name>
|
||||||
|
<description>MinecraftManager</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.36</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>nz.net.ultraq.thymeleaf</groupId>
|
||||||
|
<artifactId>thymeleaf-layout-dialect</artifactId>
|
||||||
|
<version>3.4.0</version> <!-- 使用最新稳定版本 -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-lang</groupId>
|
||||||
|
<artifactId>commons-lang</artifactId>
|
||||||
|
<version>2.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.MrGraversen</groupId>
|
||||||
|
<artifactId>minecraft-rcon</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.*</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.linearpast.minecraftmanager;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class MinecraftManagerApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(MinecraftManagerApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.linearpast.minecraftmanager.controller;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.service.impl.EmailServiceImpl;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class EmailController {
|
||||||
|
@Autowired
|
||||||
|
private EmailServiceImpl emailServiceImpl;
|
||||||
|
|
||||||
|
@GetMapping("/api/confirm")
|
||||||
|
public void confirm(@RequestParam String token, HttpServletResponse response) throws IOException {
|
||||||
|
if(!emailServiceImpl.validateToken(token)) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emailServiceImpl.markTokenAsUsed(token);
|
||||||
|
response.sendRedirect("/player/emailSuccess");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
package com.linearpast.minecraftmanager.controller;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.OperatorsService;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayerAnswersService;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayersService;
|
||||||
|
import com.linearpast.minecraftmanager.service.impl.EmailServiceImpl;
|
||||||
|
import com.linearpast.minecraftmanager.utils.Result;
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.ConfigLoader;
|
||||||
|
import com.linearpast.minecraftmanager.utils.http.HttpApiUtils;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class MainController {
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "redirect:/player/login";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/player")
|
||||||
|
public static class PlayerAccountController{
|
||||||
|
@Autowired
|
||||||
|
private PlayersService playersService;
|
||||||
|
@Autowired
|
||||||
|
private EmailServiceImpl emailServiceImpl;
|
||||||
|
@Autowired
|
||||||
|
private PlayerAnswersService playerAnswersService;
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
public String login(
|
||||||
|
@RequestParam(name = "mcName") String mcName,
|
||||||
|
@RequestParam(name = "qq") String qq,
|
||||||
|
HttpSession session,
|
||||||
|
RedirectAttributes redirectAttributes
|
||||||
|
) {
|
||||||
|
String uuid = HttpApiUtils.minecraftAccountQuery(mcName);
|
||||||
|
boolean matches = qq.matches("^\\d+$");
|
||||||
|
if(uuid == null || !matches) {
|
||||||
|
redirectAttributes.addAttribute("error", "不存在该玩家或qq号");
|
||||||
|
return "redirect:/player/login";
|
||||||
|
}
|
||||||
|
Players player = playersService.getPlayer(mcName);
|
||||||
|
Players playerIsApply = playersService.getPlayerIsApply(mcName, qq);
|
||||||
|
if(player != null && !qq.equals(player.getQq())) {
|
||||||
|
redirectAttributes.addAttribute("error", "玩家" + mcName + "已经被qq用户" + player.getQq() + "申请过白名单");
|
||||||
|
return "redirect:/player/login";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if(!playerIsApply.getConfirmationEmail().getActive()){
|
||||||
|
playersService.forceDeletePlayer(List.of(playerIsApply.getId()));
|
||||||
|
emailServiceImpl.deleteConfirmationEmail(playerIsApply.getConfirmationEmail().getId());
|
||||||
|
redirectAttributes.addAttribute("error", "未验证邮件,已清空数据,请重新登陆");
|
||||||
|
return "redirect:/player/login";
|
||||||
|
}
|
||||||
|
}catch (Exception ignored) {}
|
||||||
|
if(playerIsApply != null){
|
||||||
|
session.setAttribute("apply", playerIsApply.getStatus());
|
||||||
|
if(playerIsApply.getStatus() == (byte) 1 || playerIsApply.getStatus() == (byte) 3){
|
||||||
|
Integer score = playersService.getPlayerScoreById(playerIsApply.getId());
|
||||||
|
if(score != null) {
|
||||||
|
session.setAttribute("score", score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
session.setAttribute("qq", qq);
|
||||||
|
session.setAttribute("mcName", mcName);
|
||||||
|
session.setAttribute("isLoggedIn", true);
|
||||||
|
session.setAttribute("uuid", uuid);
|
||||||
|
return "redirect:/player/home";
|
||||||
|
}
|
||||||
|
@GetMapping("/home")
|
||||||
|
public String home(Model model, HttpSession session) {
|
||||||
|
String qq = (String) session.getAttribute("qq");
|
||||||
|
String base64 = HttpApiUtils.qqAvatarQuery(qq);
|
||||||
|
if(base64 != null) model.addAttribute("avatar", base64);
|
||||||
|
return "player/apply";
|
||||||
|
}
|
||||||
|
@GetMapping
|
||||||
|
public String index(){
|
||||||
|
return "redirect:/player/login";
|
||||||
|
}
|
||||||
|
@GetMapping("/login")
|
||||||
|
public String adminLoginIndex(@RequestParam(name = "error", required = false) String error, Model model){
|
||||||
|
model.addAttribute("error", error);
|
||||||
|
return "player/login";
|
||||||
|
}
|
||||||
|
@GetMapping("/logout")
|
||||||
|
public String logout(HttpSession session){
|
||||||
|
session.invalidate();
|
||||||
|
return "redirect:/player/login";
|
||||||
|
}
|
||||||
|
@GetMapping("/emailSuccess")
|
||||||
|
public String emailSuccess(){
|
||||||
|
return "player/email-success";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/admin")
|
||||||
|
public static class AdminAccountController{
|
||||||
|
@Autowired
|
||||||
|
private OperatorsService operatorsService;
|
||||||
|
@Autowired
|
||||||
|
private PlayersService playersService;
|
||||||
|
@PostMapping("/login")
|
||||||
|
public String adminLogin(
|
||||||
|
@RequestParam(name = "username") String username,
|
||||||
|
@RequestParam(name = "password") String password,
|
||||||
|
HttpSession session,
|
||||||
|
RedirectAttributes redirectAttributes
|
||||||
|
){
|
||||||
|
Operators login = operatorsService.login(username, password);
|
||||||
|
if(login != null){
|
||||||
|
session.setAttribute("adminAccount", login);
|
||||||
|
session.setAttribute("isLoggedIn", true);
|
||||||
|
return "redirect:/admin/home";
|
||||||
|
}
|
||||||
|
redirectAttributes.addAttribute("error", "账号密码错误");
|
||||||
|
return "redirect:/admin/login";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/welcome")
|
||||||
|
public String welcome(Model model){
|
||||||
|
int passCount = playersService.getPlayersCountByStatus((byte) 1);
|
||||||
|
int unmarkCount = playersService.getPlayersCountByStatus((byte) 2);
|
||||||
|
int denyCount = playersService.getPlayersCountByStatus((byte) 3);
|
||||||
|
model.addAttribute("email", ConfigLoader.config.get("spring.mail.username"));
|
||||||
|
model.addAttribute("passCount", passCount);
|
||||||
|
model.addAttribute("unmarkCount", unmarkCount);
|
||||||
|
model.addAttribute("denyCount", denyCount);
|
||||||
|
return "admin/welcome-page";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/home")
|
||||||
|
public String home(){
|
||||||
|
return "admin/index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/add")
|
||||||
|
public String add(){
|
||||||
|
return "admin/add-operator";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String index(){
|
||||||
|
return "redirect:/admin/login";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/login")
|
||||||
|
public String adminLoginIndex(@RequestParam(name = "error", required = false) String error, Model model){
|
||||||
|
model.addAttribute("error", error);
|
||||||
|
return "admin/login";
|
||||||
|
}
|
||||||
|
@ResponseBody
|
||||||
|
@GetMapping("/logout")
|
||||||
|
public Result<?> logout(HttpSession session){
|
||||||
|
session.invalidate();
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/application")
|
||||||
|
public String application(){
|
||||||
|
return "admin/apply-manager";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/questions")
|
||||||
|
public String question(){
|
||||||
|
return "admin/question-manager";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/answers")
|
||||||
|
public String answers(){
|
||||||
|
return "admin/answer-manager";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.linearpast.minecraftmanager.controller;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.OperatorsService;
|
||||||
|
import com.linearpast.minecraftmanager.utils.Result;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/operators")
|
||||||
|
public class OperatorController {
|
||||||
|
@Autowired
|
||||||
|
private OperatorsService operatorsService;
|
||||||
|
|
||||||
|
@PostMapping("/save")
|
||||||
|
public Result<?> save(@RequestBody Operators operators) {
|
||||||
|
if(!StringUtils.hasText(operators.getNickname()) ||
|
||||||
|
!StringUtils.hasText(operators.getPassword()) ||
|
||||||
|
!StringUtils.hasText(operators.getUsername()) ||
|
||||||
|
!StringUtils.hasText(operators.getRoleName())) {
|
||||||
|
return Result.error("错误");
|
||||||
|
}
|
||||||
|
if(operators.getUsername().length() <= 3) return Result.error("用户名应该大于3字符");
|
||||||
|
if(operators.getPassword().length() < 8 || operators.getPassword().matches("([0-9]{8,})|([a-zA-Z]){8,}"))
|
||||||
|
return Result.error("密码应同时包含数字和字母且至少8个字符");
|
||||||
|
Operators save = operatorsService.save(operators);
|
||||||
|
return save == null ? Result.error("服务器错误") : Result.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
package com.linearpast.minecraftmanager.controller;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.PlayerAnswers;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
import com.linearpast.minecraftmanager.entity.dto.ManagerAnswerDTO;
|
||||||
|
import com.linearpast.minecraftmanager.entity.dto.MarkingScoreDTO;
|
||||||
|
import com.linearpast.minecraftmanager.entity.dto.SearchAnswerDTO;
|
||||||
|
import com.linearpast.minecraftmanager.entity.view.PlayerInfoView;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayerAnswersService;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayersService;
|
||||||
|
import com.linearpast.minecraftmanager.utils.Result;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/playerAnswer")
|
||||||
|
public class PlayerAnswerController {
|
||||||
|
@Autowired
|
||||||
|
private PlayersService playersService;
|
||||||
|
@Autowired
|
||||||
|
private PlayerAnswersService playerAnswersService;
|
||||||
|
|
||||||
|
@PostMapping("/markingAnswer")
|
||||||
|
public Result<?> marking(@RequestBody MarkingScoreDTO markingScoreDTO) {
|
||||||
|
Integer playerId = markingScoreDTO.getPlayerId();
|
||||||
|
if(playerId == null) return Result.error("请重新获取数据");
|
||||||
|
List<PlayerAnswers> playerAnswers = playerAnswersService.getPlayerAnswers(new Players() {{
|
||||||
|
setId(playerId);
|
||||||
|
}});
|
||||||
|
Map<Integer, Integer> scoreMap = new HashMap<>();
|
||||||
|
for (MarkingScoreDTO.AnswerScore answerScore : markingScoreDTO.getAnswerScore()) {
|
||||||
|
scoreMap.put(answerScore.getQuestionId(), answerScore.getScore());
|
||||||
|
}
|
||||||
|
for (PlayerAnswers playerAnswer : playerAnswers) {
|
||||||
|
Integer score = scoreMap.get(playerAnswer.getId().getQuestionId());
|
||||||
|
if(score == null) {
|
||||||
|
playerAnswer.setScore(null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
playerAnswer.setScore(Math.min(playerAnswer.getQuestions().getScore(), score));
|
||||||
|
}
|
||||||
|
List<PlayerAnswers> answers = playerAnswersService.saveAllPlayerAnswers(playerAnswers);
|
||||||
|
return answers == null ? Result.error("服务器错误") : Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/getAll")
|
||||||
|
public Result<?> getAll(@RequestBody SearchAnswerDTO searchAnswerDTO) {
|
||||||
|
Page<PlayerInfoView> players = playersService.getPlayers(
|
||||||
|
searchAnswerDTO.getPlayerName(),
|
||||||
|
searchAnswerDTO.getQq(), null,
|
||||||
|
searchAnswerDTO.getStatus(),
|
||||||
|
searchAnswerDTO.getMinValue(),
|
||||||
|
searchAnswerDTO.getMaxValue(),
|
||||||
|
PageRequest.of(searchAnswerDTO.getPage() - 1, searchAnswerDTO.getSize())
|
||||||
|
);
|
||||||
|
List<ManagerAnswerDTO> result = new ArrayList<>();
|
||||||
|
List<Integer> playerIds = players.getContent().stream().map(PlayerInfoView::getId).toList();
|
||||||
|
Map<Integer, List<PlayerAnswers>> answersMap = playerAnswersService.getAllPlayerAnswers(playerIds)
|
||||||
|
.stream().collect(Collectors.groupingBy(playerAnswers -> playerAnswers.getPlayers().getId()));
|
||||||
|
|
||||||
|
for (PlayerInfoView player : players.getContent()) {
|
||||||
|
List<PlayerAnswers> playerAnswers = answersMap.getOrDefault(player.getId(), List.of());
|
||||||
|
ManagerAnswerDTO answerDTO = getManagerAnswerDTO(player, playerAnswers);
|
||||||
|
result.add(answerDTO);
|
||||||
|
}
|
||||||
|
return Result.successPage(result, players.getTotalElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ManagerAnswerDTO getManagerAnswerDTO(PlayerInfoView player, List<PlayerAnswers> playerAnswers) {
|
||||||
|
boolean readStatus = true;
|
||||||
|
Map<Integer, List<PlayerAnswers>> answersMap = new HashMap<>();
|
||||||
|
int fullScore = 0;
|
||||||
|
for (PlayerAnswers playerAnswer : playerAnswers) {
|
||||||
|
int type = playerAnswer.getQuestions().getType();
|
||||||
|
answersMap.computeIfAbsent(type, k -> new ArrayList<>()).add(playerAnswer);
|
||||||
|
if(playerAnswer.getScore() == null && type == 3){
|
||||||
|
readStatus = false;
|
||||||
|
}
|
||||||
|
fullScore += playerAnswer.getQuestions().getScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ManagerAnswerDTO(
|
||||||
|
player.getId(),
|
||||||
|
player.getPlayerName(),
|
||||||
|
player.getQq(),
|
||||||
|
player.getStatus(),
|
||||||
|
readStatus,
|
||||||
|
player.getTotalScore(),
|
||||||
|
fullScore,
|
||||||
|
answersMap.getOrDefault(1, null),
|
||||||
|
answersMap.getOrDefault(2, null),
|
||||||
|
answersMap.getOrDefault(3, null),
|
||||||
|
player.getEmailActive()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,330 @@
|
||||||
|
package com.linearpast.minecraftmanager.controller;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.linearpast.minecraftmanager.entity.*;
|
||||||
|
import com.linearpast.minecraftmanager.entity.dto.*;
|
||||||
|
import com.linearpast.minecraftmanager.entity.embeddable.PlayerAnswersId;
|
||||||
|
import com.linearpast.minecraftmanager.entity.view.PlayerInfoView;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayerAnswersService;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayersService;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.QuestionsService;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.RegionService;
|
||||||
|
import com.linearpast.minecraftmanager.service.impl.EmailServiceImpl;
|
||||||
|
import com.linearpast.minecraftmanager.utils.Result;
|
||||||
|
import com.linearpast.minecraftmanager.utils.http.HttpApiUtils;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/player")
|
||||||
|
public class PlayerController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlayersService playersService;
|
||||||
|
@Autowired
|
||||||
|
private RegionService regionService;
|
||||||
|
@Autowired
|
||||||
|
private EmailServiceImpl emailServiceImpl;
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/getApply")
|
||||||
|
public Result<?> getApplyPage(
|
||||||
|
@RequestParam(required = false) String playerName,
|
||||||
|
@RequestParam(required = false) String qq,
|
||||||
|
@RequestParam(required = false) String uuid,
|
||||||
|
@RequestParam(required = false) Byte status,
|
||||||
|
@RequestParam(required = false) Integer minValue,
|
||||||
|
@RequestParam(required = false) Integer maxValue,
|
||||||
|
@RequestParam(defaultValue = "1") Integer page,
|
||||||
|
@RequestParam(defaultValue = "10") Integer size
|
||||||
|
){
|
||||||
|
Page<PlayerInfoView> playerScores = playersService.getPlayers(
|
||||||
|
playerName, qq, uuid, status, minValue, maxValue, PageRequest.of(page - 1, size)
|
||||||
|
);
|
||||||
|
return Result.successPage(playerScores.getContent(), playerScores.getTotalElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete/{id}")
|
||||||
|
public Result<?> delete(@PathVariable Integer id){
|
||||||
|
return playersService.deletePlayer(id) ? Result.success() : Result.error("删除失败,不存在玩家或Rcon连接错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/forceDelete")
|
||||||
|
public Result<?> forceDelete(@RequestBody List<Integer> ids){
|
||||||
|
try {
|
||||||
|
playersService.forceDeletePlayer(ids);
|
||||||
|
return Result.success();
|
||||||
|
}catch (Exception ignored){}
|
||||||
|
return Result.error("删除失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/changeStatus")
|
||||||
|
public Result<?> updateStatus(@RequestBody PlayerStatusDTO playerStatusDTO, HttpSession session){
|
||||||
|
Operators operators = (Operators) session.getAttribute("adminAccount");
|
||||||
|
int code = playersService.updatePlayerStatus(playerStatusDTO.getId(), playerStatusDTO.getStatus(), operators);
|
||||||
|
return code < 1 ? Result.error("操作失败") : Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/batchDelete")
|
||||||
|
public Result<?> batchDelete(@RequestBody List<Integer> ids){
|
||||||
|
int code = playersService.deletePlayers(ids);
|
||||||
|
return code > 0 ? Result.success().msg("操作成功:" + code + "/" + ids.size() + "条数据") :
|
||||||
|
Result.error("删除失败,不存在玩家或Rcon连接错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batchChangeStatus")
|
||||||
|
public Result<?> batchPass(@RequestBody BatchStatusUpdateDTO dto, HttpSession session){
|
||||||
|
Operators operators = (Operators) session.getAttribute("adminAccount");
|
||||||
|
int code = playersService.updatePlayersStatus(dto.getIds(), dto.getStatus(), operators);
|
||||||
|
return code < 1 ? Result.error("操作失败") : Result.success().msg("操作成功:" + code + "/" + dto.getIds().size() + "条数据");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/save")
|
||||||
|
public Result<?> save(@RequestBody PlayerSaveDTO players, HttpSession session){
|
||||||
|
try {
|
||||||
|
Operators account = (Operators) session.getAttribute("adminAccount");
|
||||||
|
if(account == null) return Result.error("无权限");
|
||||||
|
players.setPid(account.getId());
|
||||||
|
if(players.getId() == null){
|
||||||
|
Players player = playersService.getPlayer(players.getPlayerName());
|
||||||
|
if(player != null) return Result.error("玩家"+ player.getPlayerName() +"已存在");
|
||||||
|
String uuid = HttpApiUtils.minecraftAccountQuery(players.getPlayerName());
|
||||||
|
if(uuid == null){
|
||||||
|
return Result.error("非正版账号");
|
||||||
|
}
|
||||||
|
Region region = regionService.findRegion(players.getCode(), null, null).get(0);
|
||||||
|
if(players.getCode() != null){
|
||||||
|
if(region.getCode() == null) return Result.error("邮政编码错误,不存在该地址");
|
||||||
|
}
|
||||||
|
ConfirmationEmail email = new ConfirmationEmail();
|
||||||
|
email.setActive(true);
|
||||||
|
ConfirmationEmail confirmationEmail = emailServiceImpl.saveConfirmationEmail(email);
|
||||||
|
Players newPlayer = new Players();
|
||||||
|
newPlayer.setPlayerName(players.getPlayerName());
|
||||||
|
newPlayer.setQq(players.getQq());
|
||||||
|
newPlayer.setUuid(uuid);
|
||||||
|
newPlayer.setStatus(players.getStatus());
|
||||||
|
newPlayer.setDescription(players.getDescription());
|
||||||
|
newPlayer.setCreateTime(LocalDateTime.parse(players.getCreateTime(),
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
||||||
|
);
|
||||||
|
newPlayer.setRegion(region);
|
||||||
|
newPlayer.setOperators(account);
|
||||||
|
newPlayer.setConfirmationEmail(confirmationEmail);
|
||||||
|
Players result = playersService.savePlayer(newPlayer);
|
||||||
|
if(result == null) return Result.error("服务器错误");
|
||||||
|
}else {
|
||||||
|
Players player = playersService.getPlayerById(players.getId());
|
||||||
|
if(player == null) return Result.error("玩家不存在");
|
||||||
|
Players playerByName = playersService.getPlayer(players.getPlayerName());
|
||||||
|
if(playerByName != null && !Objects.equals(playerByName.getId(), player.getId()))
|
||||||
|
return Result.error("玩家" + playerByName.getPlayerName() + "已存在");
|
||||||
|
if(!Objects.equals(player.getRegion().getCode(), players.getCode())){
|
||||||
|
Region newRegion = regionService.findRegion(players.getCode(), null, null).get(0);
|
||||||
|
if(players.getCode() != null){
|
||||||
|
if(newRegion.getCode() == null) return Result.error("邮政编码错误,不存在该地址");
|
||||||
|
}
|
||||||
|
player.setRegion(newRegion);
|
||||||
|
}
|
||||||
|
String uuid = HttpApiUtils.minecraftAccountQuery(players.getPlayerName());
|
||||||
|
if(uuid == null){
|
||||||
|
return Result.error("非正版账号");
|
||||||
|
}
|
||||||
|
player.setPlayerName(players.getPlayerName());
|
||||||
|
player.setQq(players.getQq());
|
||||||
|
player.setUuid(uuid);
|
||||||
|
player.setStatus(players.getStatus());
|
||||||
|
player.setCreateTime(LocalDateTime.parse(players.getCreateTime(),
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
||||||
|
);
|
||||||
|
player.setDescription(players.getDescription());
|
||||||
|
player.setOperators(account);
|
||||||
|
Players result = playersService.savePlayer(player);
|
||||||
|
if(result == null) return Result.error("服务器错误");
|
||||||
|
}
|
||||||
|
return Result.success();
|
||||||
|
}catch (Exception ignored){}
|
||||||
|
return Result.error("操作失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/answer")
|
||||||
|
public static class PlayerAnswerController{
|
||||||
|
@Autowired
|
||||||
|
private QuestionsService questionsService;
|
||||||
|
@Autowired
|
||||||
|
private PlayersService playersService;
|
||||||
|
@Autowired
|
||||||
|
private PlayerAnswersService playerAnswersService;
|
||||||
|
@Autowired
|
||||||
|
private EmailServiceImpl emailServiceImpl;
|
||||||
|
|
||||||
|
@PostMapping("/getQuestion")
|
||||||
|
public Result<?> getQuestion(@RequestBody SimpleQuestionDTO questionDTO, HttpSession session){
|
||||||
|
if(questionDTO.getCode() == null) return Result.error("请选择地址");
|
||||||
|
if(!StringUtils.hasText(questionDTO.getDescription())) return Result.error("请输入你的来由");
|
||||||
|
|
||||||
|
//更新session
|
||||||
|
session.setAttribute("code", questionDTO.getCode());
|
||||||
|
session.setAttribute("description", questionDTO.getDescription());
|
||||||
|
|
||||||
|
//判断白名单是否已存在该玩家
|
||||||
|
String playerName = (String)session.getAttribute("mcName");
|
||||||
|
Players existPlayer = playersService.getPlayer(playerName);
|
||||||
|
if(existPlayer != null) return Result.error("玩家" + playerName + "已使用qq" + existPlayer.getQq() + "申请过白名单");
|
||||||
|
|
||||||
|
//获取所有题目,并将数据进行转变以方便前端渲染
|
||||||
|
List<Questions> allQuestions = questionsService.getAllQuestions();
|
||||||
|
Map<Integer, List<Questions>> typeGroups = new HashMap<>();
|
||||||
|
if(allQuestions != null){
|
||||||
|
//一次遍历将所有题目按类型分到Map
|
||||||
|
for (Questions question : allQuestions) {
|
||||||
|
int type = question.getType();
|
||||||
|
if(type == 1){
|
||||||
|
String options = question.getOptions();
|
||||||
|
JsonArray asJsonArray = JsonParser.parseString(options).getAsJsonArray();
|
||||||
|
JsonArray result = asJsonArray.get(0).getAsJsonArray();
|
||||||
|
question.setOptions(result.toString());
|
||||||
|
} else if(type == 2){
|
||||||
|
String options = question.getOptions();
|
||||||
|
String processed = options.replaceAll("\\$\\{.*?}", "\\${}");
|
||||||
|
String[] parts = processed.split("(?<=\\$\\{})|(?=\\$\\{})");
|
||||||
|
JsonArray result = new Gson().toJsonTree(Arrays.asList(parts)).getAsJsonArray();
|
||||||
|
question.setOptions(result.toString());
|
||||||
|
}
|
||||||
|
typeGroups.computeIfAbsent(type, k -> new ArrayList<>()).add(question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//数据存储发送到前端
|
||||||
|
QuestionListDTO questionListDTO = new QuestionListDTO();
|
||||||
|
questionListDTO.setOptionQuestions(typeGroups.getOrDefault(1, null));
|
||||||
|
questionListDTO.setBlankQuestions(typeGroups.getOrDefault(2, null));
|
||||||
|
questionListDTO.setTextQuestions(typeGroups.getOrDefault(3, null));
|
||||||
|
return Result.success(questionListDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/putQuestion")
|
||||||
|
public Result<?> putQuestion(@RequestBody List<PlayerAnswerDTO> answerDTOS, HttpSession session, HttpServletRequest request){
|
||||||
|
if(answerDTOS != null && !answerDTOS.isEmpty()){
|
||||||
|
//获取session来添加一个players到数据库
|
||||||
|
String playerName = (String) session.getAttribute("mcName");
|
||||||
|
String qq = (String) session.getAttribute("qq");
|
||||||
|
Long code = (Long) session.getAttribute("code");
|
||||||
|
String uuid = (String) session.getAttribute("uuid");
|
||||||
|
String description = (String) session.getAttribute("description");
|
||||||
|
if(code == null) return Result.error("请重新登陆");
|
||||||
|
Players player = new Players();
|
||||||
|
player.setPlayerName(playerName);
|
||||||
|
player.setQq(qq);
|
||||||
|
player.setUuid(uuid);
|
||||||
|
player.setDescription(description);
|
||||||
|
player.setRegion(new Region(){{setCode(code);}});
|
||||||
|
player.setCreateTime(LocalDateTime.now());
|
||||||
|
player.setStatus((byte)2);
|
||||||
|
Players playerIsApply = playersService.getPlayerIsApply(playerName, qq);
|
||||||
|
Players players;
|
||||||
|
if(playerIsApply == null) players = playersService.savePlayer(player);
|
||||||
|
else players = null;
|
||||||
|
if(players == null) return Result.error("你已经申请过白名单");
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
//获取所有问题,比对答案,计算分数,保存答案
|
||||||
|
List<Questions> allQuestions = questionsService.getAllQuestions();
|
||||||
|
List<PlayerAnswers> answers = new ArrayList<>();
|
||||||
|
for (PlayerAnswerDTO answerDTO : answerDTOS) {
|
||||||
|
Questions questions = allQuestions.stream().filter(q -> q.getId() == answerDTO.getId()).findFirst().orElse(null);
|
||||||
|
if(questions != null){
|
||||||
|
PlayerAnswers playerAnswers = new PlayerAnswers();
|
||||||
|
playerAnswers.setPlayers(players);
|
||||||
|
playerAnswers.setQuestions(questions);
|
||||||
|
playerAnswers.setAnswer(answerDTO.getAnswer());
|
||||||
|
PlayerAnswersId playerAnswersId = new PlayerAnswersId();
|
||||||
|
playerAnswersId.setPlayerId(players.getId());
|
||||||
|
playerAnswersId.setQuestionId(questions.getId());
|
||||||
|
playerAnswers.setId(playerAnswersId);
|
||||||
|
|
||||||
|
String answer = answerDTO.getAnswer();
|
||||||
|
if(answerDTO.getType() == 1){
|
||||||
|
JsonArray playerAnswer = JsonParser.parseString(answer).getAsJsonArray();
|
||||||
|
JsonArray options = JsonParser.parseString(questions.getOptions()).getAsJsonArray();
|
||||||
|
JsonArray correctAnswer = options.get(1).getAsJsonArray();
|
||||||
|
if(correctAnswer.size() != playerAnswer.size()){
|
||||||
|
playerAnswers.setScore(0);
|
||||||
|
}else {
|
||||||
|
playerAnswers.setScore(questions.getScore());
|
||||||
|
for (int i = 0; i < correctAnswer.size(); i++) {
|
||||||
|
if(correctAnswer.get(i).getAsBoolean() != playerAnswer.get(i).getAsBoolean()){
|
||||||
|
playerAnswers.setScore(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if (answerDTO.getType() == 2){
|
||||||
|
List<String> resultList = new ArrayList<>();
|
||||||
|
JsonArray asJsonArray = JsonParser.parseString(answer).getAsJsonArray();
|
||||||
|
for (JsonElement element : asJsonArray) {
|
||||||
|
resultList.add(element.getAsString());
|
||||||
|
}
|
||||||
|
String regex = "\\$\\{(.+?)}";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(questions.getOptions());
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
while (matcher.find()) {
|
||||||
|
result.add(matcher.group(1));
|
||||||
|
}
|
||||||
|
if(resultList.equals(result)){
|
||||||
|
playerAnswers.setScore(questions.getScore());
|
||||||
|
}else {
|
||||||
|
playerAnswers.setScore(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
answers.add(playerAnswers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<PlayerAnswers> result = playerAnswersService.saveAllPlayerAnswers(answers);
|
||||||
|
|
||||||
|
String token = emailServiceImpl.generateToken(players);
|
||||||
|
String serverName = request.getServerName();
|
||||||
|
if(serverName.equals("localhost")) serverName = "127.0.0.1";
|
||||||
|
String host = String.format("%s://%s:%d", request.getScheme(), serverName, request.getServerPort());
|
||||||
|
String email = players.getQq() + "@qq.com";
|
||||||
|
String mcName = players.getPlayerName();
|
||||||
|
//邮件发送
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
emailServiceImpl.sendConfirmationEmail(mcName, email, token, host);
|
||||||
|
} catch (Exception e) {
|
||||||
|
playerAnswersService.deleteAllPlayerAnswers(players);
|
||||||
|
playersService.deletePlayer(players.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//更新session
|
||||||
|
session.setAttribute("apply", players.getStatus());
|
||||||
|
if(result != null) return Result.success().msg("请在30分钟内检查邮箱并确认\n未确认将清除申请\n验证前请勿重登本网站\n若未发送邮件请联系管理");
|
||||||
|
}catch (Exception ignored){
|
||||||
|
playerAnswersService.deleteAllPlayerAnswers(players);
|
||||||
|
playersService.deletePlayer(players.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.error("数据错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.linearpast.minecraftmanager.controller;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Questions;
|
||||||
|
import com.linearpast.minecraftmanager.entity.dto.QuestionSaveDTO;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.QuestionsService;
|
||||||
|
import com.linearpast.minecraftmanager.utils.Result;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/questions")
|
||||||
|
public class QuestionController {
|
||||||
|
@Autowired
|
||||||
|
private QuestionsService questionsService;
|
||||||
|
|
||||||
|
@PostMapping("/save")
|
||||||
|
public Result<?> saveQuestion(@RequestBody QuestionSaveDTO questionSaveDTO) {
|
||||||
|
if (questionSaveDTO != null) {
|
||||||
|
Questions questions = new Questions();
|
||||||
|
if(questionSaveDTO.getType() == (byte) 1){
|
||||||
|
JsonArray inputArray = new JsonArray();
|
||||||
|
JsonArray correct = new JsonArray();
|
||||||
|
JsonArray asJsonArray = JsonParser.parseString(questionSaveDTO.getOptionsData()).getAsJsonArray();
|
||||||
|
if(asJsonArray.size() < 2) return Result.error("至少应有两个选项");
|
||||||
|
boolean hasCorrect = false;
|
||||||
|
for (JsonElement jsonElement : asJsonArray) {
|
||||||
|
JsonObject asJsonObject = jsonElement.getAsJsonObject();
|
||||||
|
boolean check = asJsonObject.get("check").getAsBoolean();
|
||||||
|
hasCorrect = check || hasCorrect;
|
||||||
|
correct.add(check);
|
||||||
|
inputArray.add(asJsonObject.get("input").getAsString());
|
||||||
|
}
|
||||||
|
if(!hasCorrect) return Result.error("应至少有一个答案");
|
||||||
|
JsonArray resultArray = new JsonArray();
|
||||||
|
resultArray.add(inputArray);
|
||||||
|
resultArray.add(correct);
|
||||||
|
questions.setOptions(resultArray.toString());
|
||||||
|
} else if (questionSaveDTO.getType() == (byte) 2) {
|
||||||
|
questions.setOptions(questionSaveDTO.getBlankContent());
|
||||||
|
}
|
||||||
|
if(questionSaveDTO.getId() != null) questions.setId(questionSaveDTO.getId());
|
||||||
|
questions.setTitle(questionSaveDTO.getTitle());
|
||||||
|
questions.setScore(questionSaveDTO.getScore());
|
||||||
|
questions.setType(questionSaveDTO.getType());
|
||||||
|
Questions result = questionsService.saveQuestions(questions);
|
||||||
|
return result == null ? Result.error("服务器错误") : Result.success();
|
||||||
|
}
|
||||||
|
return Result.error("错误请求");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/getAll")
|
||||||
|
public Result<?> getAllQuestions(
|
||||||
|
@RequestParam(defaultValue = "1") Integer page,
|
||||||
|
@RequestParam(defaultValue = "10") Integer size
|
||||||
|
) {
|
||||||
|
Page<Questions> questions = questionsService.getQuestions(PageRequest.of(page - 1, size));
|
||||||
|
return Result.successPage(questions.getContent(), questions.getTotalElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete/{id}")
|
||||||
|
public Result<?> delete(@PathVariable Integer id){
|
||||||
|
questionsService.deleteQuestionsById(id);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/batchDelete")
|
||||||
|
public Result<?> batchDelete(@RequestBody List<Integer> ids){
|
||||||
|
questionsService.deleteQuestions(ids);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.linearpast.minecraftmanager.controller;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Region;
|
||||||
|
import com.linearpast.minecraftmanager.entity.dto.RegionFindDTO;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.RegionService;
|
||||||
|
import com.linearpast.minecraftmanager.utils.Result;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/region")
|
||||||
|
public class RegionController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RegionService regionService;
|
||||||
|
|
||||||
|
@PostMapping("/findRegion")
|
||||||
|
public Result<?> findRegion(@RequestBody RegionFindDTO regionFindDTO) {
|
||||||
|
List<Region> region = regionService.findRegion(
|
||||||
|
regionFindDTO.getCode(),
|
||||||
|
regionFindDTO.getParentCode(),
|
||||||
|
regionFindDTO.getLevel()
|
||||||
|
);
|
||||||
|
return Result.success(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "confirmation_email")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ConfirmationEmail {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Integer id;
|
||||||
|
private String token;
|
||||||
|
private Boolean used;
|
||||||
|
@Column(name = "expired_time")
|
||||||
|
private LocalDateTime expiredTime;
|
||||||
|
private Boolean active;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "operators")
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class Operators {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private Byte permissionLevel;
|
||||||
|
private String roleName;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String nickname;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.embeddable.PlayerAnswersId;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "player_answers")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PlayerAnswers {
|
||||||
|
@EmbeddedId
|
||||||
|
private PlayerAnswersId id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@MapsId("playerId")
|
||||||
|
@JoinColumn(name = "player_id")
|
||||||
|
private Players players;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@MapsId("questionId")
|
||||||
|
@JoinColumn(name = "question_id")
|
||||||
|
private Questions questions;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
private String answer;
|
||||||
|
private Integer score;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Table(name = "players")
|
||||||
|
public class Players {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "operator_id")
|
||||||
|
private Operators operators;
|
||||||
|
private String playerName;
|
||||||
|
private String uuid;
|
||||||
|
private Byte status;
|
||||||
|
private String qq;
|
||||||
|
|
||||||
|
@Column(name = "create_time")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
private String description;
|
||||||
|
@OneToOne
|
||||||
|
@JoinColumn(name = "email")
|
||||||
|
private ConfirmationEmail confirmationEmail;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "region_code")
|
||||||
|
private Region region;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Table(name = "questions")
|
||||||
|
public class Questions {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
private Byte type;
|
||||||
|
@Lob
|
||||||
|
private String options;
|
||||||
|
private Integer score;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@Table(name = "region")
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class Region {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long code;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String fullName;
|
||||||
|
|
||||||
|
@Column(name = "parent_code")
|
||||||
|
private Long parentCode;
|
||||||
|
|
||||||
|
private Byte level;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class BatchStatusUpdateDTO {
|
||||||
|
private List<Integer> ids;
|
||||||
|
private Byte status;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.PlayerAnswers;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ManagerAnswerDTO {
|
||||||
|
private Integer id;
|
||||||
|
private String playerName;
|
||||||
|
private String qq;
|
||||||
|
private Byte status;
|
||||||
|
private Boolean readStatus;
|
||||||
|
private Integer score;
|
||||||
|
private Integer fullScore;
|
||||||
|
private List<PlayerAnswers> optionAnswers;
|
||||||
|
private List<PlayerAnswers> blankAnswers;
|
||||||
|
private List<PlayerAnswers> textAnswers;
|
||||||
|
private Boolean active;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class MarkingScoreDTO {
|
||||||
|
private Integer playerId;
|
||||||
|
private List<AnswerScore> answerScore;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public static class AnswerScore{
|
||||||
|
private Integer questionId;
|
||||||
|
private Integer score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PlayerAnswerDTO {
|
||||||
|
private Integer id;
|
||||||
|
private String answer;
|
||||||
|
private Integer type;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PlayerSaveDTO {
|
||||||
|
private Integer id;
|
||||||
|
private String playerName;
|
||||||
|
private String qq;
|
||||||
|
private String description;
|
||||||
|
private Byte status;
|
||||||
|
private Integer totalScore;
|
||||||
|
private String createTime;
|
||||||
|
private Long code;
|
||||||
|
private Integer pid;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PlayerStatusDTO {
|
||||||
|
private Integer id;
|
||||||
|
private Byte status;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Questions;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class QuestionListDTO {
|
||||||
|
private List<Questions> optionQuestions;
|
||||||
|
private List<Questions> blankQuestions;
|
||||||
|
private List<Questions> textQuestions;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class QuestionSaveDTO {
|
||||||
|
private Byte type;
|
||||||
|
private Integer score;
|
||||||
|
private String title;
|
||||||
|
private String optionsData;
|
||||||
|
private String blankContent;
|
||||||
|
private Integer id;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class RegionFindDTO {
|
||||||
|
private Long code;
|
||||||
|
private Long parentCode;
|
||||||
|
private Byte level;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SearchAnswerDTO {
|
||||||
|
private String playerName;
|
||||||
|
private String qq;
|
||||||
|
private Byte status;
|
||||||
|
private Integer minValue;
|
||||||
|
private Integer maxValue;
|
||||||
|
private Integer page = 1;
|
||||||
|
private Integer size = 10;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SimpleQuestionDTO {
|
||||||
|
private Long code;
|
||||||
|
private String description;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.embeddable;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PlayerAnswersId implements Serializable {
|
||||||
|
@Column(name = "player_id")
|
||||||
|
private int playerId;
|
||||||
|
|
||||||
|
@Column(name = "question_id")
|
||||||
|
private int questionId;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.linearpast.minecraftmanager.entity.view;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.annotations.Immutable;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Immutable
|
||||||
|
@Data
|
||||||
|
@Table(name = "player_info_view")
|
||||||
|
public class PlayerInfoView {
|
||||||
|
@Id
|
||||||
|
@Column(name = "player_id")
|
||||||
|
private Integer id;
|
||||||
|
private String description;
|
||||||
|
private String uuid;
|
||||||
|
private Byte status;
|
||||||
|
private String qq;
|
||||||
|
|
||||||
|
@Column(name = "create_time")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
@Column(name = "region_code")
|
||||||
|
private Long regionCode;
|
||||||
|
|
||||||
|
@Column(name = "operator_id")
|
||||||
|
private Integer operatorId;
|
||||||
|
|
||||||
|
@Column(name = "player_name")
|
||||||
|
private String playerName;
|
||||||
|
|
||||||
|
@Column(name = "region_full_name")
|
||||||
|
private String regionFullName;
|
||||||
|
|
||||||
|
@Column(name = "operator_username")
|
||||||
|
private String operatorUsername;
|
||||||
|
|
||||||
|
@Column(name = "operator_nickname")
|
||||||
|
private String operatorNickname;
|
||||||
|
|
||||||
|
@Column(name = "total_score")
|
||||||
|
private Integer totalScore;
|
||||||
|
|
||||||
|
@Column(name = "email_active")
|
||||||
|
private Boolean emailActive;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.linearpast.minecraftmanager.exception;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(UnauthorizedException.class)
|
||||||
|
public String handlerUnauthorized(UnauthorizedException e){
|
||||||
|
if(e.getMessage().startsWith("redirect:")){
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
return "error/404.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(SystemControllerException.class)
|
||||||
|
public String handlerSystemError(SystemControllerException e){
|
||||||
|
return "error/500.html";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.linearpast.minecraftmanager.exception;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
public class SystemControllerException extends RuntimeException{
|
||||||
|
public SystemControllerException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.linearpast.minecraftmanager.exception;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||||
|
public class UnauthorizedException extends RuntimeException{
|
||||||
|
public UnauthorizedException(String message){
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.linearpast.minecraftmanager.interceptor;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.exception.UnauthorizedException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AdminInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||||
|
HttpSession session = request.getSession();
|
||||||
|
if(
|
||||||
|
session == null
|
||||||
|
|| session.getAttribute("isLoggedIn") == null
|
||||||
|
|| !((boolean) session.getAttribute("isLoggedIn"))
|
||||||
|
|| session.getAttribute("adminAccount") == null){
|
||||||
|
throw new UnauthorizedException("redirect:/admin/login?error=please login first");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.linearpast.minecraftmanager.interceptor;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.exception.UnauthorizedException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PlayerInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||||
|
HttpSession session = request.getSession();
|
||||||
|
if(session == null || session.getAttribute("mcName") == null){
|
||||||
|
throw new UnauthorizedException("redirect:/player/login?error=please login first");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.linearpast.minecraftmanager.interceptor;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AdminInterceptor adminInterceptor;
|
||||||
|
@Autowired
|
||||||
|
private PlayerInterceptor playerInterceptor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(adminInterceptor)
|
||||||
|
.addPathPatterns(
|
||||||
|
"/admin/**",
|
||||||
|
"/api/**"
|
||||||
|
).excludePathPatterns(
|
||||||
|
"/admin/login/**",
|
||||||
|
"/api/answer/**",
|
||||||
|
"/api/confirm",
|
||||||
|
"/api/region/findRegion"
|
||||||
|
);
|
||||||
|
registry.addInterceptor(playerInterceptor)
|
||||||
|
.addPathPatterns(
|
||||||
|
"/player/**",
|
||||||
|
"/api/answer/**"
|
||||||
|
).excludePathPatterns(
|
||||||
|
"/player/login/**",
|
||||||
|
"/player/emailSuccess"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.linearpast.minecraftmanager.repository;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.ConfirmationEmail;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface ConfirmationEmailRepository extends JpaRepository<ConfirmationEmail, Integer> {
|
||||||
|
Optional<ConfirmationEmail> findByToken(String token);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.linearpast.minecraftmanager.repository;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface OperatorsRepository extends JpaRepository<Operators, Integer> {
|
||||||
|
Operators findByUsernameAndPassword(String username, String password);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.linearpast.minecraftmanager.repository;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.PlayerAnswers;
|
||||||
|
import com.linearpast.minecraftmanager.entity.embeddable.PlayerAnswersId;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface PlayerAnswersRepository extends JpaRepository<PlayerAnswers, PlayerAnswersId> {
|
||||||
|
List<PlayerAnswers> findAllByPlayers_Id(Integer playerId);
|
||||||
|
|
||||||
|
@Query("SELECT pa FROM PlayerAnswers pa WHERE pa.players.id IN :playerIds")
|
||||||
|
List<PlayerAnswers> findByPlayerIds(@Param("playerIds") List<Integer> ids);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.linearpast.minecraftmanager.repository;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface PlayersRepository extends JpaRepository<Players, Integer>, JpaSpecificationExecutor<Players> {
|
||||||
|
Players findByPlayerName(String playerName);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Modifying
|
||||||
|
@Query("UPDATE Players p SET p.status = :status WHERE p.id = :id")
|
||||||
|
int updateStatusById(@Param("id") Integer id, @Param("status") Byte status);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Modifying
|
||||||
|
@Query("UPDATE Players p SET p.operators = :operators WHERE p.id = :id")
|
||||||
|
void updateOperatorsById(@Param("id") Integer id, @Param("operators") Operators operators);
|
||||||
|
|
||||||
|
@Modifying
|
||||||
|
@Transactional
|
||||||
|
@Query("UPDATE Players p SET p.status = :status, " +
|
||||||
|
"p.operators = :operators " +
|
||||||
|
"WHERE p.id IN :ids")
|
||||||
|
int bulkUpdateStatus(
|
||||||
|
@Param("ids") List<Integer> ids,
|
||||||
|
@Param("status") Byte status,
|
||||||
|
@Param("operators") Operators operators
|
||||||
|
);
|
||||||
|
|
||||||
|
Players findPlayersByPlayerNameAndQq(String playerName, String qq);
|
||||||
|
Optional<Players> findPlayersByConfirmationEmail_Token(String token);
|
||||||
|
int countByStatus(Byte status);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.linearpast.minecraftmanager.repository;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Questions;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface QuestionsRepository extends JpaRepository<Questions, Integer> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.linearpast.minecraftmanager.repository;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Region;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
import jakarta.persistence.criteria.Root;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface RegionRepository extends JpaRepository<Region, Long>, JpaSpecificationExecutor<Region> {
|
||||||
|
|
||||||
|
class RegionSpecifications {
|
||||||
|
public static Specification<Region> withDynamicQuery(
|
||||||
|
Long code, Long parentCode, Byte level) {
|
||||||
|
|
||||||
|
return (Root<Region> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
|
||||||
|
Predicate predicate = cb.conjunction();
|
||||||
|
if(code != null) predicate = cb.and(predicate, cb.equal(root.get("code"), code));
|
||||||
|
if(parentCode != null) predicate = cb.and(predicate, cb.equal(root.get("parentCode"), parentCode));
|
||||||
|
if(level != null) predicate = cb.and(predicate, cb.equal(root.get("level"), level));
|
||||||
|
return predicate;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.linearpast.minecraftmanager.repository.view;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.view.PlayerInfoView;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
import jakarta.persistence.criteria.Root;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface PlayerInfoViewRepository extends JpaRepository<PlayerInfoView, Integer> , JpaSpecificationExecutor<PlayerInfoView> {
|
||||||
|
PlayerInfoView findById(int id);
|
||||||
|
|
||||||
|
class PlayerInfoViewSpecifications {
|
||||||
|
public static Specification<PlayerInfoView> withDynamicQuery(
|
||||||
|
String playerName, String qq, String uuid, Byte status, Integer minValue, Integer maxValue) {
|
||||||
|
|
||||||
|
return (Root<PlayerInfoView> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
|
||||||
|
Predicate predicate = cb.conjunction();
|
||||||
|
if (StringUtils.hasText(playerName)) predicate = cb.and(predicate, cb.like(root.get("playerName"), "%" + playerName + "%"));
|
||||||
|
if (StringUtils.hasText(qq)) predicate = cb.and(predicate, cb.like(root.get("qq"), "%" + qq + "%"));
|
||||||
|
if (status != null) predicate = cb.and(predicate, cb.equal(root.get("status"), status));
|
||||||
|
if (StringUtils.hasText(uuid)) predicate = cb.and(predicate, cb.like(root.get("uuid"), "%" + uuid + "%"));
|
||||||
|
if (minValue != null && maxValue != null) {
|
||||||
|
predicate = cb.and(predicate, cb.between(root.get("totalScore"), minValue, maxValue));
|
||||||
|
}else if(minValue != null){
|
||||||
|
predicate = cb.and(predicate, cb.ge(root.get("totalScore"), minValue));
|
||||||
|
}else if(maxValue != null){
|
||||||
|
predicate = cb.and(predicate, cb.le(root.get("totalScore"), maxValue));
|
||||||
|
}
|
||||||
|
return predicate;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.linearpast.minecraftmanager.service;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.SelfConfig;
|
||||||
|
import com.linearpast.minecraftmanager.utils.rcon.MinecraftRconUtils;
|
||||||
|
import io.graversen.minecraft.rcon.service.ConnectOptions;
|
||||||
|
import io.graversen.minecraft.rcon.service.RconDetails;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MinecraftRconService {
|
||||||
|
@Bean
|
||||||
|
public MinecraftRconUtils rconService(SelfConfig selfConfig) {
|
||||||
|
RconDetails details = new RconDetails(selfConfig.host, selfConfig.port, selfConfig.password);
|
||||||
|
ConnectOptions connectOptions = new ConnectOptions(3, Duration.ofSeconds(3L), Duration.ofSeconds(selfConfig.heartTime));
|
||||||
|
return new MinecraftRconUtils(details, connectOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.impl;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.ConfirmationEmail;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
import com.linearpast.minecraftmanager.repository.ConfirmationEmailRepository;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.EmailService;
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.ConfigLoader;
|
||||||
|
import jakarta.mail.MessagingException;
|
||||||
|
import jakarta.mail.internet.MimeMessage;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class EmailServiceImpl implements EmailService {
|
||||||
|
@Autowired
|
||||||
|
private JavaMailSender mailSender;
|
||||||
|
@Autowired
|
||||||
|
private ConfirmationEmailRepository confirmationEmailRepository;
|
||||||
|
@Autowired
|
||||||
|
private PlayerAnswersServiceImpl playerAnswersServiceImpl;
|
||||||
|
@Autowired
|
||||||
|
private PlayersServiceImpl playersServiceImpl;
|
||||||
|
|
||||||
|
public void sendConfirmationEmail(String mcName, String toEmail, String token, String host) throws MessagingException {
|
||||||
|
MimeMessage message = mailSender.createMimeMessage();
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
|
||||||
|
|
||||||
|
// 设置邮件基本信息
|
||||||
|
helper.setFrom(ConfigLoader.config.get("spring.mail.username")); // 发件人(你的QQ邮箱)
|
||||||
|
helper.setTo(toEmail); // 收件人
|
||||||
|
helper.setSubject("邮箱验证"); // 邮件主题
|
||||||
|
|
||||||
|
// 构建HTML邮件内容(包含确认链接)
|
||||||
|
String htmlContent = buildHtmlContent(mcName, token, host);
|
||||||
|
helper.setText(htmlContent, true); // true表示内容是HTML
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
|
mailSender.send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildHtmlContent(String mcName, String token, String host) {
|
||||||
|
String baseUrl = host + "/api/confirm";
|
||||||
|
String confirmUrl = baseUrl + "?token=" + token; // 带token的确认链接
|
||||||
|
|
||||||
|
// 自定义HTML模板(可根据操作类型调整内容)
|
||||||
|
return "<html>"
|
||||||
|
+ "<head><style>.button{margin-top: 20px;margin-bottom: 20px;padding:10px 20px;background-color:#007bff;color:white;text-decoration:none;border-radius:5px;}</style></head>"
|
||||||
|
+ "<body>"
|
||||||
|
+ "<p>您正在进行玩家" + mcName + "的白名单申请操作,请点击按钮确定</p><br><br>"
|
||||||
|
+ "<a href=\"" + confirmUrl + "\" class=\"button\">点击验证</a>"
|
||||||
|
+ "<br><br><p>若您未执行此操作,请忽略此邮件。</p>"
|
||||||
|
+ "<p>链接有效期为30分钟,过期后需重新操作。</p>"
|
||||||
|
+ "</body>"
|
||||||
|
+ "</html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateToken(Players players) {
|
||||||
|
// 生成唯一token(使用UUID)
|
||||||
|
String token = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
ConfirmationEmail confirmationToken = players.getConfirmationEmail();
|
||||||
|
if(confirmationToken == null) confirmationToken = new ConfirmationEmail();
|
||||||
|
confirmationToken.setToken(token);
|
||||||
|
confirmationToken.setExpiredTime(LocalDateTime.now().plusMinutes(30));
|
||||||
|
confirmationToken.setUsed(false);
|
||||||
|
confirmationToken.setActive(false);
|
||||||
|
ConfirmationEmail confirmationEmail = this.saveConfirmationEmail(confirmationToken);
|
||||||
|
players.setConfirmationEmail(confirmationEmail);
|
||||||
|
playersServiceImpl.savePlayer(players);
|
||||||
|
|
||||||
|
return confirmationEmail.getToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validateToken(String token) {
|
||||||
|
Optional<Players> optionalToken = playersServiceImpl.getPlayerByToken(token);
|
||||||
|
if (optionalToken.isEmpty()) {
|
||||||
|
return false; // token不存在
|
||||||
|
}
|
||||||
|
|
||||||
|
Players players = optionalToken.get();
|
||||||
|
ConfirmationEmail confirmationToken = players.getConfirmationEmail();
|
||||||
|
if (confirmationToken.getUsed()) {
|
||||||
|
return confirmationToken.getActive(); // token已使用
|
||||||
|
}
|
||||||
|
if (confirmationToken.getExpiredTime().isBefore(LocalDateTime.now())) {
|
||||||
|
playerAnswersServiceImpl.deleteAllPlayerAnswers(players);
|
||||||
|
playersServiceImpl.deletePlayer(players.getId());
|
||||||
|
this.deleteConfirmationEmail(confirmationToken.getId());
|
||||||
|
return false; // token已过期
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // token有效
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markTokenAsUsed(String token) {
|
||||||
|
Optional<ConfirmationEmail> optionalToken = this.findConfirmationEmailByToken(token);
|
||||||
|
optionalToken.ifPresent(tokenEntity -> {
|
||||||
|
if(tokenEntity.getUsed() && tokenEntity.getActive()) return;
|
||||||
|
tokenEntity.setUsed(true);
|
||||||
|
tokenEntity.setActive(true);
|
||||||
|
this.saveConfirmationEmail(tokenEntity);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfirmationEmail saveConfirmationEmail(ConfirmationEmail confirmationEmail) {
|
||||||
|
return confirmationEmailRepository.save(confirmationEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<ConfirmationEmail> findConfirmationEmailByToken(String token) {
|
||||||
|
return confirmationEmailRepository.findByToken(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteConfirmationEmail(Integer id) {
|
||||||
|
confirmationEmailRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.impl;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
import com.linearpast.minecraftmanager.repository.OperatorsRepository;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.OperatorsService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class OperatorsServiceImpl implements OperatorsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OperatorsRepository operatorsRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operators login(String username, String password) {
|
||||||
|
return operatorsRepository.findByUsernameAndPassword(username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operators save(Operators operators) {
|
||||||
|
return operatorsRepository.save(operators);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.impl;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.PlayerAnswers;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
import com.linearpast.minecraftmanager.repository.PlayerAnswersRepository;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayerAnswersService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PlayerAnswersServiceImpl implements PlayerAnswersService {
|
||||||
|
@Autowired
|
||||||
|
private PlayerAnswersRepository playerAnswersRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PlayerAnswers> saveAllPlayerAnswers(List<PlayerAnswers> playerAnswers) {
|
||||||
|
return playerAnswersRepository.saveAll(playerAnswers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAllPlayerAnswers(Players players) {
|
||||||
|
List<PlayerAnswers> allByPlayersId = playerAnswersRepository.findAllByPlayers_Id(players.getId());
|
||||||
|
playerAnswersRepository.deleteAll(allByPlayersId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PlayerAnswers> getPlayerAnswers(Players players) {
|
||||||
|
return playerAnswersRepository.findAllByPlayers_Id(players.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PlayerAnswers> getAllPlayerAnswers(List<Integer> ids) {
|
||||||
|
return playerAnswersRepository.findByPlayerIds(ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,292 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.impl;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
import com.linearpast.minecraftmanager.entity.view.PlayerInfoView;
|
||||||
|
import com.linearpast.minecraftmanager.repository.PlayersRepository;
|
||||||
|
import com.linearpast.minecraftmanager.repository.view.PlayerInfoViewRepository;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.PlayersService;
|
||||||
|
import com.linearpast.minecraftmanager.utils.WhitelistTarget;
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.ConfigLoader;
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.SelfConfig;
|
||||||
|
import com.linearpast.minecraftmanager.utils.rcon.LoginWhitelistCommand;
|
||||||
|
import com.linearpast.minecraftmanager.utils.rcon.MinecraftRconUtils;
|
||||||
|
import com.linearpast.minecraftmanager.utils.rcon.SelfWhiteListCommand;
|
||||||
|
import io.graversen.minecraft.rcon.MinecraftRcon;
|
||||||
|
import io.graversen.minecraft.rcon.RconResponse;
|
||||||
|
import io.graversen.minecraft.rcon.commands.WhiteListCommand;
|
||||||
|
import io.graversen.minecraft.rcon.service.ConnectOptions;
|
||||||
|
import io.graversen.minecraft.rcon.service.RconDetails;
|
||||||
|
import io.graversen.minecraft.rcon.util.Target;
|
||||||
|
import io.graversen.minecraft.rcon.util.WhiteListModes;
|
||||||
|
import jakarta.mail.MessagingException;
|
||||||
|
import jakarta.mail.internet.MimeMessage;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||||
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PlayersServiceImpl implements PlayersService {
|
||||||
|
@Autowired
|
||||||
|
private PlayersRepository playersRepository;
|
||||||
|
@Autowired
|
||||||
|
private PlayerInfoViewRepository playerInfoViewRepository;
|
||||||
|
@Autowired
|
||||||
|
private MinecraftRconUtils rconService;
|
||||||
|
@Autowired
|
||||||
|
private JavaMailSenderImpl mailSender;
|
||||||
|
@Autowired
|
||||||
|
private SelfConfig selfConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<PlayerInfoView> getPlayers(
|
||||||
|
String playerName,
|
||||||
|
String qq,
|
||||||
|
String uuid,
|
||||||
|
Byte status,
|
||||||
|
Integer minScore,
|
||||||
|
Integer maxScore,
|
||||||
|
Pageable pageable
|
||||||
|
) {
|
||||||
|
Specification<PlayerInfoView> spec = PlayerInfoViewRepository.PlayerInfoViewSpecifications
|
||||||
|
.withDynamicQuery(playerName, qq, uuid, status, minScore, maxScore);
|
||||||
|
return playerInfoViewRepository.findAll(spec, pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deletePlayer(Integer id) {
|
||||||
|
Players byId = playersRepository.findById(id).orElse(null);
|
||||||
|
if(byId == null) return false;
|
||||||
|
rconService.connect();
|
||||||
|
MinecraftRcon minecraftRcon = rconService.minecraftRcon().orElse(null);
|
||||||
|
if(minecraftRcon == null) return false;
|
||||||
|
RconResponse response = minecraftRcon.sendSync(new SelfWhiteListCommand(Target.player(byId.getPlayerName()), WhiteListModes.REMOVE));
|
||||||
|
if(response.getResponseId() != 0) return false;
|
||||||
|
this.asyncSendEmail(byId, (byte)0, true);
|
||||||
|
playersRepository.deleteById(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forceDeletePlayer(List<Integer> ids) {
|
||||||
|
playersRepository.deleteAllById(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public int updatePlayerStatus(Integer id, Byte status, Operators operators) {
|
||||||
|
Players byId = playersRepository.findById(id).orElse(null);
|
||||||
|
if (byId == null) return 0;
|
||||||
|
rconService.connect();
|
||||||
|
RconResponse response;
|
||||||
|
MinecraftRcon minecraftRcon = rconService.minecraftRcon().orElse(null);
|
||||||
|
if(minecraftRcon == null) return 0;
|
||||||
|
if (status == 1) {
|
||||||
|
response = minecraftRcon.sendSync(new LoginWhitelistCommand(WhitelistTarget.player(byId), WhiteListModes.ADD));
|
||||||
|
} else {
|
||||||
|
response = minecraftRcon.sendSync(new SelfWhiteListCommand(Target.player(byId.getPlayerName()), WhiteListModes.REMOVE));
|
||||||
|
}
|
||||||
|
if (response.getResponseId() == 0) {
|
||||||
|
asyncSendEmail(byId, status, false);
|
||||||
|
playersRepository.updateOperatorsById(id, operators);
|
||||||
|
return playersRepository.updateStatusById(id, status);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Players getPlayer(String playerName) {
|
||||||
|
return playersRepository.findByPlayerName(playerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Players getPlayerById(Integer id) {
|
||||||
|
return playersRepository.findById(id).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Players savePlayer(Players player) {
|
||||||
|
rconService.connect();
|
||||||
|
MinecraftRcon minecraftRcon = rconService.minecraftRcon().orElse(null);
|
||||||
|
if(player.getId() == null){
|
||||||
|
if(player.getStatus() == 1) {
|
||||||
|
if(minecraftRcon == null) return null;
|
||||||
|
RconResponse response = minecraftRcon.sendSync(new LoginWhitelistCommand(WhitelistTarget.player(player), WhiteListModes.ADD));
|
||||||
|
if(response.getResponseId() != 0) return null;
|
||||||
|
asyncSendEmail(player, player.getStatus(), false);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
Players byId = playersRepository.findById(player.getId()).orElse(null);
|
||||||
|
if(byId == null) return null;
|
||||||
|
if(!byId.getStatus().equals(player.getStatus()) && (player.getStatus() == 1 || byId.getStatus() == 1)) {
|
||||||
|
if(minecraftRcon == null) return null;
|
||||||
|
RconResponse response;
|
||||||
|
if(player.getStatus() == 1) {
|
||||||
|
response = minecraftRcon.sendSync(new LoginWhitelistCommand(WhitelistTarget.player(player), WhiteListModes.ADD));
|
||||||
|
}else {
|
||||||
|
response = minecraftRcon.sendSync(new SelfWhiteListCommand(Target.player(player.getPlayerName()), WhiteListModes.REMOVE));
|
||||||
|
}
|
||||||
|
if(response.getResponseId() != 0) return null;
|
||||||
|
asyncSendEmail(player, player.getStatus(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return playersRepository.save(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Players getPlayerIsApply(String playerName, String qq) {
|
||||||
|
return playersRepository.findPlayersByPlayerNameAndQq(playerName, qq);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int deletePlayers(List<Integer> ids) {
|
||||||
|
List<Players> allById = playersRepository.findAllById(ids);
|
||||||
|
if(allById.isEmpty()) return 0;
|
||||||
|
rconService.connect();
|
||||||
|
MinecraftRcon minecraftRcon = rconService.minecraftRcon().orElse(null);
|
||||||
|
if(minecraftRcon == null) return 0;
|
||||||
|
List<Integer> successIds = new ArrayList<>();
|
||||||
|
allById.forEach(players -> {
|
||||||
|
RconResponse response = minecraftRcon.sendSync(new SelfWhiteListCommand(Target.player(players.getPlayerName()), WhiteListModes.REMOVE));
|
||||||
|
if (response.getResponseId() == 0) {
|
||||||
|
successIds.add(players.getId());
|
||||||
|
asyncSendEmail(players, (byte) 0, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
playersRepository.deleteAllById(successIds);
|
||||||
|
return successIds.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Players> getPlayerByToken(String token) {
|
||||||
|
return playersRepository.findPlayersByConfirmationEmail_Token(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int updatePlayersStatus(List<Integer> ids, Byte status, Operators operators) {
|
||||||
|
List<Players> allById = playersRepository.findAllById(ids);
|
||||||
|
if(allById.isEmpty()) return 0;
|
||||||
|
rconService.connect();
|
||||||
|
MinecraftRcon minecraftRcon = rconService.minecraftRcon().orElse(null);
|
||||||
|
if(minecraftRcon == null) return 0;
|
||||||
|
List<Integer> successIds = new ArrayList<>();
|
||||||
|
if (status == 1) {
|
||||||
|
allById.forEach(players -> {
|
||||||
|
RconResponse response = minecraftRcon.sendSync(new LoginWhitelistCommand(WhitelistTarget.player(players), WhiteListModes.ADD));
|
||||||
|
if (response.getResponseId() == 0) {
|
||||||
|
successIds.add(players.getId());
|
||||||
|
asyncSendEmail(players, status, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
allById.forEach(players -> {
|
||||||
|
RconResponse response = minecraftRcon.sendSync(new SelfWhiteListCommand(Target.player(players.getPlayerName()), WhiteListModes.REMOVE));
|
||||||
|
if (response.getResponseId() == 0) {
|
||||||
|
successIds.add(players.getId());
|
||||||
|
asyncSendEmail(players, status, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return playersRepository.bulkUpdateStatus(successIds, status, operators);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPlayersCountByStatus(Byte status) {
|
||||||
|
return playersRepository.countByStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPlayerScoreById(Integer id) {
|
||||||
|
PlayerInfoView playerInfoView = playerInfoViewRepository.findById(id).orElse(null);
|
||||||
|
if(playerInfoView == null) return null;
|
||||||
|
return playerInfoView.getTotalScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void asyncSendEmail(Players player, Byte status, boolean delete) {
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {this.sendDealEmail(player.getQq(), status, player.getPlayerName(), delete);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendDealEmail(String qq, Byte status, String playerName, boolean delete) throws MessagingException {
|
||||||
|
if(!selfConfig.emailEnable) return;
|
||||||
|
String statusText = status == 1 ? "通过" : "拒绝";
|
||||||
|
if(delete) statusText = "重置";
|
||||||
|
String mainColor = status == 1 ? "#4CAF50" : "#F44336"; // 通过为绿色,拒绝为红色
|
||||||
|
String icon = status == 1 ? "✓" : "✗";
|
||||||
|
|
||||||
|
// 使用 StringBuilder 高效拼接 HTML
|
||||||
|
String html = "<!DOCTYPE html>" +
|
||||||
|
"<html lang='zh-CN'>" +
|
||||||
|
"<head>" +
|
||||||
|
" <meta charset='UTF-8'>" +
|
||||||
|
" <meta name='viewport' content='width=device-width, initial-scale=1.0'>" +
|
||||||
|
" <title>白名单通知</title>" +
|
||||||
|
" <style>" +
|
||||||
|
" body { font-family: 'Microsoft YaHei', sans-serif; background: #f5f5f5; padding: 20px; }" +
|
||||||
|
" .card { max-width: 600px; margin: 50px auto; background: white; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); overflow: hidden; }" +
|
||||||
|
" .header { background: " + mainColor + "; color: white; padding: 30px; text-align: center; }" +
|
||||||
|
" .icon { font-size: 4rem; margin-bottom: 15px; }" +
|
||||||
|
" .content { padding: 30px; line-height: 1.8; font-size: 16px; }" +
|
||||||
|
" .notice { background: #f9f9f9; border-left: 4px solid " + mainColor + "; padding: 15px; margin: 20px 0; }" +
|
||||||
|
" .player-name { font-weight: bold; color: " + mainColor + "; }" +
|
||||||
|
" </style>" +
|
||||||
|
"</head>" +
|
||||||
|
"<body>" +
|
||||||
|
" <div class='card'>" +
|
||||||
|
" <div class='header'>" +
|
||||||
|
" <div class='icon'>" + icon + "</div>" +
|
||||||
|
" <h1>您的申请已" + statusText + "</h1>" +
|
||||||
|
" </div>" +
|
||||||
|
" <div class='content'>" +
|
||||||
|
" <p>亲爱的 <span class='player-name'>" + playerName + "</span>:</p>" +
|
||||||
|
(!delete
|
||||||
|
? " <p>您提交的服务器白名单申请已审核完毕。</p>"
|
||||||
|
: " <p>管理员已将您的申请记录移除。</p>") +
|
||||||
|
" <div class='notice'>" +
|
||||||
|
" <p>▶ 申请状态:<strong>" + statusText + "</strong></p>" +
|
||||||
|
" <p>▶ 处理时间:" + new java.util.Date() + "</p>" +
|
||||||
|
" </div>" +
|
||||||
|
" <p>" +
|
||||||
|
(status == 1
|
||||||
|
? "您现在可以进入服务器游玩,如有问题请联系管理员。"
|
||||||
|
: "") +
|
||||||
|
"</p>" +
|
||||||
|
" <hr>" +
|
||||||
|
" <p><small>本通知由系统自动发送,请勿回复</small></p>" +
|
||||||
|
" </div>" +
|
||||||
|
" </div>" +
|
||||||
|
"</body>" +
|
||||||
|
"</html>";
|
||||||
|
|
||||||
|
MimeMessage message = mailSender.createMimeMessage();
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
|
||||||
|
|
||||||
|
// 设置邮件基本信息
|
||||||
|
helper.setFrom(ConfigLoader.config.get("spring.mail.username")); // 发件人(你的QQ邮箱)
|
||||||
|
helper.setTo(qq + "@qq.com"); // 收件人
|
||||||
|
helper.setSubject("白名单处理通知"); // 邮件主题
|
||||||
|
|
||||||
|
// 构建HTML邮件内容(包含确认链接)
|
||||||
|
helper.setText(html, true); // true表示内容是HTML
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
|
mailSender.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.impl;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Questions;
|
||||||
|
import com.linearpast.minecraftmanager.repository.QuestionsRepository;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.QuestionsService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class QuestionsServiceImpl implements QuestionsService {
|
||||||
|
@Autowired
|
||||||
|
private QuestionsRepository questionsRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Questions saveQuestions(Questions questions) {
|
||||||
|
return questionsRepository.save(questions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<Questions> getQuestions(Pageable pageable) {
|
||||||
|
return questionsRepository.findAll(pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteQuestionsById(Integer id) {
|
||||||
|
questionsRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteQuestions(List<Integer> ids) {
|
||||||
|
questionsRepository.deleteAllById(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Questions> getAllQuestions() {
|
||||||
|
return questionsRepository.findAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.impl;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Region;
|
||||||
|
import com.linearpast.minecraftmanager.repository.RegionRepository;
|
||||||
|
import com.linearpast.minecraftmanager.service.inter.RegionService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class RegionServiceImpl implements RegionService {
|
||||||
|
@Autowired
|
||||||
|
private RegionRepository regionRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Region> findRegion(Long code, Long parentCode, Byte level) {
|
||||||
|
Specification<Region> spec = RegionRepository.RegionSpecifications
|
||||||
|
.withDynamicQuery(code, parentCode, level);
|
||||||
|
return regionRepository.findAll(spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.inter;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.ConfirmationEmail;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface EmailService {
|
||||||
|
ConfirmationEmail saveConfirmationEmail(ConfirmationEmail confirmationEmail);
|
||||||
|
Optional<ConfirmationEmail> findConfirmationEmailByToken(String token);
|
||||||
|
void deleteConfirmationEmail(Integer id);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.inter;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
|
||||||
|
public interface OperatorsService {
|
||||||
|
|
||||||
|
Operators login(String username, String password);
|
||||||
|
Operators save(Operators operators);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.inter;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.PlayerAnswers;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface PlayerAnswersService {
|
||||||
|
List<PlayerAnswers> saveAllPlayerAnswers(List<PlayerAnswers> playerAnswers);
|
||||||
|
void deleteAllPlayerAnswers(Players players);
|
||||||
|
List<PlayerAnswers> getPlayerAnswers(Players players);
|
||||||
|
List<PlayerAnswers> getAllPlayerAnswers(List<Integer> ids);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.inter;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Operators;
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
import com.linearpast.minecraftmanager.entity.view.PlayerInfoView;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface PlayersService {
|
||||||
|
Page<PlayerInfoView> getPlayers(
|
||||||
|
String playerName,
|
||||||
|
String qq,
|
||||||
|
String uuid,
|
||||||
|
Byte status,
|
||||||
|
Integer minScore,
|
||||||
|
Integer maxScore,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean deletePlayer(Integer id);
|
||||||
|
void forceDeletePlayer(List<Integer> ids);
|
||||||
|
int updatePlayerStatus(Integer id, Byte status, Operators operators);
|
||||||
|
Players getPlayer(String playerName);
|
||||||
|
Players getPlayerById(Integer id);
|
||||||
|
Players savePlayer(Players player);
|
||||||
|
Players getPlayerIsApply(String playerName, String qq);
|
||||||
|
int deletePlayers(List<Integer> ids) ;
|
||||||
|
Optional<Players> getPlayerByToken(String token);
|
||||||
|
int updatePlayersStatus(List<Integer> ids, Byte status, Operators operators);
|
||||||
|
Integer getPlayersCountByStatus(Byte status);
|
||||||
|
Integer getPlayerScoreById(Integer id);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.inter;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Questions;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface QuestionsService {
|
||||||
|
Questions saveQuestions(Questions questions);
|
||||||
|
Page<Questions> getQuestions(Pageable pageable);
|
||||||
|
void deleteQuestionsById(Integer id);
|
||||||
|
void deleteQuestions(List<Integer> ids);
|
||||||
|
List<Questions> getAllQuestions();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.linearpast.minecraftmanager.service.inter;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Region;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface RegionService {
|
||||||
|
List<Region> findRegion(Long code, Long parentCode, Byte level);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Result<T> {
|
||||||
|
private Integer code;
|
||||||
|
private String msg;
|
||||||
|
private Long count;
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
private Result() {}
|
||||||
|
|
||||||
|
//
|
||||||
|
public static <T> Result<T> success() {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(200);
|
||||||
|
result.setMsg("操作成功");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> Result<T> success(Integer code, String msg) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(code);
|
||||||
|
result.setMsg(msg);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> success(T data) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(200);
|
||||||
|
result.setMsg("操作成功");
|
||||||
|
result.setData(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> successPage(T data, Long total) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(200);
|
||||||
|
result.setMsg("查询成功");
|
||||||
|
result.setData(data);
|
||||||
|
result.setCount(total);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<Object> error(String msg) {
|
||||||
|
return error(500, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<Object> error(Integer code, String msg) {
|
||||||
|
Result<Object> result = new Result<>();
|
||||||
|
result.setCode(code);
|
||||||
|
result.setMsg(msg);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 链式方法
|
||||||
|
public Result<T> data(T data) {
|
||||||
|
this.data = data;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<T> msg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<T> count(Long count) {
|
||||||
|
this.count = count;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<T> code(Integer code) {
|
||||||
|
this.code = code;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
Map<String, Object> map = new HashMap<>(4);
|
||||||
|
map.put("code", code);
|
||||||
|
map.put("msg", msg);
|
||||||
|
map.put("count", count);
|
||||||
|
map.put("data", data);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.entity.Players;
|
||||||
|
|
||||||
|
public record WhitelistTarget(String name, String uuid) {
|
||||||
|
public static WhitelistTarget player(Players players) {
|
||||||
|
return new WhitelistTarget(players.getPlayerName(), players.getUuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.env.MapPropertySource;
|
||||||
|
import org.springframework.core.env.PropertySource;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ConfigLoader implements EnvironmentPostProcessor {
|
||||||
|
public static final Map<String, String> config = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||||
|
try {
|
||||||
|
PropertySource<?> source = environment.getPropertySources().stream().filter(propertySource ->
|
||||||
|
propertySource.getName().contains("application.yml")
|
||||||
|
).findFirst().orElseThrow();
|
||||||
|
if(source instanceof MapPropertySource mapPropertySource) {
|
||||||
|
for (String key : mapPropertySource.getPropertyNames()) {
|
||||||
|
config.put(key, mapPropertySource.getProperty(key).toString());
|
||||||
|
System.out.println(key + "=" + mapPropertySource.getProperty(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
System.err.println("Failed to load config: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.config;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Getter
|
||||||
|
public class SelfConfig {
|
||||||
|
|
||||||
|
public static String command;
|
||||||
|
public static String testCommand;
|
||||||
|
public static String addCommand;
|
||||||
|
|
||||||
|
//rcon
|
||||||
|
@Value("${minecraft.rcon.host}")
|
||||||
|
public String host;
|
||||||
|
|
||||||
|
@Value("${minecraft.rcon.port}")
|
||||||
|
public int port;
|
||||||
|
|
||||||
|
@Value("${minecraft.rcon.password}")
|
||||||
|
public String password;
|
||||||
|
|
||||||
|
@Value("${minecraft.rcon.heart-time}")
|
||||||
|
public long heartTime;
|
||||||
|
|
||||||
|
@Value("${email.enable}")
|
||||||
|
public boolean emailEnable;
|
||||||
|
|
||||||
|
@Value("${minecraft.rcon.wlcmd}")
|
||||||
|
public void whiteListCommand(String command) {
|
||||||
|
SelfConfig.command = command;
|
||||||
|
};
|
||||||
|
|
||||||
|
@Value("${minecraft.rcon.test-cmd}")
|
||||||
|
public void testCommand(String command) {
|
||||||
|
SelfConfig.testCommand = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${minecraft.rcon.add-cmd}")
|
||||||
|
public void addCommand(String command) {
|
||||||
|
SelfConfig.addCommand = command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.http;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class HttpApiUtils {
|
||||||
|
public static String minecraftAccountQuery(String mcName){
|
||||||
|
String host = "https://api.minecraftservices.com";
|
||||||
|
String path = "/minecraft/profile/lookup/name/" + mcName;
|
||||||
|
String method = "GET";
|
||||||
|
Map<String, String> querys = new HashMap<>();
|
||||||
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
try {
|
||||||
|
HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
|
||||||
|
String string = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println(string);
|
||||||
|
JsonObject jsonObject = JsonParser.parseString(string).getAsJsonObject();
|
||||||
|
if(Optional.ofNullable(jsonObject).isPresent() && jsonObject.has("id")){
|
||||||
|
StringBuilder id = new StringBuilder(jsonObject.get("id").getAsString()).insert(8, "-").insert(13, "-").insert(18, "-").insert(23, "-");
|
||||||
|
return id.toString();
|
||||||
|
}
|
||||||
|
}catch (Exception ignored){}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String qqAvatarQuery(String qq){
|
||||||
|
String host = "https://q.qlogo.cn";
|
||||||
|
String path = "/headimg_dl";
|
||||||
|
String method = "GET";
|
||||||
|
Map<String, String> querys = new HashMap<>();
|
||||||
|
querys.put("dst_uin", qq);
|
||||||
|
querys.put("img_type", "jpg");
|
||||||
|
querys.put("spec", "640");
|
||||||
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
try {
|
||||||
|
HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
|
||||||
|
byte[] pic = EntityUtils.toByteArray(response.getEntity());
|
||||||
|
Base64.Encoder encoder = Base64.getEncoder();
|
||||||
|
return encoder.encodeToString(pic);
|
||||||
|
}catch (Exception ignored){}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,312 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.http;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
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.conn.ClientConnectionManager;
|
||||||
|
import org.apache.http.conn.scheme.Scheme;
|
||||||
|
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||||
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||||
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HttpUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* @param path
|
||||||
|
* @param method
|
||||||
|
* @param headers
|
||||||
|
* @param querys
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static HttpResponse doGet(String host, String path, String method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
Map<String, String> querys)
|
||||||
|
throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpGet request = new HttpGet(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* post form
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* @param path
|
||||||
|
* @param method
|
||||||
|
* @param headers
|
||||||
|
* @param querys
|
||||||
|
* @param bodys
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static HttpResponse doPost(String host, String path, String method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
Map<String, String> querys,
|
||||||
|
Map<String, String> bodys)
|
||||||
|
throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bodys != null) {
|
||||||
|
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
|
||||||
|
|
||||||
|
for (String key : bodys.keySet()) {
|
||||||
|
nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
|
||||||
|
}
|
||||||
|
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
|
||||||
|
formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
request.setEntity(formEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post String
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* @param path
|
||||||
|
* @param method
|
||||||
|
* @param headers
|
||||||
|
* @param querys
|
||||||
|
* @param body
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static HttpResponse doPost(String host, String path, String method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
Map<String, String> querys,
|
||||||
|
String body)
|
||||||
|
throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(body)) {
|
||||||
|
request.setEntity(new StringEntity(body, "utf-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post stream
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* @param path
|
||||||
|
* @param method
|
||||||
|
* @param headers
|
||||||
|
* @param querys
|
||||||
|
* @param body
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static HttpResponse doPost(String host, String path, String method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
Map<String, String> querys,
|
||||||
|
byte[] body)
|
||||||
|
throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body != null) {
|
||||||
|
request.setEntity(new ByteArrayEntity(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put String
|
||||||
|
* @param host
|
||||||
|
* @param path
|
||||||
|
* @param method
|
||||||
|
* @param headers
|
||||||
|
* @param querys
|
||||||
|
* @param body
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static HttpResponse doPut(String host, String path, String method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
Map<String, String> querys,
|
||||||
|
String body)
|
||||||
|
throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPut request = new HttpPut(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(body)) {
|
||||||
|
request.setEntity(new StringEntity(body, "utf-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put stream
|
||||||
|
* @param host
|
||||||
|
* @param path
|
||||||
|
* @param method
|
||||||
|
* @param headers
|
||||||
|
* @param querys
|
||||||
|
* @param body
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static HttpResponse doPut(String host, String path, String method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
Map<String, String> querys,
|
||||||
|
byte[] body)
|
||||||
|
throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPut request = new HttpPut(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body != null) {
|
||||||
|
request.setEntity(new ByteArrayEntity(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* @param path
|
||||||
|
* @param method
|
||||||
|
* @param headers
|
||||||
|
* @param querys
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static HttpResponse doDelete(String host, String path, String method,
|
||||||
|
Map<String, String> headers,
|
||||||
|
Map<String, String> querys)
|
||||||
|
throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
|
||||||
|
StringBuilder sbUrl = new StringBuilder();
|
||||||
|
sbUrl.append(host);
|
||||||
|
if (!StringUtils.isBlank(path)) {
|
||||||
|
sbUrl.append(path);
|
||||||
|
}
|
||||||
|
if (null != querys) {
|
||||||
|
StringBuilder sbQuery = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> query : querys.entrySet()) {
|
||||||
|
if (0 < sbQuery.length()) {
|
||||||
|
sbQuery.append("&");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
|
||||||
|
sbQuery.append(query.getValue());
|
||||||
|
}
|
||||||
|
if (!StringUtils.isBlank(query.getKey())) {
|
||||||
|
sbQuery.append(query.getKey());
|
||||||
|
if (!StringUtils.isBlank(query.getValue())) {
|
||||||
|
sbQuery.append("=");
|
||||||
|
sbQuery.append(URLEncoder.encode(query.getValue(), StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 < sbQuery.length()) {
|
||||||
|
sbUrl.append("?").append(sbQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sbUrl.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpClient wrapClient(String host) {
|
||||||
|
HttpClient httpClient = new DefaultHttpClient();
|
||||||
|
if (host.startsWith("https://")) {
|
||||||
|
sslClient(httpClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void sslClient(HttpClient httpClient) {
|
||||||
|
try {
|
||||||
|
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||||
|
X509TrustManager tm = new X509TrustManager() {
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public void checkClientTrusted(X509Certificate[] xcs, String str) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public void checkServerTrusted(X509Certificate[] xcs, String str) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ctx.init(null, new TrustManager[] { tm }, null);
|
||||||
|
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
|
||||||
|
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||||
|
ClientConnectionManager ccm = httpClient.getConnectionManager();
|
||||||
|
SchemeRegistry registry = ccm.getSchemeRegistry();
|
||||||
|
registry.register(new Scheme("https", ssf, 443));
|
||||||
|
} catch (KeyManagementException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
} catch (NoSuchAlgorithmException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.rcon;
|
||||||
|
|
||||||
|
import io.graversen.minecraft.rcon.MinecraftClient;
|
||||||
|
import io.graversen.minecraft.rcon.RconConnectException;
|
||||||
|
import io.graversen.minecraft.rcon.service.ConnectOptions;
|
||||||
|
import io.graversen.minecraft.rcon.service.RconDetails;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class ConnectTask implements Callable<MinecraftClient> {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ConnectTask.class);
|
||||||
|
private final ConnectOptions connectOptions;
|
||||||
|
private final RconDetails rconDetails;
|
||||||
|
|
||||||
|
ConnectTask(ConnectOptions connectOptions, RconDetails rconDetails) {
|
||||||
|
this.connectOptions = connectOptions;
|
||||||
|
this.rconDetails = rconDetails;
|
||||||
|
log.debug("{}", connectOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinecraftClient call() throws Exception {
|
||||||
|
int currentAttempt = 0;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if (currentAttempt < this.connectOptions.getMaxRetries() && !Thread.currentThread().isInterrupted()) {
|
||||||
|
++currentAttempt;
|
||||||
|
log.debug("Connection attempt {}", currentAttempt);
|
||||||
|
|
||||||
|
MinecraftClient var8;
|
||||||
|
try {
|
||||||
|
var8 = MinecraftClient.connect(this.rconDetails.getHostname(), this.rconDetails.getPassword(), this.rconDetails.getPort());
|
||||||
|
} catch (Exception var6) {
|
||||||
|
Exception e = var6;
|
||||||
|
log.error("Connection attempt failed", e);
|
||||||
|
continue;
|
||||||
|
} finally {
|
||||||
|
if (currentAttempt < this.connectOptions.getMaxRetries()) {
|
||||||
|
this.sleep();
|
||||||
|
} else {
|
||||||
|
log.warn("Ran out of retries after {} total attempts", currentAttempt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return var8;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RconConnectException("Unable to connect to Minecraft server after %d retries", new Object[]{currentAttempt - 1});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleep() {
|
||||||
|
try {
|
||||||
|
log.debug("Pausing for {} ms", this.connectOptions.getTimeBetweenRetries().toMillis());
|
||||||
|
Thread.sleep(this.connectOptions.getTimeBetweenRetries().toMillis());
|
||||||
|
} catch (InterruptedException var2) {
|
||||||
|
InterruptedException e = var2;
|
||||||
|
e.printStackTrace();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.rcon;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.utils.WhitelistTarget;
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.SelfConfig;
|
||||||
|
import io.graversen.minecraft.rcon.commands.base.ICommand;
|
||||||
|
import io.graversen.minecraft.rcon.util.WhiteListModes;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.commons.text.StringSubstitutor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record LoginWhitelistCommand(WhitelistTarget whitelistTarget, WhiteListModes whiteListMode) implements ICommand {
|
||||||
|
public LoginWhitelistCommand(WhitelistTarget whitelistTarget, WhiteListModes whiteListMode) {
|
||||||
|
this.whitelistTarget = whitelistTarget;
|
||||||
|
this.whiteListMode = Objects.requireNonNull(whiteListMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String command() {
|
||||||
|
return switch (this.whiteListMode()) {
|
||||||
|
case ADD -> StringSubstitutor.replace(SelfConfig.addCommand + " ${name} ${uuid}", Map.of(
|
||||||
|
"name", this.whitelistTarget().name(),
|
||||||
|
"uuid", this.whitelistTarget().uuid())
|
||||||
|
);
|
||||||
|
case REMOVE, LIST, OFF, ON, RELOAD -> "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.rcon;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.SelfConfig;
|
||||||
|
import io.graversen.minecraft.rcon.IMinecraftClient;
|
||||||
|
import io.graversen.minecraft.rcon.MinecraftClient;
|
||||||
|
import io.graversen.minecraft.rcon.MinecraftRcon;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
import io.graversen.minecraft.rcon.service.ConnectOptions;
|
||||||
|
import io.graversen.minecraft.rcon.service.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class MinecraftRconUtils {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MinecraftRconUtils.class);
|
||||||
|
private final ConnectTask task;
|
||||||
|
private final RconDetails rconDetails;
|
||||||
|
private final ScheduledExecutorService executorService;
|
||||||
|
private volatile IMinecraftClient minecraftClient;
|
||||||
|
private volatile MinecraftRcon minecraftRcon;
|
||||||
|
private volatile boolean isConnected;
|
||||||
|
private volatile CountDownLatch connectionLatch;
|
||||||
|
|
||||||
|
public MinecraftRconUtils(RconDetails rconDetails, ConnectOptions connectOptions) {
|
||||||
|
this.rconDetails = rconDetails;
|
||||||
|
this.executorService = Executors.newScheduledThreadPool(2);
|
||||||
|
this.task = new ConnectTask(connectOptions, rconDetails);
|
||||||
|
startConnectionWatcher(connectOptions.getConnectionWatcherInterval().toSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect(){
|
||||||
|
isConnected = false;
|
||||||
|
try {minecraftClient.close();
|
||||||
|
}catch (Exception ignored){}
|
||||||
|
setMinecraftClient(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect(){
|
||||||
|
boolean connected = isConnected(Duration.ofSeconds(1));
|
||||||
|
if(connected) return;
|
||||||
|
doConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnected(Duration timeout) {
|
||||||
|
if(!isConnected) return false;
|
||||||
|
if(minecraftClient == null) return false;
|
||||||
|
if(minecraftRcon == null) return false;
|
||||||
|
try {
|
||||||
|
return rconTest(minecraftClient, timeout);
|
||||||
|
}catch(Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean rconTest(IMinecraftClient minecraftClient, Duration timeout){
|
||||||
|
try {
|
||||||
|
minecraftClient.sendRawSilently(SelfConfig.testCommand).get(timeout.toSeconds(), TimeUnit.SECONDS);
|
||||||
|
return true;
|
||||||
|
} catch (ExecutionException | TimeoutException | InterruptedException var3) {
|
||||||
|
log.error("Lost connection to {}", this.rconDetails.getHostname());
|
||||||
|
try {minecraftClient.close();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<MinecraftRcon> minecraftRcon() {
|
||||||
|
return Optional.ofNullable(this.minecraftRcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doConnect() {
|
||||||
|
doConnect(5);
|
||||||
|
}
|
||||||
|
public void doConnect(int timeout) {
|
||||||
|
try {
|
||||||
|
if(this.connectionLatch != null){
|
||||||
|
this.connectionLatch.await(timeout, TimeUnit.SECONDS);
|
||||||
|
this.connectionLatch = new CountDownLatch(1);
|
||||||
|
}
|
||||||
|
Future<MinecraftClient> submit = this.executorService.submit(task);
|
||||||
|
this.minecraftClient = submit.get(timeout, TimeUnit.SECONDS);
|
||||||
|
this.minecraftRcon = new MinecraftRcon(this.minecraftClient);
|
||||||
|
this.isConnected = true;
|
||||||
|
if(this.connectionLatch != null){
|
||||||
|
this.connectionLatch.countDown();
|
||||||
|
}
|
||||||
|
} catch (Exception var2) {
|
||||||
|
Exception e = var2;
|
||||||
|
disconnect();
|
||||||
|
if (this.minecraftClient != null){
|
||||||
|
this.connectionLatch.countDown();
|
||||||
|
}
|
||||||
|
log.error("Connection fail to {}", this.rconDetails.getHostname(), var2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startConnectionWatcher(long intervalSeconds) {
|
||||||
|
this.executorService.scheduleWithFixedDelay(new TestConnect(this.rconDetails), 0, intervalSeconds, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinecraftClient(MinecraftClient minecraftClient) {
|
||||||
|
this.minecraftClient = minecraftClient;
|
||||||
|
if(this.minecraftClient != null) this.minecraftRcon = new MinecraftRcon(this.minecraftClient);
|
||||||
|
else this.minecraftRcon = null;
|
||||||
|
}
|
||||||
|
public void setConnected(boolean connected) {
|
||||||
|
this.isConnected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestConnect implements Runnable {
|
||||||
|
private final RconDetails rconDetails;
|
||||||
|
TestConnect(RconDetails rconDetails) {
|
||||||
|
this.rconDetails = rconDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
if(isConnected(Duration.ofSeconds(1))) return;
|
||||||
|
minecraftClient = MinecraftClient.connect(this.rconDetails.getHostname(), this.rconDetails.getPassword(), this.rconDetails.getPort());
|
||||||
|
setMinecraftClient((MinecraftClient) minecraftClient);
|
||||||
|
setConnected(true);
|
||||||
|
}catch (Exception var2) {
|
||||||
|
disconnect();
|
||||||
|
log.error("Connection fail to {}", this.rconDetails.getHostname(), var2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.linearpast.minecraftmanager.utils.rcon;
|
||||||
|
|
||||||
|
import com.linearpast.minecraftmanager.utils.config.SelfConfig;
|
||||||
|
import io.graversen.minecraft.rcon.commands.base.BaseTargetedCommand;
|
||||||
|
import io.graversen.minecraft.rcon.util.Target;
|
||||||
|
import io.graversen.minecraft.rcon.util.WhiteListModes;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.commons.text.StringSubstitutor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class SelfWhiteListCommand extends BaseTargetedCommand {
|
||||||
|
private final WhiteListModes whiteListMode;
|
||||||
|
|
||||||
|
public SelfWhiteListCommand(Target target, WhiteListModes whiteListMode) {
|
||||||
|
super(target);
|
||||||
|
this.whiteListMode = Objects.requireNonNull(whiteListMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String command() {
|
||||||
|
return switch (this.getWhiteListMode()) {
|
||||||
|
case ADD, REMOVE ->
|
||||||
|
StringSubstitutor.replace(SelfConfig.command + " ${mode} ${target}", Map.of("mode", this.getWhiteListMode().getModeName(), "target", this.getTarget()));
|
||||||
|
case LIST, OFF, ON, RELOAD -> SelfConfig.command + " " + this.getWhiteListMode().getModeName();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/main/resources/META-INF/MANIFEST.MF
Normal file
3
src/main/resources/META-INF/MANIFEST.MF
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: com.linearpast.minecraftmanager.MinecraftManagerApplication
|
||||||
|
|
||||||
1
src/main/resources/META-INF/spring.factories
Normal file
1
src/main/resources/META-INF/spring.factories
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
org.springframework.boot.env.EnvironmentPostProcessor=com.linearpast.minecraftmanager.utils.config.ConfigLoader
|
||||||
45
src/main/resources/application.yml
Normal file
45
src/main/resources/application.yml
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
server:
|
||||||
|
port: 8484
|
||||||
|
servlet:
|
||||||
|
session:
|
||||||
|
timeout: 8h
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: MinecraftManager
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://127.0.0.1:3306/minecraft_manager_ltd?useSSL=false
|
||||||
|
username: admin
|
||||||
|
password: 123456
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
jpa:
|
||||||
|
show-sql: true
|
||||||
|
hibernate:
|
||||||
|
ddl-auto: update
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
dialect: org.hibernate.dialect.MySQL8Dialect
|
||||||
|
mail:
|
||||||
|
properties:
|
||||||
|
mail:
|
||||||
|
smtp:
|
||||||
|
auth: true
|
||||||
|
ssl:
|
||||||
|
enable: true
|
||||||
|
username: admin@163.com
|
||||||
|
password: 123456789
|
||||||
|
port: 465
|
||||||
|
host: smtp.163.com
|
||||||
|
|
||||||
|
# ========== self config ==========
|
||||||
|
minecraft:
|
||||||
|
rcon:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 25575
|
||||||
|
password: 123456
|
||||||
|
wlcmd: whitelist
|
||||||
|
heart-time: 600
|
||||||
|
test-cmd: ping
|
||||||
|
add-cmd: login whitelist
|
||||||
|
email:
|
||||||
|
enable: false
|
||||||
5
src/main/resources/static/css/all.min.css
vendored
Normal file
5
src/main/resources/static/css/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
11
src/main/resources/static/css/animate.min.css
vendored
Normal file
11
src/main/resources/static/css/animate.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/main/resources/static/css/aos.min.css
vendored
Normal file
1
src/main/resources/static/css/aos.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1345
src/main/resources/static/css/bootstrap-icons.css
vendored
Normal file
1345
src/main/resources/static/css/bootstrap-icons.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
src/main/resources/static/css/bootstrap-select.min.css
vendored
Normal file
6
src/main/resources/static/css/bootstrap-select.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
144
src/main/resources/static/css/css.css
Normal file
144
src/main/resources/static/css/css.css
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
/* devanagari */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLDz8Z11lFc-K.woff2) format('woff2');
|
||||||
|
unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLDz8Z1JlFc-K.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLDz8Z1xlFQ.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;
|
||||||
|
}
|
||||||
|
/* devanagari */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/pxiEyp8kv8JHgFVrJJbecmNE.woff2) format('woff2');
|
||||||
|
unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/pxiEyp8kv8JHgFVrJJnecmNE.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/pxiEyp8kv8JHgFVrJJfecg.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;
|
||||||
|
}
|
||||||
|
/* devanagari */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLGT9Z11lFc-K.woff2) format('woff2');
|
||||||
|
unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLGT9Z1JlFc-K.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLGT9Z1xlFQ.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;
|
||||||
|
}
|
||||||
|
/* devanagari */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLEj6Z11lFc-K.woff2) format('woff2');
|
||||||
|
unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLEj6Z1JlFc-K.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLEj6Z1xlFQ.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;
|
||||||
|
}
|
||||||
|
/* devanagari */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLCz7Z11lFc-K.woff2) format('woff2');
|
||||||
|
unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLCz7Z1JlFc-K.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLCz7Z1xlFQ.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;
|
||||||
|
}
|
||||||
|
/* devanagari */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLDD4Z11lFc-K.woff2) format('woff2');
|
||||||
|
unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLDD4Z1JlFc-K.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
src: url(../font/pxiByp8kv8JHgFVrLDD4Z1xlFQ.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;
|
||||||
|
}
|
||||||
168
src/main/resources/static/css/css1.css
Normal file
168
src/main/resources/static/css/css1.css
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/mem8YaGs126MiZpBA-UFWJ0bbck.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/mem8YaGs126MiZpBA-UFUZ0bbck.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* greek-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/mem8YaGs126MiZpBA-UFWZ0bbck.woff2) format('woff2');
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
/* greek */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/mem8YaGs126MiZpBA-UFVp0bbck.woff2) format('woff2');
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/mem8YaGs126MiZpBA-UFWp0bbck.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/mem8YaGs126MiZpBA-UFW50bbck.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/mem8YaGs126MiZpBA-UFVZ0b.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UNirkOX-hpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UNirkOVuhpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* greek-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UNirkOXuhpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
/* greek */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UNirkOUehpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UNirkOXehpOqc.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UNirkOXOhpOqc.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UNirkOUuhp.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UN7rgOX-hpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UN7rgOVuhpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* greek-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UN7rgOXuhpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
/* greek */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UN7rgOUehpOqc.woff2) format('woff2');
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UN7rgOXehpOqc.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UN7rgOXOhpOqc.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/mem5YaGs126MiZpBA-UN7rgOUuhp.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;
|
||||||
|
}
|
||||||
162
src/main/resources/static/css/css2.css
Normal file
162
src/main/resources/static/css/css2.css
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
/* arabic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalrub46O59ZMaA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalrub46F59ZMaA.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 200;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalrub46L59Y.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;
|
||||||
|
}
|
||||||
|
/* arabic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6HkvalqKbI6O59ZMaA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6HkvalqKbI6F59ZMaA.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6HkvalqKbI6L59Y.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;
|
||||||
|
}
|
||||||
|
/* arabic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXGc1nY6HkvalIkTpu0xg.woff2) format('woff2');
|
||||||
|
unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXGc1nY6HkvalIvTpu0xg.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXGc1nY6HkvalIhTps.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;
|
||||||
|
}
|
||||||
|
/* arabic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalr-ao6O59ZMaA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalr-ao6F59ZMaA.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalr-ao6L59Y.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;
|
||||||
|
}
|
||||||
|
/* arabic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalqaa46O59ZMaA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalqaa46F59ZMaA.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6Hkvalqaa46L59Y.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;
|
||||||
|
}
|
||||||
|
/* arabic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6HkvalqiaY6O59ZMaA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6HkvalqiaY6F59ZMaA.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cairo';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/SLXLc1nY6HkvalqiaY6L59Y.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;
|
||||||
|
}
|
||||||
160
src/main/resources/static/css/css3.css
Normal file
160
src/main/resources/static/css/css3.css
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/JTUSjIg1_i6t8kCHKm459WZhyzbi.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/JTUSjIg1_i6t8kCHKm459Wdhyzbi.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/JTUSjIg1_i6t8kCHKm459Wlhyw.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_ZpC3gTD_u50.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_ZpC3g3D_u50.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_ZpC3gbD_u50.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_ZpC3gfD_u50.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_ZpC3gnD_g.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_bZF3gTD_u50.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_bZF3g3D_u50.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_bZF3gbD_u50.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_bZF3gfD_u50.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_bZF3gnD_g.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_dJE3gTD_u50.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_dJE3g3D_u50.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_dJE3gbD_u50.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_dJE3gfD_u50.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/JTURjIg1_i6t8kCHKm45_dJE3gnD_g.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;
|
||||||
|
}
|
||||||
168
src/main/resources/static/css/css4.css
Normal file
168
src/main/resources/static/css/css4.css
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/KFOmCnqEu92Fr1Mu72xKOzY.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/KFOmCnqEu92Fr1Mu5mxKOzY.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* greek-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/KFOmCnqEu92Fr1Mu7mxKOzY.woff2) format('woff2');
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
/* greek */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/KFOmCnqEu92Fr1Mu4WxKOzY.woff2) format('woff2');
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/KFOmCnqEu92Fr1Mu7WxKOzY.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/KFOmCnqEu92Fr1Mu7GxKOzY.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/KFOmCnqEu92Fr1Mu4mxK.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmEU9fCRc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmEU9fABc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* greek-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmEU9fCBc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
/* greek */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmEU9fBxc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmEU9fCxc4EsA.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmEU9fChc4EsA.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmEU9fBBc4.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmWUlfCRc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmWUlfABc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* greek-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmWUlfCBc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+1F00-1FFF;
|
||||||
|
}
|
||||||
|
/* greek */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmWUlfBxc4EsA.woff2) format('woff2');
|
||||||
|
unicode-range: U+0370-03FF;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmWUlfCxc4EsA.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmWUlfChc4EsA.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/KFOlCnqEu92Fr1MmWUlfBBc4.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;
|
||||||
|
}
|
||||||
120
src/main/resources/static/css/css5.css
Normal file
120
src/main/resources/static/css/css5.css
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/XRXV3I6Li01BKofIOOaBXso.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/XRXV3I6Li01BKofIMeaBXso.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/XRXV3I6Li01BKofIOuaBXso.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/XRXV3I6Li01BKofIO-aBXso.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(../font/XRXV3I6Li01BKofINeaB.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofA6sKUbOvISTs.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofA6sKUZevISTs.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofA6sKUbuvISTs.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofA6sKUb-vISTs.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofA6sKUYevI.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;
|
||||||
|
}
|
||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofAjsOUbOvISTs.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofAjsOUZevISTs.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofAjsOUbuvISTs.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;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofAjsOUb-vISTs.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;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Nunito';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(../font/XRXW3I6Li01BKofAjsOUYevI.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;
|
||||||
|
}
|
||||||
409
src/main/resources/static/css/flaticon.css
Normal file
409
src/main/resources/static/css/flaticon.css
Normal file
|
|
@ -0,0 +1,409 @@
|
||||||
|
/*
|
||||||
|
Flaticon icon font: Flaticon
|
||||||
|
Creation date: 25/04/2017 09:15
|
||||||
|
*/
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Flaticon";
|
||||||
|
src: url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon/Flaticon.eot");
|
||||||
|
src: url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon/Flaticon.eot?#iefix") format("embedded-opentype"),
|
||||||
|
url("../font/Flaticon.woff") format("woff"),
|
||||||
|
url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon/Flaticon.ttf") format("truetype"),
|
||||||
|
url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon/Flaticon.svg#Flaticon") format("svg");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
|
@font-face {
|
||||||
|
font-family: "Flaticon";
|
||||||
|
src: url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon/Flaticon.svg#Flaticon") format("svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[class^="flaticon-"]:before, [class*=" flaticon-"]:before,
|
||||||
|
[class^="flaticon-"]:after, [class*=" flaticon-"]:after {
|
||||||
|
font-family: Flaticon;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flaticon-381-add:before { content: "\f100"; }
|
||||||
|
.flaticon-381-add-1:before { content: "\f101"; }
|
||||||
|
.flaticon-381-add-2:before { content: "\f102"; }
|
||||||
|
.flaticon-381-add-3:before { content: "\f103"; }
|
||||||
|
.flaticon-381-alarm-clock:before { content: "\f104"; }
|
||||||
|
.flaticon-381-alarm-clock-1:before { content: "\f105"; }
|
||||||
|
.flaticon-381-album:before { content: "\f106"; }
|
||||||
|
.flaticon-381-album-1:before { content: "\f107"; }
|
||||||
|
.flaticon-381-album-2:before { content: "\f108"; }
|
||||||
|
.flaticon-381-album-3:before { content: "\f109"; }
|
||||||
|
.flaticon-381-app:before { content: "\f10a"; }
|
||||||
|
.flaticon-381-archive:before { content: "\f10b"; }
|
||||||
|
.flaticon-381-back:before { content: "\f10c"; }
|
||||||
|
.flaticon-381-back-1:before { content: "\f10d"; }
|
||||||
|
.flaticon-381-back-2:before { content: "\f10e"; }
|
||||||
|
.flaticon-381-background:before { content: "\f10f"; }
|
||||||
|
.flaticon-381-background-1:before { content: "\f110"; }
|
||||||
|
.flaticon-381-battery:before { content: "\f111"; }
|
||||||
|
.flaticon-381-battery-1:before { content: "\f112"; }
|
||||||
|
.flaticon-381-battery-2:before { content: "\f113"; }
|
||||||
|
.flaticon-381-battery-3:before { content: "\f114"; }
|
||||||
|
.flaticon-381-battery-4:before { content: "\f115"; }
|
||||||
|
.flaticon-381-battery-5:before { content: "\f116"; }
|
||||||
|
.flaticon-381-battery-6:before { content: "\f117"; }
|
||||||
|
.flaticon-381-battery-7:before { content: "\f118"; }
|
||||||
|
.flaticon-381-battery-8:before { content: "\f119"; }
|
||||||
|
.flaticon-381-battery-9:before { content: "\f11a"; }
|
||||||
|
.flaticon-381-binoculars:before { content: "\f11b"; }
|
||||||
|
.flaticon-381-blueprint:before { content: "\f11c"; }
|
||||||
|
.flaticon-381-bluetooth:before { content: "\f11d"; }
|
||||||
|
.flaticon-381-bluetooth-1:before { content: "\f11e"; }
|
||||||
|
.flaticon-381-book:before { content: "\f11f"; }
|
||||||
|
.flaticon-381-bookmark:before { content: "\f120"; }
|
||||||
|
.flaticon-381-bookmark-1:before { content: "\f121"; }
|
||||||
|
.flaticon-381-box:before { content: "\f122"; }
|
||||||
|
.flaticon-381-box-1:before { content: "\f123"; }
|
||||||
|
.flaticon-381-box-2:before { content: "\f124"; }
|
||||||
|
.flaticon-381-briefcase:before { content: "\f125"; }
|
||||||
|
.flaticon-381-broken-heart:before { content: "\f126"; }
|
||||||
|
.flaticon-381-broken-link:before { content: "\f127"; }
|
||||||
|
.flaticon-381-calculator:before { content: "\f128"; }
|
||||||
|
.flaticon-381-calculator-1:before { content: "\f129"; }
|
||||||
|
.flaticon-381-calendar:before { content: "\f12a"; }
|
||||||
|
.flaticon-381-calendar-1:before { content: "\f12b"; }
|
||||||
|
.flaticon-381-calendar-2:before { content: "\f12c"; }
|
||||||
|
.flaticon-381-calendar-3:before { content: "\f12d"; }
|
||||||
|
.flaticon-381-calendar-4:before { content: "\f12e"; }
|
||||||
|
.flaticon-381-calendar-5:before { content: "\f12f"; }
|
||||||
|
.flaticon-381-calendar-6:before { content: "\f130"; }
|
||||||
|
.flaticon-381-calendar-7:before { content: "\f131"; }
|
||||||
|
.flaticon-381-clock:before { content: "\f132"; }
|
||||||
|
.flaticon-381-clock-1:before { content: "\f133"; }
|
||||||
|
.flaticon-381-clock-2:before { content: "\f134"; }
|
||||||
|
.flaticon-381-close:before { content: "\f135"; }
|
||||||
|
.flaticon-381-cloud:before { content: "\f136"; }
|
||||||
|
.flaticon-381-cloud-computing:before { content: "\f137"; }
|
||||||
|
.flaticon-381-command:before { content: "\f138"; }
|
||||||
|
.flaticon-381-compact-disc:before { content: "\f139"; }
|
||||||
|
.flaticon-381-compact-disc-1:before { content: "\f13a"; }
|
||||||
|
.flaticon-381-compact-disc-2:before { content: "\f13b"; }
|
||||||
|
.flaticon-381-compass:before { content: "\f13c"; }
|
||||||
|
.flaticon-381-compass-1:before { content: "\f13d"; }
|
||||||
|
.flaticon-381-compass-2:before { content: "\f13e"; }
|
||||||
|
.flaticon-381-controls:before { content: "\f13f"; }
|
||||||
|
.flaticon-381-controls-1:before { content: "\f140"; }
|
||||||
|
.flaticon-381-controls-2:before { content: "\f141"; }
|
||||||
|
.flaticon-381-controls-3:before { content: "\f142"; }
|
||||||
|
.flaticon-381-controls-4:before { content: "\f143"; }
|
||||||
|
.flaticon-381-controls-5:before { content: "\f144"; }
|
||||||
|
.flaticon-381-controls-6:before { content: "\f145"; }
|
||||||
|
.flaticon-381-controls-7:before { content: "\f146"; }
|
||||||
|
.flaticon-381-controls-8:before { content: "\f147"; }
|
||||||
|
.flaticon-381-controls-9:before { content: "\f148"; }
|
||||||
|
.flaticon-381-database:before { content: "\f149"; }
|
||||||
|
.flaticon-381-database-1:before { content: "\f14a"; }
|
||||||
|
.flaticon-381-database-2:before { content: "\f14b"; }
|
||||||
|
.flaticon-381-diamond:before { content: "\f14c"; }
|
||||||
|
.flaticon-381-diploma:before { content: "\f14d"; }
|
||||||
|
.flaticon-381-dislike:before { content: "\f14e"; }
|
||||||
|
.flaticon-381-divide:before { content: "\f14f"; }
|
||||||
|
.flaticon-381-division:before { content: "\f150"; }
|
||||||
|
.flaticon-381-division-1:before { content: "\f151"; }
|
||||||
|
.flaticon-381-download:before { content: "\f152"; }
|
||||||
|
.flaticon-381-earth-globe:before { content: "\f153"; }
|
||||||
|
.flaticon-381-earth-globe-1:before { content: "\f154"; }
|
||||||
|
.flaticon-381-edit:before { content: "\f155"; }
|
||||||
|
.flaticon-381-edit-1:before { content: "\f156"; }
|
||||||
|
.flaticon-381-eject:before { content: "\f157"; }
|
||||||
|
.flaticon-381-eject-1:before { content: "\f158"; }
|
||||||
|
.flaticon-381-enter:before { content: "\f159"; }
|
||||||
|
.flaticon-381-equal:before { content: "\f15a"; }
|
||||||
|
.flaticon-381-equal-1:before { content: "\f15b"; }
|
||||||
|
.flaticon-381-equal-2:before { content: "\f15c"; }
|
||||||
|
.flaticon-381-error:before { content: "\f15d"; }
|
||||||
|
.flaticon-381-exit:before { content: "\f15e"; }
|
||||||
|
.flaticon-381-exit-1:before { content: "\f15f"; }
|
||||||
|
.flaticon-381-exit-2:before { content: "\f160"; }
|
||||||
|
.flaticon-381-fast-forward:before { content: "\f161"; }
|
||||||
|
.flaticon-381-fast-forward-1:before { content: "\f162"; }
|
||||||
|
.flaticon-381-file:before { content: "\f163"; }
|
||||||
|
.flaticon-381-file-1:before { content: "\f164"; }
|
||||||
|
.flaticon-381-file-2:before { content: "\f165"; }
|
||||||
|
.flaticon-381-film-strip:before { content: "\f166"; }
|
||||||
|
.flaticon-381-film-strip-1:before { content: "\f167"; }
|
||||||
|
.flaticon-381-fingerprint:before { content: "\f168"; }
|
||||||
|
.flaticon-381-flag:before { content: "\f169"; }
|
||||||
|
.flaticon-381-flag-1:before { content: "\f16a"; }
|
||||||
|
.flaticon-381-flag-2:before { content: "\f16b"; }
|
||||||
|
.flaticon-381-flag-3:before { content: "\f16c"; }
|
||||||
|
.flaticon-381-flag-4:before { content: "\f16d"; }
|
||||||
|
.flaticon-381-focus:before { content: "\f16e"; }
|
||||||
|
.flaticon-381-folder:before { content: "\f16f"; }
|
||||||
|
.flaticon-381-folder-1:before { content: "\f170"; }
|
||||||
|
.flaticon-381-folder-10:before { content: "\f171"; }
|
||||||
|
.flaticon-381-folder-11:before { content: "\f172"; }
|
||||||
|
.flaticon-381-folder-12:before { content: "\f173"; }
|
||||||
|
.flaticon-381-folder-13:before { content: "\f174"; }
|
||||||
|
.flaticon-381-folder-14:before { content: "\f175"; }
|
||||||
|
.flaticon-381-folder-15:before { content: "\f176"; }
|
||||||
|
.flaticon-381-folder-16:before { content: "\f177"; }
|
||||||
|
.flaticon-381-folder-17:before { content: "\f178"; }
|
||||||
|
.flaticon-381-folder-18:before { content: "\f179"; }
|
||||||
|
.flaticon-381-folder-19:before { content: "\f17a"; }
|
||||||
|
.flaticon-381-folder-2:before { content: "\f17b"; }
|
||||||
|
.flaticon-381-folder-3:before { content: "\f17c"; }
|
||||||
|
.flaticon-381-folder-4:before { content: "\f17d"; }
|
||||||
|
.flaticon-381-folder-5:before { content: "\f17e"; }
|
||||||
|
.flaticon-381-folder-6:before { content: "\f17f"; }
|
||||||
|
.flaticon-381-folder-7:before { content: "\f180"; }
|
||||||
|
.flaticon-381-folder-8:before { content: "\f181"; }
|
||||||
|
.flaticon-381-folder-9:before { content: "\f182"; }
|
||||||
|
.flaticon-381-forbidden:before { content: "\f183"; }
|
||||||
|
.flaticon-381-funnel:before { content: "\f184"; }
|
||||||
|
.flaticon-381-gift:before { content: "\f185"; }
|
||||||
|
.flaticon-381-heart:before { content: "\f186"; }
|
||||||
|
.flaticon-381-heart-1:before { content: "\f187"; }
|
||||||
|
.flaticon-381-help:before { content: "\f188"; }
|
||||||
|
.flaticon-381-help-1:before { content: "\f189"; }
|
||||||
|
.flaticon-381-hide:before { content: "\f18a"; }
|
||||||
|
.flaticon-381-high-volume:before { content: "\f18b"; }
|
||||||
|
.flaticon-381-home:before { content: "\f18c"; }
|
||||||
|
.flaticon-381-home-1:before { content: "\f18d"; }
|
||||||
|
.flaticon-381-home-2:before { content: "\f18e"; }
|
||||||
|
.flaticon-381-home-3:before { content: "\f18f"; }
|
||||||
|
.flaticon-381-hourglass:before { content: "\f190"; }
|
||||||
|
.flaticon-381-hourglass-1:before { content: "\f191"; }
|
||||||
|
.flaticon-381-hourglass-2:before { content: "\f192"; }
|
||||||
|
.flaticon-381-id-card:before { content: "\f193"; }
|
||||||
|
.flaticon-381-id-card-1:before { content: "\f194"; }
|
||||||
|
.flaticon-381-id-card-2:before { content: "\f195"; }
|
||||||
|
.flaticon-381-id-card-3:before { content: "\f196"; }
|
||||||
|
.flaticon-381-id-card-4:before { content: "\f197"; }
|
||||||
|
.flaticon-381-id-card-5:before { content: "\f198"; }
|
||||||
|
.flaticon-381-idea:before { content: "\f199"; }
|
||||||
|
.flaticon-381-incoming-call:before { content: "\f19a"; }
|
||||||
|
.flaticon-381-infinity:before { content: "\f19b"; }
|
||||||
|
.flaticon-381-internet:before { content: "\f19c"; }
|
||||||
|
.flaticon-381-key:before { content: "\f19d"; }
|
||||||
|
.flaticon-381-knob:before { content: "\f19e"; }
|
||||||
|
.flaticon-381-knob-1:before { content: "\f19f"; }
|
||||||
|
.flaticon-381-layer:before { content: "\f1a0"; }
|
||||||
|
.flaticon-381-layer-1:before { content: "\f1a1"; }
|
||||||
|
.flaticon-381-like:before { content: "\f1a2"; }
|
||||||
|
.flaticon-381-link:before { content: "\f1a3"; }
|
||||||
|
.flaticon-381-link-1:before { content: "\f1a4"; }
|
||||||
|
.flaticon-381-list:before { content: "\f1a5"; }
|
||||||
|
.flaticon-381-list-1:before { content: "\f1a6"; }
|
||||||
|
.flaticon-381-location:before { content: "\f1a7"; }
|
||||||
|
.flaticon-381-location-1:before { content: "\f1a8"; }
|
||||||
|
.flaticon-381-location-2:before { content: "\f1a9"; }
|
||||||
|
.flaticon-381-location-3:before { content: "\f1aa"; }
|
||||||
|
.flaticon-381-location-4:before { content: "\f1ab"; }
|
||||||
|
.flaticon-381-locations:before { content: "\f1ac"; }
|
||||||
|
.flaticon-381-lock:before { content: "\f1ad"; }
|
||||||
|
.flaticon-381-lock-1:before { content: "\f1ae"; }
|
||||||
|
.flaticon-381-lock-2:before { content: "\f1af"; }
|
||||||
|
.flaticon-381-lock-3:before { content: "\f1b0"; }
|
||||||
|
.flaticon-381-low-volume:before { content: "\f1b1"; }
|
||||||
|
.flaticon-381-low-volume-1:before { content: "\f1b2"; }
|
||||||
|
.flaticon-381-low-volume-2:before { content: "\f1b3"; }
|
||||||
|
.flaticon-381-low-volume-3:before { content: "\f1b4"; }
|
||||||
|
.flaticon-381-magic-wand:before { content: "\f1b5"; }
|
||||||
|
.flaticon-381-magnet:before { content: "\f1b6"; }
|
||||||
|
.flaticon-381-magnet-1:before { content: "\f1b7"; }
|
||||||
|
.flaticon-381-magnet-2:before { content: "\f1b8"; }
|
||||||
|
.flaticon-381-map:before { content: "\f1b9"; }
|
||||||
|
.flaticon-381-map-1:before { content: "\f1ba"; }
|
||||||
|
.flaticon-381-map-2:before { content: "\f1bb"; }
|
||||||
|
.flaticon-381-menu:before { content: "\f1bc"; }
|
||||||
|
.flaticon-381-menu-1:before { content: "\f1bd"; }
|
||||||
|
.flaticon-381-menu-2:before { content: "\f1be"; }
|
||||||
|
.flaticon-381-menu-3:before { content: "\f1bf"; }
|
||||||
|
.flaticon-381-microphone:before { content: "\f1c0"; }
|
||||||
|
.flaticon-381-microphone-1:before { content: "\f1c1"; }
|
||||||
|
.flaticon-381-more:before { content: "\f1c2"; }
|
||||||
|
.flaticon-381-more-1:before { content: "\f1c3"; }
|
||||||
|
.flaticon-381-more-2:before { content: "\f1c4"; }
|
||||||
|
.flaticon-381-multiply:before { content: "\f1c5"; }
|
||||||
|
.flaticon-381-multiply-1:before { content: "\f1c6"; }
|
||||||
|
.flaticon-381-music-album:before { content: "\f1c7"; }
|
||||||
|
.flaticon-381-mute:before { content: "\f1c8"; }
|
||||||
|
.flaticon-381-mute-1:before { content: "\f1c9"; }
|
||||||
|
.flaticon-381-mute-2:before { content: "\f1ca"; }
|
||||||
|
.flaticon-381-network:before { content: "\f1cb"; }
|
||||||
|
.flaticon-381-network-1:before { content: "\f1cc"; }
|
||||||
|
.flaticon-381-network-2:before { content: "\f1cd"; }
|
||||||
|
.flaticon-381-network-3:before { content: "\f1ce"; }
|
||||||
|
.flaticon-381-networking:before { content: "\f1cf"; }
|
||||||
|
.flaticon-381-networking-1:before { content: "\f1d0"; }
|
||||||
|
.flaticon-381-news:before { content: "\f1d1"; }
|
||||||
|
.flaticon-381-newspaper:before { content: "\f1d2"; }
|
||||||
|
.flaticon-381-next:before { content: "\f1d3"; }
|
||||||
|
.flaticon-381-next-1:before { content: "\f1d4"; }
|
||||||
|
.flaticon-381-note:before { content: "\f1d5"; }
|
||||||
|
.flaticon-381-notebook:before { content: "\f1d6"; }
|
||||||
|
.flaticon-381-notebook-1:before { content: "\f1d7"; }
|
||||||
|
.flaticon-381-notebook-2:before { content: "\f1d8"; }
|
||||||
|
.flaticon-381-notebook-3:before { content: "\f1d9"; }
|
||||||
|
.flaticon-381-notebook-4:before { content: "\f1da"; }
|
||||||
|
.flaticon-381-notebook-5:before { content: "\f1db"; }
|
||||||
|
.flaticon-381-notepad:before { content: "\f1dc"; }
|
||||||
|
.flaticon-381-notepad-1:before { content: "\f1dd"; }
|
||||||
|
.flaticon-381-notepad-2:before { content: "\f1de"; }
|
||||||
|
.flaticon-381-notification:before { content: "\f1df"; }
|
||||||
|
.flaticon-381-off:before { content: "\f1e0"; }
|
||||||
|
.flaticon-381-on:before { content: "\f1e1"; }
|
||||||
|
.flaticon-381-pad:before { content: "\f1e2"; }
|
||||||
|
.flaticon-381-padlock:before { content: "\f1e3"; }
|
||||||
|
.flaticon-381-padlock-1:before { content: "\f1e4"; }
|
||||||
|
.flaticon-381-padlock-2:before { content: "\f1e5"; }
|
||||||
|
.flaticon-381-panel:before { content: "\f1e6"; }
|
||||||
|
.flaticon-381-panel-1:before { content: "\f1e7"; }
|
||||||
|
.flaticon-381-panel-2:before { content: "\f1e8"; }
|
||||||
|
.flaticon-381-panel-3:before { content: "\f1e9"; }
|
||||||
|
.flaticon-381-paperclip:before { content: "\f1ea"; }
|
||||||
|
.flaticon-381-pause:before { content: "\f1eb"; }
|
||||||
|
.flaticon-381-pause-1:before { content: "\f1ec"; }
|
||||||
|
.flaticon-381-pencil:before { content: "\f1ed"; }
|
||||||
|
.flaticon-381-percentage:before { content: "\f1ee"; }
|
||||||
|
.flaticon-381-percentage-1:before { content: "\f1ef"; }
|
||||||
|
.flaticon-381-perspective:before { content: "\f1f0"; }
|
||||||
|
.flaticon-381-phone-call:before { content: "\f1f1"; }
|
||||||
|
.flaticon-381-photo:before { content: "\f1f2"; }
|
||||||
|
.flaticon-381-photo-camera:before { content: "\f1f3"; }
|
||||||
|
.flaticon-381-photo-camera-1:before { content: "\f1f4"; }
|
||||||
|
.flaticon-381-picture:before { content: "\f1f5"; }
|
||||||
|
.flaticon-381-picture-1:before { content: "\f1f6"; }
|
||||||
|
.flaticon-381-picture-2:before { content: "\f1f7"; }
|
||||||
|
.flaticon-381-pin:before { content: "\f1f8"; }
|
||||||
|
.flaticon-381-play-button:before { content: "\f1f9"; }
|
||||||
|
.flaticon-381-play-button-1:before { content: "\f1fa"; }
|
||||||
|
.flaticon-381-plus:before { content: "\f1fb"; }
|
||||||
|
.flaticon-381-presentation:before { content: "\f1fc"; }
|
||||||
|
.flaticon-381-price-tag:before { content: "\f1fd"; }
|
||||||
|
.flaticon-381-print:before { content: "\f1fe"; }
|
||||||
|
.flaticon-381-print-1:before { content: "\f1ff"; }
|
||||||
|
.flaticon-381-privacy:before { content: "\f200"; }
|
||||||
|
.flaticon-381-promotion:before { content: "\f201"; }
|
||||||
|
.flaticon-381-promotion-1:before { content: "\f202"; }
|
||||||
|
.flaticon-381-push-pin:before { content: "\f203"; }
|
||||||
|
.flaticon-381-quaver:before { content: "\f204"; }
|
||||||
|
.flaticon-381-quaver-1:before { content: "\f205"; }
|
||||||
|
.flaticon-381-radar:before { content: "\f206"; }
|
||||||
|
.flaticon-381-reading:before { content: "\f207"; }
|
||||||
|
.flaticon-381-receive:before { content: "\f208"; }
|
||||||
|
.flaticon-381-record:before { content: "\f209"; }
|
||||||
|
.flaticon-381-repeat:before { content: "\f20a"; }
|
||||||
|
.flaticon-381-repeat-1:before { content: "\f20b"; }
|
||||||
|
.flaticon-381-resume:before { content: "\f20c"; }
|
||||||
|
.flaticon-381-rewind:before { content: "\f20d"; }
|
||||||
|
.flaticon-381-rewind-1:before { content: "\f20e"; }
|
||||||
|
.flaticon-381-ring:before { content: "\f20f"; }
|
||||||
|
.flaticon-381-ring-1:before { content: "\f210"; }
|
||||||
|
.flaticon-381-rotate:before { content: "\f211"; }
|
||||||
|
.flaticon-381-rotate-1:before { content: "\f212"; }
|
||||||
|
.flaticon-381-route:before { content: "\f213"; }
|
||||||
|
.flaticon-381-save:before { content: "\f214"; }
|
||||||
|
.flaticon-381-search:before { content: "\f215"; }
|
||||||
|
.flaticon-381-search-1:before { content: "\f216"; }
|
||||||
|
.flaticon-381-search-2:before { content: "\f217"; }
|
||||||
|
.flaticon-381-search-3:before { content: "\f218"; }
|
||||||
|
.flaticon-381-send:before { content: "\f219"; }
|
||||||
|
.flaticon-381-send-1:before { content: "\f21a"; }
|
||||||
|
.flaticon-381-send-2:before { content: "\f21b"; }
|
||||||
|
.flaticon-381-settings:before { content: "\f21c"; }
|
||||||
|
.flaticon-381-settings-1:before { content: "\f21d"; }
|
||||||
|
.flaticon-381-settings-2:before { content: "\f21e"; }
|
||||||
|
.flaticon-381-settings-3:before { content: "\f21f"; }
|
||||||
|
.flaticon-381-settings-4:before { content: "\f220"; }
|
||||||
|
.flaticon-381-settings-5:before { content: "\f221"; }
|
||||||
|
.flaticon-381-settings-6:before { content: "\f222"; }
|
||||||
|
.flaticon-381-settings-7:before { content: "\f223"; }
|
||||||
|
.flaticon-381-settings-8:before { content: "\f224"; }
|
||||||
|
.flaticon-381-settings-9:before { content: "\f225"; }
|
||||||
|
.flaticon-381-share:before { content: "\f226"; }
|
||||||
|
.flaticon-381-share-1:before { content: "\f227"; }
|
||||||
|
.flaticon-381-share-2:before { content: "\f228"; }
|
||||||
|
.flaticon-381-shuffle:before { content: "\f229"; }
|
||||||
|
.flaticon-381-shuffle-1:before { content: "\f22a"; }
|
||||||
|
.flaticon-381-shut-down:before { content: "\f22b"; }
|
||||||
|
.flaticon-381-silence:before { content: "\f22c"; }
|
||||||
|
.flaticon-381-silent:before { content: "\f22d"; }
|
||||||
|
.flaticon-381-smartphone:before { content: "\f22e"; }
|
||||||
|
.flaticon-381-smartphone-1:before { content: "\f22f"; }
|
||||||
|
.flaticon-381-smartphone-2:before { content: "\f230"; }
|
||||||
|
.flaticon-381-smartphone-3:before { content: "\f231"; }
|
||||||
|
.flaticon-381-smartphone-4:before { content: "\f232"; }
|
||||||
|
.flaticon-381-smartphone-5:before { content: "\f233"; }
|
||||||
|
.flaticon-381-smartphone-6:before { content: "\f234"; }
|
||||||
|
.flaticon-381-smartphone-7:before { content: "\f235"; }
|
||||||
|
.flaticon-381-speaker:before { content: "\f236"; }
|
||||||
|
.flaticon-381-speedometer:before { content: "\f237"; }
|
||||||
|
.flaticon-381-spotlight:before { content: "\f238"; }
|
||||||
|
.flaticon-381-star:before { content: "\f239"; }
|
||||||
|
.flaticon-381-star-1:before { content: "\f23a"; }
|
||||||
|
.flaticon-381-stop:before { content: "\f23b"; }
|
||||||
|
.flaticon-381-stop-1:before { content: "\f23c"; }
|
||||||
|
.flaticon-381-stopclock:before { content: "\f23d"; }
|
||||||
|
.flaticon-381-stopwatch:before { content: "\f23e"; }
|
||||||
|
.flaticon-381-stopwatch-1:before { content: "\f23f"; }
|
||||||
|
.flaticon-381-stopwatch-2:before { content: "\f240"; }
|
||||||
|
.flaticon-381-substract:before { content: "\f241"; }
|
||||||
|
.flaticon-381-substract-1:before { content: "\f242"; }
|
||||||
|
.flaticon-381-substract-2:before { content: "\f243"; }
|
||||||
|
.flaticon-381-success:before { content: "\f244"; }
|
||||||
|
.flaticon-381-success-1:before { content: "\f245"; }
|
||||||
|
.flaticon-381-success-2:before { content: "\f246"; }
|
||||||
|
.flaticon-381-sunglasses:before { content: "\f247"; }
|
||||||
|
.flaticon-381-switch:before { content: "\f248"; }
|
||||||
|
.flaticon-381-switch-1:before { content: "\f249"; }
|
||||||
|
.flaticon-381-switch-2:before { content: "\f24a"; }
|
||||||
|
.flaticon-381-switch-3:before { content: "\f24b"; }
|
||||||
|
.flaticon-381-switch-4:before { content: "\f24c"; }
|
||||||
|
.flaticon-381-switch-5:before { content: "\f24d"; }
|
||||||
|
.flaticon-381-sync:before { content: "\f24e"; }
|
||||||
|
.flaticon-381-tab:before { content: "\f24f"; }
|
||||||
|
.flaticon-381-target:before { content: "\f250"; }
|
||||||
|
.flaticon-381-television:before { content: "\f251"; }
|
||||||
|
.flaticon-381-time:before { content: "\f252"; }
|
||||||
|
.flaticon-381-transfer:before { content: "\f253"; }
|
||||||
|
.flaticon-381-trash:before { content: "\f254"; }
|
||||||
|
.flaticon-381-trash-1:before { content: "\f255"; }
|
||||||
|
.flaticon-381-trash-2:before { content: "\f256"; }
|
||||||
|
.flaticon-381-trash-3:before { content: "\f257"; }
|
||||||
|
.flaticon-381-turn-off:before { content: "\f258"; }
|
||||||
|
.flaticon-381-umbrella:before { content: "\f259"; }
|
||||||
|
.flaticon-381-unlocked:before { content: "\f25a"; }
|
||||||
|
.flaticon-381-unlocked-1:before { content: "\f25b"; }
|
||||||
|
.flaticon-381-unlocked-2:before { content: "\f25c"; }
|
||||||
|
.flaticon-381-unlocked-3:before { content: "\f25d"; }
|
||||||
|
.flaticon-381-unlocked-4:before { content: "\f25e"; }
|
||||||
|
.flaticon-381-upload:before { content: "\f25f"; }
|
||||||
|
.flaticon-381-upload-1:before { content: "\f260"; }
|
||||||
|
.flaticon-381-user:before { content: "\f261"; }
|
||||||
|
.flaticon-381-user-1:before { content: "\f262"; }
|
||||||
|
.flaticon-381-user-2:before { content: "\f263"; }
|
||||||
|
.flaticon-381-user-3:before { content: "\f264"; }
|
||||||
|
.flaticon-381-user-4:before { content: "\f265"; }
|
||||||
|
.flaticon-381-user-5:before { content: "\f266"; }
|
||||||
|
.flaticon-381-user-6:before { content: "\f267"; }
|
||||||
|
.flaticon-381-user-7:before { content: "\f268"; }
|
||||||
|
.flaticon-381-user-8:before { content: "\f269"; }
|
||||||
|
.flaticon-381-user-9:before { content: "\f26a"; }
|
||||||
|
.flaticon-381-video-camera:before { content: "\f26b"; }
|
||||||
|
.flaticon-381-video-clip:before { content: "\f26c"; }
|
||||||
|
.flaticon-381-video-player:before { content: "\f26d"; }
|
||||||
|
.flaticon-381-video-player-1:before { content: "\f26e"; }
|
||||||
|
.flaticon-381-view:before { content: "\f26f"; }
|
||||||
|
.flaticon-381-view-1:before { content: "\f270"; }
|
||||||
|
.flaticon-381-view-2:before { content: "\f271"; }
|
||||||
|
.flaticon-381-volume:before { content: "\f272"; }
|
||||||
|
.flaticon-381-warning:before { content: "\f273"; }
|
||||||
|
.flaticon-381-warning-1:before { content: "\f274"; }
|
||||||
|
.flaticon-381-wifi:before { content: "\f275"; }
|
||||||
|
.flaticon-381-wifi-1:before { content: "\f276"; }
|
||||||
|
.flaticon-381-wifi-2:before { content: "\f277"; }
|
||||||
|
.flaticon-381-windows:before { content: "\f278"; }
|
||||||
|
.flaticon-381-windows-1:before { content: "\f279"; }
|
||||||
|
.flaticon-381-zoom-in:before { content: "\f27a"; }
|
||||||
|
.flaticon-381-zoom-out:before { content: "\f27b"; }
|
||||||
128
src/main/resources/static/css/flaticon_1.css
Normal file
128
src/main/resources/static/css/flaticon_1.css
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: "Flaticon";
|
||||||
|
src: url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon_1/Flaticon_1.eot");
|
||||||
|
src: url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon_1/Flaticon_1.eot?#iefix") format("embedded-opentype"),
|
||||||
|
url("../font/Flaticon_1.woff2") format("woff2"),
|
||||||
|
url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon_1/Flaticon_1.woff") format("woff"),
|
||||||
|
url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon_1/Flaticon_1.ttf") format("truetype"),
|
||||||
|
url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon_1/Flaticon_1.svg#Flaticon") format("svg");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
|
@font-face {
|
||||||
|
font-family: "Flaticon";
|
||||||
|
src: url("http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/flaticon_1/Flaticon_1.svg#Flaticon") format("svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fimanager:before {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: "Flaticon";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
line-height: 1;
|
||||||
|
text-decoration: inherit;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
text-transform: none;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-smoothing: antialiased;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flaticon-001-arrow-down:before { content: "\f100"; }
|
||||||
|
.flaticon-002-arrow-down:before { content: "\f101"; }
|
||||||
|
.flaticon-003-arrow-up:before { content: "\f102"; }
|
||||||
|
.flaticon-004-arrow-up:before { content: "\f103"; }
|
||||||
|
.flaticon-005-back-arrow:before { content: "\f104"; }
|
||||||
|
.flaticon-006-brightness:before { content: "\f105"; }
|
||||||
|
.flaticon-007-bulleye:before { content: "\f106"; }
|
||||||
|
.flaticon-008-check:before { content: "\f107"; }
|
||||||
|
.flaticon-009-check:before { content: "\f108"; }
|
||||||
|
.flaticon-010-check:before { content: "\f109"; }
|
||||||
|
.flaticon-011-check:before { content: "\f10a"; }
|
||||||
|
.flaticon-012-checkmark:before { content: "\f10b"; }
|
||||||
|
.flaticon-013-checkmark:before { content: "\f10c"; }
|
||||||
|
.flaticon-014-checkmark:before { content: "\f10d"; }
|
||||||
|
.flaticon-015-chevron:before { content: "\f10e"; }
|
||||||
|
.flaticon-016-double-chevron:before { content: "\f10f"; }
|
||||||
|
.flaticon-017-clipboard:before { content: "\f110"; }
|
||||||
|
.flaticon-018-clock:before { content: "\f111"; }
|
||||||
|
.flaticon-019-close:before { content: "\f112"; }
|
||||||
|
.flaticon-020-close:before { content: "\f113"; }
|
||||||
|
.flaticon-021-command:before { content: "\f114"; }
|
||||||
|
.flaticon-022-copy:before { content: "\f115"; }
|
||||||
|
.flaticon-023-cut:before { content: "\f116"; }
|
||||||
|
.flaticon-024-dashboard:before { content: "\f117"; }
|
||||||
|
.flaticon-025-dashboard:before { content: "\f118"; }
|
||||||
|
.flaticon-026-delete:before { content: "\f119"; }
|
||||||
|
.flaticon-027-dot:before { content: "\f11a"; }
|
||||||
|
.flaticon-028-download:before { content: "\f11b"; }
|
||||||
|
.flaticon-029-ellipsis:before { content: "\f11c"; }
|
||||||
|
.flaticon-030-ellipsis:before { content: "\f11d"; }
|
||||||
|
.flaticon-031-ellipsis:before { content: "\f11e"; }
|
||||||
|
.flaticon-032-ellipsis:before { content: "\f11f"; }
|
||||||
|
.flaticon-033-feather:before { content: "\f120"; }
|
||||||
|
.flaticon-034-filter:before { content: "\f121"; }
|
||||||
|
.flaticon-035-flag:before { content: "\f122"; }
|
||||||
|
.flaticon-036-floppy-disk:before { content: "\f123"; }
|
||||||
|
.flaticon-037-funnel:before { content: "\f124"; }
|
||||||
|
.flaticon-038-gauge:before { content: "\f125"; }
|
||||||
|
.flaticon-039-goal:before { content: "\f126"; }
|
||||||
|
.flaticon-040-graph:before { content: "\f127"; }
|
||||||
|
.flaticon-041-graph:before { content: "\f128"; }
|
||||||
|
.flaticon-042-menu:before { content: "\f129"; }
|
||||||
|
.flaticon-043-menu:before { content: "\f12a"; }
|
||||||
|
.flaticon-044-menu:before { content: "\f12b"; }
|
||||||
|
.flaticon-045-heart:before { content: "\f12c"; }
|
||||||
|
.flaticon-046-home:before { content: "\f12d"; }
|
||||||
|
.flaticon-047-home:before { content: "\f12e"; }
|
||||||
|
.flaticon-048-home:before { content: "\f12f"; }
|
||||||
|
.flaticon-049-home:before { content: "\f130"; }
|
||||||
|
.flaticon-050-info:before { content: "\f131"; }
|
||||||
|
.flaticon-051-info:before { content: "\f132"; }
|
||||||
|
.flaticon-052-inside:before { content: "\f133"; }
|
||||||
|
.flaticon-053-lifebuoy:before { content: "\f134"; }
|
||||||
|
.flaticon-054-maximize:before { content: "\f135"; }
|
||||||
|
.flaticon-055-minimize:before { content: "\f136"; }
|
||||||
|
.flaticon-056-minus:before { content: "\f137"; }
|
||||||
|
.flaticon-057-minus:before { content: "\f138"; }
|
||||||
|
.flaticon-058-minus:before { content: "\f139"; }
|
||||||
|
.flaticon-059-minus:before { content: "\f13a"; }
|
||||||
|
.flaticon-060-on:before { content: "\f13b"; }
|
||||||
|
.flaticon-061-outside:before { content: "\f13c"; }
|
||||||
|
.flaticon-062-pencil:before { content: "\f13d"; }
|
||||||
|
.flaticon-063-pencil:before { content: "\f13e"; }
|
||||||
|
.flaticon-064-pin:before { content: "\f13f"; }
|
||||||
|
.flaticon-065-pin:before { content: "\f140"; }
|
||||||
|
.flaticon-066-plus:before { content: "\f141"; }
|
||||||
|
.flaticon-067-plus:before { content: "\f142"; }
|
||||||
|
.flaticon-068-plus:before { content: "\f143"; }
|
||||||
|
.flaticon-069-plus:before { content: "\f144"; }
|
||||||
|
.flaticon-070-power:before { content: "\f145"; }
|
||||||
|
.flaticon-071-print:before { content: "\f146"; }
|
||||||
|
.flaticon-072-printer:before { content: "\f147"; }
|
||||||
|
.flaticon-073-question:before { content: "\f148"; }
|
||||||
|
.flaticon-074-question:before { content: "\f149"; }
|
||||||
|
.flaticon-075-reload:before { content: "\f14a"; }
|
||||||
|
.flaticon-076-remove:before { content: "\f14b"; }
|
||||||
|
.flaticon-077-remove:before { content: "\f14c"; }
|
||||||
|
.flaticon-078-remove:before { content: "\f14d"; }
|
||||||
|
.flaticon-079-search:before { content: "\f14e"; }
|
||||||
|
.flaticon-080-search:before { content: "\f14f"; }
|
||||||
|
.flaticon-081-search:before { content: "\f150"; }
|
||||||
|
.flaticon-082-share:before { content: "\f151"; }
|
||||||
|
.flaticon-083-share:before { content: "\f152"; }
|
||||||
|
.flaticon-084-share:before { content: "\f153"; }
|
||||||
|
.flaticon-085-signal:before { content: "\f154"; }
|
||||||
|
.flaticon-086-star:before { content: "\f155"; }
|
||||||
|
.flaticon-087-stop:before { content: "\f156"; }
|
||||||
|
.flaticon-088-time:before { content: "\f157"; }
|
||||||
|
.flaticon-089-trash:before { content: "\f158"; }
|
||||||
|
.flaticon-090-upload:before { content: "\f159"; }
|
||||||
|
.flaticon-091-warning:before { content: "\f15a"; }
|
||||||
|
.flaticon-092-warning:before { content: "\f15b"; }
|
||||||
|
.flaticon-093-waving:before { content: "\f15c"; }
|
||||||
6620
src/main/resources/static/css/icomoon.css
Normal file
6620
src/main/resources/static/css/icomoon.css
Normal file
File diff suppressed because it is too large
Load Diff
1
src/main/resources/static/css/lightgallery.min.css
vendored
Normal file
1
src/main/resources/static/css/lightgallery.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/main/resources/static/css/line-awesome.min.css
vendored
Normal file
1
src/main/resources/static/css/line-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
10203
src/main/resources/static/css/materialdesignicons.min.css
vendored
Normal file
10203
src/main/resources/static/css/materialdesignicons.min.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
src/main/resources/static/css/metisMenu.min.css
vendored
Normal file
8
src/main/resources/static/css/metisMenu.min.css
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*!
|
||||||
|
* metismenu https://github.com/onokumus/metismenu#readme
|
||||||
|
* A jQuery menu plugin
|
||||||
|
* @version 3.0.3
|
||||||
|
* @author Osman Nuri Okumus <onokumus@gmail.com> (https://github.com/onokumus)
|
||||||
|
* @license: MIT
|
||||||
|
*/.metismenu .arrow{float:right;line-height:1.42857}[dir=rtl] .metismenu .arrow{float:left}.metismenu .glyphicon.arrow:before{content:"\e079"}.metismenu .mm-active>a>.glyphicon.arrow:before{content:"\e114"}.metismenu .fa.arrow:before{content:"\f104"}.metismenu .mm-active>a>.fa.arrow:before{content:"\f107"}.metismenu .ion.arrow:before{content:"\f3d2"}.metismenu .mm-active>a>.ion.arrow:before{content:"\f3d0"}.metismenu .plus-times{float:right}[dir=rtl] .metismenu .plus-times{float:left}.metismenu .fa.plus-times:before{content:"\f067"}.metismenu .mm-active>a>.fa.plus-times{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.metismenu .plus-minus{float:right}[dir=rtl] .metismenu .plus-minus{float:left}.metismenu .fa.plus-minus:before{content:"\f067"}.metismenu .mm-active>a>.fa.plus-minus:before{content:"\f068"}.metismenu .mm-collapse:not(.mm-show){display:none}.metismenu .mm-collapsing{position:relative;height:0;overflow:hidden;transition-timing-function:ease;transition-duration:.35s;transition-property:height,visibility}.metismenu .has-arrow{position:relative}.metismenu .has-arrow:after{position:absolute;content:"";width:.5em;height:.5em;border-width:1px 0 0 1px;border-style:solid;border-color:initial;right:1em;-webkit-transform:rotate(-45deg) translateY(-50%);transform:rotate(-45deg) translateY(-50%);-webkit-transform-origin:top;transform-origin:top;top:50%;transition:all .3s ease-out}[dir=rtl] .metismenu .has-arrow:after{right:auto;left:1em;-webkit-transform:rotate(135deg) translateY(-50%);transform:rotate(135deg) translateY(-50%)}.metismenu .has-arrow[aria-expanded=true]:after,.metismenu .mm-active>.has-arrow:after{-webkit-transform:rotate(-135deg) translateY(-50%);transform:rotate(-135deg) translateY(-50%)}[dir=rtl] .metismenu .has-arrow[aria-expanded=true]:after,[dir=rtl] .metismenu .mm-active>.has-arrow:after{-webkit-transform:rotate(225deg) translateY(-50%);transform:rotate(225deg) translateY(-50%)}
|
||||||
|
/*# sourceMappingURL=metisMenu.min.css.map */
|
||||||
141
src/main/resources/static/css/nice-select.css
Normal file
141
src/main/resources/static/css/nice-select.css
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
.nice-select {
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: solid 1px #e8e8e8;
|
||||||
|
box-sizing: border-box;
|
||||||
|
clear: both;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 40px;
|
||||||
|
outline: none;
|
||||||
|
padding-left: 18px;
|
||||||
|
padding-right: 30px;
|
||||||
|
position: relative;
|
||||||
|
text-align: left !important;
|
||||||
|
-webkit-transition: all 0.2s ease-in-out;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: auto; }
|
||||||
|
.nice-select:hover {
|
||||||
|
border-color: #dbdbdb; }
|
||||||
|
.nice-select:active, .nice-select.open, .nice-select:focus {
|
||||||
|
border-color: #999; }
|
||||||
|
.nice-select:after {
|
||||||
|
border-bottom: 3px solid #eee;
|
||||||
|
border-right: 3px solid #eee;
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
height: 10px;
|
||||||
|
margin-top: -6px;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
top: 50%;
|
||||||
|
margin-right:10px;
|
||||||
|
-webkit-transform-origin: 66% 66%;
|
||||||
|
-ms-transform-origin: 66% 66%;
|
||||||
|
transform-origin: 66% 66%;
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
-ms-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
-webkit-transition: all 0.15s ease-in-out;
|
||||||
|
transition: all 0.15s ease-in-out;
|
||||||
|
width: 10px; }
|
||||||
|
.nice-select.open:after {
|
||||||
|
-webkit-transform: rotate(-135deg);
|
||||||
|
-ms-transform: rotate(-135deg);
|
||||||
|
transform: rotate(-135deg); }
|
||||||
|
.nice-select.open .list {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
-webkit-transform: scale(1) translateY(0);
|
||||||
|
-ms-transform: scale(1) translateY(0);
|
||||||
|
transform: scale(1) translateY(0); }
|
||||||
|
.nice-select.disabled {
|
||||||
|
border-color: #ededed;
|
||||||
|
color: #999;
|
||||||
|
pointer-events: none; }
|
||||||
|
.nice-select.disabled:after {
|
||||||
|
border-color: #cccccc; }
|
||||||
|
.nice-select.wide {
|
||||||
|
width: 100%;
|
||||||
|
line-height:44px;
|
||||||
|
}
|
||||||
|
.nice-select.wide .list {
|
||||||
|
left: 0 !important;
|
||||||
|
right: 0 !important; }
|
||||||
|
.nice-select.right {
|
||||||
|
float: right; }
|
||||||
|
.nice-select.right .list {
|
||||||
|
left: auto;
|
||||||
|
right: 0; }
|
||||||
|
.nice-select.small {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 34px; }
|
||||||
|
.nice-select.small:after {
|
||||||
|
height: 4px;
|
||||||
|
width: 4px; }
|
||||||
|
.nice-select.small .option {
|
||||||
|
line-height: 34px;
|
||||||
|
min-height: 34px; }
|
||||||
|
.nice-select .list {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: 4px;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
-webkit-transform-origin: 50% 0;
|
||||||
|
-ms-transform-origin: 50% 0;
|
||||||
|
transform-origin: 50% 0;
|
||||||
|
-webkit-transform: scale(0.75) translateY(-21px);
|
||||||
|
-ms-transform: scale(0.75) translateY(-21px);
|
||||||
|
transform: scale(0.75) translateY(-21px);
|
||||||
|
-webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
|
||||||
|
transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
|
||||||
|
z-index: 9; }
|
||||||
|
.nice-select .list:hover .option:not(:hover) {
|
||||||
|
background-color: transparent !important; }
|
||||||
|
.nice-select .option {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 40px;
|
||||||
|
list-style: none;
|
||||||
|
min-height: 40px;
|
||||||
|
outline: none;
|
||||||
|
padding-left: 18px;
|
||||||
|
padding-right: 29px;
|
||||||
|
text-align: left;
|
||||||
|
-webkit-transition: all 0.2s;
|
||||||
|
transition: all 0.2s; }
|
||||||
|
.nice-select .option:hover, .nice-select .option.focus, .nice-select .option.selected.focus {
|
||||||
|
background-color: #f6f6f6; }
|
||||||
|
.nice-select .option.selected {
|
||||||
|
font-weight: bold; }
|
||||||
|
.nice-select .option.disabled {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #999;
|
||||||
|
cursor: default; }
|
||||||
|
|
||||||
|
.no-csspointerevents .nice-select .list {
|
||||||
|
display: none; }
|
||||||
|
|
||||||
|
.no-csspointerevents .nice-select.open .list {
|
||||||
|
display: block; }
|
||||||
116
src/main/resources/static/css/perfect-scrollbar.css
Normal file
116
src/main/resources/static/css/perfect-scrollbar.css
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Container style
|
||||||
|
*/
|
||||||
|
.ps {
|
||||||
|
overflow: hidden !important;
|
||||||
|
overflow-anchor: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
touch-action: auto;
|
||||||
|
-ms-touch-action: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scrollbar rail styles
|
||||||
|
*/
|
||||||
|
.ps__rail-x {
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
-webkit-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
height: 15px;
|
||||||
|
/* there must be 'bottom' or 'top' for ps__rail-x */
|
||||||
|
bottom: 0px;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps__rail-y {
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
-webkit-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
width: 15px;
|
||||||
|
/* there must be 'right' or 'left' for ps__rail-y */
|
||||||
|
right: 0;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps--active-x > .ps__rail-x,
|
||||||
|
.ps--active-y > .ps__rail-y {
|
||||||
|
display: block;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps:hover > .ps__rail-x,
|
||||||
|
.ps:hover > .ps__rail-y,
|
||||||
|
.ps--focus > .ps__rail-x,
|
||||||
|
.ps--focus > .ps__rail-y,
|
||||||
|
.ps--scrolling-x > .ps__rail-x,
|
||||||
|
.ps--scrolling-y > .ps__rail-y {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps .ps__rail-x:hover,
|
||||||
|
.ps .ps__rail-y:hover,
|
||||||
|
.ps .ps__rail-x:focus,
|
||||||
|
.ps .ps__rail-y:focus,
|
||||||
|
.ps .ps__rail-x.ps--clicking,
|
||||||
|
.ps .ps__rail-y.ps--clicking {
|
||||||
|
background-color: #eee;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scrollbar thumb styles
|
||||||
|
*/
|
||||||
|
.ps__thumb-x {
|
||||||
|
background-color: #aaa;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: background-color .2s linear, height .2s ease-in-out;
|
||||||
|
-webkit-transition: background-color .2s linear, height .2s ease-in-out;
|
||||||
|
height: 6px;
|
||||||
|
/* there must be 'bottom' for ps__thumb-x */
|
||||||
|
bottom: 2px;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps__thumb-y {
|
||||||
|
background-color: #aaa;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: background-color .2s linear, width .2s ease-in-out;
|
||||||
|
-webkit-transition: background-color .2s linear, width .2s ease-in-out;
|
||||||
|
width: 6px;
|
||||||
|
/* there must be 'right' for ps__thumb-y */
|
||||||
|
right: 2px;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps__rail-x:hover > .ps__thumb-x,
|
||||||
|
.ps__rail-x:focus > .ps__thumb-x,
|
||||||
|
.ps__rail-x.ps--clicking .ps__thumb-x {
|
||||||
|
background-color: #999;
|
||||||
|
height: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps__rail-y:hover > .ps__thumb-y,
|
||||||
|
.ps__rail-y:focus > .ps__thumb-y,
|
||||||
|
.ps__rail-y.ps--clicking .ps__thumb-y {
|
||||||
|
background-color: #999;
|
||||||
|
width: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MS supports */
|
||||||
|
@supports (-ms-overflow-style: none) {
|
||||||
|
.ps {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||||
|
.ps {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
754
src/main/resources/static/css/simple-line-icons.css
Normal file
754
src/main/resources/static/css/simple-line-icons.css
Normal file
|
|
@ -0,0 +1,754 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: 'simple-line-icons';
|
||||||
|
src: url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/simple-line-icons/fonts/Simple-Line-Icons4c82.eot?-i3a2kk');
|
||||||
|
src: url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/simple-line-icons/fonts/Simple-Line-Iconsd41d.eot?#iefix-i3a2kk') format('embedded-opentype'), url('../font/Simple-Line-Icons4c82.ttf') format('truetype'), url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/simple-line-icons/fonts/Simple-Line-Icons4c82.woff2?-i3a2kk') format('woff2'), url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/simple-line-icons/fonts/Simple-Line-Icons4c82.woff?-i3a2kk') format('woff'), url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/simple-line-icons/fonts/Simple-Line-Icons4c82.svg?-i3a2kk#simple-line-icons') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Use the following CSS code if you want to have a class per icon.
|
||||||
|
Instead of a list of all class selectors, you can use the generic [class*="icon-"] selector, but it's slower:
|
||||||
|
*/
|
||||||
|
.icon-user,
|
||||||
|
.icon-people,
|
||||||
|
.icon-user-female,
|
||||||
|
.icon-user-follow,
|
||||||
|
.icon-user-following,
|
||||||
|
.icon-user-unfollow,
|
||||||
|
.icon-login,
|
||||||
|
.icon-logout,
|
||||||
|
.icon-emotsmile,
|
||||||
|
.icon-phone,
|
||||||
|
.icon-call-end,
|
||||||
|
.icon-call-in,
|
||||||
|
.icon-call-out,
|
||||||
|
.icon-map,
|
||||||
|
.icon-location-pin,
|
||||||
|
.icon-direction,
|
||||||
|
.icon-directions,
|
||||||
|
.icon-compass,
|
||||||
|
.icon-layers,
|
||||||
|
.icon-menu,
|
||||||
|
.icon-list,
|
||||||
|
.icon-options-vertical,
|
||||||
|
.icon-options,
|
||||||
|
.icon-arrow-down,
|
||||||
|
.icon-arrow-left,
|
||||||
|
.icon-arrow-right,
|
||||||
|
.icon-arrow-up,
|
||||||
|
.icon-arrow-up-circle,
|
||||||
|
.icon-arrow-left-circle,
|
||||||
|
.icon-arrow-right-circle,
|
||||||
|
.icon-arrow-down-circle,
|
||||||
|
.icon-check,
|
||||||
|
.icon-clock,
|
||||||
|
.icon-plus,
|
||||||
|
.icon-close,
|
||||||
|
.icon-trophy,
|
||||||
|
.icon-screen-smartphone,
|
||||||
|
.icon-screen-desktop,
|
||||||
|
.icon-plane,
|
||||||
|
.icon-notebook,
|
||||||
|
.icon-mustache,
|
||||||
|
.icon-mouse,
|
||||||
|
.icon-magnet,
|
||||||
|
.icon-energy,
|
||||||
|
.icon-disc,
|
||||||
|
.icon-cursor,
|
||||||
|
.icon-cursor-move,
|
||||||
|
.icon-crop,
|
||||||
|
.icon-chemistry,
|
||||||
|
.icon-speedometer,
|
||||||
|
.icon-shield,
|
||||||
|
.icon-screen-tablet,
|
||||||
|
.icon-magic-wand,
|
||||||
|
.icon-hourglass,
|
||||||
|
.icon-graduation,
|
||||||
|
.icon-ghost,
|
||||||
|
.icon-game-controller,
|
||||||
|
.icon-fire,
|
||||||
|
.icon-eyeglass,
|
||||||
|
.icon-envelope-open,
|
||||||
|
.icon-envelope-letter,
|
||||||
|
.icon-bell,
|
||||||
|
.icon-badge,
|
||||||
|
.icon-anchor,
|
||||||
|
.icon-wallet,
|
||||||
|
.icon-vector,
|
||||||
|
.icon-speech,
|
||||||
|
.icon-puzzle,
|
||||||
|
.icon-printer,
|
||||||
|
.icon-present,
|
||||||
|
.icon-playlist,
|
||||||
|
.icon-pin,
|
||||||
|
.icon-picture,
|
||||||
|
.icon-handbag,
|
||||||
|
.icon-globe-alt,
|
||||||
|
.icon-globe,
|
||||||
|
.icon-folder-alt,
|
||||||
|
.icon-folder,
|
||||||
|
.icon-film,
|
||||||
|
.icon-feed,
|
||||||
|
.icon-drop,
|
||||||
|
.icon-drawar,
|
||||||
|
.icon-docs,
|
||||||
|
.icon-doc,
|
||||||
|
.icon-diamond,
|
||||||
|
.icon-cup,
|
||||||
|
.icon-calculator,
|
||||||
|
.icon-bubbles,
|
||||||
|
.icon-briefcase,
|
||||||
|
.icon-book-open,
|
||||||
|
.icon-basket-loaded,
|
||||||
|
.icon-basket,
|
||||||
|
.icon-bag,
|
||||||
|
.icon-action-undo,
|
||||||
|
.icon-action-redo,
|
||||||
|
.icon-wrench,
|
||||||
|
.icon-umbrella,
|
||||||
|
.icon-trash,
|
||||||
|
.icon-tag,
|
||||||
|
.icon-support,
|
||||||
|
.icon-frame,
|
||||||
|
.icon-size-fullscreen,
|
||||||
|
.icon-size-actual,
|
||||||
|
.icon-shuffle,
|
||||||
|
.icon-share-alt,
|
||||||
|
.icon-share,
|
||||||
|
.icon-rocket,
|
||||||
|
.icon-question,
|
||||||
|
.icon-pie-chart,
|
||||||
|
.icon-pencil,
|
||||||
|
.icon-note,
|
||||||
|
.icon-loop,
|
||||||
|
.icon-home,
|
||||||
|
.icon-grid,
|
||||||
|
.icon-graph,
|
||||||
|
.icon-microphone,
|
||||||
|
.icon-music-tone-alt,
|
||||||
|
.icon-music-tone,
|
||||||
|
.icon-earphones-alt,
|
||||||
|
.icon-earphones,
|
||||||
|
.icon-equalizer,
|
||||||
|
.icon-like,
|
||||||
|
.icon-dislike,
|
||||||
|
.icon-control-start,
|
||||||
|
.icon-control-rewind,
|
||||||
|
.icon-control-play,
|
||||||
|
.icon-control-pause,
|
||||||
|
.icon-control-forward,
|
||||||
|
.icon-control-end,
|
||||||
|
.icon-volume-1,
|
||||||
|
.icon-volume-2,
|
||||||
|
.icon-volume-off,
|
||||||
|
.icon-calender,
|
||||||
|
.icon-bulb,
|
||||||
|
.icon-chart,
|
||||||
|
.icon-ban,
|
||||||
|
.icon-bubble,
|
||||||
|
.icon-camrecorder,
|
||||||
|
.icon-camera,
|
||||||
|
.icon-cloud-download,
|
||||||
|
.icon-cloud-upload,
|
||||||
|
.icon-envelope,
|
||||||
|
.icon-eye,
|
||||||
|
.icon-flag,
|
||||||
|
.icon-heart,
|
||||||
|
.icon-info,
|
||||||
|
.icon-key,
|
||||||
|
.icon-link,
|
||||||
|
.icon-lock,
|
||||||
|
.icon-lock-open,
|
||||||
|
.icon-magnifier,
|
||||||
|
.icon-magnifier-add,
|
||||||
|
.icon-magnifier-remove,
|
||||||
|
.icon-paper-clip,
|
||||||
|
.icon-paper-plane,
|
||||||
|
.icon-power,
|
||||||
|
.icon-refresh,
|
||||||
|
.icon-reload,
|
||||||
|
.icon-settings,
|
||||||
|
.icon-star,
|
||||||
|
.icon-symble-female,
|
||||||
|
.icon-symbol-male,
|
||||||
|
.icon-target,
|
||||||
|
.icon-credit-card,
|
||||||
|
.icon-paypal,
|
||||||
|
.icon-social-tumblr,
|
||||||
|
.icon-social-twitter,
|
||||||
|
.icon-social-facebook,
|
||||||
|
.icon-social-instagram,
|
||||||
|
.icon-social-linkedin,
|
||||||
|
.icon-social-pintarest,
|
||||||
|
.icon-social-github,
|
||||||
|
.icon-social-gplus,
|
||||||
|
.icon-social-reddit,
|
||||||
|
.icon-social-skype,
|
||||||
|
.icon-social-dribbble,
|
||||||
|
.icon-social-behance,
|
||||||
|
.icon-social-foursqare,
|
||||||
|
.icon-social-soundcloud,
|
||||||
|
.icon-social-spotify,
|
||||||
|
.icon-social-stumbleupon,
|
||||||
|
.icon-social-youtube,
|
||||||
|
.icon-social-dropbox {
|
||||||
|
font-family: 'simple-line-icons';
|
||||||
|
speak: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 1;
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
.icon-user:before {
|
||||||
|
content: "\e005";
|
||||||
|
}
|
||||||
|
.icon-people:before {
|
||||||
|
content: "\e001";
|
||||||
|
}
|
||||||
|
.icon-user-female:before {
|
||||||
|
content: "\e000";
|
||||||
|
}
|
||||||
|
.icon-user-follow:before {
|
||||||
|
content: "\e002";
|
||||||
|
}
|
||||||
|
.icon-user-following:before {
|
||||||
|
content: "\e003";
|
||||||
|
}
|
||||||
|
.icon-user-unfollow:before {
|
||||||
|
content: "\e004";
|
||||||
|
}
|
||||||
|
.icon-login:before {
|
||||||
|
content: "\e066";
|
||||||
|
}
|
||||||
|
.icon-logout:before {
|
||||||
|
content: "\e065";
|
||||||
|
}
|
||||||
|
.icon-emotsmile:before {
|
||||||
|
content: "\e021";
|
||||||
|
}
|
||||||
|
.icon-phone:before {
|
||||||
|
content: "\e600";
|
||||||
|
}
|
||||||
|
.icon-call-end:before {
|
||||||
|
content: "\e048";
|
||||||
|
}
|
||||||
|
.icon-call-in:before {
|
||||||
|
content: "\e047";
|
||||||
|
}
|
||||||
|
.icon-call-out:before {
|
||||||
|
content: "\e046";
|
||||||
|
}
|
||||||
|
.icon-map:before {
|
||||||
|
content: "\e033";
|
||||||
|
}
|
||||||
|
.icon-location-pin:before {
|
||||||
|
content: "\e096";
|
||||||
|
}
|
||||||
|
.icon-direction:before {
|
||||||
|
content: "\e042";
|
||||||
|
}
|
||||||
|
.icon-directions:before {
|
||||||
|
content: "\e041";
|
||||||
|
}
|
||||||
|
.icon-compass:before {
|
||||||
|
content: "\e045";
|
||||||
|
}
|
||||||
|
.icon-layers:before {
|
||||||
|
content: "\e034";
|
||||||
|
}
|
||||||
|
.icon-menu:before {
|
||||||
|
content: "\e601";
|
||||||
|
}
|
||||||
|
.icon-list:before {
|
||||||
|
content: "\e067";
|
||||||
|
}
|
||||||
|
.icon-options-vertical:before {
|
||||||
|
content: "\e602";
|
||||||
|
}
|
||||||
|
.icon-options:before {
|
||||||
|
content: "\e603";
|
||||||
|
}
|
||||||
|
.icon-arrow-down:before {
|
||||||
|
content: "\e604";
|
||||||
|
}
|
||||||
|
.icon-arrow-left:before {
|
||||||
|
content: "\e605";
|
||||||
|
}
|
||||||
|
.icon-arrow-right:before {
|
||||||
|
content: "\e606";
|
||||||
|
}
|
||||||
|
.icon-arrow-up:before {
|
||||||
|
content: "\e607";
|
||||||
|
}
|
||||||
|
.icon-arrow-up-circle:before {
|
||||||
|
content: "\e078";
|
||||||
|
}
|
||||||
|
.icon-arrow-left-circle:before {
|
||||||
|
content: "\e07a";
|
||||||
|
}
|
||||||
|
.icon-arrow-right-circle:before {
|
||||||
|
content: "\e079";
|
||||||
|
}
|
||||||
|
.icon-arrow-down-circle:before {
|
||||||
|
content: "\e07b";
|
||||||
|
}
|
||||||
|
.icon-check:before {
|
||||||
|
content: "\e080";
|
||||||
|
}
|
||||||
|
.icon-clock:before {
|
||||||
|
content: "\e081";
|
||||||
|
}
|
||||||
|
.icon-plus:before {
|
||||||
|
content: "\e095";
|
||||||
|
}
|
||||||
|
.icon-close:before {
|
||||||
|
content: "\e082";
|
||||||
|
}
|
||||||
|
.icon-trophy:before {
|
||||||
|
content: "\e006";
|
||||||
|
}
|
||||||
|
.icon-screen-smartphone:before {
|
||||||
|
content: "\e010";
|
||||||
|
}
|
||||||
|
.icon-screen-desktop:before {
|
||||||
|
content: "\e011";
|
||||||
|
}
|
||||||
|
.icon-plane:before {
|
||||||
|
content: "\e012";
|
||||||
|
}
|
||||||
|
.icon-notebook:before {
|
||||||
|
content: "\e013";
|
||||||
|
}
|
||||||
|
.icon-mustache:before {
|
||||||
|
content: "\e014";
|
||||||
|
}
|
||||||
|
.icon-mouse:before {
|
||||||
|
content: "\e015";
|
||||||
|
}
|
||||||
|
.icon-magnet:before {
|
||||||
|
content: "\e016";
|
||||||
|
}
|
||||||
|
.icon-energy:before {
|
||||||
|
content: "\e020";
|
||||||
|
}
|
||||||
|
.icon-disc:before {
|
||||||
|
content: "\e022";
|
||||||
|
}
|
||||||
|
.icon-cursor:before {
|
||||||
|
content: "\e06e";
|
||||||
|
}
|
||||||
|
.icon-cursor-move:before {
|
||||||
|
content: "\e023";
|
||||||
|
}
|
||||||
|
.icon-crop:before {
|
||||||
|
content: "\e024";
|
||||||
|
}
|
||||||
|
.icon-chemistry:before {
|
||||||
|
content: "\e026";
|
||||||
|
}
|
||||||
|
.icon-speedometer:before {
|
||||||
|
content: "\e007";
|
||||||
|
}
|
||||||
|
.icon-shield:before {
|
||||||
|
content: "\e00e";
|
||||||
|
}
|
||||||
|
.icon-screen-tablet:before {
|
||||||
|
content: "\e00f";
|
||||||
|
}
|
||||||
|
.icon-magic-wand:before {
|
||||||
|
content: "\e017";
|
||||||
|
}
|
||||||
|
.icon-hourglass:before {
|
||||||
|
content: "\e018";
|
||||||
|
}
|
||||||
|
.icon-graduation:before {
|
||||||
|
content: "\e019";
|
||||||
|
}
|
||||||
|
.icon-ghost:before {
|
||||||
|
content: "\e01a";
|
||||||
|
}
|
||||||
|
.icon-game-controller:before {
|
||||||
|
content: "\e01b";
|
||||||
|
}
|
||||||
|
.icon-fire:before {
|
||||||
|
content: "\e01c";
|
||||||
|
}
|
||||||
|
.icon-eyeglass:before {
|
||||||
|
content: "\e01d";
|
||||||
|
}
|
||||||
|
.icon-envelope-open:before {
|
||||||
|
content: "\e01e";
|
||||||
|
}
|
||||||
|
.icon-envelope-letter:before {
|
||||||
|
content: "\e01f";
|
||||||
|
}
|
||||||
|
.icon-bell:before {
|
||||||
|
content: "\e027";
|
||||||
|
}
|
||||||
|
.icon-badge:before {
|
||||||
|
content: "\e028";
|
||||||
|
}
|
||||||
|
.icon-anchor:before {
|
||||||
|
content: "\e029";
|
||||||
|
}
|
||||||
|
.icon-wallet:before {
|
||||||
|
content: "\e02a";
|
||||||
|
}
|
||||||
|
.icon-vector:before {
|
||||||
|
content: "\e02b";
|
||||||
|
}
|
||||||
|
.icon-speech:before {
|
||||||
|
content: "\e02c";
|
||||||
|
}
|
||||||
|
.icon-puzzle:before {
|
||||||
|
content: "\e02d";
|
||||||
|
}
|
||||||
|
.icon-printer:before {
|
||||||
|
content: "\e02e";
|
||||||
|
}
|
||||||
|
.icon-present:before {
|
||||||
|
content: "\e02f";
|
||||||
|
}
|
||||||
|
.icon-playlist:before {
|
||||||
|
content: "\e030";
|
||||||
|
}
|
||||||
|
.icon-pin:before {
|
||||||
|
content: "\e031";
|
||||||
|
}
|
||||||
|
.icon-picture:before {
|
||||||
|
content: "\e032";
|
||||||
|
}
|
||||||
|
.icon-handbag:before {
|
||||||
|
content: "\e035";
|
||||||
|
}
|
||||||
|
.icon-globe-alt:before {
|
||||||
|
content: "\e036";
|
||||||
|
}
|
||||||
|
.icon-globe:before {
|
||||||
|
content: "\e037";
|
||||||
|
}
|
||||||
|
.icon-folder-alt:before {
|
||||||
|
content: "\e039";
|
||||||
|
}
|
||||||
|
.icon-folder:before {
|
||||||
|
content: "\e089";
|
||||||
|
}
|
||||||
|
.icon-film:before {
|
||||||
|
content: "\e03a";
|
||||||
|
}
|
||||||
|
.icon-feed:before {
|
||||||
|
content: "\e03b";
|
||||||
|
}
|
||||||
|
.icon-drop:before {
|
||||||
|
content: "\e03e";
|
||||||
|
}
|
||||||
|
.icon-drawar:before {
|
||||||
|
content: "\e03f";
|
||||||
|
}
|
||||||
|
.icon-docs:before {
|
||||||
|
content: "\e040";
|
||||||
|
}
|
||||||
|
.icon-doc:before {
|
||||||
|
content: "\e085";
|
||||||
|
}
|
||||||
|
.icon-diamond:before {
|
||||||
|
content: "\e043";
|
||||||
|
}
|
||||||
|
.icon-cup:before {
|
||||||
|
content: "\e044";
|
||||||
|
}
|
||||||
|
.icon-calculator:before {
|
||||||
|
content: "\e049";
|
||||||
|
}
|
||||||
|
.icon-bubbles:before {
|
||||||
|
content: "\e04a";
|
||||||
|
}
|
||||||
|
.icon-briefcase:before {
|
||||||
|
content: "\e04b";
|
||||||
|
}
|
||||||
|
.icon-book-open:before {
|
||||||
|
content: "\e04c";
|
||||||
|
}
|
||||||
|
.icon-basket-loaded:before {
|
||||||
|
content: "\e04d";
|
||||||
|
}
|
||||||
|
.icon-basket:before {
|
||||||
|
content: "\e04e";
|
||||||
|
}
|
||||||
|
.icon-bag:before {
|
||||||
|
content: "\e04f";
|
||||||
|
}
|
||||||
|
.icon-action-undo:before {
|
||||||
|
content: "\e050";
|
||||||
|
}
|
||||||
|
.icon-action-redo:before {
|
||||||
|
content: "\e051";
|
||||||
|
}
|
||||||
|
.icon-wrench:before {
|
||||||
|
content: "\e052";
|
||||||
|
}
|
||||||
|
.icon-umbrella:before {
|
||||||
|
content: "\e053";
|
||||||
|
}
|
||||||
|
.icon-trash:before {
|
||||||
|
content: "\e054";
|
||||||
|
}
|
||||||
|
.icon-tag:before {
|
||||||
|
content: "\e055";
|
||||||
|
}
|
||||||
|
.icon-support:before {
|
||||||
|
content: "\e056";
|
||||||
|
}
|
||||||
|
.icon-frame:before {
|
||||||
|
content: "\e038";
|
||||||
|
}
|
||||||
|
.icon-size-fullscreen:before {
|
||||||
|
content: "\e057";
|
||||||
|
}
|
||||||
|
.icon-size-actual:before {
|
||||||
|
content: "\e058";
|
||||||
|
}
|
||||||
|
.icon-shuffle:before {
|
||||||
|
content: "\e059";
|
||||||
|
}
|
||||||
|
.icon-share-alt:before {
|
||||||
|
content: "\e05a";
|
||||||
|
}
|
||||||
|
.icon-share:before {
|
||||||
|
content: "\e05b";
|
||||||
|
}
|
||||||
|
.icon-rocket:before {
|
||||||
|
content: "\e05c";
|
||||||
|
}
|
||||||
|
.icon-question:before {
|
||||||
|
content: "\e05d";
|
||||||
|
}
|
||||||
|
.icon-pie-chart:before {
|
||||||
|
content: "\e05e";
|
||||||
|
}
|
||||||
|
.icon-pencil:before {
|
||||||
|
content: "\e05f";
|
||||||
|
}
|
||||||
|
.icon-note:before {
|
||||||
|
content: "\e060";
|
||||||
|
}
|
||||||
|
.icon-loop:before {
|
||||||
|
content: "\e064";
|
||||||
|
}
|
||||||
|
.icon-home:before {
|
||||||
|
content: "\e069";
|
||||||
|
}
|
||||||
|
.icon-grid:before {
|
||||||
|
content: "\e06a";
|
||||||
|
}
|
||||||
|
.icon-graph:before {
|
||||||
|
content: "\e06b";
|
||||||
|
}
|
||||||
|
.icon-microphone:before {
|
||||||
|
content: "\e063";
|
||||||
|
}
|
||||||
|
.icon-music-tone-alt:before {
|
||||||
|
content: "\e061";
|
||||||
|
}
|
||||||
|
.icon-music-tone:before {
|
||||||
|
content: "\e062";
|
||||||
|
}
|
||||||
|
.icon-earphones-alt:before {
|
||||||
|
content: "\e03c";
|
||||||
|
}
|
||||||
|
.icon-earphones:before {
|
||||||
|
content: "\e03d";
|
||||||
|
}
|
||||||
|
.icon-equalizer:before {
|
||||||
|
content: "\e06c";
|
||||||
|
}
|
||||||
|
.icon-like:before {
|
||||||
|
content: "\e068";
|
||||||
|
}
|
||||||
|
.icon-dislike:before {
|
||||||
|
content: "\e06d";
|
||||||
|
}
|
||||||
|
.icon-control-start:before {
|
||||||
|
content: "\e06f";
|
||||||
|
}
|
||||||
|
.icon-control-rewind:before {
|
||||||
|
content: "\e070";
|
||||||
|
}
|
||||||
|
.icon-control-play:before {
|
||||||
|
content: "\e071";
|
||||||
|
}
|
||||||
|
.icon-control-pause:before {
|
||||||
|
content: "\e072";
|
||||||
|
}
|
||||||
|
.icon-control-forward:before {
|
||||||
|
content: "\e073";
|
||||||
|
}
|
||||||
|
.icon-control-end:before {
|
||||||
|
content: "\e074";
|
||||||
|
}
|
||||||
|
.icon-volume-1:before {
|
||||||
|
content: "\e09f";
|
||||||
|
}
|
||||||
|
.icon-volume-2:before {
|
||||||
|
content: "\e0a0";
|
||||||
|
}
|
||||||
|
.icon-volume-off:before {
|
||||||
|
content: "\e0a1";
|
||||||
|
}
|
||||||
|
.icon-calender:before {
|
||||||
|
content: "\e075";
|
||||||
|
}
|
||||||
|
.icon-bulb:before {
|
||||||
|
content: "\e076";
|
||||||
|
}
|
||||||
|
.icon-chart:before {
|
||||||
|
content: "\e077";
|
||||||
|
}
|
||||||
|
.icon-ban:before {
|
||||||
|
content: "\e07c";
|
||||||
|
}
|
||||||
|
.icon-bubble:before {
|
||||||
|
content: "\e07d";
|
||||||
|
}
|
||||||
|
.icon-camrecorder:before {
|
||||||
|
content: "\e07e";
|
||||||
|
}
|
||||||
|
.icon-camera:before {
|
||||||
|
content: "\e07f";
|
||||||
|
}
|
||||||
|
.icon-cloud-download:before {
|
||||||
|
content: "\e083";
|
||||||
|
}
|
||||||
|
.icon-cloud-upload:before {
|
||||||
|
content: "\e084";
|
||||||
|
}
|
||||||
|
.icon-envelope:before {
|
||||||
|
content: "\e086";
|
||||||
|
}
|
||||||
|
.icon-eye:before {
|
||||||
|
content: "\e087";
|
||||||
|
}
|
||||||
|
.icon-flag:before {
|
||||||
|
content: "\e088";
|
||||||
|
}
|
||||||
|
.icon-heart:before {
|
||||||
|
content: "\e08a";
|
||||||
|
}
|
||||||
|
.icon-info:before {
|
||||||
|
content: "\e08b";
|
||||||
|
}
|
||||||
|
.icon-key:before {
|
||||||
|
content: "\e08c";
|
||||||
|
}
|
||||||
|
.icon-link:before {
|
||||||
|
content: "\e08d";
|
||||||
|
}
|
||||||
|
.icon-lock:before {
|
||||||
|
content: "\e08e";
|
||||||
|
}
|
||||||
|
.icon-lock-open:before {
|
||||||
|
content: "\e08f";
|
||||||
|
}
|
||||||
|
.icon-magnifier:before {
|
||||||
|
content: "\e090";
|
||||||
|
}
|
||||||
|
.icon-magnifier-add:before {
|
||||||
|
content: "\e091";
|
||||||
|
}
|
||||||
|
.icon-magnifier-remove:before {
|
||||||
|
content: "\e092";
|
||||||
|
}
|
||||||
|
.icon-paper-clip:before {
|
||||||
|
content: "\e093";
|
||||||
|
}
|
||||||
|
.icon-paper-plane:before {
|
||||||
|
content: "\e094";
|
||||||
|
}
|
||||||
|
.icon-power:before {
|
||||||
|
content: "\e097";
|
||||||
|
}
|
||||||
|
.icon-refresh:before {
|
||||||
|
content: "\e098";
|
||||||
|
}
|
||||||
|
.icon-reload:before {
|
||||||
|
content: "\e099";
|
||||||
|
}
|
||||||
|
.icon-settings:before {
|
||||||
|
content: "\e09a";
|
||||||
|
}
|
||||||
|
.icon-star:before {
|
||||||
|
content: "\e09b";
|
||||||
|
}
|
||||||
|
.icon-symble-female:before {
|
||||||
|
content: "\e09c";
|
||||||
|
}
|
||||||
|
.icon-symbol-male:before {
|
||||||
|
content: "\e09d";
|
||||||
|
}
|
||||||
|
.icon-target:before {
|
||||||
|
content: "\e09e";
|
||||||
|
}
|
||||||
|
.icon-credit-card:before {
|
||||||
|
content: "\e025";
|
||||||
|
}
|
||||||
|
.icon-paypal:before {
|
||||||
|
content: "\e608";
|
||||||
|
}
|
||||||
|
.icon-social-tumblr:before {
|
||||||
|
content: "\e00a";
|
||||||
|
}
|
||||||
|
.icon-social-twitter:before {
|
||||||
|
content: "\e009";
|
||||||
|
}
|
||||||
|
.icon-social-facebook:before {
|
||||||
|
content: "\e00b";
|
||||||
|
}
|
||||||
|
.icon-social-instagram:before {
|
||||||
|
content: "\e609";
|
||||||
|
}
|
||||||
|
.icon-social-linkedin:before {
|
||||||
|
content: "\e60a";
|
||||||
|
}
|
||||||
|
.icon-social-pintarest:before {
|
||||||
|
content: "\e60b";
|
||||||
|
}
|
||||||
|
.icon-social-github:before {
|
||||||
|
content: "\e60c";
|
||||||
|
}
|
||||||
|
.icon-social-gplus:before {
|
||||||
|
content: "\e60d";
|
||||||
|
}
|
||||||
|
.icon-social-reddit:before {
|
||||||
|
content: "\e60e";
|
||||||
|
}
|
||||||
|
.icon-social-skype:before {
|
||||||
|
content: "\e60f";
|
||||||
|
}
|
||||||
|
.icon-social-dribbble:before {
|
||||||
|
content: "\e00d";
|
||||||
|
}
|
||||||
|
.icon-social-behance:before {
|
||||||
|
content: "\e610";
|
||||||
|
}
|
||||||
|
.icon-social-foursqare:before {
|
||||||
|
content: "\e611";
|
||||||
|
}
|
||||||
|
.icon-social-soundcloud:before {
|
||||||
|
content: "\e612";
|
||||||
|
}
|
||||||
|
.icon-social-spotify:before {
|
||||||
|
content: "\e613";
|
||||||
|
}
|
||||||
|
.icon-social-stumbleupon:before {
|
||||||
|
content: "\e614";
|
||||||
|
}
|
||||||
|
.icon-social-youtube:before {
|
||||||
|
content: "\e008";
|
||||||
|
}
|
||||||
|
.icon-social-dropbox:before {
|
||||||
|
content: "\e00c";
|
||||||
|
}
|
||||||
29535
src/main/resources/static/css/style.css
Normal file
29535
src/main/resources/static/css/style.css
Normal file
File diff suppressed because it is too large
Load Diff
548
src/main/resources/static/css/style1.css
Normal file
548
src/main/resources/static/css/style1.css
Normal file
|
|
@ -0,0 +1,548 @@
|
||||||
|
/*--------------------------------
|
||||||
|
|
||||||
|
avasta Web Font
|
||||||
|
Generated using nucleoapp.com
|
||||||
|
|
||||||
|
-------------------------------- */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'avasta';
|
||||||
|
src: url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/avasta/fonts/avasta.eot');
|
||||||
|
src: url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/avasta/fonts/avasta.eot') format('embedded-opentype'), url('../font/avasta.woff2') format('woff2'), url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/avasta/fonts/avasta.woff') format('woff'), url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/avasta/fonts/avasta.ttf') format('truetype'), url('http://view.jqueryfuns.com/2021/8/26/e73ec354e91f5ab06a7c2f4ae0b80a6f/icons/avasta/fonts/avasta.svg') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
/*------------------------
|
||||||
|
base class definition
|
||||||
|
-------------------------*/
|
||||||
|
.icon {
|
||||||
|
display: inline-block;
|
||||||
|
font: normal normal normal 1em/1 'avasta';
|
||||||
|
speak: none;
|
||||||
|
text-transform: none;
|
||||||
|
/* Better Font Rendering */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
/*------------------------
|
||||||
|
change icon size
|
||||||
|
-------------------------*/
|
||||||
|
/* relative units */
|
||||||
|
.icon-sm {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
.icon-lg {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
/* absolute units */
|
||||||
|
.icon-16 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.icon-32 {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
/*----------------------------------
|
||||||
|
add a square/circle background
|
||||||
|
-----------------------------------*/
|
||||||
|
.icon-bg-square,
|
||||||
|
.icon-bg-circle {
|
||||||
|
padding: 0.35em;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
.icon-bg-circle {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
/*------------------------------------
|
||||||
|
use icons as list item markers
|
||||||
|
-------------------------------------*/
|
||||||
|
.icon-ul {
|
||||||
|
padding-left: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
.icon-ul > li {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.icon-ul > li > .icon {
|
||||||
|
margin-right: 0.4em;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
/*------------------------
|
||||||
|
spinning icons
|
||||||
|
-------------------------*/
|
||||||
|
.icon-is-spinning {
|
||||||
|
-webkit-animation: icon-spin 2s infinite linear;
|
||||||
|
-moz-animation: icon-spin 2s infinite linear;
|
||||||
|
animation: icon-spin 2s infinite linear;
|
||||||
|
}
|
||||||
|
@-webkit-keyframes icon-spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-moz-keyframes icon-spin {
|
||||||
|
0% {
|
||||||
|
-moz-transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-moz-transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes icon-spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
-moz-transform: rotate(0deg);
|
||||||
|
-ms-transform: rotate(0deg);
|
||||||
|
-o-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
-moz-transform: rotate(360deg);
|
||||||
|
-ms-transform: rotate(360deg);
|
||||||
|
-o-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*------------------------
|
||||||
|
rotated/flipped icons
|
||||||
|
-------------------------*/
|
||||||
|
.icon-rotate-90 {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
-moz-transform: rotate(90deg);
|
||||||
|
-ms-transform: rotate(90deg);
|
||||||
|
-o-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
.icon-rotate-180 {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
|
||||||
|
-webkit-transform: rotate(180deg);
|
||||||
|
-moz-transform: rotate(180deg);
|
||||||
|
-ms-transform: rotate(180deg);
|
||||||
|
-o-transform: rotate(180deg);
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.icon-rotate-270 {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
|
||||||
|
-webkit-transform: rotate(270deg);
|
||||||
|
-moz-transform: rotate(270deg);
|
||||||
|
-ms-transform: rotate(270deg);
|
||||||
|
-o-transform: rotate(270deg);
|
||||||
|
transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
.icon-flip-y {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0);
|
||||||
|
-webkit-transform: scale(-1, 1);
|
||||||
|
-moz-transform: scale(-1, 1);
|
||||||
|
-ms-transform: scale(-1, 1);
|
||||||
|
-o-transform: scale(-1, 1);
|
||||||
|
transform: scale(-1, 1);
|
||||||
|
}
|
||||||
|
.icon-flip-x {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
|
||||||
|
-webkit-transform: scale(1, -1);
|
||||||
|
-moz-transform: scale(1, -1);
|
||||||
|
-ms-transform: scale(1, -1);
|
||||||
|
-o-transform: scale(1, -1);
|
||||||
|
transform: scale(1, -1);
|
||||||
|
}
|
||||||
|
/*------------------------
|
||||||
|
icons
|
||||||
|
-------------------------*/
|
||||||
|
|
||||||
|
.icon-cloud-download-95::before {
|
||||||
|
content: "\ea02";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-home-minimal::before {
|
||||||
|
content: "\ea03";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-single-04::before {
|
||||||
|
content: "\ea04";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-users-mm::before {
|
||||||
|
content: "\ea05";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-webpage::before {
|
||||||
|
content: "\ea06";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-layout-25::before {
|
||||||
|
content: "\ea07";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-analytics::before {
|
||||||
|
content: "\ea08";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chart-pie-36::before {
|
||||||
|
content: "\ea09";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chart-bar-33::before {
|
||||||
|
content: "\ea0a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-single-copy-06::before {
|
||||||
|
content: "\ea0b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-home::before {
|
||||||
|
content: "\ea0c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-single-content-03::before {
|
||||||
|
content: "\ea0d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bell-53::before {
|
||||||
|
content: "\ea0e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-email-84::before {
|
||||||
|
content: "\ea0f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-send::before {
|
||||||
|
content: "\ea10";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-at-sign::before {
|
||||||
|
content: "\ea11";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-attach-87::before {
|
||||||
|
content: "\ea12";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-edit-72::before {
|
||||||
|
content: "\ea13";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tail-right::before {
|
||||||
|
content: "\ea14";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-minimal-right::before {
|
||||||
|
content: "\ea15";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tail-left::before {
|
||||||
|
content: "\ea16";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-minimal-left::before {
|
||||||
|
content: "\ea17";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tail-up::before {
|
||||||
|
content: "\ea18";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-minimal-up::before {
|
||||||
|
content: "\ea19";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-minimal-down::before {
|
||||||
|
content: "\ea1a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tail-down::before {
|
||||||
|
content: "\ea1b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-settings-gear-64::before {
|
||||||
|
content: "\ea1c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-settings::before {
|
||||||
|
content: "\ea1d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-menu-dots::before {
|
||||||
|
content: "\ea1e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-menu-left::before {
|
||||||
|
content: "\ea1f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-funnel-40::before {
|
||||||
|
content: "\ea20";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-filter::before {
|
||||||
|
content: "\ea21";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-preferences-circle::before {
|
||||||
|
content: "\ea22";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-check-2::before {
|
||||||
|
content: "\ea23";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-cart-simple::before {
|
||||||
|
content: "\ea24";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-cart-9::before {
|
||||||
|
content: "\ea25";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-card-update::before {
|
||||||
|
content: "\ea26";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-basket::before {
|
||||||
|
content: "\ea27";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-check-circle-07::before {
|
||||||
|
content: "\ea28";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-simple-remove::before {
|
||||||
|
content: "\ea29";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-circle-remove::before {
|
||||||
|
content: "\ea2a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-alert-circle-exc::before {
|
||||||
|
content: "\ea2b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bug::before {
|
||||||
|
content: "\ea2c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-share-66::before {
|
||||||
|
content: "\ea2d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-time-3::before {
|
||||||
|
content: "\ea2e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-time::before {
|
||||||
|
content: "\ea2f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-coffee::before {
|
||||||
|
content: "\ea30";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-smile::before {
|
||||||
|
content: "\ea31";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-sad::before {
|
||||||
|
content: "\ea32";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-broken-heart::before {
|
||||||
|
content: "\ea33";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-heart-2::before {
|
||||||
|
content: "\ea34";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-pin-3::before {
|
||||||
|
content: "\ea35";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-marker-3::before {
|
||||||
|
content: "\ea36";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-globe-2::before {
|
||||||
|
content: "\ea37";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-world-2::before {
|
||||||
|
content: "\ea38";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-phone-2::before {
|
||||||
|
content: "\ea39";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-check-square-11::before {
|
||||||
|
content: "\ea3a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wallet-90::before {
|
||||||
|
content: "\ea3b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-credit-card::before {
|
||||||
|
content: "\ea3c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-payment::before {
|
||||||
|
content: "\ea3d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tag::before {
|
||||||
|
content: "\ea3e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tag-cut::before {
|
||||||
|
content: "\ea3f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tag-content::before {
|
||||||
|
content: "\ea40";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-flag-diagonal-33::before {
|
||||||
|
content: "\ea41";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-triangle-right-17::before {
|
||||||
|
content: "\ea47";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-puzzle-10::before {
|
||||||
|
content: "\ea48";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-triangle-right-17-2::before {
|
||||||
|
content: "\ea49";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-btn-play::before {
|
||||||
|
content: "\ea4a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-btn-play-2::before {
|
||||||
|
content: "\ea4b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-menu-34::before {
|
||||||
|
content: "\ea4c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-menu-left-2::before {
|
||||||
|
content: "\ea4d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-heart-2-2::before {
|
||||||
|
content: "\ea4e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-single-04-2::before {
|
||||||
|
content: "\ea4f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-users-mm-2::before {
|
||||||
|
content: "\ea50";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-l-settings::before {
|
||||||
|
content: "\ea51";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-book-open-2::before {
|
||||||
|
content: "\ea52";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-layers-3::before {
|
||||||
|
content: "\ea53";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-logo-fb-simple::before {
|
||||||
|
content: "\ea55";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-logo-twitter::before {
|
||||||
|
content: "\ea56";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-google::before {
|
||||||
|
content: "\ea57";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-logo-pinterest::before {
|
||||||
|
content: "\ea58";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-logo-instagram::before {
|
||||||
|
content: "\ea59";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-logo-dribbble::before {
|
||||||
|
content: "\ea5a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tablet-mobile::before {
|
||||||
|
content: "\ea5b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-house-search-engine::before {
|
||||||
|
content: "\ea5c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-house-pricing::before {
|
||||||
|
content: "\ea5d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-pulse-chart::before {
|
||||||
|
content: "\ea5e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-plug::before {
|
||||||
|
content: "\ea5f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-app-store::before {
|
||||||
|
content: "\ea60";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-power-level::before {
|
||||||
|
content: "\ea61";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-window-add::before {
|
||||||
|
content: "\ea62";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-form::before {
|
||||||
|
content: "\ea63";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-folder-15::before {
|
||||||
|
content: "\ea64";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-lock::before {
|
||||||
|
content: "\ea65";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-unlocked::before {
|
||||||
|
content: "\ea66";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-e-reader::before {
|
||||||
|
content: "\ea67";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-layout-grid::before {
|
||||||
|
content: "\ea68";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-single-copies::before {
|
||||||
|
content: "\ea69";
|
||||||
|
}
|
||||||
|
|
||||||
1081
src/main/resources/static/css/themify-icons.css
Normal file
1081
src/main/resources/static/css/themify-icons.css
Normal file
File diff suppressed because it is too large
Load Diff
46
src/main/resources/static/error/400.html
Normal file
46
src/main/resources/static/error/400.html
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-100">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="keywords" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<meta name="robots" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- PAGE TITLE HERE -->
|
||||||
|
<title>Error</title>
|
||||||
|
|
||||||
|
<link href="/css/bootstrap-select.min.css" rel="stylesheet">
|
||||||
|
<link href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="vh-100">
|
||||||
|
<div class="authincation h-100">
|
||||||
|
<div class="container h-100">
|
||||||
|
<div class="row justify-content-center h-100 align-items-center">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="form-input-content text-center error-page">
|
||||||
|
<h1 class="error-text fw-bold">400</h1>
|
||||||
|
<h4><i class="fa fa-thumbs-down text-danger"></i> Bad Request</h4>
|
||||||
|
<p>Your Request resulted in an error</p>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-primary" href="/">Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--**********************************
|
||||||
|
Scripts
|
||||||
|
***********************************-->
|
||||||
|
<!-- Required vendors -->
|
||||||
|
<script src="/js/global.min.js"></script>
|
||||||
|
<script src="/js/custom.min.js"></script>
|
||||||
|
<script src="/js/styleSwitcher.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
46
src/main/resources/static/error/403.html
Normal file
46
src/main/resources/static/error/403.html
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-100">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="keywords" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<meta name="robots" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- PAGE TITLE HERE -->
|
||||||
|
<title>Error</title>
|
||||||
|
|
||||||
|
<link href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="vh-100">
|
||||||
|
<div class="authincation h-100">
|
||||||
|
<div class="container h-100">
|
||||||
|
<div class="row justify-content-center h-100 align-items-center">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="form-input-content text-center error-page">
|
||||||
|
<h1 class="error-text fw-bold">403</h1>
|
||||||
|
<h4><i class="fa fa-times-circle text-danger"></i> Forbidden Error!</h4>
|
||||||
|
<p>You do not have permission to view this resource.</p>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-primary" href="/">Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--**********************************
|
||||||
|
Scripts
|
||||||
|
***********************************-->
|
||||||
|
<!-- Required vendors -->
|
||||||
|
<script src="/js/global.min.js"></script>
|
||||||
|
<script src="/js/custom.min.js"></script>
|
||||||
|
<script src="/js/styleSwitcher.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
46
src/main/resources/static/error/404.html
Normal file
46
src/main/resources/static/error/404.html
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-100">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="keywords" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<meta name="robots" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- PAGE TITLE HERE -->
|
||||||
|
<title>Error</title>
|
||||||
|
|
||||||
|
<link href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="vh-100">
|
||||||
|
<div class="authincation h-100">
|
||||||
|
<div class="container h-100">
|
||||||
|
<div class="row justify-content-center h-100 align-items-center">
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div class="form-input-content text-center error-page">
|
||||||
|
<h1 class="error-text fw-bold">404</h1>
|
||||||
|
<h4><i class="fa fa-exclamation-triangle text-warning"></i> The page you were looking for is not found!</h4>
|
||||||
|
<p>You may have mistyped the address or the page may have moved.</p>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-primary" href="/">Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--**********************************
|
||||||
|
Scripts
|
||||||
|
***********************************-->
|
||||||
|
<!-- Required vendors -->
|
||||||
|
<script src="/js/global.min.js"></script>
|
||||||
|
<script src="/js/custom.min.js"></script>
|
||||||
|
<script src="/js/styleSwitcher.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
47
src/main/resources/static/error/500.html
Normal file
47
src/main/resources/static/error/500.html
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-100">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="keywords" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<meta name="robots" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- PAGE TITLE HERE -->
|
||||||
|
<title>Error</title>
|
||||||
|
|
||||||
|
<link href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
<body class="vh-100">
|
||||||
|
<div class="authincation h-100">
|
||||||
|
<div class="container h-100">
|
||||||
|
<div class="row justify-content-center h-100 align-items-center">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="form-input-content text-center error-page">
|
||||||
|
<h1 class="error-text fw-bold">500</h1>
|
||||||
|
<h4><i class="fa fa-times-circle text-danger"></i> Internal Server Error</h4>
|
||||||
|
<p>You do not have permission to view this resource</p>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-primary" href="/">Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--**********************************
|
||||||
|
Scripts
|
||||||
|
***********************************-->
|
||||||
|
<!-- Required vendors -->
|
||||||
|
<script src="/js/global.min.js"></script>
|
||||||
|
<script src="/js/custom.min.js"></script>
|
||||||
|
<script src="/js/styleSwitcher.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user