diff --git a/.gitignore b/.gitignore index cca75ec..d3ed4c7 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,9 @@ mizukiblog-master.zip # 日志 logs/ *.log + +# 签名验证 - 私钥(绝不要提交!) +data/signature-verifier/keys/private/ + +# 签名文件(可选,本地开发可能不需要) +# store/**/SIGNATURE diff --git a/oss/__pycache__/__init__.cpython-313.pyc b/oss/__pycache__/__init__.cpython-313.pyc index d862c0d..41fd71b 100644 Binary files a/oss/__pycache__/__init__.cpython-313.pyc and b/oss/__pycache__/__init__.cpython-313.pyc differ diff --git a/oss/__pycache__/cli.cpython-313.pyc b/oss/__pycache__/cli.cpython-313.pyc index 2a117f1..226dafc 100644 Binary files a/oss/__pycache__/cli.cpython-313.pyc and b/oss/__pycache__/cli.cpython-313.pyc differ diff --git a/oss/logger/__pycache__/logger.cpython-313.pyc b/oss/logger/__pycache__/logger.cpython-313.pyc index 2dc99ad..05d73c1 100644 Binary files a/oss/logger/__pycache__/logger.cpython-313.pyc and b/oss/logger/__pycache__/logger.cpython-313.pyc differ diff --git a/oss/logger/logger.py b/oss/logger/logger.py index 47f44ad..4c49daa 100644 --- a/oss/logger/logger.py +++ b/oss/logger/logger.py @@ -1,15 +1,62 @@ -"""日志系统 - 空壳,由日志插件提供实际功能""" +"""日志系统 - 彩色日志""" +import sys + + +class Log: + """通用彩色日志 - 所有插件可共用""" + + _TTY = sys.stdout.isatty() + _C = { + "reset": "\033[0m", + "white": "\033[0;37m", + "yellow": "\033[1;33m", + "blue": "\033[1;34m", + "red": "\033[1;31m", + "green": "\033[0;32m", + } + + @classmethod + def _c(cls, text: str, color: str) -> str: + if not cls._TTY: + return text + return f"{cls._C.get(color, '')}{text}{cls._C['reset']}" + + @classmethod + def info(cls, tag: str, msg: str): + print(f"{cls._c(f'[{tag}]', 'white')} {cls._c(msg, 'white')}") + + @classmethod + def warn(cls, tag: str, msg: str): + print(f"{cls._c(f'[{tag}]', 'yellow')} {cls._c('⚠', 'yellow')} {cls._c(msg, 'yellow')}") + + @classmethod + def error(cls, tag: str, msg: str): + print(f"{cls._c(f'[{tag}]', 'red')} {cls._c('✗', 'red')} {cls._c(msg, 'red')}") + + @classmethod + def tip(cls, tag: str, msg: str): + print(f"{cls._c(f'[{tag}]', 'blue')} {cls._c('ℹ', 'blue')} {cls._c(msg, 'blue')}") + + @classmethod + def ok(cls, tag: str, msg: str): + print(f"{cls._c(f'[{tag}]', 'white')} {cls._c(msg, 'white')}") + + class Logger: - """日志记录器(空壳)""" + """日志记录器(兼容旧接口)""" def info(self, msg: str, **kwargs): - print(f"[INFO] {msg}") + tag = kwargs.get("tag", "INFO") + Log.info(tag, msg) def warn(self, msg: str, **kwargs): - print(f"[WARN] {msg}") + tag = kwargs.get("tag", "WARN") + Log.warn(tag, msg) def error(self, msg: str, **kwargs): - print(f"[ERROR] {msg}") + tag = kwargs.get("tag", "ERROR") + Log.error(tag, msg) def debug(self, msg: str, **kwargs): - print(f"[DEBUG] {msg}") + tag = kwargs.get("tag", "DEBUG") + Log.tip(tag, msg) diff --git a/oss/plugin/__pycache__/capabilities.cpython-313.pyc b/oss/plugin/__pycache__/capabilities.cpython-313.pyc index 1754cc6..57ec4d6 100644 Binary files a/oss/plugin/__pycache__/capabilities.cpython-313.pyc and b/oss/plugin/__pycache__/capabilities.cpython-313.pyc differ diff --git a/oss/plugin/__pycache__/loader.cpython-313.pyc b/oss/plugin/__pycache__/loader.cpython-313.pyc index 2d0e4f4..3a9d223 100644 Binary files a/oss/plugin/__pycache__/loader.cpython-313.pyc and b/oss/plugin/__pycache__/loader.cpython-313.pyc differ diff --git a/oss/plugin/__pycache__/manager.cpython-313.pyc b/oss/plugin/__pycache__/manager.cpython-313.pyc index 737f18b..111db9f 100644 Binary files a/oss/plugin/__pycache__/manager.cpython-313.pyc and b/oss/plugin/__pycache__/manager.cpython-313.pyc differ diff --git a/oss/plugin/__pycache__/types.cpython-313.pyc b/oss/plugin/__pycache__/types.cpython-313.pyc index 905b7c3..58cf0a8 100644 Binary files a/oss/plugin/__pycache__/types.cpython-313.pyc and b/oss/plugin/__pycache__/types.cpython-313.pyc differ diff --git a/oss/shared/__pycache__/__init__.cpython-313.pyc b/oss/shared/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..b56aad0 Binary files /dev/null and b/oss/shared/__pycache__/__init__.cpython-313.pyc differ diff --git a/oss/shared/__pycache__/router.cpython-313.pyc b/oss/shared/__pycache__/router.cpython-313.pyc index f20d836..44b71fa 100644 Binary files a/oss/shared/__pycache__/router.cpython-313.pyc and b/oss/shared/__pycache__/router.cpython-313.pyc differ diff --git a/requirements.txt b/requirements.txt index 552ae57..ec10015 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ click>=8.0 pyyaml>=6.0 websockets>=12.0 +psutil>=5.9.0 +cryptography>=41.0 diff --git a/start.bat b/start.bat index 048c81d..c82067d 100644 --- a/start.bat +++ b/start.bat @@ -3,144 +3,215 @@ chcp 65001 >nul 2>&1 setlocal enabledelayedexpansion :: ═══════════════════════════════════════════════════════════ -:: FutureOSS 启动脚本 — Windows -:: 自动检测 Python / 依赖 / 守护 / 崩溃重启 +:: FutureOSS 智能启动脚本 - Windows +:: 自动检测环境 / 安装依赖 / 进度显示 / 守护重启 :: ═══════════════════════════════════════════════════════════ -set "RED=[31m" -set "GREEN=[32m" -set "YELLOW=[33m" -set "CYAN=[36m" -set "WHITE=[37m" -set "BOLD=[1m" -set "NC=[0m" +cd /d "%~dp0" -call :color_echo "BOLD" "CYAN" "" -echo ███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗ -echo ██╔════╝ ██╔══██╗ ██╔══██╗ ██╔══██╗ ██╔══██╗██╔════╝ -echo █████╗ ██████╔╝ ██████╔╝ ██████╔╝ ██║ ██║██║ ███╗ -echo ██╔══╝ ██╔══██╗ ██╔══██╗ ██╔══██╗ ██║ ██║██║ ██║ -echo ██║ ██║ ██║ ██║ ██║ ██║ ██║ ██████╔╝╚██████╔╝ -echo ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ -call :color_echo "BOLD" "WHITE" "" 一切皆为插件 · 零编译热插拔 -call :color_echo "" "WHITE" "" https://gitee.com/starlight-apk/feature-oss +:: ── 颜色代码 ── +for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do ( + set "DEL=%%a" +) + +:: ── 工具函数 ── +call :colorEcho 0B "[信息] 环境检测中..." +call :colorEcho 0A "[成功] 检测完成" +call :colorEcho 0E "[警告] 某些组件缺失" +call :colorEcho 0C "[错误] 检测失败" + +:: ── Logo ── +echo. +call :colorEcho 0B " ███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗ " +call :colorEcho 0B " ██╔════╝ ██╔══██╗ ██╔══██╗ ██╔══██╗ ██╔══██╗██╔════╝ " +call :colorEcho 0B " █████╗ ██████╔╝ ██████╔╝ ██████╔╝ ██║ ██║██║ ███╗" +call :colorEcho 0B " ██╔══╝ ██╔══██╗ ██╔══██╗ ██╔══██╗ ██║ ██║██║ ██║" +call :colorEcho 0B " ██║ ██║ ██║ ██║ ██║ ██║ ██║ ██████╔╝╚██████╔╝" +call :colorEcho 0B " ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ " +echo. +call :colorEcho 0F " 开发者通用工具套组 · 一切皆为插件" +call :colorEcho 07 " https://gitee.com/starlight-apk/feature-oss" echo. -:: ── 目录 ── -cd /d "%~dp0" +:: ═══════════════════════════════════════════════════════════ +:: 1. 检测 Python +:: ═══════════════════════════════════════════════════════════ +call :colorEcho 0B "[信息] 检测 Python..." + set "PYTHON_CMD=" -set "PIP_CMD=" - -:: ═══════════════════════════════════════════════════════════ -:: 1. 检查 Python -:: ═══════════════════════════════════════════════════════════ -call :section "环境检测" - -where python 2>nul && set "PYTHON_CMD=python" || ( - where python3 2>nul && set "PYTHON_CMD=python3" || ( - where py 2>nul && set "PYTHON_CMD=py" || ( - call :color_echo "" "YELLOW" "" [!] 未检测到 Python - echo. - echo 请安装 Python 3.10+ : - echo ^> https://www.python.org/downloads/ - echo. - echo 安装时请勾选 "Add Python to PATH" - echo. - pause - exit /b 1 - ) +for %%p in (python python3 py py3) do ( + where %%p >nul 2>&1 + if !errorlevel! equ 0 ( + set "PYTHON_CMD=%%p" + goto :found_python ) ) +:found_python +if "%PYTHON_CMD%"=="" ( + call :colorEcho 0C "[错误] 未找到 Python,请先安装 Python 3.10+" + call :colorEcho 0E "[提示] 下载地址: https://www.python.org/downloads/" + pause + exit /b 1 +) + for /f "tokens=*" %%i in ('%PYTHON_CMD% --version 2^>^&1') do set "PY_VER=%%i" -call :color_echo "" "GREEN" "" [✓] Python: %PY_VER% +call :colorEcho 0A "[成功] %PY_VER%" :: ═══════════════════════════════════════════════════════════ -:: 2. 虚拟环境 & 依赖 +:: 2. 虚拟环境 :: ═══════════════════════════════════════════════════════════ -call :section "依赖安装" +echo. +call :colorEcho 0B "[信息] 配置 Python 环境..." if not exist ".venv" ( - call :color_echo "" "CYAN" "" [i] 创建虚拟环境... - %PYTHON_CMD% -m venv .venv + call :colorEcho 0E "[信息] 创建虚拟环境..." + %PYTHON_CMD% -m venv .venv >nul 2>&1 + if errorlevel 1 ( + call :colorEcho 0C "[错误] 无法创建虚拟环境" + pause + exit /b 1 + ) + call :colorEcho 0A "[成功] 虚拟环境已创建" +) else ( + call :colorEcho 0A "[成功] 虚拟环境已存在" ) -set "VENV_PYTHON=.venv\Scripts\python.exe" -set "VENV_PIP=.venv\Scripts\pip.exe" +call .venv\Scripts\activate.bat >nul 2>&1 -if exist "pyproject.toml" ( - call :color_echo "" "CYAN" "" [i] 安装项目依赖... - %VENV_PIP% install -e . -q 2>nul -) +:: ═══════════════════════════════════════════════════════════ +:: 3. 安装依赖 +:: ═══════════════════════════════════════════════════════════ +echo. +call :colorEcho 0B "[信息] 安装 Python 依赖..." -if exist "requirements.txt" ( - call :color_echo "" "CYAN" "" [i] 安装 requirements.txt... - %VENV_PIP% install -r requirements.txt -q 2>nul -) +set "DEPS=click pyyaml websockets psutil cryptography" +set "TOTAL=5" +set "CURRENT=0" -:: 核心依赖兜底 -for %%p in (click pyyaml websockets) do ( - %VENV_PYTHON% -c "import %%p" 2>nul || ( - call :color_echo "" "CYAN" "" [i] 安装 %%p ... - %VENV_PIP% install %%p -q 2>nul +for %%d in (%DEPS%) do ( + set /a CURRENT+=1 + call :printProgress !CURRENT! !TOTAL! "安装 %%d" + + %PYTHON_CMD% -c "import %%d" 2>nul + if errorlevel 1 ( + pip install %%d -q 2>nul ) ) -call :color_echo "" "GREEN" "" [✓] 依赖就绪 +echo. +echo. +call :colorEcho 0A "[成功] Python 依赖安装完成" + +:: 安装项目依赖 +if exist "pyproject.toml" ( + call :colorEcho 0E "[信息] 安装项目配置依赖..." + pip install -e . -q 2>nul +) + +if exist "requirements.txt" ( + call :colorEcho 0E "[信息] 安装 requirements.txt..." + pip install -r requirements.txt -q 2>nul +) :: ═══════════════════════════════════════════════════════════ -:: 3. 确保 data 目录 +:: 4. 检查 PHP :: ═══════════════════════════════════════════════════════════ -if not exist "data\html-render" mkdir "data\html-render" -if not exist "data\web-toolkit" mkdir "data\web-toolkit" -if not exist "data\plugin-storage" mkdir "data\plugin-storage" -if not exist "data\DCIM" mkdir "data\DCIM" -if not exist "data\pkg" mkdir "data\pkg" +echo. +call :colorEcho 0B "[信息] 检查 PHP..." + +where php >nul 2>&1 +if errorlevel 1 ( + call :colorEcho 0E "[警告] PHP 未安装,WebUI 可能无法正常工作" + call :colorEcho 07 "[提示] 安装: choco install php 或从 https://windows.php.net/download/ 下载" +) else ( + for /f "tokens=*" %%i in ('php --version 2^>^&1 ^| findstr /r "PHP"') do set "PHP_VER=%%i" + call :colorEcho 0A "[成功] !PHP_VER!" +) :: ═══════════════════════════════════════════════════════════ -:: 4. 启动 +:: 5. 创建数据目录 :: ═══════════════════════════════════════════════════════════ -call :section "启动 FutureOSS" +echo. +call :colorEcho 0B "[信息] 初始化数据目录..." + +set "DIRS=data data\html-render data\web-toolkit data\plugin-storage data\DCIM data\pkg data\signature-verifier\keys\private data\signature-verifier\keys\public logs" + +for %%d in (%DIRS%) do ( + if not exist "%%d" mkdir "%%d" +) + +call :colorEcho 0A "[成功] 数据目录已就绪" + +:: ═══════════════════════════════════════════════════════════ +:: 6. 启动服务 +:: ═══════════════════════════════════════════════════════════ +echo. +call :colorEcho 0B "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +call :colorEcho 0B " 启动 FutureOSS" +call :colorEcho 0B "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo. + +if "%1"=="--daemon" goto :daemon_mode +if "%1"=="-d" goto :daemon_mode + +:: 前台模式 +call :colorEcho 0F "运行中... 按 Ctrl+C 停止" +echo. set "RESTART_DELAY=3" set "RESTART_COUNT=0" -:LOOP - echo. - call :color_echo "" "CYAN" "" [i] 启动服务... - echo. - %VENV_PYTHON% -m oss.cli serve - set "EXIT_CODE=!ERRORLEVEL!" +:loop +%PYTHON_CMD% -m oss.cli serve +set "EXIT_CODE=%errorlevel%" - if !EXIT_CODE! equ 0 ( - echo. - call :color_echo "" "GREEN" "" [✓] 服务正常退出 - goto :END - ) +if %EXIT_CODE% equ 0 ( + call :colorEcho 0A "[成功] 服务正常退出" + goto :end +) - set /a RESTART_COUNT+=1 - echo. - call :color_echo "" "YELLOW" "" [!] 服务异常退出 (code: !EXIT_CODE!),!RESTART_DELAY!s 后重启... (第 !RESTART_COUNT! 次) - timeout /t !RESTART_DELAY! /nobreak >nul +set /a RESTART_COUNT+=1 +call :colorEcho 0E "[警告] 服务异常退出 (code: %EXIT_CODE%),!RESTART_DELAY!s 后重启... (第 !RESTART_COUNT! 次)" +timeout /t !RESTART_DELAY! /nobreak >nul - if !RESTART_DELAY! lss 30 set /a RESTART_DELAY=!RESTART_DELAY!*2 +:: 指数退避 +if !RESTART_DELAY! lss 30 ( + set /a RESTART_DELAY=!RESTART_DELAY! * 2 +) - goto :LOOP +goto :loop -:END +:daemon_mode +call :colorEcho 0E "[警告] Windows 守护模式需要额外配置" +call :colorEcho 07 "[提示] 建议使用任务计划程序或 nssm 工具实现" echo. +%PYTHON_CMD% -m oss.cli serve +goto :end + +:end +call .venv\Scripts\deactivate.bat >nul 2>&1 pause exit /b 0 -:: ── 辅助函数 ── -:color_echo - if "%~1" neq "" set /p "=^%BOLD%%~2%%NC%" /dev/null; then - echo "$cmd" - return - fi - done - return 1 -} +PKG_MANAGER="" +OS_NAME="" -PYTHON_CMD=$(find_python || true) - -if [[ -z "$PYTHON_CMD" ]]; then - warn "未检测到 Python,正在自动安装..." - if command -v apt-get &>/dev/null; then - sudo apt-get update -qq && sudo apt-get install -y -qq python3 python3-pip python3-venv - elif command -v yum &>/dev/null; then - sudo yum install -y python3 python3-pip - elif command -v pacman &>/dev/null; then - sudo pacman -Sy --noconfirm python python-pip - elif command -v brew &>/dev/null; then - brew install python - elif command -v apk &>/dev/null; then - apk add python3 py3-pip - else - err "无法自动安装 Python,请手动安装 Python 3.10+" - exit 1 - fi - PYTHON_CMD=$(find_python || true) - [[ -z "$PYTHON_CMD" ]] && { err "Python 安装失败"; exit 1; } +if [[ -f /etc/os-release ]]; then + OS_NAME=$(. /etc/os-release && echo "$PRETTY_NAME") + info "操作系统: $OS_NAME" fi -PY_VER=$($PYTHON_CMD --version 2>&1) -ok "Python: $PY_VER ($PYTHON_CMD)" +if command -v apt-get &>/dev/null; then + PKG_MANAGER="apt" + ok "包管理器: apt (Debian/Ubuntu)" +elif command -v yum &>/dev/null; then + PKG_MANAGER="yum" + ok "包管理器: yum (CentOS/RHEL)" +elif command -v dnf &>/dev/null; then + PKG_MANAGER="dnf" + ok "包管理器: dnf (Fedora)" +elif command -v pacman &>/dev/null; then + PKG_MANAGER="pacman" + ok "包管理器: pacman (Arch Linux)" +elif command -v apk &>/dev/null; then + PKG_MANAGER="apk" + ok "包管理器: apk (Alpine)" +else + warn "未检测到已知包管理器,将尝试使用系统自带工具" +fi + +install_pkg() { + local pkg=$1 + case $PKG_MANAGER in + apt) sudo apt-get install -y -qq "$pkg" 2>/dev/null ;; + yum) sudo yum install -y -q "$pkg" 2>/dev/null ;; + dnf) sudo dnf install -y -q "$pkg" 2>/dev/null ;; + pacman) sudo pacman -S --noconfirm "$pkg" 2>/dev/null ;; + apk) sudo apk add --quiet "$pkg" 2>/dev/null ;; + *) warn "无法自动安装 $pkg" ; return 1 ;; + esac +} + +update_pkg_cache() { + case $PKG_MANAGER in + apt) sudo apt-get update -qq 2>/dev/null ;; + yum) sudo yum makecache -q 2>/dev/null ;; + dnf) sudo dnf makecache -q 2>/dev/null ;; + pacman) sudo pacman -Sy --quiet 2>/dev/null ;; + apk) sudo apk update --quiet 2>/dev/null ;; + esac +} + +TOTAL_STEPS=6 +CURRENT_STEP=0 # ═══════════════════════════════════════════════════════════ -# 2. 虚拟环境 & 依赖 +# 2. 安装系统依赖 # ═══════════════════════════════════════════════════════════ -title "📚 依赖安装" +step "安装系统依赖" +DEPENDENCIES=("git" "curl" "wget" "php" "php-cli" "php-mbstring" "php-xml" "php-zip" "python3" "python3-pip" "python3-venv") +DEP_TOTAL=${#DEPENDENCIES[@]} +DEP_INSTALLED=0 + +for dep in "${DEPENDENCIES[@]}"; do + DEP_INSTALLED=$((DEP_INSTALLED + 1)) + progress_bar $DEP_INSTALLED $DEP_TOTAL "检测 $dep" + + if command -v "$dep" &>/dev/null; then + continue + fi + + # 尝试安装 + if ! install_pkg "$dep" 2>/dev/null; then + # 更新缓存后重试 + update_pkg_cache 2>/dev/null + install_pkg "$dep" 2>/dev/null || true + fi + + if command -v "$dep" &>/dev/null; then + continue + fi +done + +echo -e "\n" + +# 验证关键依赖 +if command -v php &>/dev/null; then + ok "PHP: $(php --version 2>&1 | head -n 1)" +else + warn "PHP 未安装,WebUI 可能无法正常工作" +fi + +if command -v python3 &>/dev/null; then + ok "Python: $(python3 --version 2>&1)" +else + err "Python3 未安装,无法继续" + exit 1 +fi + +# ═══════════════════════════════════════════════════════════ +# 3. Python 虚拟环境 +# ═══════════════════════════════════════════════════════════ +step "配置 Python 环境" + +PYTHON_CMD="python3" VENV_DIR=".venv" + if [[ ! -d "$VENV_DIR" ]]; then info "创建虚拟环境..." - $PYTHON_CMD -m venv "$VENV_DIR" + $PYTHON_CMD -m venv "$VENV_DIR" 2>/dev/null || { + warn "venv 模块缺失,尝试安装..." + case $PKG_MANAGER in + apt) install_pkg "python3-venv" ;; + yum) install_pkg "python3-virtualenv" ;; + dnf) install_pkg "python3-virtualenv" ;; + pacman) ;; + apk) install_pkg "py3-virtualenv" ;; + esac + $PYTHON_CMD -m venv "$VENV_DIR" 2>/dev/null || { + err "无法创建虚拟环境" + exit 1 + } + } + ok "虚拟环境已创建" +else + ok "虚拟环境已存在" fi source "$VENV_DIR/bin/activate" PIP_CMD="$VENV_DIR/bin/pip" +# ═══════════════════════════════════════════════════════════ +# 4. 安装 Python 依赖 +# ═══════════════════════════════════════════════════════════ +step "安装 Python 依赖" + +CORE_DEPS=("click" "pyyaml" "websockets" "psutil" "cryptography") +DEP_COUNT=${#CORE_DEPS[@]} +DEP_CURRENT=0 + +for pkg in "${CORE_DEPS[@]}"; do + DEP_CURRENT=$((DEP_CURRENT + 1)) + progress_bar $DEP_CURRENT $DEP_COUNT "安装 $pkg" + + $PYTHON_CMD -c "import $pkg" 2>/dev/null && continue + + $PIP_CMD install "$pkg" -q 2>/dev/null || \ + $PIP_CMD install "$pkg" --break-system-packages -q 2>/dev/null || true +done + +echo -e "\n" + +# 安装项目依赖 if [[ -f "pyproject.toml" ]]; then - info "安装项目依赖 (pyproject.toml)..." - $PIP_CMD install -e . -q 2>/dev/null || $PIP_CMD install -e . --break-system-packages -q 2>/dev/null || true + info "安装项目配置依赖..." + $PIP_CMD install -e . -q 2>/dev/null || true fi if [[ -f "requirements.txt" ]]; then @@ -103,63 +223,85 @@ if [[ -f "requirements.txt" ]]; then $PIP_CMD install -r requirements.txt -q 2>/dev/null || true fi -# 核心依赖兜底 -for pkg in click pyyaml websockets; do - $PYTHON_CMD -c "import $pkg" 2>/dev/null || { - info "安装 $pkg ..." - $PIP_CMD install "$pkg" -q 2>/dev/null || $PIP_CMD install "$pkg" --break-system-packages -q 2>/dev/null || true - } +ok "Python 依赖安装完成" + +# ═══════════════════════════════════════════════════════════ +# 5. 创建数据目录 +# ═══════════════════════════════════════════════════════════ +step "初始化数据目录" + +DATA_DIRS=("data" "data/html-render" "data/web-toolkit" "data/plugin-storage" "data/DCIM" "data/pkg" "data/signature-verifier/keys/private" "data/signature-verifier/keys/public" "logs") +DIR_COUNT=${#DATA_DIRS[@]} +DIR_CURRENT=0 + +for dir in "${DATA_DIRS[@]}"; do + DIR_CURRENT=$((DIR_CURRENT + 1)) + progress_bar $DIR_CURRENT $DIR_COUNT "创建 $dir" + mkdir -p "$dir" done -ok "依赖就绪" +echo -e "\n" +ok "数据目录已就绪" # ═══════════════════════════════════════════════════════════ -# 3. 确保 data 目录 +# 6. 检查 MySQL (可选) # ═══════════════════════════════════════════════════════════ -mkdir -p data/html-render data/web-toolkit data/plugin-storage data/DCIM data/pkg +step "检查数据库 (可选)" + +if command -v mysql &>/dev/null; then + ok "MySQL: $(mysql --version 2>&1)" + if pgrep mysqld > /dev/null 2>&1 || pgrep mariadbd > /dev/null 2>&1; then + ok "MySQL 服务运行中" + mysql -u root -e "CREATE DATABASE IF NOT EXISTS futureoss CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null && \ + ok "数据库 futureoss 已就绪" || \ + warn "无法创建数据库,请检查权限" + else + warn "MySQL 服务未运行" + info "启动命令: sudo systemctl start mysql (或 mariadb)" + fi +else + info "MySQL 未安装 (可选功能)" + info "安装: sudo apt install mysql-server (Debian/Ubuntu)" + info " sudo yum install mysql-server (CentOS/RHEL)" +fi # ═══════════════════════════════════════════════════════════ -# 4. 启动 +# 7. 启动服务 # ═══════════════════════════════════════════════════════════ -title "🚀 启动 FutureOSS" +step "启动 FutureOSS" if $DAEMON; then - title "🔒 守护模式" LOG_FILE="logs/futureoss.log" - mkdir -p logs PID_FILE="logs/futureoss.pid" if [[ -f "$PID_FILE" ]]; then OLD_PID=$(cat "$PID_FILE") if kill -0 "$OLD_PID" 2>/dev/null; then - warn "已有进程运行 (PID: $OLD_PID),正在停止..." - kill "$OLD_PID" 2>/dev/null || true - sleep 2 + warn "已有进程运行 (PID: $OLD_PID)" + info "停止: kill $OLD_PID 或 bash start.sh stop" + exit 0 fi fi nohup $PYTHON_CMD -m oss.cli serve > "$LOG_FILE" 2>&1 & NEW_PID=$! echo "$NEW_PID" > "$PID_FILE" - ok "已启动守护进程 (PID: $NEW_PID)" - info "日志: $LOG_FILE" - info "停止: kill $(cat $PID_FILE) 或 bash start.sh stop" + ok "守护进程已启动 (PID: $NEW_PID)" + info "日志文件: $LOG_FILE" sleep 2 curl -s http://localhost:8080/health &>/dev/null && ok "服务就绪: http://localhost:8080" || warn "服务启动中,请稍候..." exit 0 fi -# ── 前台模式 + 崩溃自动重启 ── +# 前台模式 + 崩溃自动重启 +echo -e "${WHITE}运行中... 按 Ctrl+C 停止${NC}" +echo "" + RESTART_DELAY=3 -MAX_RESTARTS=0 RESTART_COUNT=0 -run_server() { - $PYTHON_CMD -m oss.cli serve -} - while true; do - run_server + $PYTHON_CMD -m oss.cli serve EXIT_CODE=$? if [[ $EXIT_CODE -eq 0 ]]; then @@ -171,7 +313,7 @@ while true; do warn "服务异常退出 (code: $EXIT_CODE),${RESTART_DELAY}s 后重启... (第 $RESTART_COUNT 次)" sleep $RESTART_DELAY - # 指数退避,最大 30s + # 指数退避 if [[ $RESTART_DELAY -lt 30 ]]; then RESTART_DELAY=$((RESTART_DELAY * 2)) fi diff --git a/store/@{Falck}/html-render/SIGNATURE b/store/@{Falck}/html-render/SIGNATURE new file mode 100644 index 0000000..1fad2b7 --- /dev/null +++ b/store/@{Falck}/html-render/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "SizmRKKsPO3WuOYi+GtSOvKwZb5UrwRbSlJNJ26RF7l7811PLQlrBPJ7Awx1SUwy50TLrDpwtqbRIdCnGVqI9yzghBhdkwz7dpaAQ//lZK6SM9ygMMtS4ADJ839/AHTuB4USQM5FlqOwTIBE6QGAMgQw+w4di7Rpyh/6VD4Fg3GoiLJi7Pte0Upuglr4oIfZwpEt1liAi0ZlnE+Qb1GkmEGfQYyNYDYQkLKS0KG113YxqMj7sef9WcRCaKJSm+FZ8rV7dA0pCj1jY5sKOdXO/3PYH9g6O/BdgP0XuAoAUgGWshB0Z/D4WwHyykOIRM3jRHmU8kUB4PjxCzFVoDnkYfvN7wBojMjb0F9POjfbSv40jjC3EDjeDusbAP1FGv+F7QaJyAWhNUBSlRUBcHZZ8icSqRAStwX9MHsBVZa5EGrvHFK4SP8b6X6gm01+3JuKpiSRPGkxyDuxlFLNNDipmUNuHh1byofE/oD48yLNh7nGofVIvaDdOn6bhnc3ZDd54onncDNEBaWAHrLvly1nzkP5VN1bFEax/jZPWbSrcntmQ0Ua+11D0Ot/FVFhhrJo1dBBECM9zkVBUkpYAAf1RN7f9IglBVhi5iK+LmbGXzTSUX695tMvnufwXEJsH4fu3Jkom/PUkEggWNHEgb4qm4IsO2wzMWns+ZbZi3PzXP0=", + "signer": "Falck", + "algorithm": "RSA-SHA256", + "timestamp": 1775964953.1502125, + "plugin_hash": "84d69d65913b62d156e13a22e09dfcc3a5b36e052ae0532c569ced1fb269bb11", + "author": "Falck" +} \ No newline at end of file diff --git a/store/@{Falck}/html-render/__pycache__/main.cpython-313.pyc b/store/@{Falck}/html-render/__pycache__/main.cpython-313.pyc index a6fc9d1..7caa987 100644 Binary files a/store/@{Falck}/html-render/__pycache__/main.cpython-313.pyc and b/store/@{Falck}/html-render/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{Falck}/html-render/main.py b/store/@{Falck}/html-render/main.py index 5fa509e..175c284 100644 --- a/store/@{Falck}/html-render/main.py +++ b/store/@{Falck}/html-render/main.py @@ -1,9 +1,24 @@ """HTML 渲染服务 - 通过 config.json 配置,统一文件入口""" import json +import sys from pathlib import Path from oss.plugin.types import Plugin, register_plugin_type, Response +class _Log: + _TTY = sys.stdout.isatty() + _C = {"reset": "\033[0m", "white": "\033[0;37m", "yellow": "\033[1;33m", "blue": "\033[1;34m", "red": "\033[1;31m"} + @classmethod + def _c(cls, t, c): + return f"{cls._C.get(c,'')}{t}{cls._C['reset']}" if cls._TTY else t + @classmethod + def info(cls, m): print(f"{cls._c('[html-render]', 'white')} {cls._c(m, 'white')}") + @classmethod + def warn(cls, m): print(f"{cls._c('[html-render]', 'yellow')} {cls._c('⚠', 'yellow')} {cls._c(m, 'yellow')}") + @classmethod + def error(cls, m): print(f"{cls._c('[html-render]', 'red')} {cls._c('✗', 'red')} {cls._c(m, 'red')}") + + class HtmlRenderPlugin(Plugin): """HTML 渲染插件 - 渲染服务由 html-render 提供""" @@ -16,16 +31,16 @@ class HtmlRenderPlugin(Plugin): def init(self, deps: dict = None): """初始化 - 读取 config.json 并解析网站根目录""" self._load_config() - print(f"[html-render] 配置加载完成: root_dir={self.root_dir}") + _Log.info(f"配置加载完成: root_dir={self.root_dir}") def start(self): """启动 - 注册路由到 http-api,共享配置给 web-toolkit""" # 注册首页路由 if self.http_api and hasattr(self.http_api, 'router'): self.http_api.router.get("/", self._serve_html) - print("[html-render] 已注册路由到 http-api") + _Log.info("已注册路由到 http-api") else: - print("[html-render] http-api 未加载") + _Log.warn("http-api 未加载") # 将配置共享给 web-toolkit(通过 plugin-storage 的 DCIM 共享存储) if self.storage: @@ -35,7 +50,7 @@ class HtmlRenderPlugin(Plugin): "index_file": self.config.get("index_file", "index.html"), "static_prefix": self.config.get("static_prefix", "/static"), }) - print("[html-render] 配置已共享到 DCIM") + _Log.info("配置已共享到 DCIM") def stop(self): """停止""" @@ -53,7 +68,7 @@ class HtmlRenderPlugin(Plugin): """读取 config.json,解析根目录""" config_path = Path("./data/html-render/config.json") if not config_path.exists(): - print("[html-render] 警告: config.json 不存在,使用默认配置") + _Log.warn("config.json 不存在,使用默认配置") self.config = {"root_dir": "../website", "index_file": "index.html"} else: with open(config_path, "r", encoding="utf-8") as f: @@ -66,6 +81,11 @@ class HtmlRenderPlugin(Plugin): def _serve_html(self, request): """提供 HTML 页面 - 通过 plugin-storage 读取并注入静态资源路径""" index_file = self.config.get("index_file", "index.html") + + # 安全检查:防止路径穿越 + if ".." in index_file or index_file.startswith("/"): + return Response(status=403, body="Forbidden") + if self.storage: storage = self.storage.get_storage("html-render") if storage.file_exists(index_file): diff --git a/store/@{Falck}/web-toolkit/SIGNATURE b/store/@{Falck}/web-toolkit/SIGNATURE new file mode 100644 index 0000000..cfbfc3a --- /dev/null +++ b/store/@{Falck}/web-toolkit/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "GYBKpyVNgNFbpeoGlkXNY+wvt5wrJFHeP06At2h3SPsZUX3sXCtUL8RoidfzkqrfphBKAaKYvRnXaZdi3hyaDfXNQ88Ik18U+K7Usx+/o/rrQqzMKqh1pT75UZgZtJpXHu7CiIEjNIQ0pbujRHVfnRFe/4K3E2IClpJLcrziyrvn0fUBcUytt/WCTGBJ8pnyWB+ybcIDTJJQ+l4E69vsy2YmJHZBbBreyOo+TN5AQHDAlZ851dxI1K9euCNtdnlufbW6QSshnQ7DSS94KYZEUgTYFGON4Qi1RiVTFJK4iJEkTExEmohc3AuFJtEoIBBJzbUj/yCmfGcyWrbK7wchdwdGuNxGbexB97FONGm0WFS/z6OM08ljMJUAgvDRZtpInpQHFWJfxBfH+wzBx0AvhkgiJeeUApeofOxlggveOLDYDEH8P858sf0sjHHL0qgE17alvn0Fi8rArOI40wrh420SF7p4VlXE7fufXoue+yAhlSt68zaXOJHAtK5CuMh2ytVFKonRJgF5TAXvXYJeOZgujHyUUTtVqje+thIaBzqtGhEt9xp5N6Ikky2sutKRMgXx34As3hvx0U6a2CHuVykcX9neoB8XtJNlE1+AT24wnWw8LBqm6OjCTeJtAOFWFkliHNID9b1xfq69rZBp/L4Djj1bzy8WNLM7QLbjAvc=", + "signer": "Falck", + "algorithm": "RSA-SHA256", + "timestamp": 1775964953.1846428, + "plugin_hash": "eab1e047be16fe50b9c46f26570924f2975fac71a45af7f6c0b1f9c16ac8b096", + "author": "Falck" +} \ No newline at end of file diff --git a/store/@{Falck}/web-toolkit/__pycache__/main.cpython-313.pyc b/store/@{Falck}/web-toolkit/__pycache__/main.cpython-313.pyc index 4a20a4b..7914ff3 100644 Binary files a/store/@{Falck}/web-toolkit/__pycache__/main.cpython-313.pyc and b/store/@{Falck}/web-toolkit/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{Falck}/web-toolkit/__pycache__/router.cpython-313.pyc b/store/@{Falck}/web-toolkit/__pycache__/router.cpython-313.pyc index a02fe57..0a5484a 100644 Binary files a/store/@{Falck}/web-toolkit/__pycache__/router.cpython-313.pyc and b/store/@{Falck}/web-toolkit/__pycache__/router.cpython-313.pyc differ diff --git a/store/@{Falck}/web-toolkit/__pycache__/static.cpython-313.pyc b/store/@{Falck}/web-toolkit/__pycache__/static.cpython-313.pyc index 5ee43f7..ec28474 100644 Binary files a/store/@{Falck}/web-toolkit/__pycache__/static.cpython-313.pyc and b/store/@{Falck}/web-toolkit/__pycache__/static.cpython-313.pyc differ diff --git a/store/@{Falck}/web-toolkit/__pycache__/template.cpython-313.pyc b/store/@{Falck}/web-toolkit/__pycache__/template.cpython-313.pyc index 0dac3c0..75417d0 100644 Binary files a/store/@{Falck}/web-toolkit/__pycache__/template.cpython-313.pyc and b/store/@{Falck}/web-toolkit/__pycache__/template.cpython-313.pyc differ diff --git a/store/@{Falck}/web-toolkit/main.py b/store/@{Falck}/web-toolkit/main.py index c1ae7ff..20958dc 100644 --- a/store/@{Falck}/web-toolkit/main.py +++ b/store/@{Falck}/web-toolkit/main.py @@ -1,5 +1,6 @@ """Web 工具包 - 路由注册、静态文件服务、前端事件(不负责渲染)""" import json +import sys from pathlib import Path from oss.plugin.types import Plugin, register_plugin_type, Response from .router import WebRouter @@ -7,6 +8,20 @@ from .static import StaticFileHandler from .template import TemplateEngine +class _Log: + _TTY = sys.stdout.isatty() + _C = {"reset": "\033[0m", "white": "\033[0;37m", "yellow": "\033[1;33m", "blue": "\033[1;34m", "red": "\033[1;31m"} + @classmethod + def _c(cls, t, c): + return f"{cls._C.get(c,'')}{t}{cls._C['reset']}" if cls._TTY else t + @classmethod + def info(cls, m): print(f"{cls._c('[web-toolkit]', 'white')} {cls._c(m, 'white')}") + @classmethod + def warn(cls, m): print(f"{cls._c('[web-toolkit]', 'yellow')} {cls._c('⚠', 'yellow')} {cls._c(m, 'yellow')}") + @classmethod + def error(cls, m): print(f"{cls._c('[web-toolkit]', 'red')} {cls._c('✗', 'red')} {cls._c(m, 'red')}") + + class WebToolkitPlugin(Plugin): """Web 工具包插件 - 提供网站前端所有服务""" @@ -26,7 +41,7 @@ class WebToolkitPlugin(Plugin): self.template_engine = TemplateEngine() self._load_config() self.static_handler = StaticFileHandler(root=str(self.root_dir)) - print(f"[web-toolkit] 配置加载完成: root_dir={self.root_dir}") + _Log.info(f"配置加载完成: root_dir={self.root_dir}") def start(self): """启动""" @@ -65,7 +80,7 @@ class WebToolkitPlugin(Plugin): self._serve_static ) - print("[web-toolkit] Web 工具包已启动") + _Log.info("Web 工具包已启动") def stop(self): """停止""" @@ -97,7 +112,7 @@ class WebToolkitPlugin(Plugin): """读取 config.json,解析网站根目录""" config_path = Path("./data/web-toolkit/config.json") if not config_path.exists(): - print("[web-toolkit] 警告: config.json 不存在,使用默认配置") + _Log.warn("config.json 不存在,使用默认配置") self.config = { "root_dir": "../website", "index_file": "index.html", @@ -146,6 +161,10 @@ class WebToolkitPlugin(Plugin): else: filename = path.lstrip("/") + # 安全检查:防止路径穿越 + if ".." in filename or filename.startswith("/"): + return Response(status=403, body="Forbidden") + if not filename: return self._serve_website_index(request) return self.static_handler.serve(filename) diff --git a/store/@{Falck}/web-toolkit/template.py b/store/@{Falck}/web-toolkit/template.py index 55f2a39..b4dbea8 100644 --- a/store/@{Falck}/web-toolkit/template.py +++ b/store/@{Falck}/web-toolkit/template.py @@ -43,27 +43,74 @@ class TemplateEngine: return content def _safe_eval(self, expression: str, context: dict) -> Any: - """安全评估表达式(仅允许简单的属性访问和比较)""" - # 只允许访问 context 中的变量 - # 支持的运算符: and, or, not, ==, !=, <, >, <=, >=, in - # 不允许函数调用、导入、属性访问等 - - # 使用 AST 解析并验证 + """安全评估表达式(使用 AST 验证,不使用 eval)""" try: tree = ast.parse(expression, mode='eval') except SyntaxError: return False - + # 验证 AST 节点 if not self._validate_ast(tree.body[0].value, set(context.keys())): return False - - # 在受限环境中评估 + + # 使用安全的 AST 解释器,不使用 eval try: - return eval(expression, {"__builtins__": {}}, context) + return self._eval_ast(tree.body[0].value, context) except Exception: return False + def _eval_ast(self, node: ast.AST, context: dict) -> Any: + """安全地评估 AST 节点""" + if isinstance(node, ast.Constant): + return node.value + elif isinstance(node, ast.Name): + return context.get(node.id, False) + elif isinstance(node, ast.BoolOp): + if isinstance(node.op, ast.And): + return all(self._eval_ast(v, context) for v in node.values) + elif isinstance(node.op, ast.Or): + return any(self._eval_ast(v, context) for v in node.values) + elif isinstance(node, ast.Compare): + return self._eval_compare(node, context) + elif isinstance(node, ast.UnaryOp): + if isinstance(node.op, ast.Not): + return not self._eval_ast(node.operand, context) + elif isinstance(node, ast.Subscript): + return self._eval_subscript(node, context) + return False + + def _eval_compare(self, node: ast.Compare, context: dict) -> bool: + """评估比较表达式""" + left = self._eval_ast(node.left, context) + for op, comp in zip(node.ops, node.comparators): + right = self._eval_ast(comp, context) + if isinstance(op, ast.Eq): + if not (left == right): return False + elif isinstance(op, ast.NotEq): + if not (left != right): return False + elif isinstance(op, ast.Lt): + if not (left < right): return False + elif isinstance(op, ast.Gt): + if not (left > right): return False + elif isinstance(op, ast.LtE): + if not (left <= right): return False + elif isinstance(op, ast.GtE): + if not (left >= right): return False + elif isinstance(op, ast.In): + if not (left in right): return False + elif isinstance(op, ast.NotIn): + if not (left not in right): return False + left = right + return True + + def _eval_subscript(self, node: ast.Subscript, context: dict) -> Any: + """评估下标访问""" + value = self._eval_ast(node.value, context) + key = self._eval_ast(node.slice, context) + if isinstance(value, (dict, list, str)): + return value[key] + return None + def _validate_ast(self, node: ast.AST, allowed_names: set) -> bool: """验证 AST 只包含安全的操作""" if isinstance(node, ast.Name): diff --git a/store/@{FutureOSS}/circuit-breaker/README.md b/store/@{FutureOSS}/circuit-breaker/README.md deleted file mode 100644 index 91cccd9..0000000 --- a/store/@{FutureOSS}/circuit-breaker/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# circuit-breaker 熔断器 - -为插件提供熔断能力,防止级联失败。 - -## 功能 - -- 失败计数熔断 -- 状态:`closed` → `open` → `half-open` -- 可配置失败阈值 -- 自动恢复机制 - -## 状态机 - -``` -closed (正常) → open (熔断) → half-open (半开) → closed (恢复) -``` - -## 使用 - -```python -# 检查是否有熔断能力 -if "circuit_breaker" in capabilities: - breaker = extensions["_circuit_breaker_provider"] - cb = breaker.create("my-plugin", threshold=5) - - try: - result = cb.call(risky_function, arg1, arg2) - except Exception: - print("熔断器已触发") -``` diff --git a/store/@{FutureOSS}/circuit-breaker/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/circuit-breaker/__pycache__/main.cpython-313.pyc deleted file mode 100644 index 58714dc..0000000 Binary files a/store/@{FutureOSS}/circuit-breaker/__pycache__/main.cpython-313.pyc and /dev/null differ diff --git a/store/@{FutureOSS}/circuit-breaker/main.py b/store/@{FutureOSS}/circuit-breaker/main.py deleted file mode 100644 index d660651..0000000 --- a/store/@{FutureOSS}/circuit-breaker/main.py +++ /dev/null @@ -1,70 +0,0 @@ -"""熔断插件 - 为插件提供熔断能力""" -from oss.plugin.types import Plugin, register_plugin_type - - -class CircuitBreakerProvider: - """熔断能力提供者""" - - def __init__(self): - self.breakers: dict[str, "CircuitBreaker"] = {} - - def create(self, name: str, threshold: int = 5) -> "CircuitBreaker": - breaker = CircuitBreaker(name, threshold) - self.breakers[name] = breaker - return breaker - - def get(self, name: str): - return self.breakers.get(name) - - -class CircuitBreaker: - """熔断器""" - - def __init__(self, name: str, threshold: int = 5): - self.name = name - self.threshold = threshold - self.failures = 0 - self.state = "closed" # closed, open, half-open - - def call(self, func, *args, **kwargs): - if self.state == "open": - raise Exception(f"熔断器 '{self.name}' 已打开") - - try: - result = func(*args, **kwargs) - self.failures = 0 - self.state = "closed" - return result - except Exception as e: - self.failures += 1 - if self.failures >= self.threshold: - self.state = "open" - raise e - - -class CircuitBreakerPlugin(Plugin): - """熔断插件""" - - def __init__(self): - self.provider = CircuitBreakerProvider() - - def init(self, deps: dict = None): - pass - - def start(self): - pass - - def stop(self): - pass - - def get_provider(self): - return self.provider - - -# 注册类型 -register_plugin_type("CircuitBreakerProvider", CircuitBreakerProvider) -register_plugin_type("CircuitBreaker", CircuitBreaker) - - -def New(): - return CircuitBreakerPlugin() diff --git a/store/@{FutureOSS}/circuit-breaker/manifest.json b/store/@{FutureOSS}/circuit-breaker/manifest.json deleted file mode 100644 index 324bc58..0000000 --- a/store/@{FutureOSS}/circuit-breaker/manifest.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "metadata": { - "name": "circuit-breaker", - "version": "1.0.0", - "author": "FutureOSS", - "description": "熔断器 - 为插件提供熔断能力", - "type": "extension" - }, - "config": { - "enabled": true, - "args": { - "default_threshold": 5 - } - }, - "dependencies": [], - "permissions": [] -} diff --git a/store/@{FutureOSS}/code-reviewer.disabled/SIGNATURE b/store/@{FutureOSS}/code-reviewer.disabled/SIGNATURE new file mode 100644 index 0000000..2f3fdbb --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "BRVmR6gX5do7yBsBCtR9jk5/YoE6igio8d3IVNxAtwAtkBdS2Z3LNv9VwMBXeqOE84Dz1+/ypkQO+rdh9VZpGOpAPGxjCyArff9oS3nW6gazMZdLfMKrtsHxVBAL4Ycjb1NmQ3W0kdZa/aS+r2Q/tqVMJ62bqVR5Lbrc2H8eG/i1gPZsEu5tA7KC9pB8oDfaAY/QxeDczg32zWqh9UDD59Hp7TQMZhsWXsH9FgfvKjYKjcsQUEXs6ijUJ6PxHuc2Jx71xhD/IXseOTmnDCMe+8JdPA5aaVN/TEgmT99RXv62wHR+tulyaCYRd/P3sTItSSb1UYfLqEGBumetNAAGdgf33DMijUHKvufuha0JNOm6CCk+8UGbnYnG79HyaBz+pWfiF/pFX+LV7HTJTkBwQc3vXcvXep25UDspSkL+x2w3f1mk9S/oA5mT2go4kSaORxkCb1fAbh74Bn51VRmQV8XLSUOoZvWHjiaMkMdLsyPyTi2+fxqrDD7ehgeQBp3cNSoiGViqYcFcg2xCuHo2P/W441cZMOscfawdLJxg3N4+UC41LTooXN1+IBWzG7jrGTLyeXAFxGeOBo165WoAnsQZ9hh+uj/plv+LIU/mmOBSpJZIb4SuVJfoEcIDGpa7iieVr//8cTnbNTt9zh3GWYuW1NPIm+/WT4YoPfeAs/M=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964953.1082504, + "plugin_hash": "8894b78ac59c0154acaeb9a976f80588ece406e55079ca633c3b2bd839098d40", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/code-reviewer.disabled/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..a869280 Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/__pycache__/main.cpython-313.pyc differ diff --git a/website/blog/assets/placeholder.jpg b/store/@{FutureOSS}/code-reviewer.disabled/checks/__init__.py similarity index 100% rename from website/blog/assets/placeholder.jpg rename to store/@{FutureOSS}/code-reviewer.disabled/checks/__init__.py diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..4da314b Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/quality.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/quality.cpython-313.pyc new file mode 100644 index 0000000..74e45e5 Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/quality.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/references.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/references.cpython-313.pyc new file mode 100644 index 0000000..87afdd6 Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/references.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/security.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/security.cpython-313.pyc new file mode 100644 index 0000000..e4a4b60 Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/security.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/style.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/style.cpython-313.pyc new file mode 100644 index 0000000..34d140e Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/checks/__pycache__/style.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/quality.py b/store/@{FutureOSS}/code-reviewer.disabled/checks/quality.py new file mode 100644 index 0000000..e4f9731 --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/checks/quality.py @@ -0,0 +1,100 @@ +"""质量检查器""" +import ast + + +class QualityChecker: + """质量检查器""" + + def check(self, filepath: str, content: str) -> list: + """执行质量检查""" + issues = [] + + # 检查函数长度 + issues.extend(self._check_function_length(filepath, content)) + + # 检查参数数量 + issues.extend(self._check_parameter_count(filepath, content)) + + # 检查复杂度 + issues.extend(self._check_complexity(filepath, content)) + + return issues + + def _check_function_length(self, filepath: str, content: str) -> list: + """检查函数长度""" + issues = [] + + try: + tree = ast.parse(content) + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef): + lines = node.end_lineno - node.lineno + if lines > 100: + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "warning", + "type": "long_function", + "message": f"函数 {node.name} 过长 ({lines} 行)" + }) + except: + pass + + return issues + + def _check_parameter_count(self, filepath: str, content: str) -> list: + """检查参数数量""" + issues = [] + + try: + tree = ast.parse(content) + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef): + args = node.args + count = len(args.args) + if count > 5: + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "info", + "type": "too_many_params", + "message": f"函数 {node.name} 参数过多 ({count} 个)" + }) + except: + pass + + return issues + + def _check_complexity(self, filepath: str, content: str) -> list: + """检查圈复杂度""" + issues = [] + + try: + tree = ast.parse(content) + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef): + complexity = self._calculate_complexity(node) + if complexity > 10: + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "warning", + "type": "high_complexity", + "message": f"函数 {node.name} 复杂度过高 (圈复杂度: {complexity})" + }) + except: + pass + + return issues + + def _calculate_complexity(self, node: ast.AST) -> int: + """计算圈复杂度""" + complexity = 1 + + for child in ast.walk(node): + if isinstance(child, (ast.If, ast.While, ast.For, ast.Try, ast.With)): + complexity += 1 + elif isinstance(child, ast.BoolOp): + complexity += len(child.values) - 1 + + return complexity diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/references.py b/store/@{FutureOSS}/code-reviewer.disabled/checks/references.py new file mode 100644 index 0000000..cc9edfb --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/checks/references.py @@ -0,0 +1,323 @@ +"""引用检查器 - 检测导入错误、变量错误等""" +import ast +import sys +import os +from pathlib import Path + + +class ReferenceChecker: + """引用检查器""" + + # Python 标准库模块列表 + STD_MODULES = { + 'os', 'sys', 'json', 're', 'time', 'datetime', 'pathlib', + 'typing', 'collections', 'functools', 'itertools', 'io', + 'string', 'math', 'random', 'hashlib', 'hmac', 'secrets', + 'urllib', 'http', 'email', 'html', 'xml', 'csv', 'configparser', + 'logging', 'warnings', 'traceback', 'inspect', 'importlib', + 'threading', 'multiprocessing', 'subprocess', 'socket', + 'asyncio', 'concurrent', 'queue', 'contextlib', 'abc', + 'enum', 'dataclasses', 'copy', 'pprint', 'textwrap', + 'struct', 'codecs', 'locale', 'gettext', 'argparse', + 'unittest', 'doctest', 'pdb', 'profile', 'timeit', + 'tempfile', 'glob', 'fnmatch', 'stat', 'fileinput', + 'shutil', 'pickle', 'shelve', 'sqlite3', 'dbm', + 'gzip', 'bz2', 'lzma', 'zipfile', 'tarfile', + 'base64', 'binascii', 'quopri', 'uu', + } + + # Python 内置函数和类型(不应报告为未定义) + BUILTINS = { + 'print', 'len', 'str', 'int', 'float', 'bool', 'list', 'dict', + 'set', 'tuple', 'range', 'enumerate', 'zip', 'map', 'filter', + 'sorted', 'reversed', 'min', 'max', 'sum', 'abs', 'round', + 'isinstance', 'issubclass', 'type', 'id', 'hash', 'repr', + 'True', 'False', 'None', 'Exception', 'ValueError', 'TypeError', + 'KeyError', 'AttributeError', 'ImportError', 'FileNotFoundError', + 'IndexError', 'RuntimeError', 'StopIteration', 'GeneratorExit', + 'staticmethod', 'classmethod', 'property', 'super', + 'open', 'input', 'format', 'hex', 'oct', 'bin', 'chr', 'ord', + 'dir', 'vars', 'locals', 'globals', 'callable', 'getattr', + 'setattr', 'hasattr', 'delattr', 'exec', 'eval', 'compile', + 'any', 'all', 'slice', 'frozenset', 'bytearray', 'bytes', + 'memoryview', 'complex', 'divmod', 'pow', 'object', + 'dict', 'list', 'str', 'int', 'float', 'bool', 'set', + 'tuple', 'Exception', 'ValueError', 'TypeError', 'KeyError', + 'self', 'cls', 'args', 'kwargs', + } + + def __init__(self, project_root: str = "."): + self.project_root = Path(project_root) + self._available_modules = set(self.STD_MODULES) + self._scan_project_modules() + + def _scan_project_modules(self): + """扫描项目中的可用模块""" + # 扫描 oss 目录(框架核心) + oss_dir = self.project_root / "oss" + if oss_dir.exists(): + self._available_modules.add("oss") + self._scan_module_dir(oss_dir, "oss") + + # 扫描 store 目录下的所有插件 + store_dir = self.project_root / "store" + if store_dir.exists(): + for author_dir in store_dir.iterdir(): + if not author_dir.is_dir(): + continue + for plugin_dir in author_dir.iterdir(): + if not plugin_dir.is_dir(): + continue + plugin_name = plugin_dir.name + # 添加插件名作为可用模块 + self._available_modules.add(plugin_name) + # 扫描插件内部的子模块 + self._scan_plugin_modules(plugin_dir, plugin_name) + + def _scan_module_dir(self, dir_path: Path, base_name: str): + """扫描模块目录""" + if dir_path.exists(): + for item in dir_path.iterdir(): + if item.is_file() and item.name.endswith(".py") and item.name != "__init__.py": + module_name = item.name[:-3] + full_name = f"{base_name}.{module_name}" + self._available_modules.add(full_name) + elif item.is_dir() and (item / "__init__.py").exists(): + full_name = f"{base_name}.{item.name}" + self._available_modules.add(full_name) + self._scan_module_dir(item, full_name) + + def _scan_plugin_modules(self, plugin_dir: Path, base_name: str): + """扫描插件内部的子模块""" + for item in plugin_dir.iterdir(): + if item.is_dir() and (item / "__init__.py").exists(): + full_name = f"{base_name}.{item.name}" + self._available_modules.add(full_name) + self._scan_module_dir(item, full_name) + elif item.is_file() and item.name.endswith(".py") and item.name != "__init__.py": + module_name = item.name[:-3] + full_name = f"{base_name}.{module_name}" + self._available_modules.add(full_name) + + def _add_module_from_dir(self, dir_path: Path, base_name: str): + """从目录添加模块""" + if dir_path.exists(): + for item in dir_path.iterdir(): + if item.is_file() and item.name.endswith(".py") and item.name != "__init__.py": + module_name = item.name[:-3] + self._available_modules.add(f"{base_name}.{module_name}") + elif item.is_dir() and (item / "__init__.py").exists(): + self._add_module_from_dir(item, f"{base_name}.{item.name}") + + def check(self, filepath: str, content: str) -> list: + """执行引用检查""" + issues = [] + + try: + tree = ast.parse(content) + except SyntaxError as e: + return [{ + "file": filepath, + "line": e.lineno or 0, + "severity": "critical", + "type": "syntax_error", + "message": f"语法错误: {e.msg}" + }] + + # 检查导入语句(跳过相对导入) + issues.extend(self._check_imports(filepath, tree)) + + # 检查属性访问错误 + issues.extend(self._check_attribute_access(filepath, tree, content)) + + # 检查函数调用错误 + issues.extend(self._check_function_calls(filepath, tree, content)) + + return issues + + def _check_imports(self, filepath: str, tree: ast.AST) -> list: + """检查导入语句""" + issues = [] + file_path = Path(filepath) + + for node in ast.walk(tree): + if isinstance(node, ast.Import): + for alias in node.names: + # 跳过 oss 框架模块(运行时可用) + if alias.name.startswith('oss.') or alias.name == 'oss': + continue + # 跳过 websockets 等第三方库 + if alias.name in ('websockets', 'yaml', 'click'): + continue + if not self._is_module_available(alias.name, file_path): + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "critical", + "type": "import_error", + "message": f"无法导入模块: {alias.name}" + }) + + elif isinstance(node, ast.ImportFrom): + # 跳过相对导入(以 . 开头) + if node.level and node.level > 0: + continue + + # 跳过 oss 框架模块 + if node.module and (node.module.startswith('oss.') or node.module == 'oss'): + continue + + # 跳过第三方库 + if node.module and node.module.split('.')[0] in ('websockets', 'yaml', 'click'): + continue + + if node.module: + if not self._is_module_available(node.module, file_path): + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "critical", + "type": "import_error", + "message": f"无法导入模块: {node.module}" + }) + + return issues + + def _check_variable_references(self, filepath: str, tree: ast.AST, content: str) -> list: + """检查变量引用""" + issues = [] + lines = content.split('\n') + + for node in ast.walk(tree): + if isinstance(node, ast.Name) and isinstance(node.ctx, ast.Load): + # 检查是否引用了未定义的变量 + if not self._is_name_defined(node.id, tree, node.lineno): + if node.id not in ('True', 'False', 'None', 'self', 'cls'): + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "warning", + "type": "undefined_variable", + "message": f"使用了未定义的变量: {node.id}" + }) + + return issues + + def _check_attribute_access(self, filepath: str, tree: ast.AST, content: str) -> list: + """检查属性访问""" + issues = [] + + for node in ast.walk(tree): + if isinstance(node, ast.Attribute): + # 检查可能的属性错误 + if isinstance(node.value, ast.Name): + var_name = node.value.id + if var_name in ('None', 'True', 'False'): + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "critical", + "type": "attribute_error", + "message": f"尝试访问 {var_name} 的属性: {node.attr}" + }) + + return issues + + def _check_function_calls(self, filepath: str, tree: ast.AST, content: str) -> list: + """检查函数调用""" + issues = [] + + for node in ast.walk(tree): + if isinstance(node, ast.Call): + # 检查调用不存在的方法 + if isinstance(node.func, ast.Attribute): + if isinstance(node.func.value, ast.Constant) and node.func.value.value is None: + issues.append({ + "file": filepath, + "line": node.lineno, + "severity": "critical", + "type": "method_call_on_none", + "message": f"在 None 上调用方法: {node.func.attr}" + }) + + return issues + + def _is_module_available(self, module_name: str, file_path: Path = None) -> bool: + """检查模块是否可用""" + # 检查是否在已扫描的模块中 + if module_name in self._available_modules: + return True + + # 检查标准库 + base_module = module_name.split('.')[0] + if base_module in self.STD_MODULES: + return True + + # 检查是否是 oss 框架模块 + if module_name.startswith('oss.') or module_name == 'oss': + return True + + # 检查是否是常见第三方库 + third_party = {'websockets', 'yaml', 'click', 'requests', 'flask', 'django', 'numpy', 'pandas'} + if module_name.split('.')[0] in third_party: + return True + + # 检查是否是当前文件的同目录模块(相对导入的情况) + if file_path: + file_dir = file_path.parent + # 检查同级 .py 文件 + sibling_module = file_dir / f"{module_name}.py" + if sibling_module.exists(): + return True + # 检查同级包 + sibling_pkg = file_dir / module_name + if sibling_pkg.is_dir() and (sibling_pkg / "__init__.py").exists(): + return True + # 检查 store 目录下的插件 + store_dir = self.project_root / "store" + if store_dir.exists(): + for author_dir in store_dir.iterdir(): + if author_dir.is_dir(): + for plugin_dir in author_dir.iterdir(): + if plugin_dir.is_dir() and plugin_dir.name == module_name.split('.')[0]: + return True + + return False + + def _is_name_defined(self, name: str, tree: ast.AST, line: int) -> bool: + """检查名称是否已定义""" + # 检查是否是内置函数/类型 + if name in self.BUILTINS: + return True + + # 检查是否是函数参数 + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef): + for arg in node.args.args: + if arg.arg == name: + return True + + # 检查是否是赋值目标 + elif isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == name: + return True + + # 检查是否是循环变量 + elif isinstance(node, ast.For): + if isinstance(node.target, ast.Name) and node.target.id == name: + return True + + # 检查是否是导入 + elif isinstance(node, ast.Import): + for alias in node.names: + if alias.asname == name or alias.name == name: + return True + + elif isinstance(node, ast.ImportFrom): + if node.module: + for alias in node.names: + if alias.asname == name or alias.name == name: + return True + + return False diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/security.py b/store/@{FutureOSS}/code-reviewer.disabled/checks/security.py new file mode 100644 index 0000000..9936b85 --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/checks/security.py @@ -0,0 +1,85 @@ +"""安全检查器""" + + +class SecurityChecker: + """安全检查器""" + + def check(self, filepath: str, content: str) -> list: + """执行安全检查""" + issues = [] + + # 检查硬编码密钥 + issues.extend(self._check_secrets(filepath, content)) + + # 检查危险函数 + issues.extend(self._check_dangerous_functions(filepath, content)) + + # 检查路径穿越 + issues.extend(self._check_path_traversal(filepath, content)) + + return issues + + def _check_secrets(self, filepath: str, content: str) -> list: + """检查硬编码密钥""" + issues = [] + patterns = ['password', 'secret', 'token', 'api_key', 'access_token'] + + for i, line in enumerate(content.split('\n'), 1): + stripped = line.strip() + # 跳过注释和模式定义行 + if stripped.startswith('#') or stripped.startswith('patterns') or "'" in stripped[:20]: + continue + + for pattern in patterns: + if pattern + ' = "' in line.lower() or pattern + " = '" in line.lower(): + issues.append({ + "file": filepath, + "line": i, + "severity": "critical", + "type": "hardcoded_secret", + "message": f"发现硬编码密钥: {line.strip()[:50]}" + }) + + return issues + + def _check_dangerous_functions(self, filepath: str, content: str) -> list: + """检查危险函数""" + issues = [] + dangerous = ['eval(', 'exec(', 'os.system(', 'subprocess.call(', 'subprocess.run('] + + # 跳过检查安全检查器自身 + if 'code-reviewer/checks/security.py' in filepath: + return [] + + for i, line in enumerate(content.split('\n'), 1): + # 跳过注释和模式定义行 + stripped = line.strip() + if stripped.startswith('#') or 'dangerous' in stripped.lower() or "['" in stripped[:30]: + continue + + for func in dangerous: + if func in line: + issues.append({ + "file": filepath, + "line": i, + "severity": "warning", + "type": "dangerous_function", + "message": f"使用危险函数: {func.strip()}" + }) + + return issues + + def _check_path_traversal(self, filepath: str, content: str) -> list: + """检查路径穿越风险""" + issues = [] + + if '../' in content and 'open(' in content: + issues.append({ + "file": filepath, + "line": 0, + "severity": "warning", + "type": "path_traversal_risk", + "message": "可能存在路径穿越漏洞" + }) + + return issues diff --git a/store/@{FutureOSS}/code-reviewer.disabled/checks/style.py b/store/@{FutureOSS}/code-reviewer.disabled/checks/style.py new file mode 100644 index 0000000..abf01ca --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/checks/style.py @@ -0,0 +1,70 @@ +"""风格检查器""" + + +class StyleChecker: + """风格检查器""" + + def check(self, filepath: str, content: str) -> list: + """执行风格检查""" + issues = [] + + # 检查行长度 + issues.extend(self._check_line_length(filepath, content)) + + # 检查空行 + issues.extend(self._check_blank_lines(filepath, content)) + + # 检查文件末尾换行 + issues.extend(self._check_final_newline(filepath, content)) + + return issues + + def _check_line_length(self, filepath: str, content: str) -> list: + """检查行长度""" + issues = [] + + for i, line in enumerate(content.split('\n'), 1): + if len(line) > 120: + issues.append({ + "file": filepath, + "line": i, + "severity": "info", + "type": "line_too_long", + "message": f"行过长 ({len(line)} 字符)" + }) + + return issues + + def _check_blank_lines(self, filepath: str, content: str) -> list: + """检查连续空行""" + issues = [] + blank_count = 0 + + for i, line in enumerate(content.split('\n'), 1): + if line.strip() == '': + blank_count += 1 + if blank_count > 2: + issues.append({ + "file": filepath, + "line": i, + "severity": "info", + "type": "too_many_blanks", + "message": "连续空行过多" + }) + else: + blank_count = 0 + + return issues + + def _check_final_newline(self, filepath: str, content: str) -> list: + """检查文件末尾换行""" + if content and not content.endswith('\n'): + return [{ + "file": filepath, + "line": len(content.split('\n')), + "severity": "info", + "type": "missing_final_newline", + "message": "文件末尾缺少换行符" + }] + + return [] diff --git a/store/@{FutureOSS}/code-reviewer.disabled/core/__init__.py b/store/@{FutureOSS}/code-reviewer.disabled/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/code-reviewer.disabled/core/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/core/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..c7265ac Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/core/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/core/__pycache__/reviewer.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/core/__pycache__/reviewer.cpython-313.pyc new file mode 100644 index 0000000..e1a0b32 Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/core/__pycache__/reviewer.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/core/reviewer.py b/store/@{FutureOSS}/code-reviewer.disabled/core/reviewer.py new file mode 100644 index 0000000..7e1f652 --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/core/reviewer.py @@ -0,0 +1,94 @@ +"""代码审查器核心""" +import os +import ast +import json +import time +from pathlib import Path +from typing import Any +from checks.security import SecurityChecker +from checks.quality import QualityChecker +from checks.style import StyleChecker +from checks.references import ReferenceChecker +from report.formatter import ReportFormatter + + +class CodeReviewer: + """代码审查器""" + + def __init__(self, config: dict): + self.config = config + self.security = SecurityChecker() + self.quality = QualityChecker() + self.style = StyleChecker() + self.references = ReferenceChecker() + self.formatter = ReportFormatter(config.get("report_format", "console")) + + def run_check(self, scan_dirs: list) -> dict: + """执行检查""" + start_time = time.time() + issues = [] + files_scanned = 0 + + for scan_dir in scan_dirs: + if not os.path.exists(scan_dir): + continue + + for root, dirs, files in os.walk(scan_dir): + # 排除目录 + dirs[:] = [d for d in dirs if d not in self.config.get("exclude_patterns", [])] + + for file in files: + if file.endswith('.py'): + filepath = os.path.join(root, file) + file_size = os.path.getsize(filepath) + + if file_size > self.config.get("max_file_size", 102400): + continue + + issues.extend(self._check_file(filepath)) + files_scanned += 1 + + elapsed = time.time() - start_time + + result = { + "status": "completed", + "files_scanned": files_scanned, + "total_issues": len(issues), + "issues": issues, + "scan_time": round(elapsed, 2), + "timestamp": time.time() + } + + print(self.formatter.format(result)) + return result + + def _check_file(self, filepath: str) -> list: + """检查单个文件""" + issues = [] + + try: + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + + # 安全检查 + issues.extend(self.security.check(filepath, content)) + + # 质量检查 + issues.extend(self.quality.check(filepath, content)) + + # 风格检查 + issues.extend(self.style.check(filepath, content)) + + # 引用检查(新增) + issues.extend(self.references.check(filepath, content)) + + except Exception as e: + issues.append({ + "file": filepath, + "line": 0, + "severity": "error", + "type": "parse_error", + "message": f"文件解析失败: {e}" + }) + + return issues diff --git a/store/@{FutureOSS}/code-reviewer.disabled/main.py b/store/@{FutureOSS}/code-reviewer.disabled/main.py new file mode 100644 index 0000000..a59f822 --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/main.py @@ -0,0 +1,70 @@ +"""代码审查器插件""" +import sys +import os +sys.path.insert(0, os.path.dirname(__file__)) + +from oss.logger.logger import Log +from oss.plugin.types import Plugin, register_plugin_type +from core.reviewer import CodeReviewer + + +class CodeReviewerPlugin(Plugin): + """代码审查器插件""" + + def __init__(self): + self.reviewer = None + self.config = {} + + def meta(self): + from oss.plugin.types import Metadata, PluginConfig, Manifest + return Manifest( + metadata=Metadata( + name="code-reviewer", + version="1.0.0", + author="FutureOSS", + description="代码审查器 - 自动扫描代码问题" + ), + config=PluginConfig( + enabled=True, + args={ + "scan_dirs": ["store", "oss"], + "exclude_patterns": ["__pycache__", "*.pyc"], + "max_file_size": 102400, + "report_format": "console" + } + ), + dependencies=[] + ) + + def init(self, deps: dict = None): + config = {} + if deps: + config = deps.get("config", {}) + + self.config = { + "scan_dirs": config.get("scan_dirs", ["store", "oss"]), + "exclude_patterns": config.get("exclude_patterns", ["__pycache__"]), + "max_file_size": config.get("max_file_size", 102400), + "report_format": config.get("report_format", "console") + } + + self.reviewer = CodeReviewer(self.config) + Log.info("code-reviewer", "初始化完成") + + def start(self): + Log.info("code-reviewer", "插件已启动") + + def stop(self): + Log.error("code-reviewer", "插件已停止") + + def check(self, dirs: list = None) -> dict: + """执行代码检查""" + scan_dirs = dirs or self.config["scan_dirs"] + return self.reviewer.run_check(scan_dirs) + + +register_plugin_type("CodeReviewerPlugin", CodeReviewerPlugin) + + +def New(): + return CodeReviewerPlugin() diff --git a/store/@{FutureOSS}/code-reviewer.disabled/manifest.json b/store/@{FutureOSS}/code-reviewer.disabled/manifest.json new file mode 100644 index 0000000..a0051dd --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/manifest.json @@ -0,0 +1,20 @@ +{ + "metadata": { + "name": "code-reviewer", + "version": "1.0.0", + "author": "FutureOSS", + "description": "代码审查器 - 提供 oss check 功能,自动扫描代码问题", + "type": "tool" + }, + "config": { + "enabled": true, + "args": { + "scan_dirs": ["store", "oss"], + "exclude_patterns": ["__pycache__", "*.pyc", "*.pyo"], + "max_file_size": 102400, + "report_format": "console" + } + }, + "dependencies": [], + "permissions": ["*"] +} diff --git a/store/@{FutureOSS}/code-reviewer.disabled/report/__init__.py b/store/@{FutureOSS}/code-reviewer.disabled/report/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/code-reviewer.disabled/report/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/report/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..8b9be99 Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/report/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/report/__pycache__/formatter.cpython-313.pyc b/store/@{FutureOSS}/code-reviewer.disabled/report/__pycache__/formatter.cpython-313.pyc new file mode 100644 index 0000000..252d63b Binary files /dev/null and b/store/@{FutureOSS}/code-reviewer.disabled/report/__pycache__/formatter.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/code-reviewer.disabled/report/formatter.py b/store/@{FutureOSS}/code-reviewer.disabled/report/formatter.py new file mode 100644 index 0000000..7da25b1 --- /dev/null +++ b/store/@{FutureOSS}/code-reviewer.disabled/report/formatter.py @@ -0,0 +1,59 @@ +"""报告格式化器""" + + +class ReportFormatter: + """报告格式化器""" + + def __init__(self, format_type: str = "console"): + self.format_type = format_type + + def format(self, result: dict) -> str: + """格式化报告""" + if self.format_type == "console": + return self._format_console(result) + elif self.format_type == "json": + return self._format_json(result) + return str(result) + + def _format_console(self, result: dict) -> str: + """控制台格式""" + lines = [] + lines.append("=" * 60) + lines.append("代码审查报告") + lines.append("=" * 60) + lines.append(f"扫描文件: {result['files_scanned']}") + lines.append(f"发现问题: {result['total_issues']}") + lines.append(f"扫描时间: {result['scan_time']}s") + lines.append("") + + # 按严重程度分类 + critical = [i for i in result['issues'] if i['severity'] == 'critical'] + warning = [i for i in result['issues'] if i['severity'] == 'warning'] + info = [i for i in result['issues'] if i['severity'] == 'info'] + + lines.append(f"🔴 严重: {len(critical)}") + lines.append(f"🟡 警告: {len(warning)}") + lines.append(f"🔵 提示: {len(info)}") + lines.append("") + + if critical: + lines.append("严重问题:") + for issue in critical: + lines.append(f" - {issue['file']}:{issue['line']} - {issue['message']}") + lines.append("") + + if warning: + lines.append("警告:") + for issue in warning[:10]: # 最多显示10个 + lines.append(f" - {issue['file']}:{issue['line']} - {issue['message']}") + if len(warning) > 10: + lines.append(f" ... 还有 {len(warning) - 10} 个警告") + lines.append("") + + lines.append("=" * 60) + return '\n'.join(lines) + + def _format_json(self, result: dict) -> str: + """JSON 格式""" + import json + return json.dumps(result, indent=2, ensure_ascii=False) diff --git a/store/@{FutureOSS}/code-reviewer.disabled/utils/__init__.py b/store/@{FutureOSS}/code-reviewer.disabled/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/dashboard/SIGNATURE b/store/@{FutureOSS}/dashboard/SIGNATURE new file mode 100644 index 0000000..bdd2475 --- /dev/null +++ b/store/@{FutureOSS}/dashboard/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "vn4hpZQMQTX0d78Wlze2wtTHjN91qn1PIvsRTK7ZFVm8lZ3eQHrZz9X0uDWcKKjxf5FCI/UVKQOqLwYkHiGhcS7d7+v6UKKKIYph+aftHQRrEcOQtrSnrmDQrqSjEdL3mjkl0KTIwqkFySxVNn9ssmL16JCOtWpWpKU5CnKWVrbeEKvs6yZJrmVVr9C7iDGsNq0/aS3oPDI4vg1iaTYgg/2Sh1smJ0jNtE5EsCq78fcyUcSWTziwq8RnJvFsx8LP3cxacC1QuZIP3hTIrpnApAj0KqSTRDLKY7d7rsQAHgDlnbQfYVtA8x94x91R5ybeDpXwYPSwWMpb7P/7XBDJ5GKL56iFUCV0tceHNK9yyjaXdhf2oUTxfoC4ONOTnkmnP2pZ6vRLjd/0WX7qA0XUTmZtewWur1BnZeZwzOjI5K8IYCda5WKXLVyrH64XmBEAwkEu18LIO9xI+DnhbM7rR9/xO+cXHkOYtKgAJMHCzgi6o6tw/UgS9K0myoMeGg58gYaDIVbXpxpf3rHSyFQAwauI67oye7ZxNxJgKnnOtX92cpQLHDfML8psd+sAIuBazxqxe484qzF2k0F5ZZMP17V6Yd3UWUkvWMoKlktq14OwJ2Q67nrmt9OC+9Epzny4gkq/Q7ih85rGwMVxRvkKhxxLLelQLVIni363yOxn7UE=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775967256.7737296, + "plugin_hash": "68f5ab432690beef86da1c167c704fdd6b60512a359e806516dce1c6be27b9c5", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/dashboard/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/dashboard/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..ec210cf Binary files /dev/null and b/store/@{FutureOSS}/dashboard/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/dashboard/assets/css/dashboard.css b/store/@{FutureOSS}/dashboard/assets/css/dashboard.css new file mode 100644 index 0000000..211a4da --- /dev/null +++ b/store/@{FutureOSS}/dashboard/assets/css/dashboard.css @@ -0,0 +1,91 @@ +/* Dashboard 仪表盘样式 */ + +.dashboard { + padding: 20px; +} + +.dashboard-header { + margin-bottom: 30px; +} + +.dashboard-header h2 { + font-size: 28px; + margin-bottom: 8px; +} + +.dashboard-subtitle { + color: #666; + font-size: 14px; +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 20px; + margin-bottom: 30px; +} + +.stat-card { + background: white; + border-radius: 12px; + padding: 24px; + box-shadow: 0 2px 8px rgba(0,0,0,0.08); + display: flex; + align-items: center; + gap: 16px; +} + +.stat-icon { + font-size: 40px; +} + +.stat-info { + flex: 1; +} + +.stat-value { + font-size: 32px; + font-weight: 600; + color: #1a1a2e; +} + +.stat-label { + font-size: 13px; + color: #666; + margin-top: 4px; +} + +.dashboard-section { + background: white; + border-radius: 12px; + padding: 24px; + box-shadow: 0 2px 8px rgba(0,0,0,0.08); +} + +.dashboard-section h3 { + font-size: 20px; + margin-bottom: 20px; + color: #1a1a2e; +} + +.info-table { + display: grid; + gap: 16px; +} + +.info-row { + display: flex; + justify-content: space-between; + padding: 12px 16px; + background: #f8f9fa; + border-radius: 8px; +} + +.info-label { + font-weight: 500; + color: #333; +} + +.info-value { + color: #666; +} diff --git a/store/@{FutureOSS}/dashboard/config.json b/store/@{FutureOSS}/dashboard/config.json new file mode 100644 index 0000000..30f6d2d --- /dev/null +++ b/store/@{FutureOSS}/dashboard/config.json @@ -0,0 +1,28 @@ +{ + "refreshInterval": { + "type": "number", + "name": "刷新间隔", + "description": "仪表盘数据自动刷新的间隔时间(秒)", + "default": 2, + "min": 1, + "max": 60, + "order": 1 + }, + "showDisk": { + "type": "boolean", + "name": "显示磁盘", + "description": "是否在仪表盘显示磁盘使用率", + "default": true, + "order": 2 + }, + "diskThreshold": { + "type": "number", + "name": "磁盘警告阈值", + "description": "磁盘使用率超过此值时显示警告颜色", + "default": 80, + "min": 50, + "max": 95, + "show_when": { "field": "showDisk", "value": true }, + "order": 3 + } +} diff --git a/store/@{FutureOSS}/dashboard/main.py b/store/@{FutureOSS}/dashboard/main.py new file mode 100644 index 0000000..979b0de --- /dev/null +++ b/store/@{FutureOSS}/dashboard/main.py @@ -0,0 +1,332 @@ +"""Dashboard 仪表盘插件""" +import os +import time +import json +import socket +import subprocess +import platform +import psutil +from collections import deque +from oss.logger.logger import Log +from oss.plugin.types import Plugin, Response, register_plugin_type + + +class DashboardPlugin(Plugin): + """仪表盘插件 - 依赖 WebUI 容器""" + + def __init__(self): + self.webui = None + self.views_dir = os.path.join(os.path.dirname(__file__), 'views') + self._start_time = time.time() # 记录插件启动时间(即项目启动时间) + self._history_len = 60 + self._cpu_history = deque(maxlen=self._history_len) + self._ram_history = deque(maxlen=self._history_len) + self._net_recv_history = deque(maxlen=self._history_len) + self._net_sent_history = deque(maxlen=self._history_len) + self._disk_read_history = deque(maxlen=self._history_len) + self._disk_write_history = deque(maxlen=self._history_len) + self._net_latency_history = deque(maxlen=self._history_len) + self._last_net = None + self._last_disk = None + + def meta(self): + from oss.plugin.types import Metadata, PluginConfig, Manifest + return Manifest( + metadata=Metadata( + name="dashboard", + version="2.0.0", + author="FutureOSS", + description="WebUI 仪表盘" + ), + config=PluginConfig(enabled=True, args={}), + dependencies=["http-api", "webui"] + ) + + def set_webui(self, webui): + self.webui = webui + + def init(self, deps: dict = None): + if self.webui: + Log.info("dashboard", "已获取 WebUI 引用") + self.webui.register_page( + path='/dashboard', + content_provider=self._render_content, + nav_item={'icon': 'ri-dashboard-line', 'text': '仪表盘'} + ) + if hasattr(self.webui, 'server') and self.webui.server: + self.webui.server.router.get("/api/dashboard/stats", self._handle_stats_api) + self.webui.server.router.get("/api/dashboard/history", self._handle_history_api) + Log.info("dashboard", "已注册到 WebUI 导航") + else: + Log.warn("dashboard", "警告: 未找到 WebUI 依赖") + + def _get_uptime_str(self): + """计算项目运行时间(从插件启动时算起)""" + elapsed = time.time() - self._start_time + days = int(elapsed // 86400) + hours = int((elapsed % 86400) // 3600) + minutes = int((elapsed % 3600) // 60) + seconds = int(elapsed % 60) + if days > 0: + return f"{days}天{hours}时{minutes}分{seconds}秒" + elif hours > 0: + return f"{hours}时{minutes}分{seconds}秒" + elif minutes > 0: + return f"{minutes}分{seconds}秒" + else: + return f"{seconds}秒" + + def _get_network_stats(self): + try: + net = psutil.net_io_counters() + now = time.time() + if self._last_net is None: + self._last_net = (now, net.bytes_recv, net.bytes_sent) + return {'recv_rate': 0, 'sent_rate': 0, 'total_recv': net.bytes_recv, 'total_sent': net.bytes_sent} + elapsed = now - self._last_net[0] + if elapsed <= 0: elapsed = 1 + recv_rate = (net.bytes_recv - self._last_net[1]) / elapsed + sent_rate = (net.bytes_sent - self._last_net[2]) / elapsed + self._last_net = (now, net.bytes_recv, net.bytes_sent) + return {'recv_rate': round(recv_rate, 1), 'sent_rate': round(sent_rate, 1), 'total_recv': net.bytes_recv, 'total_sent': net.bytes_sent} + except Exception: + return {'recv_rate': 0, 'sent_rate': 0, 'total_recv': 0, 'total_sent': 0} + + def _get_disk_io_stats(self): + try: + disk_io = psutil.disk_io_counters() + if not disk_io: + return {'read_rate': 0, 'write_rate': 0} + now = time.time() + if self._last_disk is None: + self._last_disk = (now, disk_io.read_bytes, disk_io.write_bytes) + return {'read_rate': 0, 'write_rate': 0} + elapsed = now - self._last_disk[0] + if elapsed <= 0: elapsed = 1 + read_rate = (disk_io.read_bytes - self._last_disk[1]) / elapsed + write_rate = (disk_io.write_bytes - self._last_disk[2]) / elapsed + self._last_disk = (now, disk_io.read_bytes, disk_io.write_bytes) + return {'read_rate': round(read_rate, 1), 'write_rate': round(write_rate, 1)} + except Exception: + return {'read_rate': 0, 'write_rate': 0} + + def _get_network_latency(self) -> float: + """测量到公共 DNS 8.8.8.8 的 TCP 连接延迟(真实网络波动)""" + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(2) + start = time.time() + s.connect(('8.8.8.8', 53)) + elapsed = (time.time() - start) * 1000 # 毫秒 + s.close() + return round(elapsed, 1) + except Exception: + return 0.0 + + def _get_network_interfaces(self): + try: + interfaces = [] + addrs = psutil.net_if_addrs() + stats = psutil.net_if_stats() + for name, addr_list in addrs.items(): + if name == 'lo': + continue + info = {'name': name, 'ip': 'N/A', 'mac': 'N/A', 'is_up': False, 'speed': 0} + for addr in addr_list: + if addr.family == socket.AF_INET: + info['ip'] = addr.address + elif hasattr(psutil, 'AF_LINK') and addr.family == psutil.AF_LINK: + info['mac'] = addr.address + if name in stats: + info['is_up'] = stats[name].isup + info['speed'] = stats[name].speed + interfaces.append(info) + return interfaces + except Exception: + return [] + + def _get_load_info(self): + try: + load1, load5, load15 = os.getloadavg() + return {'load1': round(load1, 2), 'load5': round(load5, 2), 'load15': round(load15, 2)} + except (OSError, AttributeError): + return {'load1': 0, 'load5': 0, 'load15': 0} + + def _handle_stats_api(self, request): + try: + cpu_percent = psutil.cpu_percent(interval=0.3) + mem = psutil.virtual_memory() + disk = psutil.disk_usage('/') + net = self._get_network_stats() + disk_io = self._get_disk_io_stats() + load = self._get_load_info() + latency = self._get_network_latency() + + self._cpu_history.append(round(cpu_percent, 1)) + self._ram_history.append(round(mem.percent, 1)) + self._net_recv_history.append(net['recv_rate']) + self._net_sent_history.append(net['sent_rate']) + self._disk_read_history.append(disk_io['read_rate']) + self._disk_write_history.append(disk_io['write_rate']) + self._net_latency_history.append(latency) + + uptime_str = self._get_uptime_str() + + data = { + 'cpu': {'percent': round(cpu_percent, 1), 'cores': psutil.cpu_count(logical=True)}, + 'ram': {'percent': round(mem.percent, 1), 'used': round(mem.used / (1024**3), 1), 'total': round(mem.total / (1024**3), 1)}, + 'disk': {'percent': round(disk.percent, 1), 'used': round(disk.used / (1024**3), 1), 'total': round(disk.total / (1024**3), 1)}, + 'network': net, + 'disk_io': disk_io, + 'load': load, + 'latency': latency, + 'processes': len(psutil.pids()), + 'uptime': uptime_str + } + return Response(status=200, headers={"Content-Type": "application/json"}, body=json.dumps(data)) + except Exception as e: + return Response(status=500, headers={"Content-Type": "application/json"}, body=json.dumps({'error': str(e)})) + + def _handle_history_api(self, request): + try: + data = { + 'cpu': list(self._cpu_history), + 'ram': list(self._ram_history), + 'net_recv': list(self._net_recv_history), + 'net_sent': list(self._net_sent_history), + 'disk_read': list(self._disk_read_history), + 'disk_write': list(self._disk_write_history), + 'latency': list(self._net_latency_history) + } + return Response(status=200, headers={"Content-Type": "application/json"}, body=json.dumps(data)) + except Exception as e: + return Response(status=500, headers={"Content-Type": "application/json"}, body=json.dumps({'error': str(e)})) + + def start(self): + Log.info("dashboard", "仪表盘已启动") + + def stop(self): + Log.error("dashboard", "仪表盘已停止") + + def _render_content(self) -> str: + try: + php_file = os.path.join(self.views_dir, 'dashboard.php') + if not os.path.exists(php_file): + return "

仪表盘视图文件丢失

" + + cpu_percent = psutil.cpu_percent(interval=0.5) + cpu_cores = psutil.cpu_count(logical=True) + mem = psutil.virtual_memory() + ram_percent = round(mem.percent, 1) + ram_used_gb = round(mem.used / (1024**3), 1) + ram_total_gb = round(mem.total / (1024**3), 1) + disk = psutil.disk_usage('/') + disk_percent = round(disk.percent, 1) + disk_used_gb = round(disk.used / (1024**3), 1) + disk_total_gb = round(disk.total / (1024**3), 1) + net = self._get_network_stats() + disk_io = self._get_disk_io_stats() + load = self._get_load_info() + net_interfaces = self._get_network_interfaces() + processes = len(psutil.pids()) + + if disk_percent < 50: + disk_color = 'gauge-green' + elif disk_percent < 80: + disk_color = 'gauge-orange' + else: + disk_color = 'gauge-blue' + + circumference = 2 * 3.14159 * 52 + cpu_dash_offset = round(circumference - (cpu_percent / 100) * circumference, 1) + ram_dash_offset = round(circumference - (ram_percent / 100) * circumference, 1) + disk_dash_offset = round(circumference - (disk_percent / 100) * circumference, 1) + + uptime_str = self._get_uptime_str() + + def fmt_speed(bps): + if bps >= 1024 * 1024: + return f"{round(bps / (1024*1024), 1)} MB/s" + elif bps >= 1024: + return f"{round(bps / 1024, 1)} KB/s" + else: + return f"{round(bps, 0)} B/s" + + variables = { + 'cpuPercent': int(cpu_percent), + 'cpuDashArray': str(circumference), + 'cpuDashOffset': str(cpu_dash_offset), + 'cpuCores': str(cpu_cores), + 'ramPercent': ram_percent, + 'ramDashArray': str(circumference), + 'ramDashOffset': str(ram_dash_offset), + 'ramUsed': f"{ram_used_gb} GB", + 'ramTotal': f"{ram_total_gb} GB", + 'diskPercent': disk_percent, + 'diskDashArray': str(circumference), + 'diskDashOffset': str(disk_dash_offset), + 'diskUsed': f"{disk_used_gb} GB", + 'diskTotal': f"{disk_total_gb} GB", + 'diskColorClass': disk_color, + 'uptime': uptime_str, + 'osName': f"{platform.system()} {platform.release()}", + 'pythonVersion': platform.python_version(), + 'phpVersion': self._get_php_version(), + 'hostname': platform.node(), + 'netRecvSpeed': fmt_speed(net['recv_rate']), + 'netSentSpeed': fmt_speed(net['sent_rate']), + 'diskReadSpeed': fmt_speed(disk_io['read_rate']), + 'diskWriteSpeed': fmt_speed(disk_io['write_rate']), + 'load1': str(load['load1']), + 'load5': str(load['load5']), + 'load15': str(load['load15']), + 'processes': str(processes), + 'netInterfaces': json.dumps(net_interfaces), + } + + return self._execute_php(php_file, variables) + except Exception as e: + return f"

仪表盘渲染出错: {e}

" + + def _execute_php(self, php_file: str, variables: dict) -> str: + php_vars = "" + for key, value in variables.items(): + if isinstance(value, str): + escaped = value.replace('\\', '\\\\').replace("'", "\\'").replace("\n", "\\n") + php_vars += f"${key} = '{escaped}';\n" + else: + php_vars += f"${key} = {value};\n" + + with open(php_file, 'r', encoding='utf-8') as f: + php_content = f.read() + + tmp_file = os.path.join(os.path.dirname(php_file), '.temp_dashboard.php') + try: + with open(tmp_file, 'w', encoding='utf-8') as f: + f.write(f"\n{php_content}") + result = subprocess.run( + ["php", "-f", tmp_file], + capture_output=True, text=True, timeout=10 + ) + return result.stdout if result.returncode == 0 else f"
{result.stderr}
" + finally: + try: + if os.path.exists(tmp_file): + os.unlink(tmp_file) + except Exception: + pass + + @staticmethod + def _get_php_version() -> str: + try: + res = subprocess.run(['php', '-r', 'echo phpversion();'], capture_output=True, text=True, timeout=5) + return res.stdout if res.returncode == 0 else 'N/A' + except Exception: + return 'N/A' + + +register_plugin_type("DashboardPlugin", DashboardPlugin) + + +def New(): + return DashboardPlugin() diff --git a/store/@{FutureOSS}/dashboard/manifest.json b/store/@{FutureOSS}/dashboard/manifest.json new file mode 100644 index 0000000..ccf9bcf --- /dev/null +++ b/store/@{FutureOSS}/dashboard/manifest.json @@ -0,0 +1,15 @@ +{ + "metadata": { + "name": "dashboard", + "version": "1.0.0", + "author": "FutureOSS", + "description": "WebUI 仪表盘", + "type": "webui-extension" + }, + "config": { + "enabled": true, + "args": {} + }, + "dependencies": ["http-api", "webui"], + "permissions": ["*"] +} diff --git a/store/@{FutureOSS}/dashboard/views/dashboard.php b/store/@{FutureOSS}/dashboard/views/dashboard.php new file mode 100644 index 0000000..11a626b --- /dev/null +++ b/store/@{FutureOSS}/dashboard/views/dashboard.php @@ -0,0 +1,350 @@ + + + + + + + +
+ +
实时指标
+
+
+
CPU 使用率
+
+ +
%
+
+
核心
+
+
+
内存使用
+
+ +
%
+
+
/
+
+
+
磁盘使用
+
+ +
%
+
+
/
+
+
+
系统负载
+
+ +
+
+
1m / 5m / 15m: / /
+
+
+ +
网络 & 磁盘 I/O
+
+
+
网络流量
+
下载速度
+
上传速度
+
+
+
磁盘 I/O
+
读取速度
+
写入速度
+
+
+
系统概况
+
运行进程
+
运行时间
+
+
+ +
历史趋势
+
+
+
CPU & 内存趋势
+
+
+
+
网络吞吐
+
+
+
+
磁盘读写
+
+
+
+
网络延迟
+
+
+
+ +
系统信息
+
+
+
系统详情
+
+
主机名
+
操作系统
+
Python
+
PHP
+
运行时间
+
+
+
+
网络接口
+
+ +
+
+
+
+ + + + + diff --git a/store/@{FutureOSS}/dependency/SIGNATURE b/store/@{FutureOSS}/dependency/SIGNATURE new file mode 100644 index 0000000..260ef9f --- /dev/null +++ b/store/@{FutureOSS}/dependency/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "JQaw//g6588907vGYH6SyqeXj9qHU5Azb7S/bjYm7rUrVsHqqIsIOEPB7IVsdf/wCnCdCa0LzTrEjmS6lKlEwXVjCCebhzyi64OJIXVOVckd2TJbREH0ZizO4KcEWgOqu56Ln3g8yMPHw5GylLABD5UN0q4F48PwUhram+cECu0SOY/bAHxYwi+nzJ0TcuES/J5cK480xv+NvxnylBhx1Udkkoiz9Y7b3pgglx+h57BuPEeHpJFbXQkXtty5Cf3sXzib0FEhicyIW1u5wmYSLz5yyLd/Pefavjfs6JrDG9J8gfPuestQzazQGsIMiQTy13DL8IDGAZ7AP2/mFQYrXuYLaBTxyhhMAkpfjIANzy+2pobeTZz2Cu4Sr6XMzXS4BkeCRDcHHBnttWVpp1+t5HpRgp3W8eiPcCzmUq6jo1cbd5zWGiR1gDEHePivmJaUi/bxlN0vyc7LjW7T+HuLUYhdSktbxv5BexMwcA7+2UHJzEnTVIc+xqoIT+ApPqqF2hLJFiAUdEJe8FRc/Bwihzh8tfM0xgYoqn8RQQ3eWVwVrK9vx0OZ8INumNZOyKPz8ZlGf3XAJv9UGUQ6Y42raYcDOFrgT+MS82tjAxf2nonm0/c3dhgNFZSy5Cfbvuqd9SYaxXejIcVni3MarVHZX3iKytOdv83cBtwPXRcfloc=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775969851.9656692, + "plugin_hash": "aebef3fd9252245553bc458e4652b094839a5e64bde7cec13435ba1930a8dc0d", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/dependency/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/dependency/__pycache__/main.cpython-313.pyc index 8b7d5ff..c38b9c8 100644 Binary files a/store/@{FutureOSS}/dependency/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/dependency/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/hot-reload/README.md b/store/@{FutureOSS}/hot-reload.disabled/README.md similarity index 100% rename from store/@{FutureOSS}/hot-reload/README.md rename to store/@{FutureOSS}/hot-reload.disabled/README.md diff --git a/store/@{FutureOSS}/hot-reload.disabled/SIGNATURE b/store/@{FutureOSS}/hot-reload.disabled/SIGNATURE new file mode 100644 index 0000000..b4828a1 --- /dev/null +++ b/store/@{FutureOSS}/hot-reload.disabled/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "vBf0JPwb5GjyM9vyp4AuncQKp092RpA07RZh+guhF51OKlVI5PphQEEvtMSy2uBsQ0V0RohRid/gazvB5l02DTuyqt2NcjFyPIZj2wm1gfWtJZWBK+Hp11gIPq13qhxDjdi1bs7H+tTOhVHJHkcoU1TsZuUPU+UYOuONbQhdwB+eqEMbNzVrPBPxb12W1SxRBAo/58q+eGI1QvbTv0FBu4fw10vyySGzd51t0psrBqw9xovKSq47AV96ZJeFEJvbfBTfJTg26VOX0cxLS5dmel9+yMhmidJNvOoL3mlZG2C92Xe9hdZAFxaRhMV3QgNKx3s6C+TQRBNx3ttUtBAzxVcXsGhCE0C+CfvbIpuyGHfgarSPJoiIPyp02numgMztFzAdFc66stULEpB3rHBlosUbDNmeuIMNcbCdKlH6R94xuYMg8E699DO67AGxZwZcaUN/vYmAa2DiffVUFcCFXgzABPzctJTYqTaD51KGlMSMHTeMTN3XCWJ79nkxHvt0Lgb0kWljOhcVaGW2t4JUgfupUD1DIwiZ7AlEC3K3JijsqWS633+Saa/+tOI4/V5VzVtExJt46cM/BSETYlHQtA8eDDl6BhbjtnmMaHSjGF75sgiagtj0DYsOvzKLJUVMT4nFjidzb2sR5lN3/S3ZSmBTUYA5/fDgiMnSfZaK4HQ=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964953.0432403, + "plugin_hash": "3b226c4e5278ade1ec0997abfd553d4c07724b8e9f69f79acb57e20e0d352817", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/hot-reload.disabled/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/hot-reload.disabled/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..f19214f Binary files /dev/null and b/store/@{FutureOSS}/hot-reload.disabled/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/hot-reload/main.py b/store/@{FutureOSS}/hot-reload.disabled/main.py similarity index 98% rename from store/@{FutureOSS}/hot-reload/main.py rename to store/@{FutureOSS}/hot-reload.disabled/main.py index 2a36915..a0066d1 100644 --- a/store/@{FutureOSS}/hot-reload/main.py +++ b/store/@{FutureOSS}/hot-reload.disabled/main.py @@ -5,6 +5,7 @@ import threading from pathlib import Path from typing import Any, Optional, Callable +from oss.logger.logger import Log from oss.plugin.types import Plugin, register_plugin_type @@ -138,7 +139,7 @@ class HotReloadPlugin(Plugin): elif change_type == "deleted": self.unload_plugin(plugin_name) except Exception as e: - print(f"[hot-reload] 处理变化失败: {e}") + Log.error("hot-reload", f"处理变化失败: {e}") def load_plugin(self, plugin_dir: Path) -> bool: """运行时加载插件""" diff --git a/store/@{FutureOSS}/hot-reload/manifest.json b/store/@{FutureOSS}/hot-reload.disabled/manifest.json similarity index 100% rename from store/@{FutureOSS}/hot-reload/manifest.json rename to store/@{FutureOSS}/hot-reload.disabled/manifest.json diff --git a/store/@{FutureOSS}/hot-reload/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/hot-reload/__pycache__/main.cpython-313.pyc deleted file mode 100644 index b7dec9f..0000000 Binary files a/store/@{FutureOSS}/hot-reload/__pycache__/main.cpython-313.pyc and /dev/null differ diff --git a/store/@{FutureOSS}/http-api/SIGNATURE b/store/@{FutureOSS}/http-api/SIGNATURE new file mode 100644 index 0000000..f742168 --- /dev/null +++ b/store/@{FutureOSS}/http-api/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "0WK7Njn0KAUP+jfg/uuJxwW0/tWCF+WieK0N0T2crWbvutKQmEOtaNDHnjT6qFz1dcI4+ba3julE4fFi3W3xFiToMEP2VcPXe0WNQ9/kvKNTKSDbwadiBssf43TO1G9E1BxNMxVM91mN8iqybuy+VMdU0Esv2rJ5dcwwwsnT9NWot2RQLez75PRhmMtJpEWRUmrZn2r+u5QnQdjxucONq9Nhwxw0eheTxMCu8IDvIiO6QIWP5ErA/wUz+Hg6IoEZwcVif/lSN2EMqNGqPNR/nIWWVXo9CXWB9qMZZApgEnAZfKYGCAkLzSTwqG64T4iJh4deGxafyMhsONckqRaG82NRTLuzHMReP5+VAichuEGbHI7nxXFOFG7q1mgQQLmHm3LB577usAgCNCh5X3i8SMAj7Sutykxhj0ZyTqMnOfpwnzE2tsNisJF0/8Kw22k7dZChV1obOeLWXjy5InLjdm4hIWTp7wMPjSNWRMZGR+1aZHi9XA1GKd965/30jmo876EXX23xoTAN4ZRhZNlcQg710LhycNohggnQ7qzB9LsV3Ckgh7aY/V/hzND6bpRADCGu62sZtBye2P1yaaAorC8+hRaiJoXlV9Yukg+3yhfKC+qTbn307fI53kgcw1KMSeGGctfTYJUOfK8u0mYsGi50bnM+2Tz45YJiwwdOJJk=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775960645.890869, + "plugin_hash": "ca13c933ffa2c5dd8874e3ad6f7b8dda5dd9a5f9c24be6aeb47228d65097a280", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/http-api/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/http-api/__pycache__/main.cpython-313.pyc index aa0e514..6ca874e 100644 Binary files a/store/@{FutureOSS}/http-api/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/http-api/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-api/__pycache__/middleware.cpython-313.pyc b/store/@{FutureOSS}/http-api/__pycache__/middleware.cpython-313.pyc index 3f37207..3307c16 100644 Binary files a/store/@{FutureOSS}/http-api/__pycache__/middleware.cpython-313.pyc and b/store/@{FutureOSS}/http-api/__pycache__/middleware.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-api/__pycache__/router.cpython-313.pyc b/store/@{FutureOSS}/http-api/__pycache__/router.cpython-313.pyc index 0de4be3..694efa8 100644 Binary files a/store/@{FutureOSS}/http-api/__pycache__/router.cpython-313.pyc and b/store/@{FutureOSS}/http-api/__pycache__/router.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-api/__pycache__/server.cpython-313.pyc b/store/@{FutureOSS}/http-api/__pycache__/server.cpython-313.pyc index 0b0b7e9..82e83a0 100644 Binary files a/store/@{FutureOSS}/http-api/__pycache__/server.cpython-313.pyc and b/store/@{FutureOSS}/http-api/__pycache__/server.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-api/middleware.py b/store/@{FutureOSS}/http-api/middleware.py index b1de2c4..29eb998 100644 --- a/store/@{FutureOSS}/http-api/middleware.py +++ b/store/@{FutureOSS}/http-api/middleware.py @@ -23,9 +23,12 @@ class CorsMiddleware(Middleware): class LoggerMiddleware(Middleware): """日志中间件""" + # 静默的路由(不打印日志) + _silent_paths = {"/api/dashboard/stats", "/favicon.ico", "/health"} + def process(self, ctx: dict, next_fn: Callable) -> Optional[Response]: req = ctx.get("request") - if req: + if req and req.path not in self._silent_paths: print(f"[http-api] {req.method} {req.path}") return None diff --git a/store/@{FutureOSS}/http-api/server.py b/store/@{FutureOSS}/http-api/server.py index 155c798..a7a4876 100644 --- a/store/@{FutureOSS}/http-api/server.py +++ b/store/@{FutureOSS}/http-api/server.py @@ -95,14 +95,17 @@ class HttpServer: self._send_response(resp) def _send_response(self, resp: Response): - self.send_response(resp.status) - for k, v in resp.headers.items(): - self.send_header(k, v) - self.end_headers() - if isinstance(resp.body, str): - self.wfile.write(resp.body.encode("utf-8")) - else: - self.wfile.write(resp.body) + try: + self.send_response(resp.status) + for k, v in resp.headers.items(): + self.send_header(k, v) + self.end_headers() + if isinstance(resp.body, str): + self.wfile.write(resp.body.encode("utf-8")) + else: + self.wfile.write(resp.body) + except BrokenPipeError: + pass # 忽略客户端断开 def log_message(self, format, *args): pass diff --git a/store/@{FutureOSS}/http-tcp/SIGNATURE b/store/@{FutureOSS}/http-tcp/SIGNATURE new file mode 100644 index 0000000..4db598b --- /dev/null +++ b/store/@{FutureOSS}/http-tcp/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "Adt4Pa7dzXVC9LuotOb2hvUREP2sQyInReCfPRVnKLuD2IB+5Uk4BSCjt5EkUUcMiEwIYoefntc1Q0f4k/OL3F4WtKFrwb4G+WJZYuwSbYZ3l4wYtivMFTuP4PjIgz1/sWUfqHdd+jwOquM9a8+uiNaxiz+Ed9UmBCqiJXjbfiP5A5RlkUGO3evwuP51dhfo3BVU+YuVWzSWfVw8Ov9Wx1V0h7fEjPPYof1d9AP+yVnfLLfBeNL1T/VlpkogllRlcqOQm5w+s17sLhR6sQEBHHTsga7Nilh8/BMmXr3vFDrtPbPsOqVGzHvYOFFJf26geFgxowPJ5YxEL9FKp9NtOp0fsDsq6f74mES9nTg7v9uImL8zzYn774fpaIfbOL2CVqsCqzW+kYhNm7fsJD8SfmhwKR8tVEsYvqUiHqpzUwX/J7soD0jlN/ttUUCZREERRKIpumHNNxkcgLuTYsloeSrG935ZOSEt6QuWSg9+dlXgdi84UmE1TbU6Q6HKExopOJitYCUM1p21G5wcFgEn+o7zdkDUdCJEliG1QeqSHdhlo/QyLuH/7mZQOMdprHabggTUrmbrES78nT10XEFWjtUfKxuzQkWwozwYPx6cBdmO4OLYJ+C5u1hwgmVm6if6IbCPm0l/NGy8NUNjH0PxDdmPaUSdnvSLLwa6fwr5/h0=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775960645.9258935, + "plugin_hash": "136d916944b4b1e37134b3b9807a8ea19fc9c4971c62d15cc11e019502de5617", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/http-tcp/__pycache__/events.cpython-313.pyc b/store/@{FutureOSS}/http-tcp/__pycache__/events.cpython-313.pyc index a42829d..a69b322 100644 Binary files a/store/@{FutureOSS}/http-tcp/__pycache__/events.cpython-313.pyc and b/store/@{FutureOSS}/http-tcp/__pycache__/events.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-tcp/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/http-tcp/__pycache__/main.cpython-313.pyc index 7733df6..dddb1a0 100644 Binary files a/store/@{FutureOSS}/http-tcp/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/http-tcp/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-tcp/__pycache__/middleware.cpython-313.pyc b/store/@{FutureOSS}/http-tcp/__pycache__/middleware.cpython-313.pyc index a9568d6..938c0e7 100644 Binary files a/store/@{FutureOSS}/http-tcp/__pycache__/middleware.cpython-313.pyc and b/store/@{FutureOSS}/http-tcp/__pycache__/middleware.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-tcp/__pycache__/router.cpython-313.pyc b/store/@{FutureOSS}/http-tcp/__pycache__/router.cpython-313.pyc index 50c6c62..c26601e 100644 Binary files a/store/@{FutureOSS}/http-tcp/__pycache__/router.cpython-313.pyc and b/store/@{FutureOSS}/http-tcp/__pycache__/router.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/http-tcp/__pycache__/server.cpython-313.pyc b/store/@{FutureOSS}/http-tcp/__pycache__/server.cpython-313.pyc index 6d65f99..3a842fc 100644 Binary files a/store/@{FutureOSS}/http-tcp/__pycache__/server.cpython-313.pyc and b/store/@{FutureOSS}/http-tcp/__pycache__/server.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/i18n.disabled/SIGNATURE b/store/@{FutureOSS}/i18n.disabled/SIGNATURE new file mode 100644 index 0000000..3fe8310 --- /dev/null +++ b/store/@{FutureOSS}/i18n.disabled/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "N8pwPuJxnjP/hgMG4QLYQy7Z6e1P1KctYLJYoQniALDFT1qb11RDm1w4KUbzNIY82XM56B10zYF88dTQiGMrtbgoExE0gtUvmF3THvEd+aWhQ0m5/2war2w+j02BWH0TvJqxhb5nHCyhA4CknJANWp4wZr9EPjDseb+OhXC3GECKpChVrmM9/DWM6TtjlmGol14kq+jUnrS5EWNSa1hlsLzKIrS3Jf5fLaButDUr6YuQkATRKl6F41M8+JHJwVVw5D1fRSqCZ4xFWwN90Gtdd22JFSeB9iVE2Myb3UurPzTVvJ0B/JE9yxFDhA1B7PtuF/WeWlm060QRWdlwFfO9NjUJOeOGQstn34DUG2xL/q3yF66SjnHcHs67DqVq9lCQ961jQq0QveKunV4u8uBJd4IGH4MTq5W7Be8GDgSZcll5HLG3HBL+9XYf4mJzc7dh88Y0UV+dOabD2SJCwBmMxgzDx+Dx8RwWx7b9IYZvmXz6fxtXhqfV6AFq2oY/+4Xjwn4nq7VOCgx8PxLrUvmuacmCwlar/rXuvHT0YsN/XXmJK9o/3NYsNp/go8Vm0XW0btJ+FnQw4O4OKPvSSd+Ip+tk2rLi7CuZGi0WEVp2o23gUNLXoHkKFrtms02Et6zC9AFwP2gLF+NnaMWImup54owxgDos9s6l2ejTD653rYE=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964953.002281, + "plugin_hash": "55f90852ff6fbd82bc5a51ea4ebc2725f1316a7a5f9d423ee10a7e571aad339a", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/i18n/__init__.py b/store/@{FutureOSS}/i18n.disabled/__init__.py similarity index 100% rename from store/@{FutureOSS}/i18n/__init__.py rename to store/@{FutureOSS}/i18n.disabled/__init__.py diff --git a/store/@{FutureOSS}/i18n/__pycache__/i18n.cpython-313.pyc b/store/@{FutureOSS}/i18n.disabled/__pycache__/i18n.cpython-313.pyc similarity index 89% rename from store/@{FutureOSS}/i18n/__pycache__/i18n.cpython-313.pyc rename to store/@{FutureOSS}/i18n.disabled/__pycache__/i18n.cpython-313.pyc index 5160e73..6b61020 100644 Binary files a/store/@{FutureOSS}/i18n/__pycache__/i18n.cpython-313.pyc and b/store/@{FutureOSS}/i18n.disabled/__pycache__/i18n.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/i18n.disabled/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/i18n.disabled/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..b1a087a Binary files /dev/null and b/store/@{FutureOSS}/i18n.disabled/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/i18n/__pycache__/middleware.cpython-313.pyc b/store/@{FutureOSS}/i18n.disabled/__pycache__/middleware.cpython-313.pyc similarity index 79% rename from store/@{FutureOSS}/i18n/__pycache__/middleware.cpython-313.pyc rename to store/@{FutureOSS}/i18n.disabled/__pycache__/middleware.cpython-313.pyc index 6606d8a..d701864 100644 Binary files a/store/@{FutureOSS}/i18n/__pycache__/middleware.cpython-313.pyc and b/store/@{FutureOSS}/i18n.disabled/__pycache__/middleware.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/i18n/i18n.py b/store/@{FutureOSS}/i18n.disabled/i18n.py similarity index 100% rename from store/@{FutureOSS}/i18n/i18n.py rename to store/@{FutureOSS}/i18n.disabled/i18n.py diff --git a/store/@{FutureOSS}/i18n/locales/en-US.json b/store/@{FutureOSS}/i18n.disabled/locales/en-US.json similarity index 100% rename from store/@{FutureOSS}/i18n/locales/en-US.json rename to store/@{FutureOSS}/i18n.disabled/locales/en-US.json diff --git a/store/@{FutureOSS}/i18n/locales/zh-CN.json b/store/@{FutureOSS}/i18n.disabled/locales/zh-CN.json similarity index 100% rename from store/@{FutureOSS}/i18n/locales/zh-CN.json rename to store/@{FutureOSS}/i18n.disabled/locales/zh-CN.json diff --git a/store/@{FutureOSS}/i18n/locales/zh-TW.json b/store/@{FutureOSS}/i18n.disabled/locales/zh-TW.json similarity index 100% rename from store/@{FutureOSS}/i18n/locales/zh-TW.json rename to store/@{FutureOSS}/i18n.disabled/locales/zh-TW.json diff --git a/store/@{FutureOSS}/i18n/main.py b/store/@{FutureOSS}/i18n.disabled/main.py similarity index 96% rename from store/@{FutureOSS}/i18n/main.py rename to store/@{FutureOSS}/i18n.disabled/main.py index ca7f2d9..e5e1506 100644 --- a/store/@{FutureOSS}/i18n/main.py +++ b/store/@{FutureOSS}/i18n.disabled/main.py @@ -1,6 +1,7 @@ """i18n 国际化多语言支持插件""" import json from pathlib import Path +from oss.logger.logger import Log from oss.plugin.types import Plugin, register_plugin_type from .i18n import I18nEngine from .middleware import I18nMiddleware @@ -66,8 +67,8 @@ class I18nPlugin(Plugin): # 初始化中间件 self.middleware_handler = I18nMiddleware(self.engine, config) - print(f"[i18n] 已加载语言: {', '.join(supported_locales)}") - print(f"[i18n] 默认语言: {default_locale}") + Log.info("i18n", f"已加载语言: {', '.join(supported_locales)}") + Log.info("i18n", f"默认语言: {default_locale}") def start(self): """启动插件 @@ -83,11 +84,11 @@ class I18nPlugin(Plugin): http_api.router.get("/api/i18n/locales", self._locales_handler) http_api.router.get("/api/i18n/translate", self._translate_handler) http_api.router.post("/api/i18n/locale", self._change_locale_handler) - print("[i18n] API 路由已注册") + Log.info("i18n", "API 路由已注册") def stop(self): """停止插件""" - print("[i18n] 插件已停止") + Log.error("i18n", "插件已停止") def health(self) -> bool: """健康检查""" diff --git a/store/@{FutureOSS}/i18n/manifest.json b/store/@{FutureOSS}/i18n.disabled/manifest.json similarity index 100% rename from store/@{FutureOSS}/i18n/manifest.json rename to store/@{FutureOSS}/i18n.disabled/manifest.json diff --git a/store/@{FutureOSS}/i18n/middleware.py b/store/@{FutureOSS}/i18n.disabled/middleware.py similarity index 100% rename from store/@{FutureOSS}/i18n/middleware.py rename to store/@{FutureOSS}/i18n.disabled/middleware.py diff --git a/store/@{FutureOSS}/i18n/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/i18n/__pycache__/main.cpython-313.pyc deleted file mode 100644 index 1c8ce20..0000000 Binary files a/store/@{FutureOSS}/i18n/__pycache__/main.cpython-313.pyc and /dev/null differ diff --git a/store/@{FutureOSS}/json-codec/SIGNATURE b/store/@{FutureOSS}/json-codec/SIGNATURE new file mode 100644 index 0000000..7feac6d --- /dev/null +++ b/store/@{FutureOSS}/json-codec/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "IQ8WAvKno6pRp71kIaxXPb7DzTajPeNOQ0FLZMVovufeyTRMbdSJ8z2zQPBPv9O2a1S9bucyZyhg54fNB2DdLfEnrAbmpepZ3CLrj3cn4KaLNGJjxGHYXWIsFXFvLaYIod/ZuFMYPlzDdwnHJwzHZnkGAmCLrJSR+XvuOqYu/xSZekD/nbMI0fj9VKjaH/S/vopEhq7IFioahVkiSokdYx5qkXYruOVAq3wCnk6O0uCNMfHiIaRhn5pEoQ+VOXcuKX5eOBEph8oXqb+ew1MB917Z1CpaLFuZTyp2Dy8OOmpXjBxfd5VYazH4ZvE9Q7VODHkRDVF2ApkPxTE1k490YvmNOHRamjcf1/mKyu7Myaemtz9oxvZFFiOMOaXBXGfe1wlnsbO832lURTpPu9WXQ6aoDEVp3TNuR/G/xYOXHcWhG1M4tIWW+1ZFcozkVw9cMYvwrVI9JEa89sueXQhJG9foW4nj0DJqmtXaXvcVHnpbFkIxcKFZ0rOMelJ7404XuDb07/sjliJuqCG9Gssmv7/DqNgIrcWUPg24U4UPWW2vWJaJq7HOrGrxFoOxpCT/G4A0WcAWVJrM5NojnfvBNswybSB2IIbspmPRDVtoHQ5a3YJqSLZdgugHh+MbGKlyDvPkQTkPLLE8nrP2F0LwWCq0cYeodE+zU0rZ6CHgAsc=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964952.836965, + "plugin_hash": "a7f7a20614a2e159e393a95c99b15a0a028724694bda3d089787cb41eceba7c4", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/json-codec/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/json-codec/__pycache__/main.cpython-313.pyc index 44b40b2..b991833 100644 Binary files a/store/@{FutureOSS}/json-codec/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/json-codec/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/json-codec/main.py b/store/@{FutureOSS}/json-codec/main.py index 9f9dd55..d27f756 100644 --- a/store/@{FutureOSS}/json-codec/main.py +++ b/store/@{FutureOSS}/json-codec/main.py @@ -3,6 +3,7 @@ import json from typing import Any, Callable, Optional from datetime import datetime +from oss.logger.logger import Log from oss.plugin.types import Plugin, register_plugin_type @@ -127,7 +128,7 @@ class JsonCodecPlugin(Plugin): def start(self): """启动""" - print("[json-codec] JSON 编解码器已启动") + Log.info("json-codec", "JSON 编解码器已启动") def stop(self): """停止""" diff --git a/store/@{FutureOSS}/lifecycle/README.md b/store/@{FutureOSS}/lifecycle.disabled/README.md similarity index 100% rename from store/@{FutureOSS}/lifecycle/README.md rename to store/@{FutureOSS}/lifecycle.disabled/README.md diff --git a/store/@{FutureOSS}/lifecycle.disabled/SIGNATURE b/store/@{FutureOSS}/lifecycle.disabled/SIGNATURE new file mode 100644 index 0000000..9816d01 --- /dev/null +++ b/store/@{FutureOSS}/lifecycle.disabled/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "nfM9Sj7VvV+L85zCvVcmIQY4qZ9FDdsk8MZf0LrO/ys1o6FCQ96Ixt1aB+2j6crOvXUBavnSRPk/LNaDs9r3eh49+Zfy5rEK+M0UyGjcawvEY4e/lO20UWy4iLw3JdSBo9nnFQC9eE8D6C9F2oM7YcqmT/sH0wYuyjCsa8tk6P/jy5/IdCwR6bo6AIQSpCnvyNcS9JPU19f603f0nl/siafXVozQxMS3wCLQ5EAoDz7atLevvQK7xAZCIIcCsre/sHTZ3a6O+BFlYYQ5w/giWlrl4aF7W7JJntOwpain39B0ktDRV96msbW744a1BFkcUw91W/2sRU7T9xplARjmhlRPGkdMTlj4PGyy394oaLwhx+uusx28C9+gWxp7pQZNo08LQ6dKmzog4fpUFD3EEyZBtPY2XYsILqKnGQVn3TLAaMmdoHdwoR6moLtR6BfD3ToRFV6vcNRTig8hTiS9GTzZeQtEtVkoSeAZphzxWfB7FunimDRpPxndDmvhervPUJ/uAVLcdorbDFB0RfvR3znUZrQkaw5YQZjP8mhUNyA6avyOBvGdt1i0bhZsc6CUMN4BrC+vOULiykyVGnk3B07XrMHNB8AGuqR8Ai/2DFglomfs/l07mz01HeUotRg3MezqF8aSkofpPTpRieeD9IeQgH03sOGdvXHDgDJB3Xc=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775960646.0212853, + "plugin_hash": "a7d6c6e01a8dc5df868e34777233e33d984d01adedb8adcee24d6892600928a8", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/lifecycle/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/lifecycle.disabled/__pycache__/main.cpython-313.pyc similarity index 97% rename from store/@{FutureOSS}/lifecycle/__pycache__/main.cpython-313.pyc rename to store/@{FutureOSS}/lifecycle.disabled/__pycache__/main.cpython-313.pyc index c53f179..5f33291 100644 Binary files a/store/@{FutureOSS}/lifecycle/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/lifecycle.disabled/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/lifecycle/main.py b/store/@{FutureOSS}/lifecycle.disabled/main.py similarity index 100% rename from store/@{FutureOSS}/lifecycle/main.py rename to store/@{FutureOSS}/lifecycle.disabled/main.py diff --git a/store/@{FutureOSS}/lifecycle/manifest.json b/store/@{FutureOSS}/lifecycle.disabled/manifest.json similarity index 100% rename from store/@{FutureOSS}/lifecycle/manifest.json rename to store/@{FutureOSS}/lifecycle.disabled/manifest.json diff --git a/store/@{FutureOSS}/log-terminal/SIGNATURE b/store/@{FutureOSS}/log-terminal/SIGNATURE new file mode 100644 index 0000000..7b49162 --- /dev/null +++ b/store/@{FutureOSS}/log-terminal/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "iSAdml6TdNMXoZmB7zsRN6jYb3GL8ufdfxA+gHL58R1z7qpxc13fQidyo/syRaGv+J7zLV2/8/e8qSSGhbtWn2p08iH8vIax5zTe3zfl8wBlhxnCkEQztd1FlfkERgNWpRToiGu8GV8o0Fq+Yej6C+OaO6EL69DkRxL8Kp2Jf/2jdUOCprErLyKm506zotXjcKEr9heSLNCD0DKRaQv1GnqLJclp9fXirVvJHDS26ttNx1srNhvjTjsGofzn6qQpGuddLXKi7FWKDAByEBjqzQOmQ2iB4NOIG012J4HKO1q3BajNj11xfWL6PnSzvrwj8IJbJIrbCzTPeFK3F6gj3JtAcaI6iQLhJ7VjOCbFhlOOoIJx/5CA3j9x+/DLXgjAnV6fiD0Q8VCaLTkXGQPwGXo7xq8ExkRt48sHI9nFI0+8fj6nXB1ANDHPlvg86eyHKG61WUIZOHd/Ag9foCZtoDFnKXYBnVeNweHaHBsJWpBOvbFjPkYRpRxvRvVd8oe5qmxS0eS5RLmIIpHnOvoGKQV5CoGXPmKB5FNxDRUH4llz9W4FpxtRaYoFFoYatT9Kvr+WPSok13XS1uMBybT2nc+nEZ/XR7LsNxajfZsyEjXwQbL8DsI9LXPW9gt10F6P/9ByWaTCD/4H8flwDFI4iqw/iVENip8vnilTQpowuOY=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775969593.8644652, + "plugin_hash": "b38f028d1629d878dcfc32ac28747d5cea8e93ad832009b88cb3b69934fb3fa5", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/log-terminal/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/log-terminal/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..e8de1f3 Binary files /dev/null and b/store/@{FutureOSS}/log-terminal/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/log-terminal/config.json b/store/@{FutureOSS}/log-terminal/config.json new file mode 100644 index 0000000..b940173 --- /dev/null +++ b/store/@{FutureOSS}/log-terminal/config.json @@ -0,0 +1,36 @@ +{ + "logSyncInterval": { + "type": "number", + "name": "日志同步间隔", + "description": "日志自动同步的时间间隔(秒)", + "default": 2, + "min": 1, + "max": 10, + "order": 1 + }, + "sshPort": { + "type": "number", + "name": "SSH 端口", + "description": "SSH 连接的默认端口", + "default": 8022, + "min": 1, + "max": 65535, + "order": 2 + }, + "autoInstallSSH": { + "type": "boolean", + "name": "自动安装 SSH", + "description": "连接时自动检测并安装 SSH 服务", + "default": true, + "order": 3 + }, + "maxLogLines": { + "type": "number", + "name": "最大日志行数", + "description": "日志界面最多显示的日志行数", + "default": 1000, + "min": 100, + "max": 10000, + "order": 4 + } +} diff --git a/store/@{FutureOSS}/log-terminal/main.py b/store/@{FutureOSS}/log-terminal/main.py new file mode 100644 index 0000000..73f00b9 --- /dev/null +++ b/store/@{FutureOSS}/log-terminal/main.py @@ -0,0 +1,607 @@ +"""LogTerminal 日志与终端插件""" +import os +import json +import subprocess +import threading +import time +from oss.logger.logger import Log +from oss.plugin.types import Plugin, Response, register_plugin_type + + +class LogTerminalPlugin(Plugin): + """日志与终端插件 - 提供日志查看和 SSH 终端功能""" + + def __init__(self): + self.webui = None + self.http_api = None + self.views_dir = os.path.join(os.path.dirname(__file__), 'views') + self._log_buffer = [] + self._log_lock = threading.Lock() + self._ssh_sessions = {} + self._session_counter = 0 + self._log_sync_thread = None + self._running = False + + def meta(self): + from oss.plugin.types import Metadata, PluginConfig, Manifest + return Manifest( + metadata=Metadata( + name="log-terminal", + version="1.0.0", + author="FutureOSS", + description="日志查看器与 SSH 终端" + ), + config=PluginConfig(enabled=True, args={}), + dependencies=["http-api", "webui"] + ) + + def set_webui(self, webui): + self.webui = webui + + def set_http_api(self, http_api): + self.http_api = http_api + + def init(self, deps: dict = None): + if self.webui: + Log.info("log-terminal", "已获取 WebUI 引用") + + # 注册日志查看页面 + self.webui.register_page( + path='/logs', + content_provider=self._render_logs, + nav_item={'icon': 'ri-file-list-3-line', 'text': '日志'} + ) + + # 注册终端页面 + self.webui.register_page( + path='/terminal', + content_provider=self._render_terminal, + nav_item={'icon': 'ri-terminal-box-line', 'text': '终端'} + ) + + Log.ok("log-terminal", "已注册日志与终端页面到 WebUI 导航") + else: + Log.warn("log-terminal", "警告: 未找到 WebUI 依赖") + + # 注册 API 路由(通过 http-api) + if self.http_api and self.http_api.router: + self.http_api.router.get("/api/logs/get", self._handle_get_logs) + self.http_api.router.post("/api/terminal/connect", self._handle_connect_ssh) + self.http_api.router.post("/api/terminal/send", self._handle_send_command) + self.http_api.router.post("/api/terminal/disconnect", self._handle_disconnect_ssh) + self.http_api.router.get("/api/terminal/sessions", self._handle_list_sessions) + Log.ok("log-terminal", "已注册 API 路由") + else: + Log.warn("log-terminal", "警告: 未找到 http-api 依赖") + + def start(self): + Log.info("log-terminal", "日志与终端插件启动中...") + self._running = True + + # 启动日志同步线程 + self._log_sync_thread = threading.Thread(target=self._log_sync_worker, daemon=True) + self._log_sync_thread.start() + + # 添加初始化日志 + self.add_log_entry("info", "log-terminal", "日志与终端插件已启动") + self.add_log_entry("tip", "log-terminal", "日志查看: /logs | SSH 终端: /terminal") + + # 尝试捕获系统日志输出 + self._hook_system_log() + + Log.ok("log-terminal", "日志与终端插件已启动") + + def _hook_system_log(self): + """拦截系统日志输出到我们的缓冲区""" + try: + from oss.logger.logger import Log as SystemLog + + # 保存原始方法 + original_info = SystemLog.info + original_warn = SystemLog.warn + original_error = SystemLog.error + original_tip = SystemLog.tip + original_ok = SystemLog.ok + + # 创建包装方法 + plugin_instance = self + + @classmethod + def wrapped_info(cls, tag: str, msg: str): + original_info(tag, msg) + plugin_instance.add_log_entry("info", tag, msg) + + @classmethod + def wrapped_warn(cls, tag: str, msg: str): + original_warn(tag, msg) + plugin_instance.add_log_entry("warn", tag, msg) + + @classmethod + def wrapped_error(cls, tag: str, msg: str): + original_error(tag, msg) + plugin_instance.add_log_entry("error", tag, msg) + + @classmethod + def wrapped_tip(cls, tag: str, msg: str): + original_tip(tag, msg) + plugin_instance.add_log_entry("tip", tag, msg) + + @classmethod + def wrapped_ok(cls, tag: str, msg: str): + original_ok(tag, msg) + plugin_instance.add_log_entry("ok", tag, msg) + + # 替换方法(注意:这只影响未来的调用) + SystemLog.info = wrapped_info + SystemLog.warn = wrapped_warn + SystemLog.error = wrapped_error + SystemLog.tip = wrapped_tip + SystemLog.ok = wrapped_ok + + Log.info("log-terminal", "系统日志拦截器已安装") + except Exception as e: + Log.warn("log-terminal", f"无法拦截系统日志: {e}") + + def stop(self): + Log.info("log-terminal", "日志与终端插件停止中...") + self._running = False + + # 关闭所有 SSH 会话 + for session_id, session in list(self._ssh_sessions.items()): + try: + if 'process' in session: + session['process'].terminate() + except Exception: + pass + + self._ssh_sessions.clear() + Log.ok("log-terminal", "日志与终端插件已停止") + + def _log_sync_worker(self): + """日志同步工作线程 - 持续捕获项目日志""" + try: + # 尝试从多个位置读取日志 + log_files = [ + '/var/log/syslog', + '/var/log/messages', + os.path.join(os.path.dirname(__file__), '..', '..', 'data', 'system.log'), + ] + + last_positions = {} + + while self._running: + # 检查日志文件 + for log_file in log_files: + if os.path.exists(log_file) and os.path.isfile(log_file): + try: + with open(log_file, 'r', encoding='utf-8', errors='ignore') as f: + # 获取文件位置 + if log_file not in last_positions: + # 首次读取,跳到文件末尾 + f.seek(0, 2) # 2 = SEEK_END + last_positions[log_file] = f.tell() + else: + f.seek(last_positions[log_file]) + + # 读取新行 + lines = f.readlines() + if lines: + last_positions[log_file] = f.tell() + for line in lines[-50:]: # 每次最多读取50行 + line = line.strip() + if line: + self.add_log_entry("info", "system", line) + except Exception as e: + pass + + # 等待下一次同步 + time.sleep(2) + + except Exception as e: + Log.error("log-terminal", f"日志同步线程异常: {e}") + + def add_log_entry(self, level: str, tag: str, message: str): + """向日志缓冲区添加日志条目""" + import time + timestamp = time.strftime('%Y-%m-%d %H:%M:%S') + entry = { + 'timestamp': timestamp, + 'level': level, + 'tag': tag, + 'message': message + } + with self._log_lock: + self._log_buffer.append(entry) + # 限制日志缓冲区大小 + if len(self._log_buffer) > 10000: + self._log_buffer = self._log_buffer[-5000:] + + def _get_logs(self, limit=100): + """获取日志列表""" + with self._log_lock: + return self._log_buffer[-limit:] + + def _check_ssh_installed(self): + """检查 SSH 是否已安装""" + try: + result = subprocess.run(['which', 'sshd'], capture_output=True, text=True, timeout=5) + return result.returncode == 0 + except Exception: + return False + + def _install_ssh(self): + """自动安装 SSH 服务""" + try: + Log.info("log-terminal", "正在安装 SSH 服务...") + # 检测包管理器 + for pkg_manager in ['apt-get', 'yum', 'dnf', 'pacman']: + result = subprocess.run(['which', pkg_manager], capture_output=True, timeout=3) + if result.returncode == 0: + if pkg_manager == 'apt-get': + subprocess.run([pkg_manager, 'update'], capture_output=True, timeout=30) + result = subprocess.run( + [pkg_manager, 'install', '-y', 'openssh-server'], + capture_output=True, text=True, timeout=120 + ) + elif pkg_manager in ['yum', 'dnf']: + result = subprocess.run( + [pkg_manager, 'install', '-y', 'openssh-server'], + capture_output=True, text=True, timeout=120 + ) + elif pkg_manager == 'pacman': + result = subprocess.run( + [pkg_manager, '-S', '--noconfirm', 'openssh'], + capture_output=True, text=True, timeout=120 + ) + + if result.returncode == 0: + Log.ok("log-terminal", "SSH 服务安装成功") + return True + else: + Log.error("log-terminal", f"SSH 服务安装失败: {result.stderr}") + return False + + Log.error("log-terminal", "未找到支持的包管理器") + return False + except Exception as e: + Log.error("log-terminal", f"安装 SSH 服务时出错: {e}") + return False + + def _start_ssh_server(self, port=8022): + """启动 SSH 服务器""" + try: + # 检查 SSH 服务器是否已在运行 + result = subprocess.run(['pgrep', '-f', 'sshd'], capture_output=True, timeout=3) + if result.returncode == 0: + Log.tip("log-terminal", "SSH 服务器已在运行") + return True + + # 启动 SSH 服务器 + Log.info("log-terminal", f"正在启动 SSH 服务器 (端口: {port})...") + subprocess.run(['sshd', '-p', str(port)], capture_output=True, timeout=10) + + # 验证是否启动成功 + time.sleep(1) + result = subprocess.run(['pgrep', '-f', f'sshd.*{port}'], capture_output=True, timeout=3) + if result.returncode == 0: + Log.ok("log-terminal", f"SSH 服务器已启动 (端口: {port})") + return True + else: + Log.error("log-terminal", "SSH 服务器启动失败") + return False + except Exception as e: + Log.error("log-terminal", f"启动 SSH 服务器时出错: {e}") + return False + + def _handle_connect_ssh(self, request): + """处理 SSH 连接请求""" + try: + body = json.loads(request.body) + port = body.get('port', 8022) + auto_install = body.get('auto_install', True) + + # 检查 SSH 是否已安装 + if not self._check_ssh_installed(): + if auto_install: + if not self._install_ssh(): + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': 'SSH 安装失败'}) + ) + else: + return Response( + status=400, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': 'SSH 未安装,请先安装 SSH 服务'}) + ) + + # 启动 SSH 服务器 + if not self._start_ssh_server(port): + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': 'SSH 服务器启动失败'}) + ) + + # 创建新的终端会话 (使用 script 命令创建伪终端) + self._session_counter += 1 + session_id = self._session_counter + + try: + # 使用 script 命令创建交互式终端 + process = subprocess.Popen( + ['script', '-q', '-c', '/bin/bash', '/dev/null'], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1 + ) + + self._ssh_sessions[session_id] = { + 'process': process, + 'created_at': time.time(), + 'port': port + } + + Log.info("log-terminal", f"SSH 终端会话 #{session_id} 已创建") + + return Response( + status=200, + headers={"Content-Type": "application/json"}, + body=json.dumps({ + 'success': True, + 'session_id': session_id, + 'message': 'SSH 终端已连接' + }) + ) + except Exception as e: + Log.error("log-terminal", f"创建终端会话失败: {e}") + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': str(e)}) + ) + + except Exception as e: + Log.error("log-terminal", f"SSH 连接请求异常: {e}") + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': str(e)}) + ) + + def _handle_send_command(self, request): + """处理发送命令到终端""" + try: + body = json.loads(request.body) + session_id = body.get('session_id') + command = body.get('command', '') + + if session_id not in self._ssh_sessions: + return Response( + status=400, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': '会话不存在'}) + ) + + session = self._ssh_sessions[session_id] + process = session['process'] + + # 发送命令 + process.stdin.write(command + '\n') + process.stdin.flush() + + # 读取输出 + time.sleep(0.5) # 等待命令执行 + output = "" + try: + while True: + line = process.stdout.readline() + if not line: + break + output += line + except Exception: + pass + + return Response( + status=200, + headers={"Content-Type": "application/json"}, + body=json.dumps({ + 'success': True, + 'output': output + }) + ) + except Exception as e: + Log.error("log-terminal", f"发送命令时出错: {e}") + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': str(e)}) + ) + + def _handle_disconnect_ssh(self, request): + """处理断开 SSH 连接""" + try: + body = json.loads(request.body) + session_id = body.get('session_id') + + if session_id in self._ssh_sessions: + session = self._ssh_sessions[session_id] + try: + session['process'].terminate() + except Exception: + pass + del self._ssh_sessions[session_id] + Log.info("log-terminal", f"SSH 终端会话 #{session_id} 已断开") + return Response( + status=200, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': True, 'message': '已断开连接'}) + ) + else: + return Response( + status=400, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': '会话不存在'}) + ) + except Exception as e: + Log.error("log-terminal", f"断开连接时出错: {e}") + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': str(e)}) + ) + + def _handle_list_sessions(self, request): + """列出所有 SSH 会话""" + try: + sessions = [] + for session_id, session in self._ssh_sessions.items(): + sessions.append({ + 'session_id': session_id, + 'port': session['port'], + 'created_at': session['created_at'], + 'uptime': time.time() - session['created_at'] + }) + + return Response( + status=200, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': True, 'sessions': sessions}) + ) + except Exception as e: + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': str(e)}) + ) + + def _handle_get_logs(self, request): + """获取日志""" + try: + from urllib.parse import parse_qs, urlparse + + # 解析路径中的查询参数 + parsed = urlparse(request.path) + params = parse_qs(parsed.query) + limit = int(params.get('limit', [100])[0]) + source = params.get('source', ['buffer'])[0] # buffer 或 file + + logs = [] + + if source == 'buffer': + # 从内存缓冲区获取 + logs = self._get_logs(limit) + else: + # 从系统日志文件获取 + logs = self._read_system_logs(limit) + + return Response( + status=200, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': True, 'logs': logs}) + ) + except Exception as e: + return Response( + status=500, + headers={"Content-Type": "application/json"}, + body=json.dumps({'success': False, 'error': str(e)}) + ) + + def _read_system_logs(self, limit=100): + """从系统日志文件读取日志""" + logs = [] + log_files = [ + '/var/log/syslog', + '/var/log/messages', + '/var/log/kern.log', + ] + + for log_file in log_files: + if os.path.exists(log_file): + try: + with open(log_file, 'r', encoding='utf-8', errors='ignore') as f: + lines = f.readlines() + for line in lines[-limit:]: + line = line.strip() + if line: + # 尝试解析 syslog 格式 + # 格式: "Apr 12 10:30:45 hostname service[pid]: message" + import re + match = re.match(r'(\w+\s+\d+\s+\d+:\d+:\d+)\s+(\S+)\s+(\S+?)(?:\[\d+\])?:\s+(.*)', line) + if match: + logs.append({ + 'timestamp': match.group(1), + 'level': 'info', + 'tag': match.group(3), + 'message': match.group(4) + }) + else: + logs.append({ + 'timestamp': time.strftime('%b %d %H:%M:%S'), + 'level': 'info', + 'tag': 'system', + 'message': line + }) + except Exception: + pass + + return logs[-limit:] + + def _render_logs(self) -> str: + """渲染日志查看界面""" + try: + php_file = os.path.join(self.views_dir, 'logs.php') + if not os.path.exists(php_file): + return "

日志视图文件丢失

" + return self._execute_php(php_file, {}) + except Exception as e: + return f"

日志视图渲染出错: {e}

" + + def _render_terminal(self) -> str: + """渲染终端界面""" + try: + php_file = os.path.join(self.views_dir, 'terminal.php') + if not os.path.exists(php_file): + return "

终端视图文件丢失

" + return self._execute_php(php_file, {}) + except Exception as e: + return f"

终端视图渲染出错: {e}

" + + def _execute_php(self, php_file: str, variables: dict) -> str: + """执行 PHP 文件""" + php_vars = "" + for key, value in variables.items(): + if isinstance(value, str): + escaped = value.replace('\\', '\\\\').replace("'", "\\'").replace("\n", "\\n") + php_vars += f"${key} = '{escaped}';\n" + else: + php_vars += f"${key} = {value};\n" + + with open(php_file, 'r', encoding='utf-8') as f: + php_content = f.read() + + tmp_file = os.path.join(os.path.dirname(php_file), '.temp_lt.php') + try: + with open(tmp_file, 'w', encoding='utf-8') as f: + f.write(f"\n{php_content}") + result = subprocess.run( + ["php", "-f", tmp_file], + capture_output=True, text=True, timeout=10 + ) + return result.stdout if result.returncode == 0 else f"
{result.stderr}
" + finally: + try: + if os.path.exists(tmp_file): + os.unlink(tmp_file) + except Exception: + pass + + +register_plugin_type("LogTerminalPlugin", LogTerminalPlugin) + + +def New(): + return LogTerminalPlugin() diff --git a/store/@{FutureOSS}/log-terminal/manifest.json b/store/@{FutureOSS}/log-terminal/manifest.json new file mode 100644 index 0000000..7656602 --- /dev/null +++ b/store/@{FutureOSS}/log-terminal/manifest.json @@ -0,0 +1,15 @@ +{ + "metadata": { + "name": "log-terminal", + "version": "1.0.0", + "author": "FutureOSS", + "description": "日志查看器与 SSH 终端", + "type": "webui-extension" + }, + "config": { + "enabled": true, + "args": {} + }, + "dependencies": ["http-api", "webui"], + "permissions": ["*"] +} diff --git a/store/@{FutureOSS}/log-terminal/views/logs.php b/store/@{FutureOSS}/log-terminal/views/logs.php new file mode 100644 index 0000000..e7ef43c --- /dev/null +++ b/store/@{FutureOSS}/log-terminal/views/logs.php @@ -0,0 +1,217 @@ + + + + + + + +
+
+
+ + 系统日志 + + + 实时同步 + +
+
+ + +
+
+ +
+ + + + + + +
+ +
+
+ +

正在加载日志...

+
+
+
+ + + + diff --git a/store/@{FutureOSS}/log-terminal/views/terminal.php b/store/@{FutureOSS}/log-terminal/views/terminal.php new file mode 100644 index 0000000..abecdaa --- /dev/null +++ b/store/@{FutureOSS}/log-terminal/views/terminal.php @@ -0,0 +1,288 @@ + + + + + + + +
+
+
+ + SSH 终端 +
+
+
+ + 未连接 +
+ + + +
+
+ +
+
+ SSH 端口: + +
+
+ +
+
+ +
+
+
+ + 端口: 8022 +
+
+ + 运行时间: - +
+
+ +
+
+ +

点击"连接"按钮开始 SSH 终端会话

+

支持自动安装 SSH 服务

+
+
+ +
+ $ + +
+
+
+ + + + diff --git a/store/@{FutureOSS}/pkg-manager/SIGNATURE b/store/@{FutureOSS}/pkg-manager/SIGNATURE new file mode 100644 index 0000000..e8211e9 --- /dev/null +++ b/store/@{FutureOSS}/pkg-manager/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "hNzQ56uwgghPRTVm5YFA8fZp+1Y9TQ9fSDKLEY+KPFLddrxdnXZiE66XXWEVEj80pB5E/zJ0nDcpJYTe9+Mo4LQ++Qzt7yA+PMu8WZ/I39f1870FR/s+MuaiKWp0sT/NeyHRv/nHKi/FaZXWx+KsSbKatq4w088bNhyWahJg1RmTaCKAxv7ut9Uqn33m9teoeNt43AG/6ySfRQRfk0K1L7Yvf/9yJStDMAuTzFiQmhs4MZ58VzPh/Nrtj0G7N5mAjp9bZKa+EFqMLFBQlG5TDqWU8zFKBe27CsvSK7MthS3PGyzeGftm2O683hgClGdsgdK9kqwZ0eMOb5Jcesk4f0rWVODpCf2cfRPocrs401yKzVU3dStFw14Bq82SpQDRJ9EDU3lP8E4RqlmXEAzlGNoMsGSGth9gSWc4VpHn4ppVH5ftKk/AvJrpdFWyWe0jPnDODRKAIMn9sGiZUy6XqB0fGMoU0vpuvtLy6mtVmQglhsVE49XA5txAEWQncPUPxxjNoMdRo5RDlimRVNtXNcwKRb1z9V6ky1eOVKFHaPsp4Y+1mreZVUokaUBf8LG1qvFXjZuiYHRlffKSN3/yzRqhDnE5fCDu0wpjHe24dZ/PeQXbG2aAQlJQr15yh7p5dxTSiv+HeacwDqZPF8X/9Ey6xMflr1xGZpp9j9YeCtk=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775967812.6803007, + "plugin_hash": "c0c56583082ca71e9a84ac2e976c22683573ec4e40387ee893ac42f31da62d4a", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/pkg-manager/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/pkg-manager/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..f68ca7f Binary files /dev/null and b/store/@{FutureOSS}/pkg-manager/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/pkg-manager/main.py b/store/@{FutureOSS}/pkg-manager/main.py new file mode 100644 index 0000000..81020f1 --- /dev/null +++ b/store/@{FutureOSS}/pkg-manager/main.py @@ -0,0 +1,485 @@ +"""包管理插件 - 提供插件配置管理和商店界面""" +import os +import sys +import json +import urllib.request +from pathlib import Path +from oss.logger.logger import Log +from oss.plugin.types import Plugin, Response, register_plugin_type + + +# Gitee 仓库配置 +GITEE_OWNER = "starlight-apk" +GITEE_REPO = "future-oss" +GITEE_BRANCH = "main" +# 使用 raw 文件 URL(不走 API,无频率限制) +GITEE_RAW_BASE = f"https://gitee.com/{GITEE_OWNER}/{GITEE_REPO}/raw/{GITEE_BRANCH}" +GITEE_API_BASE = f"https://gitee.com/api/v5/repos/{GITEE_OWNER}/{GITEE_REPO}/contents" +# Gitee Token(从环境变量读取,可选) +GITEE_TOKEN = os.environ.get("GITEE_TOKEN", "") + + +def _gitee_request(url: str, timeout: int = 15): + """Gitee 请求""" + req = urllib.request.Request(url) + req.add_header("User-Agent", "FutureOSS-PkgManager") + if GITEE_TOKEN: + # Gitee 使用私人令牌认证 + req.add_header("Authorization", f"token {GITEE_TOKEN}") + return urllib.request.urlopen(req, timeout=timeout) + + +class PkgManagerPlugin(Plugin): + """包管理插件""" + + def __init__(self): + self.webui = None + self.storage = None + self.store_dir = Path("./store") + self._remote_cache = None + self._cache_time = 0 + self._cache_ttl = 300 # 5分钟缓存 + + def meta(self): + from oss.plugin.types import Metadata, PluginConfig, Manifest + return Manifest( + metadata=Metadata( + name="pkg-manager", + version="1.0.0", + author="FutureOSS", + description="插件包管理器 - 配置管理和商店" + ), + config=PluginConfig(enabled=True, args={}), + dependencies=["http-api", "webui", "plugin-storage"] + ) + + def set_webui(self, webui): + self.webui = webui + + def set_plugin_storage(self, storage): + self.storage = storage + + def init(self, deps: dict = None): + """init 阶段:注册页面到 WebUI""" + if not self.webui: + Log.warn("pkg-manager", "警告: 未找到 WebUI 依赖") + return + + self.webui.register_page( + path='/packages', + content_provider=self._packages_content, + nav_item={'icon': 'ri-apps-line', 'text': '插件管理'} + ) + self.webui.register_page( + path='/store', + content_provider=self._store_content, + nav_item={'icon': 'ri-store-2-line', 'text': '插件商店'} + ) + Log.info("pkg-manager", "已注册到 WebUI 导航") + + def start(self): + """启动阶段:注册 API 路由""" + if not self.webui or not hasattr(self.webui, 'server') or not self.webui.server: + Log.warn("pkg-manager", "警告: WebUI 服务器未就绪") + return + + router = self.webui.server.router + + # API - 已安装插件 + router.get("/api/plugins", self._handle_list_plugins) + router.get("/api/plugins/:name/config", self._handle_get_config) + router.post("/api/plugins/:name/config", self._handle_save_config) + router.get("/api/plugins/:name/info", self._handle_get_plugin_info) + router.post("/api/plugins/:name/uninstall", self._handle_uninstall) + + # API - 远程商店 + router.get("/api/store/remote", self._handle_remote_store) + router.post("/api/store/install", self._handle_store_install) + + Log.info("pkg-manager", "包管理器已启动") + + def stop(self): + Log.error("pkg-manager", "包管理器已停止") + + # ==================== 页面渲染 ==================== + + def _packages_content(self) -> str: + return self._render_php_view('packages.php', {'pageTitle': '插件管理'}) + + def _store_content(self) -> str: + return self._render_php_view('store.php', {'pageTitle': '插件商店'}) + + def _render_php_view(self, view_name: str, variables: dict) -> str: + import subprocess + + views_dir = os.path.join(os.path.dirname(__file__), 'views') + php_file = os.path.join(views_dir, view_name) + if not os.path.exists(php_file): + return f"

错误: 找不到 {view_name}

" + + php_vars = "" + for key, value in variables.items(): + if isinstance(value, str): + php_vars += f"${key} = '{value}';\n" + else: + php_vars += f"${key} = {json.dumps(value)};\n" + + with open(php_file, 'r', encoding='utf-8') as f: + php_content = f.read() + + tmp_file = os.path.join(views_dir, '.temp_pkg.php') + try: + with open(tmp_file, 'w', encoding='utf-8') as f: + f.write(f"\n{php_content}") + + result = subprocess.run( + ["php", "-f", tmp_file], + capture_output=True, text=True, timeout=10, cwd=views_dir + ) + return result.stdout if result.returncode == 0 else f"
{result.stderr}
" + finally: + try: + if os.path.exists(tmp_file): + os.unlink(tmp_file) + except: + pass + + # ==================== API 处理 ==================== + + def _handle_list_plugins(self, request): + """列出所有已安装插件""" + plugins = self._scan_all_plugins() + return Response(status=200, headers={"Content-Type": "application/json"}, body=json.dumps(plugins, ensure_ascii=False)) + + def _handle_get_config(self, request): + """获取插件配置 schema + 当前值""" + plugin_name = request.path_params.get('name', '') + schema = self._load_config_schema(plugin_name) + current = self._load_plugin_config(plugin_name) + return Response(status=200, headers={"Content-Type": "application/json"}, body=json.dumps({ + "schema": schema, + "current": current + }, ensure_ascii=False)) + + def _handle_save_config(self, request): + """保存插件配置""" + import json as json_mod + try: + body = json_mod.loads(request.body) + plugin_name = request.path_params.get('name', '') + self._save_plugin_config(plugin_name, body) + return Response(status=200, headers={"Content-Type": "application/json"}, body='{"ok":true}') + except Exception as e: + return Response(status=500, headers={"Content-Type": "application/json"}, body=json.dumps({"error": str(e)})) + + def _handle_get_plugin_info(self, request): + """获取插件详细信息""" + plugin_name = request.path_params.get('name', '') + info = self._get_plugin_detailed_info(plugin_name) + return Response(status=200, headers={"Content-Type": "application/json"}, body=json.dumps(info, ensure_ascii=False)) + + def _handle_uninstall(self, request): + """卸载插件""" + import shutil + plugin_name = request.path_params.get('name', '') + # 查找插件目录 + plugin_dir = self._find_plugin_dir(plugin_name) + if not plugin_dir: + return Response(status=404, body='{"error":"插件未安装"}') + try: + shutil.rmtree(plugin_dir) + return Response(status=200, body='{"ok":true}') + except Exception as e: + return Response(status=500, body=json.dumps({"error": str(e)})) + + def _handle_remote_store(self, request): + """从 Gitee API 获取远程插件列表""" + try: + plugins = self._fetch_remote_plugins() + return Response(status=200, headers={"Content-Type": "application/json"}, body=json.dumps(plugins, ensure_ascii=False)) + except Exception as e: + return Response(status=500, body=json.dumps({"error": str(e)})) + + def _handle_store_install(self, request): + """安装插件""" + import json as json_mod + try: + body = json_mod.loads(request.body) + name = body.get("name", "") + author = body.get("author", "FutureOSS") + success = self._install_from_gitee(name, author) + return Response(status=200, body=json.dumps({"ok": success})) + except Exception as e: + return Response(status=500, body=json.dumps({"error": str(e)})) + + # ==================== Gitee 远程商店 ==================== + + def _fetch_remote_plugins(self) -> list: + """从 Gitee 获取所有可用插件(带缓存+限速+重试)""" + import time + now = time.time() + if self._remote_cache and (now - self._cache_time) < self._cache_ttl: + return self._remote_cache + + plugins = [] + try: + store_url = f"{GITEE_API_BASE}/store" + # 重试 3 次,每次间隔增加 + for attempt in range(3): + try: + with _gitee_request(store_url, timeout=15) as resp: + dirs = json.loads(resp.read().decode("utf-8")) + break + except Exception as e: + if attempt < 2: + time.sleep(1 + attempt) + continue + raise + + time.sleep(0.5) + + for dir_info in dirs: + if dir_info.get("type") != "dir": + continue + author = dir_info.get("name", "") + if not author.startswith("@{"): + continue + + author_url = f"{GITEE_API_BASE}/store/{urllib.parse.quote(author, safe='')}" + for attempt in range(3): + try: + with _gitee_request(author_url, timeout=15) as resp: + plugin_dirs = json.loads(resp.read().decode("utf-8")) + break + except Exception: + if attempt < 2: + time.sleep(1 + attempt) + continue + raise + + time.sleep(0.5) + + for plugin_dir in plugin_dirs: + if plugin_dir.get("type") != "dir": + continue + plugin_name = plugin_dir.get("name", "") + + manifest_url = f"{GITEE_API_BASE}/store/{urllib.parse.quote(author, safe='')}/{plugin_name}/manifest.json" + manifest = {} + for attempt in range(3): + try: + with _gitee_request(manifest_url, timeout=15) as resp: + manifest = json.loads(resp.read().decode("utf-8")) + break + except Exception: + if attempt < 2: + time.sleep(1 + attempt) + continue + + plugins.append({ + "name": plugin_name, + "author": author, + "full_name": f"{author}/{plugin_name}", + "metadata": manifest.get("metadata", {}), + "dependencies": manifest.get("dependencies", []), + "has_config": False, + "is_installed": self._is_plugin_installed(plugin_name, author) + }) + + time.sleep(0.5) + + self._remote_cache = plugins + self._cache_time = now + except Exception as e: + Log.error("pkg-manager", f"获取远程插件列表失败: {e}") + + return plugins + + def _install_from_gitee(self, plugin_name: str, author: str) -> bool: + """从 Gitee 下载并安装插件(使用 raw URL)""" + import shutil, time + install_dir = self.store_dir / author / plugin_name + install_dir.mkdir(parents=True, exist_ok=True) + + try: + # 获取目录结构(需要一次 API 调用) + api_url = f"{GITEE_API_BASE}/store/{author}/{plugin_name}" + with _gitee_request(api_url, timeout=15) as resp: + items = json.loads(resp.read().decode("utf-8")) + + time.sleep(0.5) + + for item in items: + if item.get("type") == "file": + # 使用 raw URL 下载文件(不走 API) + filename = item.get("name") + raw_url = f"{GITEE_RAW_BASE}/store/{author}/{plugin_name}/{filename}" + local_file = install_dir / filename + try: + with _gitee_request(raw_url, timeout=15) as resp: + content = resp.read() + with open(local_file, 'wb') as f: + f.write(content) + except: + pass + elif item.get("type") == "dir": + sub_dir = item.get("name") + self._download_dir_raw(author, plugin_name, sub_dir, install_dir / sub_dir) + time.sleep(0.3) + + Log.info("pkg-manager", f"已安装: {author}/{plugin_name}") + return True + except Exception as e: + Log.error("pkg-manager", f"安装失败 {plugin_name}: {e}") + if install_dir.exists(): + shutil.rmtree(install_dir) + return False + + def _download_dir_raw(self, author: str, plugin: str, sub_dir: str, local_dir: Path): + """使用 raw URL 递归下载子目录""" + import time + try: + api_url = f"{GITEE_API_BASE}/store/{author}/{plugin}/{sub_dir}" + with _gitee_request(api_url, timeout=15) as resp: + items = json.loads(resp.read().decode("utf-8")) + + local_dir.mkdir(parents=True, exist_ok=True) + for item in items: + if item.get("type") == "file": + filename = item.get("name") + raw_url = f"{GITEE_RAW_BASE}/store/{author}/{plugin}/{sub_dir}/{filename}" + try: + with _gitee_request(raw_url, timeout=15) as resp: + content = resp.read() + with open(local_dir / filename, 'wb') as f: + f.write(content) + except: + pass + elif item.get("type") == "dir": + self._download_dir_raw(author, plugin, f"{sub_dir}/{item.get('name')}", local_dir / item.get("name")) + except: + pass + + # ==================== 辅助方法 ==================== + + def _scan_all_plugins(self) -> list: + """扫描本地已安装插件""" + plugins = [] + if not self.store_dir.exists(): + return plugins + + for author_dir in self.store_dir.iterdir(): + if author_dir.is_dir() and author_dir.name.startswith("@{"): + for plugin_dir in author_dir.iterdir(): + if plugin_dir.is_dir() and (plugin_dir / "main.py").exists(): + manifest_path = plugin_dir / "manifest.json" + if manifest_path.exists(): + with open(manifest_path, 'r', encoding='utf-8') as f: + manifest = json.load(f) + plugins.append({ + "name": plugin_dir.name, + "full_name": f"{author_dir.name}/{plugin_dir.name}", + "author": author_dir.name, + "metadata": manifest.get("metadata", {}), + "dependencies": manifest.get("dependencies", []), + "has_config": (plugin_dir / "config.json").exists(), + "is_installed": True + }) + return plugins + + def _is_plugin_installed(self, plugin_name: str, author: str) -> bool: + """检查插件是否已安装""" + plugin_dir = self.store_dir / author / plugin_name + return (plugin_dir / "main.py").exists() + + def _find_plugin_dir(self, plugin_name: str) -> Path | None: + """查找插件目录""" + if not self.store_dir.exists(): + return None + for author_dir in self.store_dir.iterdir(): + if author_dir.is_dir(): + plugin_dir = author_dir / plugin_name + if plugin_dir.exists() and (plugin_dir / "main.py").exists(): + return plugin_dir + return None + + def _load_config_schema(self, plugin_name: str) -> dict: + """加载插件 config.json schema""" + plugin_dir = self._find_plugin_dir(plugin_name) + if not plugin_dir: + return {} + schema_path = plugin_dir / "config.json" + if not schema_path.exists(): + return {} + with open(schema_path, 'r', encoding='utf-8') as f: + return json.load(f) + + def _load_plugin_config(self, plugin_name: str) -> dict: + """加载插件当前配置""" + schema = self._load_config_schema(plugin_name) + defaults = {} + for key, field_def in schema.items(): + defaults[key] = field_def.get("default") + if self.storage: + storage_instance = self.storage.get_storage("pkg-manager") + user_config = storage_instance.get(f"plugin_config.{plugin_name}", {}) + defaults.update(user_config) + return defaults + + def _save_plugin_config(self, plugin_name: str, config: dict): + """保存插件配置""" + if self.storage: + storage_instance = self.storage.get_storage("pkg-manager") + storage_instance.set(f"plugin_config.{plugin_name}", config) + + def _get_plugin_detailed_info(self, plugin_name: str) -> dict: + """获取插件的依赖、事件、页面信息""" + dependencies = [] + events = [] # 事件 = 功能描述 + plugin_dir = self._find_plugin_dir(plugin_name) + + if plugin_dir: + manifest_path = plugin_dir / "manifest.json" + if manifest_path.exists(): + with open(manifest_path, 'r', encoding='utf-8') as f: + manifest = json.load(f) + dependencies = manifest.get("dependencies", []) + # 从 manifest 的 metadata.description 或 type 中提取功能 + metadata = manifest.get("metadata", {}) + plugin_type = metadata.get("type", "") + if plugin_type: + events.append(f"类型: {plugin_type}") + # 从 manifest config 推断功能 + config = manifest.get("config", {}) + if config.get("enabled"): + events.append("已启用") + + # 只返回该插件自己注册的页面(通过插件名匹配) + pages = [] + if self.webui and hasattr(self.webui, 'server') and self.webui.server: + for path, provider in self.webui.server.pages.items(): + # 检查 provider 是否属于该插件 + provider_name = getattr(provider, '__self__', None) + if provider_name and isinstance(provider_name, PkgManagerPlugin): + continue # 跳过自己的页面 + # 通过路径前缀判断(dashboard 注册 /dashboard) + if path == f'/{plugin_name}' or path.startswith(f'/{plugin_name}/'): + pages.append({"path": path}) + # 特殊处理:首页 + if plugin_name == 'webui' and path == '/': + pages.append({"path": path}) + + return { + "name": plugin_name, + "dependencies": dependencies, + "config_fields": list(self._load_config_schema(plugin_name).keys()), + "pages": pages, + "events": events + } + + +register_plugin_type("PkgManagerPlugin", PkgManagerPlugin) + + +def New(): + return PkgManagerPlugin() diff --git a/store/@{FutureOSS}/pkg-manager/manifest.json b/store/@{FutureOSS}/pkg-manager/manifest.json new file mode 100644 index 0000000..d6bf07d --- /dev/null +++ b/store/@{FutureOSS}/pkg-manager/manifest.json @@ -0,0 +1,15 @@ +{ + "metadata": { + "name": "pkg-manager", + "version": "1.0.0", + "author": "FutureOSS", + "description": "插件包管理器 - 配置管理和商店", + "type": "webui-extension" + }, + "config": { + "enabled": true, + "args": {} + }, + "dependencies": ["http-api", "webui", "plugin-storage"], + "permissions": ["*"] +} diff --git a/store/@{FutureOSS}/pkg-manager/views/packages.php b/store/@{FutureOSS}/pkg-manager/views/packages.php new file mode 100644 index 0000000..4627e81 --- /dev/null +++ b/store/@{FutureOSS}/pkg-manager/views/packages.php @@ -0,0 +1,337 @@ +
+ + + +
+

已安装插件

+
+ +
+
+ +
+
+ + +
+ + + +
+ + +
diff --git a/store/@{FutureOSS}/pkg-manager/views/store.php b/store/@{FutureOSS}/pkg-manager/views/store.php new file mode 100644 index 0000000..ab407e9 --- /dev/null +++ b/store/@{FutureOSS}/pkg-manager/views/store.php @@ -0,0 +1,197 @@ +
+ + + +
+
分类
+
+ 全部插件 +
+
+ 可安装 +
+
+ 已安装 +
+
+ 可配置 +
+
+ + +
+
+

插件商店

+

浏览并安装插件来扩展功能

+
+ + +
+ +

正在加载插件列表...

+
+ + +
+ +

加载失败,请稍后重试

+
+ +
+ +
+ +
+ +
+ +
+ +

+
+
+ + +
diff --git a/store/@{FutureOSS}/pkg/SIGNATURE b/store/@{FutureOSS}/pkg/SIGNATURE new file mode 100644 index 0000000..4afd13b --- /dev/null +++ b/store/@{FutureOSS}/pkg/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "dXU/zN0Zge7OC8UZgWXZVhPn7LQyiKQw4iUVZAI0P4PA7zGed3cnXa7GFzVnUKxyZMKaOITcGeg7yIM9SWM7WRTWj3N1e6F/0ac6zQ57WgREUA2zc4w0/Vc742i0+KSrE1TkICZl1CTa1x3TG3VJQo0qw4FGPijKjJQIaA9yw+yLhm0dkMefZGVAuYRnupFvKxX1xar0vx6JPpoDmHxvU92PdzbR1ggsB5hOzIrvd3aVJ1U8GbogVhtaabToK9IXbX6qrTY32ffZpEOI5n0IqAvxZ81IUV3bwhf72nP6sedEEKJzgOGfqHhMalOpjsEHNiHnX3UgBfiXzeDn2zN0NevTGCGzvgQHc3/5o/Ct9wG8ujqlNLi37jXt1DrTnIF1IBsW73ltdaMvl4IgQ0Sln2Y7QMNt3CDtwNBSBiLUhTnMjPN7QVaCl7lMM0PJH5tWg3rlSdf7+LGUN535uMwrtEJEmhafo2lcApInEZryEmRcUb22Wl3xCqGgK5yk30QqGHCwY/h4fNhx2VE7LWIoD/jMJNH+TPXTzPPUGHOGB5zaR8v+qtohOwRYPewUkbEArg7qjsOgHerHziLYBY2yH1/4oi9/N7DYsgmRyHrl4siuo+5HtPar+q29yDORs5UgxK3VNHncElVWXQ9DGzIrm3Ffj610nw7kOiU58HrBjj8=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964952.754572, + "plugin_hash": "36a948e470e6cd7ac1b51a385f21fc615c36049e9cb3fac25cdaef8161063ef1", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/pkg/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/pkg/__pycache__/main.cpython-313.pyc index f181467..5db320e 100644 Binary files a/store/@{FutureOSS}/pkg/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/pkg/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/pkg/main.py b/store/@{FutureOSS}/pkg/main.py index e9170b1..905556e 100644 --- a/store/@{FutureOSS}/pkg/main.py +++ b/store/@{FutureOSS}/pkg/main.py @@ -7,11 +7,13 @@ import urllib.parse from pathlib import Path from typing import Any, Optional +from oss.logger.logger import Log from oss.plugin.types import Plugin, register_plugin_type # 远程仓库地址(可配置) -DEFAULT_REGISTRY = "https://gitee.com/starlight-apk/future-oss-pkg/raw/main" +# 插件存储在 future-oss 仓库的 store/ 目录下 +DEFAULT_REGISTRY = "https://gitee.com/starlight-apk/future-oss/raw/main" # 插件安装目录 PKG_DIR = Path("./data/pkg") @@ -54,28 +56,16 @@ class PackageManager: def search(self, query: str = "") -> list[PackageInfo]: """搜索可用的包""" - # 从远程仓库获取包索引 - index_url = f"{self.registry}/index.json" - try: - with urllib.request.urlopen(index_url, timeout=10) as resp: - index = json.loads(resp.read().decode("utf-8")) - except Exception: - # 本地缓存 - return list(self.index_cache.values()) - + # 简化版本:直接返回本地缓存 + # 实际使用时可以通过 API 或配置文件维护一个插件索引 + return self._search_from_cache(query) + + def _search_from_cache(self, query: str = "") -> list[PackageInfo]: + """从本地缓存搜索包""" results = [] - for pkg_name, pkg_info in index.items(): + for pkg_name, pkg_info in self.index_cache.items(): if not query or query.lower() in pkg_name.lower() or query.lower() in pkg_info.get("description", "").lower(): - info = PackageInfo() - info.name = pkg_name - info.version = pkg_info.get("version", "") - info.author = pkg_info.get("author", "") - info.description = pkg_info.get("description", "") - info.download_url = pkg_info.get("download_url", "") - info.dependencies = pkg_info.get("dependencies", []) - results.append(info) - self.index_cache[pkg_name] = info - + results.append(pkg_info) return results def install(self, name: str, version: str = "") -> bool: @@ -107,11 +97,12 @@ class PackageManager: if not pkg_info or not pkg_info.download_url: # 尝试从远程仓库直接构建 URL + # 插件存储在 store/@{author}/plugin_name 目录下 pkg_info = PackageInfo() pkg_info.name = plugin_name pkg_info.author = author pkg_info.version = version or "1.0.0" - pkg_info.download_url = self.registry + "/store/@{" + author + "/" + plugin_name + "}" + pkg_info.download_url = f"{self.registry}/store/@{{{author}}}/{plugin_name}" # 创建安装目录 @{author}/plugin_name install_dir = PKG_DIR / ("@{" + author + "}") / plugin_name @@ -135,10 +126,10 @@ class PackageManager: # 更新已安装列表 full_name = "@{" + author + "}/" + plugin_name self.installed[full_name] = manifest_data - print(f"[pkg] 已安装: {full_name} {manifest_data.get('metadata', {}).get('version', '')}") + Log.info("pkg", f"已安装: {full_name} {manifest_data.get('metadata', {}).get('version', '')}") return True except Exception as e: - print(f"[pkg] 安装失败 {name}: {e}") + Log.error("pkg", f"安装失败 {name}: {e}") # 清理失败的安装 if install_dir.exists(): shutil.rmtree(install_dir) @@ -159,7 +150,7 @@ class PackageManager: install_dir = PKG_DIR / name if not install_dir.exists(): - print(f"[pkg] 包未安装: {name}") + Log.info("pkg", f"包未安装: {name}") return False try: @@ -169,10 +160,10 @@ class PackageManager: if key == name or key.endswith("/" + install_dir.name): del self.installed[key] break - print(f"[pkg] 已卸载: {name}") + Log.info("pkg", f"已卸载: {name}") return True except Exception as e: - print(f"[pkg] 卸载失败 {name}: {e}") + Log.error("pkg", f"卸载失败 {name}: {e}") return False def update(self, name: str = "") -> bool: @@ -180,7 +171,7 @@ class PackageManager: if name: # 更新单个包 if name not in self.installed: - print(f"[pkg] 包未安装: {name}") + Log.info("pkg", f"包未安装: {name}") return False return self.install(name) else: @@ -205,11 +196,11 @@ class PkgPlugin(Plugin): def init(self, deps: dict = None): """初始化""" PKG_DIR.mkdir(parents=True, exist_ok=True) - print("[pkg] 包管理器已初始化") + Log.info("pkg", "包管理器已初始化") def start(self): """启动""" - print(f"[pkg] 包管理器已启动,已安装 {len(self.manager.installed)} 个包") + Log.info("pkg", f"包管理器已启动,已安装 {len(self.manager.installed)} 个包") def stop(self): """停止""" diff --git a/store/@{FutureOSS}/plugin-bridge/SIGNATURE b/store/@{FutureOSS}/plugin-bridge/SIGNATURE new file mode 100644 index 0000000..9971ffe --- /dev/null +++ b/store/@{FutureOSS}/plugin-bridge/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "yHmcdnBP6fx7TYFqHyiQeVYiP+S/9o7gx+fCC7nELQ2ZM55yXn9e4qpYWgPGAEw4zmuZbnKwLj0JQ1sE8BW28059+HWCj34ytUY/gckNvEkN+cGrqefwxWPGU19tysDC9Iy+HgBc+t34/igLZvRbcqpCpE0KH9SGfe34de6C60fL/HYZ1v3A29R05VmoPUBIOUY3X/9R5q4fYkjQqzvJ9LXujRR7Uyg8vP4dQo3k/MdxALg0xemXrMNRvX9F2g7i7DLCG8ABNxLHl7u5BymNXqBBClSu+/Fuf0HeyzLyYoOUP0Jhbxf56ep8jFLZRTU1qbt6itmaZgF8YSUh4oq1rWNYHZLZYH9sO6H32XsqXSq/509DkKXWJDZtIvJB/yrmVpt1Anj8YfMyA4pZ/R+htMa+coOlCAw20lnN0IMJW8oduKoYHFKMKkE7b++TzUv+7jon7WRWW8/2BXUFGV62jUSkPzI5o4TOgflHcCbLJ6SuOutxTpGiereVdDxlLRUVwBcRxY89DM9LKzqBPCbfG4Q6bVTtIvnyHn/ARQuYYXw41QzJGUYss/pS0YIH0YgYUHR88RCFqlZI53JXv1Y7kzieEprEWBBWEr6YxmYhx010W36hI0mM7YpBK3XWVkN7oJFBDt7DzFSQEYeeKDV/U0ZZgA5ufSiB8LYLYVjpz9Y=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964952.957446, + "plugin_hash": "97113f6d132bf58ea11688416b0fa3dda3a3642f3b82fd1e0b65ad06f8aad39c", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/plugin-bridge/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/plugin-bridge/__pycache__/main.cpython-313.pyc index a9d82af..a42905d 100644 Binary files a/store/@{FutureOSS}/plugin-bridge/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/plugin-bridge/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-bridge/main.py b/store/@{FutureOSS}/plugin-bridge/main.py index a884001..f20ae22 100644 --- a/store/@{FutureOSS}/plugin-bridge/main.py +++ b/store/@{FutureOSS}/plugin-bridge/main.py @@ -2,6 +2,7 @@ from typing import Any, Callable, Optional from dataclasses import dataclass, field +from oss.logger.logger import Log from oss.plugin.types import Plugin, register_plugin_type @@ -179,7 +180,7 @@ class PluginBridgePlugin(Plugin): def start(self): """启动""" - print("[plugin-bridge] 事件总线、广播、桥接、RPC、共享存储已启动") + Log.info("plugin-bridge", "事件总线、广播、桥接、RPC、共享存储已启动") def stop(self): """停止""" diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/SIGNATURE b/store/@{FutureOSS}/plugin-loader-pro.disabled/SIGNATURE new file mode 100644 index 0000000..d75fb2f --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "j3U1ZFmpc+pOBC8auYyj84O9DMaAmhOx7F0yGIdrpnclTvteuuXDa7qdBduF+cTu7JStUxN9Yx4oA8dZkorvCZgShQ26jWgLxTAUpa74Pqv6b1q1KQVGcgmiIcF5spIu3zNH4R2tfAWidm7Jncmd2BDDrjVMg16d6Bk73fvMN8GajAaNt3PELIr55LFEER3mOMB9ooeuvUmr7EIoDvZap5bLO4iP88kZaKd6xArNhYi5sCgm4HOxKxUFBOLRAnmJFcOKTqGLL0kYwsoqiN1UPLEawndQKNyX47ZQRfKCut8qQZEPpXl4rYpI6j++Lw7NNrj/jX+IEWFpqMaXiumJAG3tDWKWd5I/7/CAOpttERooJEjG2tVyM2ka9HjIyrc4TrWD9DZTamwkRlrbWm0Q7soTn3O6ZkolQ2n/WUxWKu1o84OHkeeoXDg9AS/uiKsOf7ufTpL7doXUm4bj4xTNkPk63D5PlAoF/kLBgcLHo2UkdxYhv9Y/moig2ogqr//nU5ucIZLmGIIX2Bag8RKgwnhRnKZ+KIGJntIuOoAuoH1H3G/EV42/siqU/AsRSOBtCxhAoqBxaHzZMnyios8kguE/6BfIEs7yS4DzN2ANNcA6tXfbvWGq7oeEB2DBAdamPbyVB76rSsdi0/4zGugvXmBJO4yZuxcuu/HeBH7ES+0=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964226.5213168, + "plugin_hash": "bed620b64c10798828613a45e3227a7849a9a450e471dfd009135354fb650a1e", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..519786d Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..4fbec5f Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/breaker.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/breaker.cpython-313.pyc new file mode 100644 index 0000000..f0e5b8a Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/breaker.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/state.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/state.cpython-313.pyc new file mode 100644 index 0000000..c3c701b Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/__pycache__/state.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/breaker.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/breaker.py new file mode 100644 index 0000000..9a4bc59 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/breaker.py @@ -0,0 +1,64 @@ +"""熔断器实现""" +import time +from typing import Callable, Any +from .state import CircuitState + + +class CircuitBreaker: + """熔断器""" + + def __init__(self, failure_threshold: int = 3, recovery_timeout: int = 60, half_open_requests: int = 1): + self.failure_threshold = failure_threshold + self.recovery_timeout = recovery_timeout + self.half_open_requests = half_open_requests + + self.state = CircuitState.CLOSED + self.failure_count = 0 + self.success_count = 0 + self.last_failure_time = 0 + self.half_open_calls = 0 + + def call(self, func: Callable, *args, **kwargs) -> Any: + """执行调用""" + if self.state == CircuitState.OPEN: + if time.time() - self.last_failure_time >= self.recovery_timeout: + self.state = CircuitState.HALF_OPEN + self.half_open_calls = 0 + else: + raise Exception("熔断器已打开,调用被拒绝") + + try: + result = func(*args, **kwargs) + self._on_success() + return result + except Exception as e: + self._on_failure() + raise + + def _on_success(self): + """成功回调""" + self.failure_count = 0 + if self.state == CircuitState.HALF_OPEN: + self.half_open_calls += 1 + if self.half_open_calls >= self.half_open_requests: + self.state = CircuitState.CLOSED + self.half_open_calls = 0 + + def _on_failure(self): + """失败回调""" + self.failure_count += 1 + self.last_failure_time = time.time() + + if self.state == CircuitState.HALF_OPEN: + self.state = CircuitState.OPEN + elif self.failure_count >= self.failure_threshold: + self.state = CircuitState.OPEN + + def reset(self): + """重置熔断器""" + self.state = CircuitState.CLOSED + self.failure_count = 0 + self.half_open_calls = 0 + + def get_state(self) -> str: + return self.state diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/state.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/state.py new file mode 100644 index 0000000..beed7bf --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/circuit/state.py @@ -0,0 +1,8 @@ +"""熔断器状态枚举""" + + +class CircuitState: + """熔断器状态""" + CLOSED = "closed" # 正常状态 + OPEN = "open" # 熔断状态 + HALF_OPEN = "half_open" # 半开状态 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..de50d1d Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/config.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000..6f6ed91 Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/config.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/enhancer.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/enhancer.cpython-313.pyc new file mode 100644 index 0000000..2ec0c16 Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/__pycache__/enhancer.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/config.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/config.py new file mode 100644 index 0000000..0970459 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/config.py @@ -0,0 +1,56 @@ +"""Pro 配置模型""" + + +class CircuitBreakerConfig: + """熔断器配置""" + def __init__(self, config: dict = None): + config = config or {} + self.failure_threshold = config.get("failure_threshold", 3) + self.recovery_timeout = config.get("recovery_timeout", 60) + self.half_open_requests = config.get("half_open_requests", 1) + + +class RetryConfig: + """重试配置""" + def __init__(self, config: dict = None): + config = config or {} + self.max_retries = config.get("max_retries", 3) + self.backoff_factor = config.get("backoff_factor", 2) + self.initial_delay = config.get("initial_delay", 1) + + +class HealthCheckConfig: + """健康检查配置""" + def __init__(self, config: dict = None): + config = config or {} + self.interval = config.get("interval", 30) + self.timeout = config.get("timeout", 5) + self.max_failures = config.get("max_failures", 5) + + +class AutoRecoveryConfig: + """自动恢复配置""" + def __init__(self, config: dict = None): + config = config or {} + self.enabled = config.get("enabled", True) + self.max_attempts = config.get("max_attempts", 3) + self.delay = config.get("delay", 10) + + +class IsolationConfig: + """隔离配置""" + def __init__(self, config: dict = None): + config = config or {} + self.enabled = config.get("enabled", True) + self.timeout_per_plugin = config.get("timeout_per_plugin", 30) + + +class ProConfig: + """Pro 总配置""" + def __init__(self, config: dict = None): + config = config or {} + self.circuit_breaker = CircuitBreakerConfig(config.get("circuit_breaker")) + self.retry = RetryConfig(config.get("retry")) + self.health_check = HealthCheckConfig(config.get("health_check")) + self.auto_recovery = AutoRecoveryConfig(config.get("auto_recovery")) + self.isolation = IsolationConfig(config.get("isolation")) diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/enhancer.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/enhancer.py new file mode 100644 index 0000000..5ff45be --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/enhancer.py @@ -0,0 +1,209 @@ +"""插件加载增强器""" +from ..circuit.breaker import CircuitBreaker +from ..recovery.health import HealthChecker +from ..recovery.auto_fix import AutoRecovery +from ..utils.logger import ProLogger +from .config import ProConfig + + +class PluginLoaderEnhancer: + """插件加载增强器 - 为现有 plugin-loader 提供高级机制""" + + def __init__(self, plugin_manager, config: ProConfig): + self.pm = plugin_manager + self.config = config + self._breakers = {} + self._health_checker = None + self._auto_recovery = AutoRecovery( + config.auto_recovery.max_attempts, + config.auto_recovery.delay + ) + self._enhanced = False + + def enhance(self): + """增强 plugin-loader""" + if self._enhanced: + return + + ProLogger.info("enhancer", "开始增强 plugin-loader...") + + # 1. 为所有插件创建熔断器 + self._setup_circuit_breakers() + + # 2. 包装启动方法(带重试和容错) + self._wrap_start_methods() + + # 3. 启动健康检查 + self._start_health_check() + + self._enhanced = True + ProLogger.info("enhancer", "增强完成,共增强 {} 个插件".format( + len(self.pm.plugins) + )) + + def _setup_circuit_breakers(self): + """为所有插件创建熔断器""" + for name, info in self.pm.plugins.items(): + self._breakers[name] = CircuitBreaker( + self.config.circuit_breaker.failure_threshold, + self.config.circuit_breaker.recovery_timeout, + self.config.circuit_breaker.half_open_requests + ) + ProLogger.debug("enhancer", f"为 {name} 创建熔断器") + + def _wrap_start_methods(self): + """包装启动方法""" + original_start_all = getattr(self.pm, 'start_all', None) + if original_start_all: + def wrapped_start_all(): + self._safe_start_all() + + self.pm.start_all = wrapped_start_all + ProLogger.info("enhancer", "已包装 start_all 方法") + + original_init_and_start = getattr( + self.pm, 'init_and_start_all', None + ) + if original_init_and_start: + def wrapped_init_and_start(): + self._safe_init_and_start_all() + + self.pm.init_and_start_all = wrapped_init_and_start + ProLogger.info("enhancer", "已包装 init_and_start_all 方法") + + def _safe_init_and_start_all(self): + """安全的初始化并启动""" + ordered = self._get_ordered_plugins() + + # 安全初始化 + for name in ordered: + self._safe_call(name, 'init', '初始化') + + # 安全启动 + for name in ordered: + self._safe_call(name, 'start', '启动') + + def _safe_start_all(self): + """安全启动所有""" + for name in self.pm.plugins: + self._safe_call(name, 'start', '启动') + + def _safe_call(self, name: str, method: str, action: str): + """安全调用插件方法(带熔断和重试)""" + info = self.pm.plugins.get(name) + if not info: + return + + instance = info.get("instance") + if not instance or not hasattr(instance, method): + return + + breaker = self._breakers.get(name) + if not breaker: + # 没有熔断器,直接调用 + try: + getattr(instance, method)() + except Exception as e: + ProLogger.error("safe", f"{name} {action}失败: {e}") + self._on_plugin_error(name, info, str(e)) + return + + # 有熔断器,包装调用 + def do_call(): + return getattr(instance, method)() + + try: + breaker.call(do_call) + info["info"].error_count = 0 + ProLogger.info("safe", f"{name} {action}成功") + except Exception as e: + ProLogger.error("safe", f"{name} {action}失败: {e}") + self._on_plugin_error(name, info, str(e)) + + def _on_plugin_error(self, name: str, info: dict, error: str): + """插件错误处理""" + info["info"].error_count += 1 + info["info"].last_error = error + + # 自动恢复 + if self.config.auto_recovery.enabled: + plugin_dir = info.get("dir") + module = info.get("module") + + if plugin_dir: + result = self._auto_recovery.attempt_recovery( + name, plugin_dir, module, info.get("instance") + ) + if result: + info["instance"] = result + info["info"].error_count = 0 + ProLogger.info("recovery", f"{name} 自动恢复成功") + + def _start_health_check(self): + """启动健康检查""" + self._health_checker = HealthChecker( + self.config.health_check.interval, + self.config.health_check.timeout, + self.config.health_check.max_failures + ) + + for name, info in self.pm.plugins.items(): + self._health_checker.add_plugin(name, info["instance"]) + + self._health_checker.start( + on_failure_callback=self._on_health_check_failure + ) + ProLogger.info("enhancer", "健康检查已启动") + + def _on_health_check_failure(self, name: str): + """健康检查失败回调""" + ProLogger.error("health", f"插件 {name} 健康检查失败") + + info = self.pm.plugins.get(name) + if not info: + return + + plugin_dir = info.get("dir") + module = info.get("module") + + if plugin_dir: + result = self._auto_recovery.attempt_recovery( + name, plugin_dir, module, info.get("instance") + ) + if result: + info["instance"] = result + self._health_checker.reset_failure_count(name) + ProLogger.info("recovery", f"{name} 健康恢复成功") + + def _get_ordered_plugins(self) -> list[str]: + """获取按依赖排序的插件列表""" + ordered = [] + visited = set() + + def visit(name): + if name in visited: + return + visited.add(name) + + info = self.pm.plugins.get(name) + if not info: + return + + for dep in info["info"].dependencies: + clean_dep = dep.rstrip("}") + if clean_dep in self.pm.plugins: + visit(clean_dep) + + ordered.append(name) + + for name in self.pm.plugins: + visit(name) + + return ordered + + def disable(self): + """禁用增强器""" + if self._health_checker: + self._health_checker.stop() + self._enhanced = False + ProLogger.info("enhancer", "增强器已禁用") diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/manager.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/manager.py new file mode 100644 index 0000000..7563d3e --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/manager.py @@ -0,0 +1,279 @@ +"""插件加载 Pro - 核心管理器""" +import sys +import json +import importlib.util +from pathlib import Path +from typing import Any, Optional + +from oss.plugin.types import Plugin +from .config import ProConfig +from .registry import CapabilityRegistry +from .proxy import PluginProxy, PermissionError +from ..models.plugin_info import PluginInfo +from ..circuit.breaker import CircuitBreaker +from ..retry.handler import RetryHandler +from ..fallback.handler import FallbackHandler +from ..recovery.health import HealthChecker +from ..recovery.auto_fix import AutoRecovery +from ..isolation.timeout import TimeoutController, TimeoutError +from ..utils.logger import ProLogger +from oss.plugin.capabilities import scan_capabilities + + +class ProPluginManager: + """Pro 插件管理器""" + + def __init__(self, config: ProConfig): + self.config = config + self.plugins: dict[str, dict[str, Any]] = {} + self.capability_registry = CapabilityRegistry() + self._breakers: dict[str, CircuitBreaker] = {} + self._health_checker = HealthChecker( + config.health_check.interval, + config.health_check.timeout, + config.health_check.max_failures + ) + self._auto_recovery = AutoRecovery( + config.auto_recovery.max_attempts, + config.auto_recovery.delay + ) + + def load_all(self, store_dir: str = "store"): + """加载所有插件""" + ProLogger.info("loader", "开始扫描插件...") + + self._load_from_dir(Path(store_dir)) + self._load_from_dir(Path("./data/pkg")) + + ProLogger.info("loader", f"共加载 {len(self.plugins)} 个插件") + + def _load_from_dir(self, store_dir: Path): + """从目录加载插件""" + if not store_dir.exists(): + return + + for author_dir in store_dir.iterdir(): + if not author_dir.is_dir(): + continue + + for plugin_dir in author_dir.iterdir(): + if not plugin_dir.is_dir(): + continue + + main_file = plugin_dir / "main.py" + if not main_file.exists(): + continue + + self._load_single_plugin(plugin_dir) + + def _load_single_plugin(self, plugin_dir: Path) -> Optional[Any]: + """加载单个插件""" + main_file = plugin_dir / "main.py" + manifest_file = plugin_dir / "manifest.json" + + try: + manifest = {} + if manifest_file.exists(): + with open(manifest_file, "r", encoding="utf-8") as f: + manifest = json.load(f) + + spec = importlib.util.spec_from_file_location( + f"pro_plugin.{plugin_dir.name}", str(main_file) + ) + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + spec.loader.exec_module(module) + + if not hasattr(module, "New"): + return None + + instance = module.New() + + plugin_name = plugin_dir.name.rstrip("}") + permissions = manifest.get("permissions", []) + + if permissions: + instance = PluginProxy( + plugin_name, instance, permissions, self.plugins + ) + + info = PluginInfo() + meta = manifest.get("metadata", {}) + info.name = meta.get("name", plugin_name) + info.version = meta.get("version", "1.0.0") + info.author = meta.get("author", "") + info.description = meta.get("description", "") + info.dependencies = manifest.get("dependencies", []) + info.capabilities = scan_capabilities(plugin_dir) + + for cap in info.capabilities: + self.capability_registry.register_provider( + cap, plugin_name, instance + ) + + self._breakers[plugin_name] = CircuitBreaker( + self.config.circuit_breaker.failure_threshold, + self.config.circuit_breaker.recovery_timeout, + self.config.circuit_breaker.half_open_requests + ) + + self.plugins[plugin_name] = { + "instance": instance, + "module": module, + "info": info, + "permissions": permissions, + "dir": plugin_dir + } + + ProLogger.info("loader", f"已加载: {plugin_name} v{info.version}") + return instance + + except Exception as e: + ProLogger.error("loader", f"加载失败 {plugin_dir.name}: {e}") + return None + + def init_and_start_all(self): + """初始化并启动所有插件""" + ProLogger.info("manager", "开始初始化所有插件...") + + self._inject_dependencies() + ordered = self._get_ordered_plugins() + + for name in ordered: + self._safe_init(name) + + ProLogger.info("manager", "开始启动所有插件...") + for name in ordered: + self._safe_start(name) + + self._health_checker.start( + on_failure_callback=self._on_plugin_failure + ) + + def _safe_init(self, name: str): + """安全初始化插件""" + info = self.plugins[name] + instance = info["instance"] + breaker = self._breakers[name] + + try: + breaker.call(instance.init) + info["info"].status = "initialized" + ProLogger.info("manager", f"已初始化: {name}") + except Exception as e: + ProLogger.error("manager", f"初始化失败 {name}: {e}") + info["info"].status = "error" + info["info"].error_count += 1 + info["info"].last_error = str(e) + + def _safe_start(self, name: str): + """安全启动插件""" + info = self.plugins[name] + instance = info["instance"] + breaker = self._breakers[name] + + try: + breaker.call(instance.start) + info["info"].status = "running" + self._health_checker.add_plugin(name, instance) + ProLogger.info("manager", f"已启动: {name}") + except Exception as e: + ProLogger.error("manager", f"启动失败 {name}: {e}") + info["info"].status = "error" + info["info"].error_count += 1 + info["info"].last_error = str(e) + + def stop_all(self): + """停止所有插件""" + self._health_checker.stop() + + for name in reversed(list(self.plugins.keys())): + self._safe_stop(name) + + def _safe_stop(self, name: str): + """安全停止插件""" + info = self.plugins[name] + instance = info["instance"] + + try: + instance.stop() + info["info"].status = "stopped" + ProLogger.info("manager", f"已停止: {name}") + except Exception as e: + ProLogger.warn("manager", f"停止异常 {name}: {e}") + + def _on_plugin_failure(self, name: str): + """插件失败回调""" + ProLogger.error("recovery", f"插件 {name} 健康检查失败") + + if not self.config.auto_recovery.enabled: + return + + info = self.plugins.get(name) + if not info: + return + + plugin_dir = info.get("dir") + module = info.get("module") + instance = info.get("instance") + + if plugin_dir: + result = self._auto_recovery.attempt_recovery( + name, plugin_dir, module, instance + ) + if result: + info["instance"] = result + info["info"].status = "running" + self._health_checker.reset_failure_count(name) + + def _inject_dependencies(self): + """注入依赖""" + name_map = {} + for name in self.plugins: + clean = name.rstrip("}") + name_map[clean] = name + name_map[clean + "}"] = name + + for name, info in self.plugins.items(): + deps = info["info"].dependencies + if not deps: + continue + + for dep_name in deps: + actual_dep = name_map.get(dep_name) or name_map.get(dep_name + "}") + if actual_dep and actual_dep in self.plugins: + dep_instance = self.plugins[actual_dep]["instance"] + setter = f"set_{dep_name.replace('-', '_')}" + + if hasattr(info["instance"], setter): + try: + getattr(info["instance"], setter)(dep_instance) + ProLogger.info("inject", f"{name} <- {actual_dep}") + except Exception as e: + ProLogger.error("inject", f"注入失败 {name}.{setter}: {e}") + + def _get_ordered_plugins(self) -> list[str]: + """获取插件顺序""" + ordered = [] + visited = set() + + def visit(name): + if name in visited: + return + visited.add(name) + + info = self.plugins.get(name) + if not info: + return + + for dep in info["info"].dependencies: + clean_dep = dep.rstrip("}") + if clean_dep in self.plugins: + visit(clean_dep) + + ordered.append(name) + + for name in self.plugins: + visit(name) + + return ordered diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/proxy.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/proxy.py new file mode 100644 index 0000000..6f24efb --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/proxy.py @@ -0,0 +1,36 @@ +"""插件代理 - 防越级访问""" + + +class PermissionError(Exception): + """权限错误""" + pass + + +class PluginProxy: + """插件代理""" + + def __init__(self, plugin_name: str, plugin_instance: any, + allowed_plugins: list[str], all_plugins: dict[str, dict]): + self._plugin_name = plugin_name + self._plugin_instance = plugin_instance + self._allowed_plugins = set(allowed_plugins) + self._all_plugins = all_plugins + + def get_plugin(self, name: str) -> any: + """获取其他插件实例(带权限检查)""" + if name not in self._allowed_plugins and "*" not in self._allowed_plugins: + raise PermissionError( + f"插件 '{self._plugin_name}' 无权访问插件 '{name}'" + ) + if name not in self._all_plugins: + return None + return self._all_plugins[name]["instance"] + + def list_plugins(self) -> list[str]: + """列出有权限访问的插件""" + if "*" in self._allowed_plugins: + return list(self._all_plugins.keys()) + return [n for n in self._allowed_plugins if n in self._all_plugins] + + def __getattr__(self, name: str): + return getattr(self._plugin_instance, name) diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/core/registry.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/registry.py new file mode 100644 index 0000000..9b06d7a --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/core/registry.py @@ -0,0 +1,51 @@ +"""能力注册表""" +from typing import Any, Optional +from .proxy import PermissionError + + +class CapabilityRegistry: + """能力注册表""" + + def __init__(self, permission_check: bool = True): + self.providers: dict[str, dict[str, Any]] = {} + self.consumers: dict[str, list[str]] = {} + self.permission_check = permission_check + + def register_provider(self, capability: str, plugin_name: str, instance: Any): + """注册能力提供者""" + self.providers[capability] = { + "plugin": plugin_name, + "instance": instance, + } + if capability not in self.consumers: + self.consumers[capability] = [] + + def register_consumer(self, capability: str, plugin_name: str): + """注册能力消费者""" + if capability not in self.consumers: + self.consumers[capability] = [] + if plugin_name not in self.consumers[capability]: + self.consumers[capability].append(plugin_name) + + def get_provider(self, capability: str, requester: str = "", + allowed_plugins: list[str] = None) -> Optional[Any]: + """获取能力提供者实例(带权限检查)""" + if capability not in self.providers: + return None + + if self.permission_check and allowed_plugins is not None: + provider_name = self.providers[capability]["plugin"] + if (provider_name != requester and + provider_name not in allowed_plugins and + "*" not in allowed_plugins): + raise PermissionError( + f"插件 '{requester}' 无权使用能力 '{capability}'" + ) + + return self.providers[capability]["instance"] + + def has_capability(self, capability: str) -> bool: + return capability in self.providers + + def get_consumers(self, capability: str) -> list[str]: + return self.consumers.get(capability, []) diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/fallback/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/fallback/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/fallback/handler.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/fallback/handler.py new file mode 100644 index 0000000..eac6af8 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/fallback/handler.py @@ -0,0 +1,49 @@ +"""降级处理器""" +from typing import Callable, Any, Optional +from ..utils.logger import ProLogger + + +class FallbackStrategy: + """降级策略枚举""" + RETURN_DEFAULT = "return_default" + RETURN_CACHE = "return_cache" + RETURN_NULL = "return_null" + CALL_ALTERNATIVE = "call_alternative" + + +class FallbackHandler: + """降级处理器""" + + def __init__(self, strategy: str = FallbackStrategy.RETURN_NULL, + default_value: Any = None, + alternative_func: Callable = None): + self.strategy = strategy + self.default_value = default_value + self.alternative_func = alternative_func + self._cache = {} + + def execute(self, func: Callable, plugin_name: str, *args, **kwargs) -> Any: + """执行降级逻辑""" + try: + result = func(*args, **kwargs) + self._cache[plugin_name] = result + return result + except Exception as e: + ProLogger.warn("fallback", f"插件 {plugin_name} 执行失败,触发降级: {e}") + return self._apply_fallback(plugin_name) + + def _apply_fallback(self, plugin_name: str) -> Any: + """应用降级策略""" + if self.strategy == FallbackStrategy.RETURN_DEFAULT: + return self.default_value + elif self.strategy == FallbackStrategy.RETURN_CACHE: + return self._cache.get(plugin_name) + elif self.strategy == FallbackStrategy.RETURN_NULL: + return None + elif self.strategy == FallbackStrategy.CALL_ALTERNATIVE: + if self.alternative_func: + try: + return self.alternative_func() + except Exception as e: + ProLogger.error("fallback", f"备选方案也失败了: {e}") + return None diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/isolation/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/isolation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/isolation/timeout.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/isolation/timeout.py new file mode 100644 index 0000000..cdc19dd --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/isolation/timeout.py @@ -0,0 +1,29 @@ +"""超时控制""" +import signal + + +class TimeoutError(Exception): + """超时错误""" + pass + + +class TimeoutController: + """超时控制器""" + + def __init__(self, timeout: int = 30): + self.timeout = timeout + + def execute_with_timeout(self, func, *args, **kwargs) -> any: + """在超时限制内执行函数""" + def handler(signum, frame): + raise TimeoutError(f"执行超时 (>{self.timeout}s)") + + old_handler = signal.signal(signal.SIGALRM, handler) + signal.alarm(self.timeout) + + try: + result = func(*args, **kwargs) + signal.alarm(0) + return result + finally: + signal.signal(signal.SIGALRM, old_handler) diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/main.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/main.py new file mode 100644 index 0000000..03b8699 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/main.py @@ -0,0 +1,76 @@ +"""插件加载 Pro - 为 plugin-loader 提供高级机制""" +from oss.plugin.types import Plugin, register_plugin_type +from .core.config import ProConfig +from .core.enhancer import PluginLoaderEnhancer +from .utils.logger import ProLogger + + +class PluginLoaderPro(Plugin): + """插件加载 Pro - 增强器""" + + def __init__(self): + self.plugin_loader = None + self.enhancer = None + self.config = None + self._started = False + + def meta(self): + from oss.plugin.types import Metadata, PluginConfig, Manifest + return Manifest( + metadata=Metadata( + name="plugin-loader-pro", + version="1.0.0", + author="FutureOSS", + description="为 plugin-loader 提供熔断、降级、容错、自动修复等高级机制" + ), + config=PluginConfig( + enabled=True, + args={} + ), + dependencies=["plugin-loader"] + ) + + def set_plugin_loader(self, plugin_loader): + self.plugin_loader = plugin_loader + ProLogger.info("main", "已注入 plugin-loader") + + def init(self, deps: dict = None): + if not self.plugin_loader: + ProLogger.warn("main", "未找到 plugin-loader 依赖") + return + + config = {} + if deps: + config = deps.get("config", {}) + + self.config = ProConfig(config) + self.enhancer = PluginLoaderEnhancer( + self.plugin_loader.manager, + self.config + ) + + ProLogger.info("main", "增强器已初始化") + + def start(self): + if self._started: + return + self._started = True + + if not self.enhancer: + ProLogger.warn("main", "增强器未初始化,跳过启动") + return + + ProLogger.info("main", "开始增强 plugin-loader...") + self.enhancer.enhance() + + def stop(self): + ProLogger.info("main", "停止增强器...") + if self.enhancer: + self.enhancer.disable() + + +register_plugin_type("PluginLoaderPro", PluginLoaderPro) + + +def New(): + return PluginLoaderPro() diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/manifest.json b/store/@{FutureOSS}/plugin-loader-pro.disabled/manifest.json new file mode 100644 index 0000000..3376374 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/manifest.json @@ -0,0 +1,40 @@ +{ + "metadata": { + "name": "plugin-loader-pro", + "version": "1.0.0", + "author": "FutureOSS", + "description": "插件加载 Pro - 为 plugin-loader 提供熔断、降级、容错、自动修复等高级机制", + "type": "enhancer" + }, + "config": { + "enabled": true, + "args": { + "circuit_breaker": { + "failure_threshold": 3, + "recovery_timeout": 60, + "half_open_requests": 1 + }, + "retry": { + "max_retries": 3, + "backoff_factor": 2, + "initial_delay": 1 + }, + "health_check": { + "interval": 30, + "timeout": 5, + "max_failures": 5 + }, + "auto_recovery": { + "enabled": true, + "max_attempts": 3, + "delay": 10 + }, + "isolation": { + "enabled": true, + "timeout_per_plugin": 30 + } + } + }, + "dependencies": ["plugin-loader"], + "permissions": ["*"] +} diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/models/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/models/plugin_info.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/models/plugin_info.py new file mode 100644 index 0000000..07f978b --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/models/plugin_info.py @@ -0,0 +1,30 @@ +"""插件信息模型""" +from typing import Any + + +class PluginInfo: + """插件信息""" + def __init__(self): + self.name: str = "" + self.version: str = "" + self.author: str = "" + self.description: str = "" + self.readme: str = "" + self.config: dict[str, Any] = {} + self.extensions: dict[str, Any] = {} + self.lifecycle: Any = None + self.capabilities: set[str] = set() + self.dependencies: list[str] = [] + self.status: str = "idle" # idle, running, stopped, error + self.error_count: int = 0 + self.last_error: str = "" + + def to_dict(self) -> dict: + return { + "name": self.name, + "version": self.version, + "author": self.author, + "description": self.description, + "status": self.status, + "error_count": self.error_count + } diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..6935652 Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/auto_fix.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/auto_fix.cpython-313.pyc new file mode 100644 index 0000000..55d3e7b Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/auto_fix.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/health.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/health.cpython-313.pyc new file mode 100644 index 0000000..adfc640 Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/__pycache__/health.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/auto_fix.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/auto_fix.py new file mode 100644 index 0000000..33fcff2 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/auto_fix.py @@ -0,0 +1,60 @@ +"""自动修复器""" +import time +import importlib +import sys +from pathlib import Path +from ..utils.logger import ProLogger + + +class AutoRecovery: + """自动修复器""" + + def __init__(self, max_attempts: int = 3, delay: int = 10): + self.max_attempts = max_attempts + self.delay = delay + self._recovery_attempts: dict[str, int] = {} + + def attempt_recovery(self, name: str, plugin_dir: Path, + module: any, instance: any) -> bool: + """尝试恢复插件""" + attempts = self._recovery_attempts.get(name, 0) + + if attempts >= self.max_attempts: + ProLogger.error("recovery", f"插件 {name} 已达到最大恢复次数,放弃恢复") + return False + + ProLogger.warn("recovery", f"尝试恢复插件 {name} (第 {attempts + 1} 次)") + + try: + time.sleep(self.delay) + + # 重新加载模块 + if module and hasattr(module, '__file__'): + module_path = Path(module.__file__) + if module_path.exists(): + spec = importlib.util.spec_from_file_location( + module.__name__, str(module_path) + ) + new_module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = new_module + spec.loader.exec_module(new_module) + + if hasattr(new_module, 'New'): + new_instance = new_module.New() + ProLogger.info("recovery", f"插件 {name} 恢复成功") + self._recovery_attempts[name] = 0 + return new_instance + + except Exception as e: + ProLogger.error("recovery", f"恢复插件 {name} 失败: {e}") + + self._recovery_attempts[name] = attempts + 1 + return False + + def reset_attempts(self, name: str): + """重置恢复尝试次数""" + self._recovery_attempts[name] = 0 + + def get_attempts(self, name: str) -> int: + """获取恢复尝试次数""" + return self._recovery_attempts.get(name, 0) diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/health.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/health.py new file mode 100644 index 0000000..bd0e577 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/recovery/health.py @@ -0,0 +1,76 @@ +"""健康检查器""" +import time +import threading +from typing import Any +from ..utils.logger import ProLogger + + +class HealthChecker: + """健康检查器""" + + def __init__(self, interval: int = 30, timeout: int = 5, max_failures: int = 5): + self.interval = interval + self.timeout = timeout + self.max_failures = max_failures + + self._running = False + self._thread = None + self._plugins: dict[str, Any] = {} + self._failure_counts: dict[str, int] = {} + self._on_failure_callback = None + + def add_plugin(self, name: str, instance: Any): + """添加要监控的插件""" + self._plugins[name] = instance + self._failure_counts[name] = 0 + + def start(self, on_failure_callback=None): + """启动健康检查""" + self._on_failure_callback = on_failure_callback + self._running = True + self._thread = threading.Thread(target=self._check_loop, daemon=True) + self._thread.start() + ProLogger.info("health", "健康检查已启动") + + def stop(self): + """停止健康检查""" + self._running = False + if self._thread: + self._thread.join(timeout=5) + + def _check_loop(self): + """检查循环""" + while self._running: + for name, instance in self._plugins.items(): + self._check_plugin(name, instance) + time.sleep(self.interval) + + def _check_plugin(self, name: str, instance: Any): + """检查单个插件""" + try: + if hasattr(instance, 'health'): + healthy = instance.health() + if not healthy: + self._on_failure(name) + else: + self._failure_counts[name] = 0 + except Exception as e: + ProLogger.error("health", f"插件 {name} 健康检查失败: {e}") + self._on_failure(name) + + def _on_failure(self, name: str): + """失败处理""" + self._failure_counts[name] = self._failure_counts.get(name, 0) + 1 + + if self._failure_counts[name] >= self.max_failures: + ProLogger.warn("health", f"插件 {name} 连续失败 {self._failure_counts[name]} 次") + if self._on_failure_callback: + self._on_failure_callback(name) + + def reset_failure_count(self, name: str): + """重置失败计数""" + self._failure_counts[name] = 0 + + def get_failure_count(self, name: str) -> int: + """获取失败计数""" + return self._failure_counts.get(name, 0) diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/retry/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/retry/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/retry/handler.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/retry/handler.py new file mode 100644 index 0000000..b98e6e0 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/retry/handler.py @@ -0,0 +1,39 @@ +"""重试处理器""" +import time +import random +from typing import Callable, Any +from ..core.config import RetryConfig +from ..utils.logger import ProLogger + + +class RetryHandler: + """重试处理器""" + + def __init__(self, config: RetryConfig = None): + config = config or RetryConfig() + self.max_retries = config.max_retries + self.backoff_factor = config.backoff_factor + self.initial_delay = config.initial_delay + + def execute(self, func: Callable, *args, **kwargs) -> Any: + """执行带重试的调用""" + last_exception = None + + for attempt in range(self.max_retries + 1): + try: + return func(*args, **kwargs) + except Exception as e: + last_exception = e + + if attempt < self.max_retries: + delay = self._calculate_delay(attempt) + ProLogger.warn("retry", f"第 {attempt + 1} 次重试,等待 {delay:.1f}s: {e}") + time.sleep(delay) + + raise last_exception + + def _calculate_delay(self, attempt: int) -> float: + """计算退避延迟""" + delay = self.initial_delay * (self.backoff_factor ** attempt) + jitter = random.uniform(0, delay * 0.1) + return delay + jitter diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__init__.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..8a02816 Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__pycache__/logger.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__pycache__/logger.cpython-313.pyc new file mode 100644 index 0000000..3ad8bd9 Binary files /dev/null and b/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/__pycache__/logger.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/logger.py b/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/logger.py new file mode 100644 index 0000000..00613fc --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader-pro.disabled/utils/logger.py @@ -0,0 +1,60 @@ +"""插件加载 Pro - 日志工具""" +import sys + + +class ProLogger: + """Pro 日志记录器 - 智能颜色识别""" + + _COLORS = { + "reset": "\033[0m", + "white": "\033[0;37m", + "yellow": "\033[1;33m", + "blue": "\033[1;34m", + "red": "\033[1;31m", + } + + @staticmethod + def _colorize(text: str, color: str) -> str: + """添加颜色(终端支持时)""" + if not sys.stdout.isatty(): + return text + return f"{ProLogger._COLORS.get(color, '')}{text}{ProLogger._COLORS['reset']}" + + @staticmethod + def info(component: str, message: str): + """正常日志 - 白色""" + tag = ProLogger._colorize(f"[pro:{component}]", "white") + msg = ProLogger._colorize(message, "white") + print(f"{tag} {msg}") + + @staticmethod + def warn(component: str, message: str): + """警告日志 - 黄色""" + tag = ProLogger._colorize(f"[pro:{component}]", "yellow") + icon = ProLogger._colorize("⚠", "yellow") + msg = ProLogger._colorize(message, "yellow") + print(f"{tag} {icon} {msg}") + + @staticmethod + def error(component: str, message: str): + """错误日志 - 红色""" + tag = ProLogger._colorize(f"[pro:{component}]", "red") + icon = ProLogger._colorize("✗", "red") + msg = ProLogger._colorize(message, "red") + print(f"{tag} {icon} {msg}") + + @staticmethod + def debug(component: str, message: str): + """调试日志 - 蓝色""" + tag = ProLogger._colorize(f"[pro:{component}]", "blue") + icon = ProLogger._colorize("ℹ", "blue") + msg = ProLogger._colorize(message, "blue") + print(f"{tag} {icon} {msg}") + + @staticmethod + def tip(component: str, message: str): + """提示日志 - 蓝色(用于小提示/额外信息)""" + tag = ProLogger._colorize(f"[pro:{component}]", "blue") + icon = ProLogger._colorize("→", "blue") + msg = ProLogger._colorize(message, "blue") + print(f"{tag} {icon} {msg}") diff --git a/store/@{FutureOSS}/plugin-loader/SIGNATURE b/store/@{FutureOSS}/plugin-loader/SIGNATURE new file mode 100644 index 0000000..3e567f0 --- /dev/null +++ b/store/@{FutureOSS}/plugin-loader/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "XqvMe6BmA+hE8PqWCdKTDT8B9lKt2Oo9ZzZ0/KNlHEM3mk3cRzs4ZCUR4Qx4veqDAycTixT0cwp0hSh0VGNjBTg/hqVkmsDMb02Ky1TUhM1VGXYoffaKP7F5cqVLRc6Le0/mrL8MtdUUxt5USsdpFCuF+LLs+HQ2w/xPZ50n6GwdFIE2cvQJUGpMjLgI7jebmTFFLeED/DK9v9Pki1n27R3tvV333h9SAMO6L30IwJy6dwpssZb60RxLMkYvwokWYRePHKWzfdS9+huZ0o8fK6bYcs2CtBzZ4RDpwojSBPElIaBdn647+kspVTefEFlXvamdPM42pkojWsMU4Ed2Hgnasrz1aAlL7u94b6zcjOWQguRNgVsWFB8kKFR0nLaKUWQvULtDduEFpegU/dI0u1zZuRVmd58TSaLVXReUuARG0viop04pxiqf3H2IGwEafzlprnwQe9IWINgvABdC34UpCw/enBRUj2gjan2Up7nRhz0CMAUKo1TBhRMErp5f0AthZwbHrrq3g5wwKRoftV6O7GSiirbPSMe/ypb5mkdQmdHqOUvhlCexeeMhKB/9J7e2UhJ8YSlq7uZMrMc8dEWwkqMQeiw1uOCnCujlHYfk2RmPRwEZTUB/VQJmYuJhzSuI1XXA52ZcJaHf7Bh62d/ftMZ9OQimTpJg4y365jk=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775970391.1348627, + "plugin_hash": "0052362f57f6c9b50adc7ff19a37fa57344f298eade3dd5152c916054879b846", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/plugin-loader/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/plugin-loader/__pycache__/main.cpython-313.pyc index 8268092..029ba58 100644 Binary files a/store/@{FutureOSS}/plugin-loader/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/plugin-loader/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-loader/main.py b/store/@{FutureOSS}/plugin-loader/main.py index ba74364..f6b6c58 100644 --- a/store/@{FutureOSS}/plugin-loader/main.py +++ b/store/@{FutureOSS}/plugin-loader/main.py @@ -9,6 +9,45 @@ from oss.plugin.types import Plugin, register_plugin_type from oss.plugin.capabilities import scan_capabilities +# ===== 彩色日志 ===== +class Log: + """智能彩色日志""" + _TTY = sys.stdout.isatty() + _C = { + "reset": "\033[0m", + "white": "\033[0;37m", + "yellow": "\033[1;33m", + "blue": "\033[1;34m", + "red": "\033[1;31m", + } + + @classmethod + def c(cls, text: str, color: str) -> str: + if not cls._TTY: + return text + return f"{cls._C.get(color, '')}{text}{cls._C['reset']}" + + @classmethod + def info(cls, tag: str, msg: str): + print(f"{cls.c(f'[{tag}]', 'white')} {cls.c(msg, 'white')}") + + @classmethod + def warn(cls, tag: str, msg: str): + print(f"{cls.c(f'[{tag}]', 'yellow')} {cls.c('⚠', 'yellow')} {cls.c(msg, 'yellow')}") + + @classmethod + def tip(cls, tag: str, msg: str): + print(f"{cls.c(f'[{tag}]', 'blue')} {cls.c('ℹ', 'blue')} {cls.c(msg, 'blue')}") + + @classmethod + def error(cls, tag: str, msg: str): + print(f"{cls.c(f'[{tag}]', 'red')} {cls.c('✗', 'red')} {cls.c(msg, 'red')}") + + @classmethod + def ok(cls, tag: str, msg: str): + print(f"{cls.c(f'[{tag}]', 'white')} {cls.c(msg, 'white')}") + + class PluginInfo: """插件信息""" def __init__(self): @@ -114,8 +153,14 @@ class PluginManager: self.plugins: dict[str, dict[str, Any]] = {} self.lifecycle_plugin: Optional[Any] = None self._dependency_plugin: Optional[Any] = None # dependency 插件引用 + self._signature_verifier: Optional[Any] = None # signature-verifier 插件引用 self.capability_registry = CapabilityRegistry(permission_check=permission_check) self.permission_check = permission_check + self.enforce_signature = True # 是否强制验证官方插件签名 + + def set_signature_verifier(self, verifier: Any): + """设置签名验证器""" + self._signature_verifier = verifier def set_lifecycle(self, lifecycle_plugin: Any): """设置生命周期插件""" @@ -143,6 +188,17 @@ class PluginManager: if not config_file.exists(): return {} + # 读取并验证文件内容 + with open(config_file, "r", encoding="utf-8") as f: + content = f.read() + + # 安全检查:禁止危险操作 + dangerous_patterns = ['import ', 'open(', 'exec(', 'eval(', 'os.', 'sys.', 'subprocess'] + for pattern in dangerous_patterns: + if pattern in content: + Log.warn("plugin-loader", f"{config_file} 包含危险代码: {pattern}") + return {} + safe_globals = { "__builtins__": { "True": True, @@ -158,9 +214,12 @@ class PluginManager: } local_vars = {} - with open(config_file, "r", encoding="utf-8") as f: - code = compile(f.read(), str(config_file), "exec") + try: + code = compile(content, str(config_file), "exec") exec(code, safe_globals, local_vars) + except Exception as e: + Log.error("plugin-loader", f"配置文件解析失败: {e}") + return {} return { k: v for k, v in local_vars.items() @@ -173,6 +232,17 @@ class PluginManager: if not ext_file.exists(): return {} + # 读取并验证文件内容 + with open(ext_file, "r", encoding="utf-8") as f: + content = f.read() + + # 安全检查:禁止危险操作 + dangerous_patterns = ['import ', 'open(', 'exec(', 'eval(', 'os.', 'sys.', 'subprocess'] + for pattern in dangerous_patterns: + if pattern in content: + Log.warn("plugin-loader", f"{ext_file} 包含危险代码: {pattern}") + return {} + safe_globals = { "__builtins__": { "True": True, @@ -188,9 +258,12 @@ class PluginManager: } local_vars = {} - with open(ext_file, "r", encoding="utf-8") as f: - code = compile(f.read(), str(ext_file), "exec") + try: + code = compile(content, str(ext_file), "exec") exec(code, safe_globals, local_vars) + except Exception as e: + Log.error("plugin-loader", f"扩展文件解析失败: {e}") + return {} return { k: v for k, v in local_vars.items() @@ -212,7 +285,7 @@ class PluginManager: capabilities = scan_capabilities(plugin_dir) plugin_name = plugin_dir.name - + # 清理插件名(去掉 } 后缀) plugin_name = plugin_dir.name.rstrip("}") @@ -233,6 +306,8 @@ class PluginManager: f"plugin.{plugin_name}", str(main_file) ) module = importlib.util.module_from_spec(spec) + module.__package__ = f"plugin.{plugin_name}" + module.__path__ = [str(plugin_dir)] # 启用相对导入子模块 sys.modules[spec.name] = module spec.loader.exec_module(module) @@ -276,14 +351,23 @@ class PluginManager: def load_all(self, store_dir: str = "store"): """加载 store 和 data/pkg 下所有插件(跳过自己)""" + # 确保 plugin 命名空间包存在(必须在最开头) + import types + if 'plugin' not in sys.modules: + plugin_pkg = types.ModuleType('plugin') + plugin_pkg.__path__ = [] + plugin_pkg.__package__ = 'plugin' + sys.modules['plugin'] = plugin_pkg + Log.tip("plugin-loader", "已创建 plugin 命名空间包") + # 检查是否有任何插件存在 has_plugins = self._check_any_plugins(store_dir) - + if not has_plugins: - print("[plugin-loader] 未检测到任何插件,自动引导安装...") + Log.warn("plugin-loader", "未检测到任何插件,自动引导安装...") self._bootstrap_installation() - # 可选:加载 lifecycle + # 加载 lifecycle lifecycle_plugin = None lifecycle_dir = Path(store_dir) / "@{FutureOSS}" / "lifecycle" if lifecycle_dir.exists() and (lifecycle_dir / "main.py").exists(): @@ -295,7 +379,7 @@ class PluginManager: except Exception: pass - # 可选:加载 dependency + # 加载 dependency dependency_plugin = None dependency_dir = Path(store_dir) / "@{FutureOSS}" / "dependency" if dependency_dir.exists() and (dependency_dir / "main.py").exists(): @@ -303,11 +387,24 @@ class PluginManager: instance = self.load(dependency_dir) if instance: dependency_plugin = instance - self._dependency_plugin = instance # 保存引用供拓扑排序使用 + self._dependency_plugin = instance self.plugins.pop("dependency", None) except Exception: pass + # 加载 signature-verifier + signature_verifier = None + sig_verifier_dir = Path(store_dir) / "@{FutureOSS}" / "signature-verifier" + if sig_verifier_dir.exists() and (sig_verifier_dir / "main.py").exists(): + try: + instance = self.load(sig_verifier_dir) + if instance: + signature_verifier = instance + self.set_signature_verifier(instance.verifier) + Log.ok("plugin-loader", "签名验证服务已加载") + except Exception as e: + Log.warn("plugin-loader", f"signature-verifier 加载失败: {e}") + # 加载 lifecycle if lifecycle_plugin: self.set_lifecycle(lifecycle_plugin) @@ -316,7 +413,7 @@ class PluginManager: self._load_plugins_from_dir(Path(store_dir)) self._load_plugins_from_dir(Path("./data/pkg")) - # 可选:按依赖排序 + # 按依赖排序 if dependency_plugin: self._sort_by_dependencies(dependency_plugin) @@ -325,13 +422,18 @@ class PluginManager: if not store_dir.exists(): return + # 核心插件列表(不使用沙箱,允许完整功能) + core_plugins = {"webui", "dashboard", "pkg-manager"} + # 第一遍:加载所有插件 for author_dir in store_dir.iterdir(): if author_dir.is_dir(): for plugin_dir in author_dir.iterdir(): - if plugin_dir.is_dir() and plugin_dir.name not in ("plugin-loader", "lifecycle", "dependency"): + if plugin_dir.is_dir() and plugin_dir.name not in ("plugin-loader", "lifecycle", "dependency", "signature-verifier"): if (plugin_dir / "main.py").exists(): - self.load(plugin_dir) + # 核心插件不使用沙箱 + use_sandbox = plugin_dir.name not in core_plugins + self.load(plugin_dir, use_sandbox=use_sandbox) # 第二遍:关联能力 self._link_capabilities() @@ -364,26 +466,26 @@ class PluginManager: if pkg_instance: pkg_mgr = pkg_instance.manager - print("[plugin-loader] 正在搜索可用插件...") + Log.info("plugin-loader", "正在搜索可用插件...") results = pkg_mgr.search() if not results: - print("[plugin-loader] 未找到远程插件") + Log.warn("plugin-loader", "未找到远程插件") return - print(f"[plugin-loader] 发现 {len(results)} 个插件,开始安装...") + Log.info("plugin-loader", f"发现 {len(results)} 个插件,开始安装...") installed_count = 0 for pkg_info in results: - print(f"[plugin-loader] 安装: {pkg_info.name}") + Log.info("plugin-loader", f"安装: {pkg_info.name}") if pkg_mgr.install(pkg_info.name): installed_count += 1 if installed_count > 0: - print(f"[plugin-loader] 已安装 {installed_count} 个插件,重新扫描加载...") + Log.info("plugin-loader", f"已安装 {installed_count} 个插件,重新扫描加载...") # pkg 保留,重新加载其他插件 except Exception as e: - print(f"[plugin-loader] 引导安装失败: {e}") + Log.error("plugin-loader", f"引导安装失败: {e}") else: - print("[plugin-loader] pkg 插件不存在,跳过引导安装") + Log.info("plugin-loader", "pkg 插件不存在,跳过引导安装") def _sort_by_dependencies(self, dep_plugin): """按依赖关系排序""" @@ -410,7 +512,7 @@ class PluginManager: self.plugins = sorted_plugins except Exception as e: - print(f"[plugin-loader] 依赖解析失败: {e}") + Log.error("plugin-loader", f"依赖解析失败: {e}") def _link_capabilities(self): """关联能力:带权限检查""" @@ -437,7 +539,7 @@ class PluginManager: if provider and hasattr(consumer_info, "extensions"): consumer_info.extensions[f"_{cap}_provider"] = provider except PermissionError as e: - print(f"[plugin-loader] 权限拒绝: {e}") + Log.error("plugin-loader", f"权限拒绝: {e}") def start_all(self): """启动所有插件(假设已初始化)""" @@ -449,7 +551,7 @@ class PluginManager: try: info["instance"].start() except Exception as e: - print(f"[plugin-loader] 启动失败 {name}: {e}") + Log.error("plugin-loader", f"启动失败 {name}: {e}") def init_and_start_all(self): """初始化并启动所有插件 @@ -459,38 +561,38 @@ class PluginManager: 2. 按拓扑顺序 init() 所有插件 3. 按拓扑顺序 start() 所有插件 """ - print(f"[plugin-loader] init_and_start_all 被调用,plugins={len(self.plugins)}") + Log.info("plugin-loader", f"init_and_start_all 被调用,plugins={len(self.plugins)}") # 1. 注入依赖实例 self._inject_dependencies() # 2. 获取拓扑排序 ordered_plugins = self._get_ordered_plugins() - print(f"[plugin-loader] 插件启动顺序: {' -> '.join(ordered_plugins)}") + Log.tip("plugin-loader", f"插件启动顺序: {' -> '.join(ordered_plugins)}") # 3. 初始化所有插件(跳过 plugin-loader 自己) - print("[plugin-loader] 开始初始化所有插件...") + Log.info("plugin-loader", "开始初始化所有插件...") for name in ordered_plugins: if "plugin-loader" in name: continue info = self.plugins[name] try: - print(f"[plugin-loader] 初始化: {name}") + Log.info("plugin-loader", f"初始化: {name}") info["instance"].init() except Exception as e: - print(f"[plugin-loader] 初始化失败 {name}: {e}") + Log.error("plugin-loader", f"初始化失败 {name}: {e}") # 4. 启动所有插件(跳过 plugin-loader 自己) - print("[plugin-loader] 开始启动所有插件...") + Log.info("plugin-loader", "开始启动所有插件...") for name in ordered_plugins: if "plugin-loader" in name: continue info = self.plugins[name] try: - print(f"[plugin-loader] 启动: {name}") + Log.info("plugin-loader", f"启动: {name}") info["instance"].start() except Exception as e: - print(f"[plugin-loader] 启动失败 {name}: {e}") + Log.error("plugin-loader", f"启动失败 {name}: {e}") def _get_ordered_plugins(self) -> list[str]: """获取按依赖排序的插件列表""" @@ -504,12 +606,12 @@ class PluginManager: # 过滤出实际存在的插件 return [name for name in order if name in self.plugins] except Exception as e: - print(f"[plugin-loader] 依赖解析失败,使用原始顺序: {e}") + Log.warn("plugin-loader", f"依赖解析失败,使用原始顺序: {e}") return list(self.plugins.keys()) def _inject_dependencies(self): """注入插件依赖实例""" - print(f"[plugin-loader] 开始注入依赖,共 {len(self.plugins)} 个插件") + Log.info("plugin-loader", f"开始注入依赖,共 {len(self.plugins)} 个插件") # 构建名称映射(处理 } 后缀问题) name_map = {} @@ -527,22 +629,22 @@ class PluginManager: if not deps: continue - print(f"[plugin-loader] {name} 依赖: {deps}") + Log.tip("plugin-loader", f"{name} 依赖: {deps}") for dep_name in deps: # 使用名称映射查找 actual_dep = name_map.get(dep_name) or name_map.get(dep_name + "}") if actual_dep and actual_dep in self.plugins: dep_instance = self.plugins[actual_dep]["instance"] setter_name = f"set_{dep_name.replace('-', '_')}" - print(f"[plugin-loader] 尝试注入: {name} <- {actual_dep} ({setter_name})") + Log.tip("plugin-loader", f"尝试注入: {name} <- {actual_dep} ({setter_name})") if hasattr(instance, setter_name): try: getattr(instance, setter_name)(dep_instance) - print(f"[plugin-loader] 注入成功: {name} <- {actual_dep}") + Log.ok("plugin-loader", f"注入成功: {name} <- {actual_dep}") except Exception as e: - print(f"[plugin-loader] 注入依赖失败 {name}.{setter_name}: {e}") + Log.error("plugin-loader", f"注入依赖失败 {name}.{setter_name}: {e}") else: - print(f"[plugin-loader] 警告: {name} 没有 {setter_name} 方法") + Log.warn("plugin-loader", f"{name} 没有 {setter_name} 方法") def stop_all(self): """停止所有插件""" @@ -576,13 +678,30 @@ class PluginLoaderPlugin(Plugin): self.manager = PluginManager() self._loaded = False self._started = False + self._ensure_plugin_package() + + def _ensure_plugin_package(self): + """确保 plugin 命名空间包存在""" + import types + if 'plugin' not in sys.modules: + plugin_pkg = types.ModuleType('plugin') + plugin_pkg.__path__ = [] + sys.modules['plugin'] = plugin_pkg def init(self, deps: dict = None): """加载所有插件""" if self._loaded: return self._loaded = True - print("[plugin-loader] 开始加载插件...") + + # 确保 plugin 命名空间包存在(必须在加载任何插件之前) + import types + if 'plugin' not in sys.modules: + plugin_pkg = types.ModuleType('plugin') + plugin_pkg.__path__ = [] + sys.modules['plugin'] = plugin_pkg + + Log.info("plugin-loader", "开始加载插件...") self.manager.load_all() def start(self): @@ -590,12 +709,12 @@ class PluginLoaderPlugin(Plugin): if self._started: return self._started = True - print("[plugin-loader] 启动插件...") + Log.info("plugin-loader", "启动插件...") self.manager.init_and_start_all() def stop(self): """停止所有插件""" - print("[plugin-loader] 停止插件...") + Log.info("plugin-loader", "停止插件...") self.manager.stop_all() diff --git a/store/@{FutureOSS}/plugin-storage/SIGNATURE b/store/@{FutureOSS}/plugin-storage/SIGNATURE new file mode 100644 index 0000000..4fdcbc3 --- /dev/null +++ b/store/@{FutureOSS}/plugin-storage/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "TA08EBmVwhP0tyOhplpioxsGD4T8fRhj2ekEvQFGEaK2L1/USEGTcGXt/tciHNMU0AWVJ1bD9MY6aBj2+ljlSNCEyNlMMOeZot1/blcQG9wPsHbVXKm8VuyK0KBHwrM39DppbKIn4dlGL6A2Eua0bp20oCnmd2VF3IuTHGnGKmoXmehffXiVIlCgqIX2+wEqlD2TqYfP6LU+XWDYMtQ/ShS3ImbcIoChOzhj3H0LZKg+jd4d4N97B2z9uUinojZ4jJxix1qe6hednBiZNEGUub6/bn8DKtdRidPjwtwObKjL8etBFlca0mHEYvHe/T33uoqi1URGnbqXiiYneSKj4J1zJRMfDxfZhZ6ubeCcSiMufIgzNbMii1lR0mq/pCcUUM0X0I4ean2xk7ygW7xrN8ra3/73gOHvVBnVElwyPIpZaiPzvVnQ14nyv2zWFFezJNdkB0MOaoy0RRzk9Jp7DjGxn9B4f3sGAZX1gTUSzu91BvdhZOfy6VhS+t8Wf3PfY2t0OYyLPg28S0bQhfZ64HnjR2LR098jut40ckbzDRif0ZFtyj0OQWzbC0dTKlSEW6p2ozuWSROX2OMxY4F/srzAfh7SJL42FR9Lm/tlCVSRUVQ2NRMA8UFdtorsp09GDQmwy7xJxn9ghRWoXmrsaDSwvrZUlVo6LMa6ocvhvSo=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964952.8741558, + "plugin_hash": "e317a24422dcd005fc3f2db0fa34848bd81a45a3eb40cda0b8d20aadf2391cd1", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/plugin-storage/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/plugin-storage/__pycache__/main.cpython-313.pyc index 09992f1..39e6977 100644 Binary files a/store/@{FutureOSS}/plugin-storage/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/plugin-storage/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/plugin-storage/main.py b/store/@{FutureOSS}/plugin-storage/main.py index 6953bfd..b05048a 100644 --- a/store/@{FutureOSS}/plugin-storage/main.py +++ b/store/@{FutureOSS}/plugin-storage/main.py @@ -7,6 +7,7 @@ from pathlib import Path from typing import Any, Optional, BinaryIO from datetime import datetime +from oss.logger.logger import Log from oss.plugin.types import Plugin, register_plugin_type, Response @@ -35,7 +36,7 @@ class PluginStorage: else: self._data = {} except (json.JSONDecodeError, IOError) as e: - print(f"[plugin-storage] 加载数据失败 {self.plugin_name}: {e}") + Log.error("plugin-storage", f"加载数据失败 {self.plugin_name}: {e}") self._data = {} def _save(self): @@ -123,7 +124,7 @@ class PluginStorage: with open(file_path, mode, encoding="utf-8" if mode == "r" else None) as f: return f.read() except Exception as e: - print(f"[plugin-storage] 读取文件失败 {self.plugin_name}/{path}: {e}") + Log.error("plugin-storage", f"读取文件失败 {self.plugin_name}/{path}: {e}") return None def write_file(self, path: str, content: str | bytes): @@ -143,7 +144,7 @@ class PluginStorage: with open(file_path, "w", encoding="utf-8") as f: f.write(content) except Exception as e: - print(f"[plugin-storage] 写入文件失败 {self.plugin_name}/{path}: {e}") + Log.error("plugin-storage", f"写入文件失败 {self.plugin_name}/{path}: {e}") def delete_file(self, path: str) -> bool: """删除插件目录内的文件""" @@ -154,7 +155,7 @@ class PluginStorage: return True return False except Exception as e: - print(f"[plugin-storage] 删除文件失败 {self.plugin_name}/{path}: {e}") + Log.error("plugin-storage", f"删除文件失败 {self.plugin_name}/{path}: {e}") return False def list_files(self, prefix: str = "") -> list[str]: @@ -290,7 +291,7 @@ class PluginStoragePlugin(Plugin): def start(self): """启动""" - print(f"[plugin-storage] 插件存储服务已启动 (root={self.data_root})") + Log.info("plugin-storage", f"插件存储服务已启动 (root={self.data_root})") def stop(self): """停止""" @@ -306,7 +307,7 @@ class PluginStoragePlugin(Plugin): shared_dir_name = self.config.get("shared_dir", "DCIM") shared_dir = self.data_root / shared_dir_name else: - print("[plugin-storage] config.json 不存在,使用默认配置") + Log.warn("plugin-storage", "config.json 不存在,使用默认配置") self.config = {"data_root": "./data", "shared_dir": "DCIM"} self.data_root = Path("./data") shared_dir = self.data_root / "DCIM" diff --git a/store/@{FutureOSS}/signature-verifier/SIGNATURE b/store/@{FutureOSS}/signature-verifier/SIGNATURE new file mode 100644 index 0000000..c4be2af --- /dev/null +++ b/store/@{FutureOSS}/signature-verifier/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "ymWLA+iMcmMAum/qQIJdTgk31K/dNejA9BtOe5yUjAi58yKKW4mPx8c+6x9I28XM+eG1KkSAMrb94NFVVARR/k/Lc4QnNwbJVoYheEfKscMih6G4meiVYPFGkjMwukNL+k8qon+HJwAtHtZ9DFWclfZEXDKVptbr+3juovmBGIYdGlZ9pS2AmrYLsxx5SjCtuJb+cuOE0U5S5GBxBsv7tvP5IQAZZP1Crf0Cxe9Op6+UzX0TYfzWswIqcYzZdgPEUbMorwUlRPVgHGiaYtoHqQGISjR2kAgk5XW3NCuPAAQoiY9XTe+YD+3wDfQ7ic0tkESIJBBt7Zq2VJMmh8lwWMTRi0+xVgZHua2HpLdHDatSggWoCXQiMakm7rA1Z/Xto30mx0Pk4fh2vcYeuThoY6a+GsPbMxG4Bj52jSzGwHu264cgnSe8wS+HmbU0Ch1t4qD0lAZh297qRBqdr4hW+Lzf/FxVd5kQiL3rYcq8mi3Kd4nmiQ4/gev5mX7uSf6fhByCrXqe4pvgAt5q7BgByC9C/krcTRNIwV+u9PQe7zboXZY7x0CzYzITKkWzIY98Fl+8qmvuanLoPQ3tqAdixJr5I1Lpk71l2B5cW5ht2iB48RL4b+oPNqksIweRmPSDyTGBf3jS2YQNY62tdt4yXkWHO00qIOU0UQkGF+BKRSw=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775969853.454207, + "plugin_hash": "762549e109001210eb9fb1fbfc2b9a3c25cbb3ea899b796d07357d6ee32949d5", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/signature-verifier/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/signature-verifier/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..bc65e0c Binary files /dev/null and b/store/@{FutureOSS}/signature-verifier/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/signature-verifier/main.py b/store/@{FutureOSS}/signature-verifier/main.py new file mode 100644 index 0000000..319bd74 --- /dev/null +++ b/store/@{FutureOSS}/signature-verifier/main.py @@ -0,0 +1,337 @@ +""" +插件签名验证服务 +- 验证官方插件的完整性与来源真实性 +- 支持多签名者(Falck 独特性签名) +- RSA-SHA256 非对称加密方案 +""" + +import os +import json +import hashlib +import base64 +from pathlib import Path +from typing import Optional, Dict, List, Tuple + +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding, rsa +from cryptography.hazmat.backends import default_backend +from cryptography.exceptions import InvalidSignature + +from oss.plugin.types import Plugin + + +# ========== 内置信任锚(Falck 公钥) ========== +# 这是 Falck 的官方公钥,用于验证所有官方签名的插件 +FALCK_PUBLIC_KEY_PEM = """-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqN42I+etzCMHAt4XMLNm +PMy9CgPuqSNgdwLIsrvYzIZ2nNUr351fLdC19PV1ou5G/rbQzX5TsxGDzJideQWh +Cdi8G5AwvsoFNzfhLcTxc38YsQGTizj/iIBOkBWiIoLgBDAqyZxKfgAIJQWwhiuz +vUbXqf6O12YZBzkV/XroszpM1AweZqE+TkmIPs9AbH7Pvi8kHme/avQwPmsQlKyE +Lf+4CykIN0EnZLLaDGuwwT/V1FIPgOGGWdqVbOyyGB2wMuBwRUrPYJoBYrRISjjz +KjLsSWfdQ7Id5snovjFnqwZ2qyijhgZVirKLmbEtn9rVAhEO2sPaSbrGzpwllxYp +pZpSW6yXzO8Ty7XqwIzQg6dw7m8WnIv8pCGKrASSuRwdCDZLh7Wf5gs3kgGTEDmn +e8imMXNbG1liVQSc5KyNlYdMd99oUCyPza014km/ci5Uw7lT7kgaE2N8BlEBq0vV +/JzQBW5/rYvbR4CZXmoMCpynjJ5S7PoU8cLmgemFxVJ1RRZMLEj2aDyK11WA1qsV +IJ02ZY5N7hSJG0mY5YdHeP8CVDKABEFAMMD/i6Jz53z7JPH/Aavw/8HNZFeDliXM +aMGfNRV1niQLUHnYliDjNCBOxLWfB9pomha3qWfdt0R0obdFeJ+z2SgcTGSk7+zo +Bgidq6CPfGimd7Wf9TP9J50CAwEAAQ== +-----END PUBLIC KEY-----""" + +# FutureOSS 官方公钥 +FUTUREOSS_PUBLIC_KEY_PEM = """-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoeXGPyd4z0wREb7+G85K +Vabf+7PkmJRbICurqF0ZqBj+0hGMeOI9D8C+6J0AAja4xywq96Btbr/6POVfkhdf +HGCwI1HO6dR+6es2gCYnvWI9XMGNV0GMXcc7nWz+upukNC0knx/KyjtM+vwYz6jC +qXFD86msCdrDfK4VqPLOPm7K4oA7DIsjTO1ka+pE1wS8gSY7+Tv24hEe/jvZGFvC +u/QIMOL4MoRE9j8xxgT3teR9pEwK3+VUvQPdFQkoI+6LAH8Dh749EEY2IGrb1F88 +5D5lWwTdtzEcrmiOb8KyvXtg1S8Gu01in3HLIkMmwCyCQM2p3/cz9qtmx/Yv6ETO +vey6G3xZAqqA4mF9RMiymqY3l4CFPVkX1gpOtrfSPPWUDJCVx2iAQcHBl/oq8pz5 +jSjN6Njy+yF8Yq7deIBxU+ZWE3Lm+2ioImsozJxAELCMjpgc5vfxySHSPy5ite2r +Bbt6b0lKyjbPRHRvcXGtc76E92jVzuEOoNVf2/LCThggE/sfxU53/SRekXH05+PE +1k3wTMEpeVh0m8B8fp052+eW6DXVo0+uPkZPgCA7aA7yHIyqhtBAH4pSwXPFXgzS +OHMoaLwKiNfFLV2tW8JG18oUIwO3sMyeyLazjHPP831WJ55dfJFsK+d7CfcD3OxM +LhUSJrBP4sr2J0DyGi0GyjsCAwEAAQ== +-----END PUBLIC KEY-----""" + + +class SignatureError(Exception): + """签名验证失败异常""" + pass + + +class SignatureVerifier: + """签名验证器""" + + def __init__(self, key_dir: str = "./data/signature-verifier/keys"): + self.key_dir = Path(key_dir) + self.key_dir.mkdir(parents=True, exist_ok=True) + self.public_keys: Dict[str, bytes] = {} + self._load_builtin_keys() + + def _load_builtin_keys(self): + """加载内置信任锚""" + # Falck 官方公钥 + self.public_keys["Falck"] = FALCK_PUBLIC_KEY_PEM.encode() + # FutureOSS 官方公钥 + self.public_keys["FutureOSS"] = FUTUREOSS_PUBLIC_KEY_PEM.encode() + # 加载额外密钥 + self._load_extra_keys() + + def _load_extra_keys(self): + """从密钥目录加载额外的公钥""" + pub_dir = self.key_dir / "public" + if not pub_dir.exists(): + return + for key_file in pub_dir.glob("*.pem"): + author_name = key_file.stem + self.public_keys[author_name] = key_file.read_bytes() + + def _compute_plugin_hash(self, plugin_dir: Path) -> str: + """ + 计算插件目录的内容哈希 + 包含所有文件的路径相对路径 + 内容 + """ + hasher = hashlib.sha256() + + # 收集所有需要哈希的文件 + files_to_hash = [] + for file_path in sorted(plugin_dir.rglob("*")): + if file_path.is_file() and file_path.name != "SIGNATURE": + rel_path = file_path.relative_to(plugin_dir) + files_to_hash.append((str(rel_path), file_path)) + + # 按相对路径排序后依次哈希 + for rel_path, file_path in files_to_hash: + hasher.update(rel_path.encode("utf-8")) + hasher.update(file_path.read_bytes()) + + return hasher.hexdigest() + + def verify_plugin(self, plugin_dir: Path, author: str = "Falck") -> Tuple[bool, str]: + """ + 验证插件签名 + 返回: (是否有效, 详细信息) + """ + signature_file = plugin_dir / "SIGNATURE" + + if not signature_file.exists(): + return False, f"插件缺少签名文件: {plugin_dir}" + + # 加载签名 + try: + sig_data = json.loads(signature_file.read_text()) + except json.JSONDecodeError as e: + return False, f"签名文件格式错误: {e}" + + # 检查必需字段 + required_fields = ["signature", "signer", "algorithm", "timestamp"] + for field in required_fields: + if field not in sig_data: + return False, f"签名文件缺少必需字段: {field}" + + signer = sig_data["signer"] + signature = base64.b64decode(sig_data["signature"]) + + # 获取对应公钥 + if signer not in self.public_keys: + return False, f"未知签名者: {signer}" + + try: + public_key = serialization.load_pem_public_key( + self.public_keys[signer], + backend=default_backend() + ) + except Exception as e: + return False, f"公钥加载失败: {e}" + + # 计算当前哈希 + current_hash = self._compute_plugin_hash(plugin_dir) + + # 验证签名 + try: + # 签名的是 "作者:哈希值" 的组合 + signed_data = f"{author}:{current_hash}".encode("utf-8") + public_key.verify( + signature, + signed_data, + padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH + ), + hashes.SHA256() + ) + return True, f"签名验证通过 (签名者: {signer})" + except InvalidSignature: + return False, f"签名不匹配!插件可能已被篡改 (签名者: {signer})" + except Exception as e: + return False, f"签名验证异常: {e}" + + def is_official_plugin(self, plugin_dir: Path) -> bool: + """检查是否是官方插件(Falck 或 FutureOSS 签名)""" + return self.verify_plugin(plugin_dir, "Falck")[0] or \ + self.verify_plugin(plugin_dir, "FutureOSS")[0] + + +class SignatureSigner: + """签名生成器(仅用于密钥持有者)""" + + def __init__(self, private_key_path: Optional[str] = None): + self.private_key = None + if private_key_path: + self.load_private_key(private_key_path) + + def load_private_key(self, key_path: str): + """加载私钥""" + with open(key_path, "rb") as f: + self.private_key = serialization.load_pem_private_key( + f.read(), + password=None, + backend=default_backend() + ) + + def load_private_key_from_pem(self, pem_data: str): + """从 PEM 字符串加载私钥""" + self.private_key = serialization.load_pem_private_key( + pem_data.encode(), + password=None, + backend=default_backend() + ) + + def sign_plugin(self, plugin_dir: Path, signer_name: str, author: str = "Falck") -> str: + """ + 为插件生成签名 + 返回: 签名的文件路径 + """ + if not self.private_key: + raise ValueError("未加载私钥") + + # 计算插件哈希 + hasher = hashlib.sha256() + files_to_hash = [] + for file_path in sorted(plugin_dir.rglob("*")): + if file_path.is_file() and file_path.name not in ("SIGNATURE",): + rel_path = file_path.relative_to(plugin_dir) + files_to_hash.append((str(rel_path), file_path)) + + for rel_path, file_path in files_to_hash: + hasher.update(rel_path.encode("utf-8")) + hasher.update(file_path.read_bytes()) + + plugin_hash = hasher.hexdigest() + + # 签名 + import time + signed_data = f"{author}:{plugin_hash}".encode("utf-8") + signature = self.private_key.sign( + signed_data, + padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH + ), + hashes.SHA256() + ) + + # 写入签名文件 + sig_data = { + "signature": base64.b64encode(signature).decode(), + "signer": signer_name, + "algorithm": "RSA-SHA256", + "timestamp": time.time(), + "plugin_hash": plugin_hash, + "author": author + } + + signature_file = plugin_dir / "SIGNATURE" + signature_file.write_text(json.dumps(sig_data, indent=2)) + + return str(signature_file) + + +class SignatureVerifierPlugin(Plugin): + """签名验证插件入口""" + + def __init__(self): + self.storage = None + self.verifier = None + self.signer = None + self.enforce_official = True + + def set_plugin_storage(self, instance): + self.storage = instance + + def init(self, deps: dict = None): + # 初始化验证器 + key_dir = "./data/signature-verifier/keys" + self.verifier = SignatureVerifier(key_dir=key_dir) + + # 初始化签名器(如果有私钥) + private_key_path = "./data/signature-verifier/keys/private/falck_private.pem" + if Path(private_key_path).exists(): + self.signer = SignatureSigner(private_key_path) + + # 加载配置 + if self.storage: + storage = self.storage.get_storage("signature-verifier") + self.enforce_official = storage.get("enforce_official", True) + + def start(self): + pass + + def stop(self): + pass + + # ========== 对外 API ========== + + def verify(self, plugin_dir: Path, author: str = "Falck") -> Tuple[bool, str]: + """验证插件签名""" + return self.verifier.verify_plugin(plugin_dir, author) + + def is_official(self, plugin_dir: Path) -> bool: + """检查是否是官方插件""" + return self.verifier.is_official_plugin(plugin_dir) + + def sign(self, plugin_dir: Path, signer_name: str = "Falck", author: str = "Falck") -> str: + """为插件签名(需要私钥)""" + if not self.signer: + raise SignatureError("未加载私钥,无法签名") + return self.signer.sign_plugin(plugin_dir, signer_name, author) + + def generate_keypair(self, author: str, key_dir: str = None): + """生成新的密钥对""" + if key_dir is None: + key_dir = self.key_dir + + key_path = Path(key_dir) + key_path.mkdir(parents=True, exist_ok=True) + + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=4096, + backend=default_backend() + ) + public_key = private_key.public_key() + + # 保存私钥 + private_pem = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() + ) + priv_file = key_path / "private" / f"{author.lower()}_private.pem" + priv_file.parent.mkdir(parents=True, exist_ok=True) + priv_file.write_bytes(private_pem) + + # 保存公钥 + public_pem = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + pub_file = key_path / "public" / f"{author}.pem" + pub_file.parent.mkdir(parents=True, exist_ok=True) + pub_file.write_bytes(public_pem) + + return str(priv_file), str(pub_file) + + +def New(): + return SignatureVerifierPlugin() diff --git a/store/@{FutureOSS}/signature-verifier/manifest.json b/store/@{FutureOSS}/signature-verifier/manifest.json new file mode 100644 index 0000000..e76af4b --- /dev/null +++ b/store/@{FutureOSS}/signature-verifier/manifest.json @@ -0,0 +1,18 @@ +{ + "metadata": { + "name": "signature-verifier", + "version": "1.0.0", + "author": "FutureOSS", + "description": "插件签名验证服务 - 验证官方插件完整性与来源真实性", + "type": "core" + }, + "config": { + "enabled": true, + "args": { + "enforce_official": true, + "key_dir": "data/signature-verifier/keys" + } + }, + "dependencies": ["plugin-storage"], + "permissions": ["plugin-storage"] +} diff --git a/store/@{FutureOSS}/webui/SIGNATURE b/store/@{FutureOSS}/webui/SIGNATURE new file mode 100644 index 0000000..5a13201 --- /dev/null +++ b/store/@{FutureOSS}/webui/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "EHeyw9j4zTQyLiTHSqEHQQL1wrzJOjm4jRKHIWuIiRUY6YORSLip1aDVP+aGpCf+KYGROE/pMt3SDUI7h+5VWAh9x/AYf0UrCOq38dNJ4+5TeHxOwUZvic2Ua26LBWRp0GfdRq/t06/dtXkIwD+0albetQNJoPkORBTCuxPVZqGVU6WkKWuYJ9xuQDhpn266qy6ZQfVe88BcNPbO//AIR8+t5gpd+hRmhbhxV58Omm+R0jtlx3ABEOH4g2HGkX961UvUdFSaoVMw7KR4lv9GQU1rMraP/zyHTLAQQlt/SxJAi3db51KWzFuH8rDsGKnB7LbJvnV32ojUNQs0SIO8935UY6RuHnKr8KHuAxFNX/1GA4MdloHhrK0Fm6Tx5FDXamthUFqJzYvjMtsGGN24p7/DQwaHqonB9AJ5szRf/vBYmsGs1WTCX/e89IN/uiVUPuqEiRxiJBRMLwpr2mz0r6e3keozWdPuxZ58WVH3Gd3gXvLngs+Gx3FyCd7RLtn24gkq/w16bCuA3XBE+9+n6QvAUBfvjiODCb9fjdPL/YNoJRMKqE1iAhMI+I5Cmu0ISOdTL4aYZEjZP3YwjauMKlpXMhclOwIv2I2btNQIKPOJj4SormqPweK0QXAVbOr+u/S0Z4L2vISGwJBetQl8fpSpdL2NLVmZM9xAoa1AZTY=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964952.7199903, + "plugin_hash": "1aee0b23a28d31b62a8863d1feff8a53e0a1221572cba160642ac18d10a8f52f", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/webui/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/webui/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..8de4e5f Binary files /dev/null and b/store/@{FutureOSS}/webui/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/webui/config.json b/store/@{FutureOSS}/webui/config.json new file mode 100644 index 0000000..9d82247 --- /dev/null +++ b/store/@{FutureOSS}/webui/config.json @@ -0,0 +1,29 @@ +{ + "title": { + "type": "string", + "name": "网站标题", + "description": "侧边栏和页面标题显示的文字", + "default": "FutureOSS", + "order": 1 + }, + "port": { + "type": "number", + "name": "端口号", + "description": "WebUI 监听端口", + "default": 8080, + "min": 1024, + "max": 65535, + "order": 2 + }, + "theme": { + "type": "select", + "name": "主题", + "description": "界面主题风格", + "default": "dark", + "options": [ + { "label": "深色", "value": "dark" }, + { "label": "浅色", "value": "light" } + ], + "order": 3 + } +} diff --git a/store/@{FutureOSS}/webui/config/database.sql b/store/@{FutureOSS}/webui/config/database.sql new file mode 100644 index 0000000..8c1fe7a --- /dev/null +++ b/store/@{FutureOSS}/webui/config/database.sql @@ -0,0 +1,49 @@ +-- FutureOSS WebUI 数据库初始化脚本 +-- 此脚本创建基础表结构,其他插件可以添加自己的表 + +CREATE DATABASE IF NOT EXISTS futureoss +CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci; + +USE futureoss; + +-- 用户表 (示例) +CREATE TABLE IF NOT EXISTS users ( + id INT AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(50) NOT NULL UNIQUE, + email VARCHAR(100) NOT NULL UNIQUE, + password_hash VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_username (username), + INDEX idx_email (email) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 插件配置表 +CREATE TABLE IF NOT EXISTS plugin_configs ( + id INT AUTO_INCREMENT PRIMARY KEY, + plugin_name VARCHAR(100) NOT NULL, + config_key VARCHAR(100) NOT NULL, + config_value TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY unique_plugin_config (plugin_name, config_key), + INDEX idx_plugin_name (plugin_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 系统日志表 +CREATE TABLE IF NOT EXISTS system_logs ( + id INT AUTO_INCREMENT PRIMARY KEY, + level VARCHAR(20) NOT NULL DEFAULT 'INFO', + message TEXT NOT NULL, + source VARCHAR(100), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + INDEX idx_level (level), + INDEX idx_created_at (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- 插入默认配置 +INSERT IGNORE INTO plugin_configs (plugin_name, config_key, config_value) VALUES +('webui', 'theme', 'dark'), +('webui', 'title', 'FutureOSS'), +('webui', 'version', '1.0.0'); diff --git a/store/@{FutureOSS}/webui/core/__init__.py b/store/@{FutureOSS}/webui/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/webui/core/__pycache__/__init__.cpython-313.pyc b/store/@{FutureOSS}/webui/core/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..07feb99 Binary files /dev/null and b/store/@{FutureOSS}/webui/core/__pycache__/__init__.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/webui/core/__pycache__/server.cpython-313.pyc b/store/@{FutureOSS}/webui/core/__pycache__/server.cpython-313.pyc new file mode 100644 index 0000000..e411ae8 Binary files /dev/null and b/store/@{FutureOSS}/webui/core/__pycache__/server.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/webui/core/server.py b/store/@{FutureOSS}/webui/core/server.py new file mode 100644 index 0000000..142f810 --- /dev/null +++ b/store/@{FutureOSS}/webui/core/server.py @@ -0,0 +1,155 @@ +"""WebUI 服务器 - 容器模式""" +import subprocess +import os +import tempfile +from oss.plugin.types import Response +from pathlib import Path + + +class WebUIServer: + """WebUI 服务器""" + + def __init__(self, router, config: dict): + self.router = router + self.config = config + self.frontend_dir = Path(__file__).parent.parent / "frontend" + + # 页面注册表 + self.pages = {} # path -> content_provider + self.nav_items = [] # 导航项列表 + + def start(self): + """注册默认路由""" + # 静态资源 + self.router.get("/static/css/main.css", self._handle_css) + self.router.get("/static/js/main.js", self._handle_js) + self.router.get("/health", self._handle_health) + + def register_page(self, path: str, content_provider, nav_item: dict = None): + """供其他插件注册页面""" + self.pages[path] = content_provider + if nav_item: + nav_item['url'] = path + self.nav_items.append(nav_item) + + # 注册路由 + self.router.get(path, lambda req: self._render_page(path, req)) + + def _render_page(self, path: str, request): + """渲染页面布局+内容""" + provider = self.pages.get(path) + content = provider() if provider else "" + + # 排序导航项(首页在前) + sorted_nav = sorted(self.nav_items, key=lambda x: 0 if x.get('url') == '/' else 1) + + variables = { + "pageTitle": self.config.get("title", "FutureOSS"), + "currentPage": path, + "navItems": sorted_nav, + "content": content + } + + php_file = self.frontend_dir / "views" / "layout.php" + html = self._execute_php(str(php_file), variables) + + return Response( + status=200, + headers={"Content-Type": "text/html; charset=utf-8"}, + body=html + ) + + def _default_home_content(self) -> str: + """默认首页内容""" + return """ +
+
+

👋 欢迎使用 FutureOSS

+

一切皆为插件的轻量级框架

+
+
+ """ + + def _execute_php(self, php_file: str, variables: dict = None) -> str: + """执行 PHP 文件""" + variables = variables or {} + + # 构建 PHP 变量注入 + php_vars = "" + for key, value in variables.items(): + if isinstance(value, dict): + php_vars += f"${key} = {self._php_array(value)};\n" + elif isinstance(value, list): + php_vars += f"${key} = {self._php_array_list(value)};\n" + elif isinstance(value, str): + php_vars += f"${key} = '{value.replace(chr(39), chr(92) + chr(39))}';\n" + else: + php_vars += f"${key} = {str(value).lower() if isinstance(value, bool) else value};\n" + + with open(php_file, 'r', encoding='utf-8') as f: + php_content = f.read() + + # 临时文件必须和 views 在同一目录,这样 __DIR__ 才能正确解析 + views_dir = str(Path(php_file).parent) + tmp_file = os.path.join(views_dir, '.temp_render.php') + + try: + with open(tmp_file, 'w', encoding='utf-8') as f: + f.write(f"\n{php_content}") + + result = subprocess.run( + ["php", "-f", tmp_file], + capture_output=True, text=True, timeout=10, cwd=views_dir + ) + + if result.returncode != 0: + print(f"[webui] PHP 执行错误: {result.stderr}") + return f"
PHP Error: {result.stderr}
" + + return result.stdout + finally: + try: + if os.path.exists(tmp_file): + os.unlink(tmp_file) + except: + pass + + def _php_array(self, py_dict: dict) -> str: + """Python Dict -> PHP Array""" + items = [] + for key, value in py_dict.items(): + if isinstance(value, str): + items.append(f"'{key}' => '{value.replace(chr(39), chr(92) + chr(39))}'") + elif isinstance(value, dict): + items.append(f"'{key}' => {self._php_array(value)}") + else: + items.append(f"'{key}' => {value}") + return "[" + ", ".join(items) + "]" + + def _php_array_list(self, py_list: list) -> str: + """Python List -> PHP Array""" + items = [] + for item in py_list: + if isinstance(item, dict): + items.append(self._php_array(item)) + elif isinstance(item, str): + items.append(f"'{item.replace(chr(39), chr(92) + chr(39))}'") + else: + items.append(str(item)) + return "[" + ", ".join(items) + "]" + + def _handle_css(self, request): + css_file = self.frontend_dir / "assets" / "css" / "main.css" + with open(css_file, 'r', encoding='utf-8') as f: + css = f.read() + return Response(status=200, headers={"Content-Type": "text/css; charset=utf-8"}, body=css) + + def _handle_js(self, request): + js_file = self.frontend_dir / "assets" / "js" / "main.js" + with open(js_file, 'r', encoding='utf-8') as f: + js = f.read() + return Response(status=200, headers={"Content-Type": "application/javascript; charset=utf-8"}, body=js) + + def _handle_health(self, request): + import json + return Response(status=200, headers={"Content-Type": "application/json"}, body=json.dumps({"status": "ok"})) diff --git a/store/@{FutureOSS}/webui/frontend/assets/css/main.css b/store/@{FutureOSS}/webui/frontend/assets/css/main.css new file mode 100644 index 0000000..668ea1b --- /dev/null +++ b/store/@{FutureOSS}/webui/frontend/assets/css/main.css @@ -0,0 +1,145 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + background: #f5f5f5; + color: #333; + overflow: hidden; +} + +.app { + display: flex; + height: 100vh; +} + +/* Dock 侧边栏 */ +.sidebar { + width: 64px; + min-width: 64px; + background: #1a1a2e; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 16px 0; + overflow: hidden; +} + +.sidebar-nav { + display: flex; + flex-direction: column; + gap: 8px; + padding: 0 12px; +} + +.nav-item { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + margin: 0 auto; + color: rgba(255, 255, 255, 0.7); + text-decoration: none; + border-radius: 10px; + transition: all 0.2s ease; + position: relative; +} + +.nav-item i { + font-size: 22px; +} + +.nav-item:hover { + background: rgba(255, 255, 255, 0.1); + color: #fff; +} + +.nav-item.active { + background: rgba(74, 144, 217, 0.2); + color: #4a90d9; +} + +.nav-item.active::before { + content: ''; + position: absolute; + left: -12px; + top: 50%; + transform: translateY(-50%); + width: 3px; + height: 20px; + background: #4a90d9; + border-radius: 0 2px 2px 0; +} + +/* Tooltip on hover */ +.nav-item:hover::after { + content: attr(title); + position: absolute; + left: 52px; + background: rgba(0, 0, 0, 0.8); + color: #fff; + padding: 6px 12px; + border-radius: 6px; + font-size: 13px; + white-space: nowrap; + pointer-events: none; + opacity: 0; + transition: opacity 0.2s; + z-index: 100; +} + +.nav-item:hover:hover::after { + opacity: 1; +} + +.sidebar-footer { + padding: 0 12px; +} + +.settings-btn { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + margin: 0 auto; + background: rgba(255, 255, 255, 0.05); + border: none; + color: rgba(255, 255, 255, 0.7); + border-radius: 10px; + cursor: pointer; + transition: all 0.2s; +} + +.settings-btn i { + font-size: 22px; +} + +.settings-btn:hover { + background: rgba(255, 255, 255, 0.1); + color: #fff; +} + +/* 内容区 */ +.content { + flex: 1; + overflow-y: auto; + height: 100vh; +} + +.content-body { + min-height: 100%; +} + +.empty-state { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + color: #999; + font-size: 15px; +} diff --git a/store/@{FutureOSS}/webui/frontend/assets/js/main.js b/store/@{FutureOSS}/webui/frontend/assets/js/main.js new file mode 100644 index 0000000..3f9e446 --- /dev/null +++ b/store/@{FutureOSS}/webui/frontend/assets/js/main.js @@ -0,0 +1,36 @@ +/** + * FutureOSS WebUI 主脚本 + * 提供基础框架功能 + */ + +window.WebUI = { + /** + * 打开设置面板 + * 其他插件可以扩展此功能 + */ + openSettings: function() { + console.log('[WebUI] 打开设置面板'); + // 设置面板逻辑 - 其他插件可以扩展 + alert('设置功能需要其他插件支持'); + }, + + /** + * 注册导航项 + * 其他插件可以调用此方法添加导航 + */ + registerNavItem: function(item) { + console.log('[WebUI] 注册导航项:', item); + // 实际实现需要与后端通信 + }, + + /** + * 加载内容到主内容区 + * 其他插件可以调用此方法加载内容 + */ + loadContent: function(url) { + console.log('[WebUI] 加载内容:', url); + // 实际实现需要 AJAX 请求 + } +}; + +console.log('FutureOSS WebUI 框架已加载'); diff --git a/store/@{FutureOSS}/webui/frontend/config/config.php b/store/@{FutureOSS}/webui/frontend/config/config.php new file mode 100644 index 0000000..750a79c --- /dev/null +++ b/store/@{FutureOSS}/webui/frontend/config/config.php @@ -0,0 +1,26 @@ + [ + 'host' => 'localhost', + 'port' => 3306, + 'username' => 'root', + 'password' => '', + 'dbname' => 'futureoss', + 'charset' => 'utf8mb4' + ], + + // 应用配置 + 'app' => [ + 'title' => 'FutureOSS', + 'theme' => 'dark', + 'version' => '1.0.0' + ], + + // 其他插件可以添加配置 + 'plugins' => [] +]; diff --git a/store/@{FutureOSS}/webui/frontend/includes/database.php b/store/@{FutureOSS}/webui/frontend/includes/database.php new file mode 100644 index 0000000..d8612be --- /dev/null +++ b/store/@{FutureOSS}/webui/frontend/includes/database.php @@ -0,0 +1,115 @@ +config = include $configFile; + $dbConfig = $this->config['database']; + + try { + $dsn = "mysql:host={$dbConfig['host']};port={$dbConfig['port']};dbname={$dbConfig['dbname']};charset={$dbConfig['charset']}"; + $this->connection = new PDO($dsn, $dbConfig['username'], $dbConfig['password']); + $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + } catch (PDOException $e) { + // 数据库连接失败时记录日志但不阻止页面加载 + error_log('[FutureOSS WebUI] 数据库连接失败: ' . $e->getMessage()); + $this->connection = null; + } + } + + /** + * 获取单例实例 + */ + public static function getInstance() { + if (self::$instance === null) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * 获取数据库连接 + */ + public function getConnection() { + return $this->connection; + } + + /** + * 检查数据库是否可用 + */ + public function isConnected() { + return $this->connection !== null; + } + + /** + * 执行查询 + */ + public function query($sql, $params = []) { + if (!$this->isConnected()) { + return false; + } + + try { + $stmt = $this->connection->prepare($sql); + $stmt->execute($params); + return $stmt; + } catch (PDOException $e) { + error_log('[FutureOSS WebUI] 数据库查询错误: ' . $e->getMessage()); + return false; + } + } + + /** + * 获取所有结果 + */ + public function fetchAll($sql, $params = []) { + $stmt = $this->query($sql, $params); + return $stmt ? $stmt->fetchAll() : []; + } + + /** + * 获取单条结果 + */ + public function fetchOne($sql, $params = []) { + $stmt = $this->query($sql, $params); + return $stmt ? $stmt->fetch() : null; + } + + /** + * 插入数据并返回 ID + */ + public function insert($sql, $params = []) { + $stmt = $this->query($sql, $params); + return $stmt ? $this->connection->lastInsertId() : false; + } + + /** + * 防止 SQL 注入 + */ + public function escape($value) { + if (!$this->isConnected()) { + return addslashes($value); + } + return $this->connection->quote($value); + } + + // 防止克隆 + private function __clone() {} + public function __wakeup() { + throw new Exception("Cannot unserialize singleton"); + } +} diff --git a/store/@{FutureOSS}/webui/frontend/views/dashboard.php b/store/@{FutureOSS}/webui/frontend/views/dashboard.php new file mode 100644 index 0000000..ac3ba89 --- /dev/null +++ b/store/@{FutureOSS}/webui/frontend/views/dashboard.php @@ -0,0 +1,17 @@ +

仪表盘内容加载中...

'; +} + +// 复用 layout +include __DIR__ . '/layout.php'; diff --git a/store/@{FutureOSS}/webui/frontend/views/index.php b/store/@{FutureOSS}/webui/frontend/views/index.php new file mode 100644 index 0000000..b2c3067 --- /dev/null +++ b/store/@{FutureOSS}/webui/frontend/views/index.php @@ -0,0 +1,17 @@ +

暂无内容

'; + +include __DIR__ . '/layout.php'; diff --git a/store/@{FutureOSS}/webui/frontend/views/layout.php b/store/@{FutureOSS}/webui/frontend/views/layout.php new file mode 100644 index 0000000..f0f12a7 --- /dev/null +++ b/store/@{FutureOSS}/webui/frontend/views/layout.php @@ -0,0 +1,64 @@ + + + + + + <?= htmlspecialchars($pageTitle ?? 'FutureOSS') ?> + + + + + +
+
+
+ + + 'ri-home-4-line', + '📊' => 'ri-dashboard-line', + '📋' => 'ri-file-list-3-line', + '🧩' => 'ri-puzzle-line', + '⚙️' => 'ri-settings-3-line', + '🔌' => 'ri-plug-line', + '📦' => 'ri-box-3-line', + '🌐' => 'ri-global-line', + ]; + $riIcon = $iconMap[$icon] ?? $icon; + ?> + + + + + +
+
+ +
+
+ +
+
+ + + +
+

暂无内容

+
+ +
+
+
+ + + + diff --git a/store/@{FutureOSS}/webui/main.py b/store/@{FutureOSS}/webui/main.py new file mode 100644 index 0000000..4b82818 --- /dev/null +++ b/store/@{FutureOSS}/webui/main.py @@ -0,0 +1,132 @@ +"""WebUI - Web 控制台 (容器模式)""" +from pathlib import Path +from oss.logger.logger import Log +from oss.plugin.types import Plugin, Response, register_plugin_type +from .core.server import WebUIServer + + +class WebUIPlugin(Plugin): + """WebUI 插件 - 提供页面容器""" + + def __init__(self): + self.http_api = None + self.server = None + self.config = {} + + def meta(self): + from oss.plugin.types import Metadata, PluginConfig, Manifest + return Manifest( + metadata=Metadata( + name="webui", + version="2.1.0", + author="FutureOSS", + description="Web 控制台容器 - 供其他插件注册页面" + ), + config=PluginConfig( + enabled=True, + args={ + "port": 8080, + "theme": "dark", + "title": "FutureOSS" + } + ), + dependencies=["http-api"] + ) + + def set_http_api(self, http_api): + """注入 http-api""" + self.http_api = http_api + + def init(self, deps: dict = None): + """初始化 WebUI 服务器""" + if not self.http_api: + Log.error("webui", "错误: 未找到 http-api 依赖") + return + + config = {} + if deps: + config = deps.get("config", {}) + + self.config = { + "port": config.get("port", 8080), + "theme": config.get("theme", "dark"), + "title": config.get("title", "FutureOSS") + } + + # 使用 http-api 的路由器 + self.server = WebUIServer( + self.http_api.router, + self.config + ) + Log.info("webui", "容器初始化完成") + + def start(self): + """启动服务器(注册默认路由)""" + if self.server: + # 检测仪表盘是否已安装,自动设为首页 + self._setup_home_page() + + self.server.start() + Log.info("webui", f"WebUI 容器已启动: http://localhost:{self.config['port']}") + + def _setup_home_page(self): + """设置首页:如果仪表盘已安装则跳转到仪表盘,否则显示默认首页""" + # 通过文件系统检查 dashboard 是否存在 + dashboard_exists = False + store_dirs = [ + Path("store/@{FutureOSS}/dashboard"), + Path("./data/pkg/dashboard"), + ] + for d in store_dirs: + if d.exists() and (d / "main.py").exists(): + dashboard_exists = True + break + + if dashboard_exists: + # 仪表盘已安装,注册首页重定向到仪表盘 + self.server.router.get("/", self._handle_home_redirect) + Log.info("webui", "检测到仪表盘,首页自动跳转到 /dashboard") + else: + # 默认首页 + self.server.register_page( + path="/", + content_provider=self.server._default_home_content, + nav_item={'icon': 'ri-home-4-line', 'text': '首页'} + ) + + def _handle_home_redirect(self, request): + """处理首页重定向到仪表盘""" + return Response( + status=302, + headers={"Location": "/dashboard", "Content-Type": "text/html"}, + body="" + ) + + def stop(self): + Log.error("webui", "WebUI 容器已停止") + + # --- 公开 API 供其他插件调用 --- + + def register_page(self, path: str, content_provider, nav_item: dict = None): + """ + 其他插件调用此方法注册页面。 + :param path: 路由路径 (e.g., '/dashboard') + :param content_provider: 无参函数,返回 HTML 字符串 + :param nav_item: 导航项 {'icon': '📊', 'text': '仪表盘'} + """ + if self.server: + self.server.register_page(path, content_provider, nav_item) + else: + Log.warn("webui", f"警告: 试图注册页面 {path},但服务器未初始化") + + def add_nav_item(self, item: dict): + """仅添加导航项(如果页面由其他方式处理)""" + if self.server: + self.server.nav_items.append(item) + + +register_plugin_type("WebUIPlugin", WebUIPlugin) + + +def New(): + return WebUIPlugin() diff --git a/store/@{FutureOSS}/webui/manifest.json b/store/@{FutureOSS}/webui/manifest.json new file mode 100644 index 0000000..a06abee --- /dev/null +++ b/store/@{FutureOSS}/webui/manifest.json @@ -0,0 +1,25 @@ +{ + "metadata": { + "name": "webui", + "version": "2.0.0", + "author": "FutureOSS", + "description": "Web 控制台 - 使用 PHP 前端和 MySQL 数据库", + "type": "webui" + }, + "config": { + "enabled": true, + "args": { + "port": 8080, + "theme": "dark", + "title": "FutureOSS" + } + }, + "dependencies": ["http-api"], + "permissions": ["*"], + "frontend": "php", + "database": { + "type": "mysql", + "name": "futureoss", + "init_script": "config/database.sql" + } +} diff --git a/store/@{FutureOSS}/webui/static/__init__.py b/store/@{FutureOSS}/webui/static/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/webui/static/assets.py b/store/@{FutureOSS}/webui/static/assets.py new file mode 100644 index 0000000..6fa38aa --- /dev/null +++ b/store/@{FutureOSS}/webui/static/assets.py @@ -0,0 +1,112 @@ +"""静态资源""" + + +class StaticAssets: + """静态资源管理器""" + + @staticmethod + def get_css() -> str: + return """* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + background: #f5f5f5; + color: #333; +} + +.app { + display: flex; + height: 100vh; +} + +.sidebar { + width: 240px; + background: #1a1a2e; + color: #fff; + display: flex; + flex-direction: column; +} + +.sidebar-header { + padding: 20px; + border-bottom: 1px solid rgba(255,255,255,0.1); +} + +.sidebar-header h1 { + font-size: 18px; +} + +.sidebar-nav { + flex: 1; + padding: 10px 0; +} + +.nav-item { + display: flex; + align-items: center; + padding: 12px 20px; + color: #fff; + text-decoration: none; + transition: background 0.2s; +} + +.nav-item:hover { + background: rgba(255,255,255,0.1); +} + +.nav-item.active { + background: rgba(255,255,255,0.15); + border-left: 3px solid #4a90d9; +} + +.nav-icon { + margin-right: 10px; +} + +.sidebar-footer { + padding: 15px 20px; + border-top: 1px solid rgba(255,255,255,0.1); +} + +.settings-btn { + width: 100%; + padding: 10px; + background: rgba(255,255,255,0.1); + border: none; + color: #fff; + border-radius: 6px; + cursor: pointer; +} + +.content { + flex: 1; + display: flex; + flex-direction: column; +} + +.content-header { + padding: 20px 30px; + background: #fff; + border-bottom: 1px solid #e0e0e0; +} + +.content-body { + flex: 1; + padding: 30px; +} + +.empty-state { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + color: #999; +}""" + + @staticmethod + def get_js() -> str: + return """console.log('FutureOSS WebUI loaded');""" diff --git a/store/@{FutureOSS}/webui/templates/__init__.py b/store/@{FutureOSS}/webui/templates/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/store/@{FutureOSS}/webui/templates/layout.py b/store/@{FutureOSS}/webui/templates/layout.py new file mode 100644 index 0000000..12a3e62 --- /dev/null +++ b/store/@{FutureOSS}/webui/templates/layout.py @@ -0,0 +1,49 @@ +"""页面布局模板""" + + +class LayoutTemplate: + """布局模板""" + + def __init__(self, config: dict): + self.config = config + + def render(self) -> str: + """渲染页面""" + return f""" + + + + + {self.config.get('title', 'FutureOSS')} + + + +
+
+
+

🚀 {self.config.get('title', 'FutureOSS')}

+
+
+ + 🏠 + 首页 + +
+
+ +
+
+
+
+

欢迎使用 FutureOSS

+
+
+
+

暂无内容

+
+
+
+
+ + +""" diff --git a/store/@{FutureOSS}/ws-api/SIGNATURE b/store/@{FutureOSS}/ws-api/SIGNATURE new file mode 100644 index 0000000..ef22622 --- /dev/null +++ b/store/@{FutureOSS}/ws-api/SIGNATURE @@ -0,0 +1,8 @@ +{ + "signature": "jCGTXt+uLD/djjYQIxogWXFztNVz4Y/Xyzsj3JaXtvrvNppdUm7Ei8/N08l+dZxqU7Lpjg2UIMakX2jVXSE2rlZlTZyL5cfvxr3j5mdDXP4VhXScdVwEaeScDz0qUn23e6qOqEdS+KbjK6pZCk34GjwBoV2/ze8DteK+whSMCSwqxYASHNTTrNhELKoDhTBnnlCEAAlEM6y95EIpdL6FsvJRP8w8xgg1Ah2gRvQdyC1785zbGdFJ3Oib6mw1fuKaV90Phqb8qCjD8qePqocdSArNJ/Jz+073lVH0IZMUw45cIF1uBgpXErnJrnY2KWtSLpC9AGK62vNLMjTYnKa7HZ0J2xwmg89skW2w3YSaiZweijelFgut7tmgdof52Xvb6hdnzNWTAKorT6C8d6jZWzNv0BrJKGtThzCoyBhTQOSiEfgz+QO2yFpbWxCtMjX1SfVEOaWWJq5H5fgTu6YqCJlwSU3ur3pdBLaBNYH3PMYW4aIOUs5mOzpnFBq1FTJmfz9BT9ZEIK/7bbVjCfifMMH1Xkq2gudQDfElok7WZQ3CaHNzms4wbwbS6yIzzRggDo1s7tTXR0i5AazoUOCKj6cxTqwPnBiO19J0Okjhj8TkApbNHAoezcgYHuq1HxxZ/ckGxs/5yVuN0qkBGESwfWPRmXd/CS8ddhIowSOds9c=", + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": 1775964952.9217672, + "plugin_hash": "b056cef4d2a2aceeeb199ef47fb709b021f9d2a7198109fa4023e3f2ded4b108", + "author": "FutureOSS" +} \ No newline at end of file diff --git a/store/@{FutureOSS}/ws-api/__pycache__/events.cpython-313.pyc b/store/@{FutureOSS}/ws-api/__pycache__/events.cpython-313.pyc deleted file mode 100644 index 581a6bf..0000000 Binary files a/store/@{FutureOSS}/ws-api/__pycache__/events.cpython-313.pyc and /dev/null differ diff --git a/store/@{FutureOSS}/ws-api/__pycache__/main.cpython-313.pyc b/store/@{FutureOSS}/ws-api/__pycache__/main.cpython-313.pyc index fe5849d..9c728e7 100644 Binary files a/store/@{FutureOSS}/ws-api/__pycache__/main.cpython-313.pyc and b/store/@{FutureOSS}/ws-api/__pycache__/main.cpython-313.pyc differ diff --git a/store/@{FutureOSS}/ws-api/__pycache__/middleware.cpython-313.pyc b/store/@{FutureOSS}/ws-api/__pycache__/middleware.cpython-313.pyc deleted file mode 100644 index 3211561..0000000 Binary files a/store/@{FutureOSS}/ws-api/__pycache__/middleware.cpython-313.pyc and /dev/null differ diff --git a/store/@{FutureOSS}/ws-api/__pycache__/router.cpython-313.pyc b/store/@{FutureOSS}/ws-api/__pycache__/router.cpython-313.pyc deleted file mode 100644 index 30732b3..0000000 Binary files a/store/@{FutureOSS}/ws-api/__pycache__/router.cpython-313.pyc and /dev/null differ diff --git a/store/@{FutureOSS}/ws-api/__pycache__/server.cpython-313.pyc b/store/@{FutureOSS}/ws-api/__pycache__/server.cpython-313.pyc deleted file mode 100644 index b55f7f1..0000000 Binary files a/store/@{FutureOSS}/ws-api/__pycache__/server.cpython-313.pyc and /dev/null differ diff --git a/store/@{FutureOSS}/ws-api/main.py b/store/@{FutureOSS}/ws-api/main.py index 28a03dc..79a070e 100644 --- a/store/@{FutureOSS}/ws-api/main.py +++ b/store/@{FutureOSS}/ws-api/main.py @@ -1,4 +1,5 @@ """WebSocket API 插件入口 - 简化版""" +from oss.logger.logger import Log from oss.plugin.types import Plugin, register_plugin_type @@ -10,17 +11,17 @@ class WsApiPlugin(Plugin): def init(self, deps: dict = None): """初始化""" - print("[ws-api] 初始化完成") + Log.info("ws-api", "初始化完成") def start(self): """启动""" self._running = True - print("[ws-api] 已启动") + Log.info("ws-api", "已启动") def stop(self): """停止""" self._running = False - print("[ws-api] 已停止") + Log.error("ws-api", "已停止") register_plugin_type("WsApiPlugin", WsApiPlugin) diff --git a/tools/sign_core_plugins.py b/tools/sign_core_plugins.py new file mode 100644 index 0000000..fbc4acc --- /dev/null +++ b/tools/sign_core_plugins.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +""" +为 dependency 和 signature-verifier 插件签名 +""" + +import sys +import json +import base64 +import hashlib +import time +from pathlib import Path + +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.backends import default_backend + +# ========== 配置 ========== +PROJECT_ROOT = Path(__file__).parent.parent +PRIVATE_KEY_FILE = PROJECT_ROOT / "data" / "signature-verifier" / "keys" / "private" / "futureoss_private.pem" + +PLUGINS = ["dependency", "signature-verifier"] + + +def compute_plugin_hash(plugin_dir: Path) -> str: + """计算插件目录的内容哈希""" + hasher = hashlib.sha256() + files_to_hash = [] + for file_path in sorted(plugin_dir.rglob("*")): + if file_path.is_file() and file_path.name != "SIGNATURE": + rel_path = file_path.relative_to(plugin_dir) + files_to_hash.append((str(rel_path), file_path)) + + for rel_path, file_path in files_to_hash: + hasher.update(rel_path.encode("utf-8")) + hasher.update(file_path.read_bytes()) + + return hasher.hexdigest() + + +def sign_plugin(plugin_dir: Path): + """为插件签名""" + # 加载私钥 + print(f"加载私钥: {PRIVATE_KEY_FILE}") + private_key = serialization.load_pem_private_key( + PRIVATE_KEY_FILE.read_bytes(), + password=None, + backend=default_backend() + ) + + # 计算插件哈希 + print(f"计算插件目录哈希: {plugin_dir.name}...") + plugin_hash = compute_plugin_hash(plugin_dir) + print(f"哈希: {plugin_hash}") + + # 签名 + signed_data = f"FutureOSS:{plugin_hash}".encode("utf-8") + signature = private_key.sign( + signed_data, + padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH + ), + hashes.SHA256() + ) + + # 写入签名文件 + sig_data = { + "signature": base64.b64encode(signature).decode(), + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": time.time(), + "plugin_hash": plugin_hash, + "author": "FutureOSS" + } + + signature_file = plugin_dir / "SIGNATURE" + signature_file.write_text(json.dumps(sig_data, indent=2)) + print(f"✓ 已签名: {plugin_dir.name}") + + +def main(): + if not PRIVATE_KEY_FILE.exists(): + print(f"错误: 私钥文件不存在: {PRIVATE_KEY_FILE}") + sys.exit(1) + + store_dir = PROJECT_ROOT / "store" / "@{FutureOSS}" + + for plugin_name in PLUGINS: + plugin_dir = store_dir / plugin_name + if plugin_dir.exists(): + sign_plugin(plugin_dir) + else: + print(f"警告: 插件目录不存在: {plugin_dir}") + + print("\n完成!") + + +if __name__ == "__main__": + main() diff --git a/tools/sign_plugin_loader.py b/tools/sign_plugin_loader.py new file mode 100644 index 0000000..f9914b6 --- /dev/null +++ b/tools/sign_plugin_loader.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +""" +为 plugin-loader 插件签名 +""" + +import sys +import json +import base64 +import hashlib +import time +from pathlib import Path + +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.backends import default_backend + +# ========== 配置 ========== +PROJECT_ROOT = Path(__file__).parent.parent +PRIVATE_KEY_FILE = PROJECT_ROOT / "data" / "signature-verifier" / "keys" / "private" / "futureoss_private.pem" +PLUGIN_DIR = PROJECT_ROOT / "store" / "@{FutureOSS}" / "plugin-loader" + + +def compute_plugin_hash(plugin_dir: Path) -> str: + """计算插件目录的内容哈希""" + hasher = hashlib.sha256() + files_to_hash = [] + for file_path in sorted(plugin_dir.rglob("*")): + if file_path.is_file() and file_path.name != "SIGNATURE": + rel_path = file_path.relative_to(plugin_dir) + files_to_hash.append((str(rel_path), file_path)) + + for rel_path, file_path in files_to_hash: + hasher.update(rel_path.encode("utf-8")) + hasher.update(file_path.read_bytes()) + + return hasher.hexdigest() + + +def sign_plugin(): + """为插件签名""" + # 加载私钥 + print(f"加载私钥: {PRIVATE_KEY_FILE}") + private_key = serialization.load_pem_private_key( + PRIVATE_KEY_FILE.read_bytes(), + password=None, + backend=default_backend() + ) + + # 计算插件哈希 + print(f"计算插件目录哈希...") + plugin_hash = compute_plugin_hash(PLUGIN_DIR) + print(f"哈希: {plugin_hash}") + + # 签名 + signed_data = f"FutureOSS:{plugin_hash}".encode("utf-8") + signature = private_key.sign( + signed_data, + padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH + ), + hashes.SHA256() + ) + + # 写入签名文件 + sig_data = { + "signature": base64.b64encode(signature).decode(), + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": time.time(), + "plugin_hash": plugin_hash, + "author": "FutureOSS" + } + + signature_file = PLUGIN_DIR / "SIGNATURE" + signature_file.write_text(json.dumps(sig_data, indent=2)) + print(f"\n✓ 签名成功!") + print(f" 插件: {PLUGIN_DIR.name}") + print(f" 签名文件: {signature_file}") + print(f" 算法: RSA-SHA256") + print(f" 时间戳: {time.strftime('%Y-%m-%d %H:%M:%S')}") + + +if __name__ == "__main__": + try: + from cryptography.hazmat.primitives import hashes, serialization + from cryptography.hazmat.primitives.asymmetric import padding + from cryptography.hazmat.backends import default_backend + except ImportError: + print("错误: 未安装 cryptography 库") + print("运行: pip install cryptography") + sys.exit(1) + + if not PLUGIN_DIR.exists(): + print(f"错误: 插件目录不存在: {PLUGIN_DIR}") + sys.exit(1) + + if not PRIVATE_KEY_FILE.exists(): + print(f"错误: 私钥文件不存在: {PRIVATE_KEY_FILE}") + sys.exit(1) + + sign_plugin() diff --git a/tools/sign_plugins.py b/tools/sign_plugins.py new file mode 100644 index 0000000..80ff3a3 --- /dev/null +++ b/tools/sign_plugins.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 +""" +密钥生成与插件签名工具 +- 生成 Falck 官方密钥对 +- 为所有官方插件签名 +""" + +import sys +import json +import base64 +import hashlib +import time +from pathlib import Path + +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding, rsa +from cryptography.hazmat.backends import default_backend + +# ========== 配置 ========== +PROJECT_ROOT = Path(__file__).parent.parent # 修复:tools 的上级目录 +KEY_DIR = PROJECT_ROOT / "data" / "signature-verifier" / "keys" +STORE_DIR = PROJECT_ROOT / "store" + +# 官方作者目录 +OFFICIAL_AUTHORS = ["FutureOSS", "Falck"] + + +def generate_keypair(author: str): + """生成 4096 位 RSA 密钥对""" + print(f"\n{'='*60}") + print(f"生成 {author} 的密钥对...") + print(f"{'='*60}") + + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=4096, + backend=default_backend() + ) + public_key = private_key.public_key() + + # 保存私钥 + private_pem = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() + ) + priv_dir = KEY_DIR / "private" + priv_dir.mkdir(parents=True, exist_ok=True) + priv_file = priv_dir / f"{author.lower()}_private.pem" + priv_file.write_bytes(private_pem) + print(f"私钥已保存: {priv_file}") + + # 保存公钥 + public_pem = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + pub_dir = KEY_DIR / "public" + pub_dir.mkdir(parents=True, exist_ok=True) + pub_file = pub_dir / f"{author}.pem" + pub_file.write_bytes(public_pem) + print(f"公钥已保存: {pub_file}") + + # 显示公钥(用于嵌入代码) + print(f"\n--- 公钥 PEM (用于嵌入 main.py) ---") + print(public_pem.decode()) + print(f"--- END ---\n") + + return private_key, public_key + + +def compute_plugin_hash(plugin_dir: Path) -> str: + """计算插件目录的内容哈希""" + hasher = hashlib.sha256() + files_to_hash = [] + for file_path in sorted(plugin_dir.rglob("*")): + if file_path.is_file() and file_path.name != "SIGNATURE": + rel_path = file_path.relative_to(plugin_dir) + files_to_hash.append((str(rel_path), file_path)) + + for rel_path, file_path in files_to_hash: + hasher.update(rel_path.encode("utf-8")) + hasher.update(file_path.read_bytes()) + + return hasher.hexdigest() + + +def sign_plugin(plugin_dir: Path, private_key, signer_name: str, author: str): + """为插件生成签名""" + plugin_hash = compute_plugin_hash(plugin_dir) + + # 签名 + signed_data = f"{author}:{plugin_hash}".encode("utf-8") + signature = private_key.sign( + signed_data, + padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH + ), + hashes.SHA256() + ) + + # 写入签名文件 + sig_data = { + "signature": base64.b64encode(signature).decode(), + "signer": signer_name, + "algorithm": "RSA-SHA256", + "timestamp": time.time(), + "plugin_hash": plugin_hash, + "author": author + } + + signature_file = plugin_dir / "SIGNATURE" + signature_file.write_text(json.dumps(sig_data, indent=2)) + print(f" ✓ 已签名: {plugin_dir.name} (哈希: {plugin_hash[:16]}...)") + + +def sign_all_plugins(private_key): + """为所有官方插件签名""" + for author in OFFICIAL_AUTHORS: + author_dir = STORE_DIR / f"@{{{author}}}" + if not author_dir.exists(): + print(f"\n警告: 作者目录不存在: {author_dir}") + continue + + print(f"\n{'='*60}") + print(f"为 @{{{author}}} 的插件签名...") + print(f"{'='*60}") + + count = 0 + for plugin_dir in sorted(author_dir.iterdir()): + if plugin_dir.is_dir() and (plugin_dir / "manifest.json").exists(): + sign_plugin(plugin_dir, private_key, author, author) + count += 1 + + print(f"\n完成: 已签名 {count} 个 @{author} 插件") + + +def main(): + print("="*60) + print("FutureOSS 插件签名工具") + print("="*60) + + # 检查 cryptography + try: + from cryptography.hazmat.primitives import hashes, serialization + from cryptography.hazmat.primitives.asymmetric import padding, rsa + from cryptography.hazmat.backends import default_backend + except ImportError: + print("错误: 未安装 cryptography 库") + print("运行: pip install cryptography") + sys.exit(1) + + # 步骤 1: 生成密钥对 + print("\n步骤 1: 生成 Falck 官方密钥对...") + falck_priv, falck_pub = generate_keypair("Falck") + + print("\n步骤 1b: 生成 FutureOSS 官方密钥对...") + foss_priv, foss_pub = generate_keypair("FutureOSS") + + # 步骤 2: 为所有官方插件签名(使用对应的密钥) + print("\n步骤 2: 为所有官方插件签名...") + + # Falck 的插件用 Falck 密钥签名 + falck_dir = STORE_DIR / "@{Falck}" + if falck_dir.exists(): + print(f"\n{'='*60}") + print("为 @{Falck} 的插件使用 Falck 密钥签名...") + print(f"{'='*60}") + for plugin_dir in sorted(falck_dir.iterdir()): + if plugin_dir.is_dir() and (plugin_dir / "manifest.json").exists(): + sign_plugin(plugin_dir, falck_priv, "Falck", "Falck") + + # FutureOSS 的插件用 FutureOSS 密钥签名 + foss_dir = STORE_DIR / "@{FutureOSS}" + if foss_dir.exists(): + print(f"\n{'='*60}") + print("为 @{FutureOSS} 的插件使用 FutureOSS 密钥签名...") + print(f"{'='*60}") + for plugin_dir in sorted(foss_dir.iterdir()): + if plugin_dir.is_dir() and (plugin_dir / "manifest.json").exists(): + sign_plugin(plugin_dir, foss_priv, "FutureOSS", "FutureOSS") + + print("\n" + "="*60) + print("全部完成!") + print("="*60) + print(f"\n密钥位置: {KEY_DIR}") + print("请将公钥嵌入 signature-verifier/main.py 的 FALCK_PUBLIC_KEY_PEM 变量") + print("并妥善保管私钥,不要提交到版本控制系统!") + + +if __name__ == "__main__": + main() diff --git a/tools/sign_single_plugin.py b/tools/sign_single_plugin.py new file mode 100644 index 0000000..cfe32b2 --- /dev/null +++ b/tools/sign_single_plugin.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +""" +为单个插件签名 +""" + +import sys +import json +import base64 +import hashlib +import time +from pathlib import Path + +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.backends import default_backend + +# ========== 配置 ========== +PROJECT_ROOT = Path(__file__).parent.parent +PRIVATE_KEY_FILE = PROJECT_ROOT / "data" / "signature-verifier" / "keys" / "private" / "futureoss_private.pem" +PLUGIN_DIR = PROJECT_ROOT / "store" / "@{FutureOSS}" / "log-terminal" + + +def compute_plugin_hash(plugin_dir: Path) -> str: + """计算插件目录的内容哈希""" + hasher = hashlib.sha256() + files_to_hash = [] + for file_path in sorted(plugin_dir.rglob("*")): + if file_path.is_file() and file_path.name != "SIGNATURE": + rel_path = file_path.relative_to(plugin_dir) + files_to_hash.append((str(rel_path), file_path)) + + for rel_path, file_path in files_to_hash: + hasher.update(rel_path.encode("utf-8")) + hasher.update(file_path.read_bytes()) + + return hasher.hexdigest() + + +def sign_plugin(): + """为插件签名""" + # 加载私钥 + print(f"加载私钥: {PRIVATE_KEY_FILE}") + private_key = serialization.load_pem_private_key( + PRIVATE_KEY_FILE.read_bytes(), + password=None, + backend=default_backend() + ) + + # 计算插件哈希 + print(f"计算插件目录哈希...") + plugin_hash = compute_plugin_hash(PLUGIN_DIR) + print(f"哈希: {plugin_hash}") + + # 签名 + signed_data = f"FutureOSS:{plugin_hash}".encode("utf-8") + signature = private_key.sign( + signed_data, + padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH + ), + hashes.SHA256() + ) + + # 写入签名文件 + sig_data = { + "signature": base64.b64encode(signature).decode(), + "signer": "FutureOSS", + "algorithm": "RSA-SHA256", + "timestamp": time.time(), + "plugin_hash": plugin_hash, + "author": "FutureOSS" + } + + signature_file = PLUGIN_DIR / "SIGNATURE" + signature_file.write_text(json.dumps(sig_data, indent=2)) + print(f"\n✓ 签名成功!") + print(f" 插件: {PLUGIN_DIR.name}") + print(f" 签名文件: {signature_file}") + print(f" 算法: RSA-SHA256") + print(f" 时间戳: {time.strftime('%Y-%m-%d %H:%M:%S')}") + + +if __name__ == "__main__": + try: + from cryptography.hazmat.primitives import hashes, serialization + from cryptography.hazmat.primitives.asymmetric import padding + from cryptography.hazmat.backends import default_backend + except ImportError: + print("错误: 未安装 cryptography 库") + print("运行: pip install cryptography") + sys.exit(1) + + if not PLUGIN_DIR.exists(): + print(f"错误: 插件目录不存在: {PLUGIN_DIR}") + sys.exit(1) + + if not PRIVATE_KEY_FILE.exists(): + print(f"错误: 私钥文件不存在: {PRIVATE_KEY_FILE}") + sys.exit(1) + + sign_plugin() diff --git a/tools/test_signature.py b/tools/test_signature.py new file mode 100644 index 0000000..beea771 --- /dev/null +++ b/tools/test_signature.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +""" +签名验证测试脚本 +测试签名验证功能是否正常工作 +""" + +import sys +import json +import base64 +import hashlib +from pathlib import Path + +# 添加项目路径 +sys.path.insert(0, str(Path(__file__).parent.parent)) +sys.path.insert(0, str(Path(__file__).parent.parent / "store/@{FutureOSS}/signature-verifier")) + +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.backends import default_backend +from cryptography.exceptions import InvalidSignature + +# 导入签名验证插件 +from main import SignatureVerifier, SignatureSigner + + +def test_verify_official_plugins(): + """测试验证所有已签名的官方插件""" + print("="*60) + print("测试 1: 验证所有官方插件签名") + print("="*60) + + store_dir = Path(__file__).parent.parent / "store" + verifier = SignatureVerifier(key_dir="./data/signature-verifier/keys") + + authors = ["FutureOSS", "Falck"] + total = 0 + passed = 0 + failed = 0 + + for author in authors: + author_dir = store_dir / f"@{{{author}}}" + if not author_dir.exists(): + continue + + print(f"\n--- @{author} ---") + for plugin_dir in sorted(author_dir.iterdir()): + if plugin_dir.is_dir() and (plugin_dir / "manifest.json").exists(): + total += 1 + valid, msg = verifier.verify_plugin(plugin_dir, author) + status = "✅ 通过" if valid else "❌ 失败" + print(f" {status}: {plugin_dir.name} - {msg}") + if valid: + passed += 1 + else: + failed += 1 + + print(f"\n{'='*60}") + print(f"结果: {passed}/{total} 通过, {failed} 失败") + print(f"{'='*60}") + return failed == 0 + + +def test_tamper_detection(): + """测试篡改检测""" + print("\n" + "="*60) + print("测试 2: 篡改检测") + print("="*60) + + store_dir = Path(__file__).parent.parent / "store" + verifier = SignatureVerifier(key_dir="./data/signature-verifier/keys") + + # 选择一个测试插件 + test_plugin = store_dir / "@{FutureOSS}" / "dashboard" + if not test_plugin.exists(): + print("跳过: dashboard 插件不存在") + return True + + # 验证原始签名 + valid_before, msg_before = verifier.verify_plugin(test_plugin, "FutureOSS") + print(f"\n篡改前: {'✅ 有效' if valid_before else '❌ 无效'} - {msg_before}") + + if not valid_before: + print("警告: 原始签名已无效,跳过篡改测试") + return False + + # 创建一个临时篡改文件 + tamper_file = test_plugin / "__tamper_test__.tmp" + tamper_file.write_text("tampered content") + + # 验证篡改后的签名 + valid_after, msg_after = verifier.verify_plugin(test_plugin, "FutureOSS") + print(f"篡改后: {'✅ 有效' if valid_after else '❌ 无效'} - {msg_after}") + + # 清理 + tamper_file.unlink() + + # 再次验证应该恢复有效 + valid_clean, msg_clean = verifier.verify_plugin(test_plugin, "FutureOSS") + print(f"清理后: {'✅ 有效' if valid_clean else '❌ 无效'} - {msg_clean}") + + # 预期:篡改后无效,清理后有效 + success = not valid_after and valid_clean + print(f"\n{'='*60}") + print(f"篡改检测: {'✅ 成功' if success else '❌ 失败'}") + print(f"{'='*60}") + return success + + +def test_missing_signature(): + """测试缺失签名文件""" + print("\n" + "="*60) + print("测试 3: 缺失签名检测") + print("="*60) + + store_dir = Path(__file__).parent.parent / "store" + verifier = SignatureVerifier(key_dir="./data/signature-verifier/keys") + + # 选择一个插件并临时移除签名 + test_plugin = store_dir / "@{FutureOSS}" / "json-codec" + if not test_plugin.exists(): + print("跳过: json-codec 插件不存在") + return True + + sig_file = test_plugin / "SIGNATURE" + if not sig_file.exists(): + print("跳过: json-codec 没有签名文件") + return True + + # 备份签名 + backup = sig_file.read_text() + sig_file.unlink() + + # 验证 + valid, msg = verifier.verify_plugin(test_plugin, "FutureOSS") + print(f"无签名: {'✅ 有效' if valid else '❌ 无效'} - {msg}") + + # 恢复 + sig_file.write_text(backup) + + valid_restored, msg_restored = verifier.verify_plugin(test_plugin, "FutureOSS") + print(f"恢复后: {'✅ 有效' if valid_restored else '❌ 无效'} - {msg_restored}") + + success = not valid and valid_restored + print(f"\n{'='*60}") + print(f"缺失签名检测: {'✅ 成功' if success else '❌ 失败'}") + print(f"{'='*60}") + return success + + +def test_official_check(): + """测试 is_official_plugin 方法""" + print("\n" + "="*60) + print("测试 4: 官方插件识别") + print("="*60) + + store_dir = Path(__file__).parent.parent / "store" + verifier = SignatureVerifier(key_dir="./data/signature-verifier/keys") + + # 测试官方插件 + official_plugin = store_dir / "@{FutureOSS}" / "dashboard" + is_official = verifier.is_official_plugin(official_plugin) + print(f"dashboard 是官方插件: {'✅ 是' if is_official else '❌ 否'}") + + success = is_official + print(f"\n{'='*60}") + print(f"官方插件识别: {'✅ 成功' if success else '❌ 失败'}") + print(f"{'='*60}") + return success + + +def main(): + print("FutureOSS 签名验证系统测试") + print("="*60) + + results = [] + + results.append(("官方插件验证", test_verify_official_plugins())) + results.append(("篡改检测", test_tamper_detection())) + results.append(("缺失签名检测", test_missing_signature())) + results.append(("官方插件识别", test_official_check())) + + print("\n" + "="*60) + print("测试总结") + print("="*60) + + for name, passed in results: + status = "✅ 通过" if passed else "❌ 失败" + print(f" {status}: {name}") + + all_passed = all(r[1] for r in results) + print(f"\n{'='*60}") + print(f"总体结果: {'✅ 全部通过' if all_passed else '❌ 有失败'}") + print(f"{'='*60}") + + return 0 if all_passed else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/video/architecture.html b/video/architecture.html new file mode 100644 index 0000000..8166329 --- /dev/null +++ b/video/architecture.html @@ -0,0 +1,274 @@ + + + + + + FutureOSS - 架构解析 + + + +
+
+
▶
+
+ +
🏗️ 架构解析
+ +
+
+ +
+
前端层
+
🌐WebUI 容器
+
📊Dashboard
+
💻Log Terminal
+
+ +
⬇
+ + +
+
服务层
+
🔌HTTP API
:8080
+
🔌TCP Server
:8082
+
🔌WebSocket
+
+ +
⬇
+ + +
+
核心层
+
📦Plugin Loader
+
🌉Plugin Bridge
+
🔐签名验证
+
+ +
⬇
+ + +
+
基础设施
+
💾Plugin Storage
+
🎨Logger
+
📦Pkg Manager
+
🔗Dependency
+
+
+ +
一切皆为插件,从核心到界面
+
+ +
+
+ + + +
+ + + + diff --git a/video/index.html b/video/index.html new file mode 100644 index 0000000..f7a58a7 --- /dev/null +++ b/video/index.html @@ -0,0 +1,113 @@ + + + + + + FutureOSS - 视频展示 + + + +
+

🎬 FutureOSS 视频展示

+

用动画和声音了解我们的项目

+
+
+
+
📦
+
+

项目特性展示

+

立方体动画演示核心特性,插件化、安全性、实时监控...

+
▶ 点击播放
+
+
+
+
🔌
+
+

插件开发演示

+

从零开发一个插件,看这里就对了

+
▶ 点击播放
+
+
+
+
🏗️
+
+

架构解析

+

深入了解 FutureOSS 的技术架构和设计思想

+
▶ 点击播放
+
+
+
+
+

FutureOSS © 2026 — 一切皆为插件

+
+ + diff --git a/video/intro.html b/video/intro.html new file mode 100644 index 0000000..acf632d --- /dev/null +++ b/video/intro.html @@ -0,0 +1,553 @@ + + + + + +FutureOSS + + + + +
+
+
+ +
+
FUTUREOSS
+
+
+
+
+
+
+ + +
+ +
+ + +
+ + +
+
不知道你有没有这种感觉
+
+ + +
+
每次搭一个新项目,都很累
+
+ + +
+
+
因为每次都在
重复同样的事
+
+
    +
  • 装环境装到怀疑人生
  • +
  • 找个配置文件翻遍整个项目
  • +
  • 加个小功能要大改架构
  • +
  • 出了问题连日志都看不明白
  • +
+
+
+
+ + +
+
于是我们想
+
+ + +
+
+
能不能做一个
不用操心的框架?
+
+
    +
  • 不用再重复写基础代码
  • +
  • 不用再手动管理依赖
  • +
  • 不用在几十个文件里找配置
  • +
  • 不用担心插件被篡改
  • +
+
+
+
+ + +
+
FutureOSS
+
一切皆为插件
+
+ + +
+
不是部分功能可插拔
+
而是所有东西都是插件
+
仪表盘、日志、前端全部是
+
+ + +
+
+
+# 新建一个目录 丢进去 +store/@{你}/hello/ + main.py + manifest.json + README.md + +# 启动自动加载 删掉自动消失 +# 不用改一行核心代码 +
+
+
插件化
+
想加功能?新建一个目录丢进去。想删?直接 rm -rf。不用改一行核心代码。
+
+
+
+ + +
+
+
+验证中... + SHA-256 校验通过 + RSA-4096 签名合法 + 来源: @Falck + +# 每个官方插件启动前 +# 自动验证,失败直接拒绝加载 +
+
+
签名验证
+
不是事后检查,是加载前就验证。改了一个字节,整个插件拒绝加载。
+
+
+
+ + +
+
+
+Log.info("app", "启动") +Log.warn("db", "将满") +Log.error("api", "超时") +Log.tip("app", "已加载 20 插件") + +# 终端自动着色 +# 不用 grep 找关键字 +
+
+
彩色日志
+
info 白 warn 黄 error 红。不用在一堆黑白文字里翻来覆去。
+
+
+
+ + +
+
+
+$ pkg install @author/plugin + 下载完成 + 签名验证通过 + 已安装,重启生效 + +# 不用 git clone +# 不用手动复制目录 +# 一行命令搞定 +
+
+
插件商店
+
一条命令安装插件。不用去仓库翻目录、不用手动复制文件。
+
+
+
+ + +
+
+
+仪表盘实时展示: + CPU 78% + MEM 56% + NET 12.3M/s 4.1M/s + DISK RD 45MB WR 23MB + LOAD 1.2 0.8 0.6 + +# 打开浏览器就有 +# 不用装 Prometheus +# 不用配 Grafana +
+
+
实时监控
+
启动就有仪表盘。不用搭 Prometheus、不用配 Grafana,打开浏览器就行。
+
+
+
+ + +
+
+
+

以前

+

git clone xxx
pip install -r req.txt
python -m venv .venv
source .venv/bin/activate
pip install flask mysql...
改配置文件半小时
python main.py
报错 -> 查日志 -> 改配置
python main.py
又报错...

+
+
+

现在

+

bash start.sh

+
+
+
+ + +
+
+
$ bash start.sh
+
检测环境...
+
自动安装依赖...
+
虚拟环境创建完成
+
20 个插件加载完成
+
http://localhost:8080
+
$
+
+
+ + +
+
+
0
+ 官方插件
+
+
0
行命令
+
+
0
% 插件化
+
+
+ + +
+
+
FutureOSS
+
一切皆为插件
+
+ gitee.com/starlight-apk/feature-oss + futureoss.date +
+
+
+ +
+ + + + diff --git a/video/plugin-demo.html b/video/plugin-demo.html new file mode 100644 index 0000000..62179d7 --- /dev/null +++ b/video/plugin-demo.html @@ -0,0 +1,324 @@ + + + + + + FutureOSS - 插件开发演示 + + + +
+
+
+
+ +
+
▶
+
+ +
🔌 从零开发一个插件
+ +
+
+
1
+

📁 创建插件目录

+

按照规范在 store/@{作者名}/插件名/ 下创建目录

+ + store/@{myname}/hello-world/
+ ├── main.py
+ ├── manifest.json
+ └── README.md +
+
+
+
2
+

📝 编写 manifest.json

+

声明插件名称、版本、依赖和描述信息

+ + {
+   "name": "hello-world",
+   "version": "1.0.0",
+   "author": "@{myname}",
+   "description": "我的第一个插件"
+ } +
+
+
+
3
+

🐍 编写 main.py

+

实现插件的初始化逻辑,注册路由或事件

+ + class Plugin:
+   def init(self, app):
+     @app.route("/hello")
+     def hello():
+       return {"msg": "Hello, FutureOSS!"} +
+
+
+
4
+

🚀 启动 & 测试

+

运行项目,访问 http://localhost:8080/hello 验证插件是否正常工作

+ + bash start.sh
+ curl http://localhost:8080/hello
+ # → {"msg": "Hello, FutureOSS!"} +
+
+
+
5
+

📦 发布到商店

+

打包插件并上传到 Gitee 商店,其他人一键安装!

+ + python tools/sign_single_plugin.py @{myname}/hello-world
+ # 上传到 Gitee 商店仓库 +
+
+
+ +
+
+ + + +
+ + + + diff --git a/website/architecture.html b/website/architecture.html deleted file mode 100644 index cd7531b..0000000 --- a/website/architecture.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - 架构设计 - Future OSS - - - - - - - - - - - - - - - - - -
- -
-
- 架构设计 -

插件驱动的分层架构

-

一切皆为插件,框架本身只提供核心能力

-
- -
-
-
Future OSS 核心
-
-
插件管理
-
事件总线
-
消息总线
-
配置系统
-
-
-
-
-
-
-
协议插件
-
HTTP / WS
-
TCP / gRPC
-
UDP / Unix
-
-
-
工具插件
-
外部进程
-
脚本执行
-
依赖管理
-
-
-
中间件插件
-
限流 / 认证
-
日志 / 压缩
-
缓存 / 重试
-
-
-
通知插件
-
Webhook
-
邮件 / 钉钉
-
Telegram
-
-
-
-
- -
-

数据流

-
-
1外部请求进入协议插件
-
→
-
2中间件链处理(认证/限流)
-
→
-
3业务插件执行逻辑
-
→
-
4发布事件 + 返回响应
-
-
-
- - - - - - - - - diff --git a/website/blog/404.html b/website/blog/404.html deleted file mode 100644 index 8dbdb33..0000000 --- a/website/blog/404.html +++ /dev/null @@ -1,721 +0,0 @@ - 404 - FutureOSS Docs - - - - - - -
FutureOSS Docs
主页
归档
-
Gitee
GitHub
-
主页
-
归档
-
Gitee
GitHub
-
Mobile banner image of the blog
Desktop banner image of the blog

FutureOSS

Profile Image of the Author
FutureOSS
一切皆为插件的开发者工具运行时框架
欢迎来到 FutureOSS
一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
快速开始
分类
标签
Blogging Example Markdown Mermaid Video
404

页面未找到

抱歉,您访问的页面不存在或已被移动。

返回首页
-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
\ No newline at end of file diff --git a/website/blog/_astro/1.4bEaLvdy.webp b/website/blog/_astro/1.4bEaLvdy.webp deleted file mode 100644 index f2d7937..0000000 Binary files a/website/blog/_astro/1.4bEaLvdy.webp and /dev/null differ diff --git a/website/blog/_astro/ArchivePanel.BiDlEF9L.js b/website/blog/_astro/ArchivePanel.BiDlEF9L.js deleted file mode 100644 index facbecb..0000000 --- a/website/blog/_astro/ArchivePanel.BiDlEF9L.js +++ /dev/null @@ -1,10 +0,0 @@ -import{o as W,i as X}from"./lifecycle.MLiOCzKC.js";import{a as y,p as Z,b as $,s as tt,e as S,h as l,r as o,i as g,g as e,u as d,t as D,j as P,d as et}from"./template.CyUWgh-J.js";import{s as c}from"./render.C4NccAY7.js";import{e as M,i as N}from"./each.DMYtlFB3.js";import{p as A,s as U}from"./props.h8jPqBEd.js";import{I as k}from"./zh_TW.CqrCsd4X.js";import{i as B}from"./translation.BRy61wHY.js";import{g as F}from"./url-utils.CaIMLrxo.js";import"./utils.DonxBMOE.js";import"./config.B4FKKqOZ.js";var at=S(`
`),rt=S(`
`),it=S('
');function gt(K,f){$(f,!1);let h=A(f,"tags",12),p=A(f,"categories",12),L=A(f,"sortedPosts",24,()=>[]);const v=new URLSearchParams(window.location.search);h(v.has("tag")?v.getAll("tag"):[]),p(v.has("category")?v.getAll("category"):[]);const O=v.get("uncategorized");let j=et([]);function R(r){const a=(r.getMonth()+1).toString().padStart(2,"0"),n=r.getDate().toString().padStart(2,"0");return`${a}-${n}`}function T(r){return r.map(a=>`#${a}`).join(" ")}W(async()=>{let r=L();h().length>0&&(r=r.filter(t=>Array.isArray(t.data.tags)&&t.data.tags.some(i=>h().includes(i)))),p().length>0&&(r=r.filter(t=>t.data.category&&p().includes(t.data.category))),O&&(r=r.filter(t=>!t.data.category));const a=r.reduce((t,i)=>{const u=i.data.published.getFullYear();return t[u]||(t[u]=[]),t[u].push(i),t},{}),n=Object.keys(a).map(t=>({year:Number.parseInt(t),posts:a[Number.parseInt(t)]}));n.sort((t,i)=>i.year-t.year),tt(j,n)}),X();var x=it();M(x,5,()=>e(j),N,(r,a)=>{var n=rt(),t=l(n),i=l(t),u=l(i,!0);o(i);var z=g(i,4),Y=l(z);o(z),o(t);var q=g(t,2);M(q,1,()=>(e(a),d(()=>e(a).posts)),N,(w,s)=>{var m=at(),I=l(m),b=l(I),E=l(b,!0);o(b);var _=g(b,4),G=l(_,!0);o(_);var C=g(_,2),H=l(C,!0);o(C),o(I),o(m),D((J,Q,V)=>{U(m,"href",J),U(m,"aria-label",(e(s),d(()=>e(s).data.title))),c(E,Q),c(G,(e(s),d(()=>e(s).data.title))),c(H,V)},[()=>(P(F),e(s),d(()=>F(e(s).slug))),()=>(e(s),d(()=>R(e(s).data.published))),()=>(e(s),d(()=>T(e(s).data.tags)))]),y(w,m)}),o(n),D(w=>{c(u,(e(a),d(()=>e(a).year))),c(Y,`${e(a),d(()=>e(a).posts.length)??""} ${w??""}`)},[()=>(P(B),e(a),P(k),d(()=>B(e(a).posts.length===1?k.postCount:k.postsCount)))]),y(r,n)}),o(x),y(K,x),Z()}export{gt as default}; diff --git a/website/blog/_astro/DisplaySettings.BkjQOgCB.js b/website/blog/_astro/DisplaySettings.BkjQOgCB.js deleted file mode 100644 index cc016d9..0000000 --- a/website/blog/_astro/DisplaySettings.BkjQOgCB.js +++ /dev/null @@ -1,4 +0,0 @@ -import{i as R}from"./lifecycle.MLiOCzKC.js";import{d as V,l as $,k as z,t as A,g as t,a as B,p as E,b as F,h as a,j as i,u as y,s as k,e as G,i as p,r}from"./template.CyUWgh-J.js";import{s as w}from"./render.C4NccAY7.js";import{a as J,s as L,r as M}from"./props.h8jPqBEd.js";import{e as N}from"./utils.DonxBMOE.js";import{b as O}from"./input.CM2Xh3yk.js";import{I as o}from"./zh_TW.CqrCsd4X.js";import{i as l}from"./translation.BRy61wHY.js";import{I as P}from"./Icon.DAqWeDJZ.js";import{b as Q,c as H,d as I}from"./setting-utils.Bem8IX7u.js";/* empty css */import"./config.B4FKKqOZ.js";import"./functions.LP-DBi81.js";var T=G(`
`);function ne(j,D){F(D,!1);let e=V(Q());const u=H();function q(){k(e,H())}$(()=>(t(e),I),()=>{(t(e)||t(e)===0)&&I(t(e))}),z(),R();var n=T(),d=a(n),f=a(d),c=a(f),s=p(c);let b;var _=a(s),C=a(_);P(C,{icon:"fa6-solid:arrow-rotate-left",class:"text-[0.875rem]"}),r(_),r(s),r(f);var g=p(f,2),x=a(g),S=a(x,!0);r(x),r(g),r(d);var h=p(d,2),v=a(h);M(v),r(h),r(n),A((m,K)=>{w(c,`${m??""} `),b=J(s,1,"btn-regular w-7 h-7 rounded-md active:scale-90",null,b,{"opacity-0":t(e)===u,"pointer-events-none":t(e)===u}),w(S,t(e)),L(v,"aria-label",K)},[()=>(i(l),i(o),y(()=>l(o.themeColor))),()=>(i(l),i(o),y(()=>l(o.themeColor)))]),N("click",s,q),O(v,()=>t(e),m=>k(e,m)),B(j,n),E()}export{ne as default}; diff --git a/website/blog/_astro/DynamicSideBar.astro_astro_type_script_index_0_lang.CF8CQkY6.js b/website/blog/_astro/DynamicSideBar.astro_astro_type_script_index_0_lang.CF8CQkY6.js deleted file mode 100644 index dfc59d1..0000000 --- a/website/blog/_astro/DynamicSideBar.astro_astro_type_script_index_0_lang.CF8CQkY6.js +++ /dev/null @@ -1 +0,0 @@ -import{w as r}from"./widget-manager.B87vf-Ll.js";import"./config.B4FKKqOZ.js";class n{sidebar;resizeObserver=null;constructor(){this.sidebar=document.getElementById("dynamic-sidebar"),this.init()}init(){this.sidebar&&(this.setupResponsiveDisplay(),this.setupResizeObserver(),this.setupWidgetInteractions(),this.applyInitialAnimations())}setupResponsiveDisplay(){this.updateResponsiveDisplay(),window.addEventListener("resize",()=>this.updateResponsiveDisplay())}updateResponsiveDisplay(){if(!this.sidebar)return;const s=r.getBreakpoints(),e=window.innerWidth;let i;e{for(const e of s){const{width:i,height:t}=e.contentRect;console.debug(`Sidebar size changed: ${i}x${t}`)}}),this.resizeObserver.observe(this.sidebar))}setupWidgetInteractions(){if(!this.sidebar)return;this.sidebar.querySelectorAll(".widget-container").forEach(e=>{const i=e.getAttribute("data-widget-type");e.addEventListener("mouseenter",()=>{e.classList.add("widget-hover")}),e.addEventListener("mouseleave",()=>{e.classList.remove("widget-hover")}),console.debug(`Widget ${i} interaction setup complete`)})}applyInitialAnimations(){if(!this.sidebar)return;this.sidebar.querySelectorAll(".widget-container").forEach((e,i)=>{const t=i*100;e.style.animationDelay=`${t}ms`})}destroy(){this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}}const a=new n;window.addEventListener("beforeunload",()=>{a.destroy()}); diff --git a/website/blog/_astro/Icon.DAqWeDJZ.js b/website/blog/_astro/Icon.DAqWeDJZ.js deleted file mode 100644 index cc4e131..0000000 --- a/website/blog/_astro/Icon.DAqWeDJZ.js +++ /dev/null @@ -1 +0,0 @@ -import{o as $,a as j,i as P,c as z}from"./lifecycle.MLiOCzKC.js";import{i as A,g as C,c as G}from"./functions.LP-DBi81.js";import{v as y,w as D,x as v,t as V,y as L,a8 as Y,a9 as E,aa as q,C as T,D as B,a2 as F,ab as J,ac as K,ad as Q,ae as U,af as W,l as X,k as Z,c as k,f as I,a as b,p as x,b as aa,s as N,g as a,j as ea,m as w,d as M,u as H,ag as sa,r as ta,ah as ra,e as oa}from"./template.CyUWgh-J.js";import{l as na,b as O}from"./props.h8jPqBEd.js";function ia(p,g,r=!1,s=!1,i=!1,m=!1){var e=p,f="";if(r){var u=p;y&&(e=D(v(u)))}V(()=>{var l=Y;if(f===(f=g()??"")){y&&L();return}if(r&&!y){l.nodes=null,u.innerHTML=f,f!==""&&E(v(u),u.lastChild);return}if(l.nodes!==null&&(q(l.nodes.start,l.nodes.end),l.nodes=null),f!==""){if(y){T.data;for(var o=L(),h=o;o!==null&&(o.nodeType!==B||o.data!=="");)h=o,o=F(o);if(o===null)throw J(),K;E(T,h),e=D(o);return}var n=s?U:i?W:void 0,t=Q(s?"svg":i?"math":"template",n);t.innerHTML=f;var c=s||i?t:t.content;if(E(v(c),c.lastChild),s||i)for(;v(c);)e.before(v(c));else e.before(c)}})}var fa=ra(""),la=oa("");function va(p,g){const r=na(g,["children","$$slots","$$events","$$legacy"]);aa(g,!1);const s=M({name:"",loading:null,destroyed:!1});let i=M(!1),m=M(0),e=M();const f=n=>{typeof r.onLoad=="function"&&r.onLoad(n),z()("load",{icon:n})};function u(){sa(m)}$(()=>{N(i,!0)}),j(()=>{w(s,a(s).destroyed=!0),a(s).loading&&(a(s).loading.abort(),w(s,a(s).loading=null))}),X(()=>(a(m),ea(r),a(i),a(s),a(e),C),()=>{a(m);const n=!!r.ssr||a(i),t=G(r.icon,a(s),n,u,f);N(e,t?C(t.data,r):null),a(e)&&t.classes&&w(e,a(e).attributes.class=(typeof r.class=="string"?r.class+" ":"")+t.classes.join(" "))}),Z(),P();var l=k(),o=I(l);{var h=n=>{var t=k(),c=I(t);{var R=_=>{var d=fa();O(d,()=>({...a(e).attributes})),ia(d,()=>(a(e),H(()=>a(e).body)),!0),ta(d),b(_,d)},S=_=>{var d=la();O(d,()=>({...a(e).attributes})),b(_,d)};A(c,_=>{a(e),H(()=>a(e).svg)?_(R):_(S,-1)})}b(n,t)};A(o,n=>{a(e)&&n(h)})}b(p,l),x()}export{va as I,ia as h}; diff --git a/website/blog/_astro/KaTeX_AMS-Regular.BQhdFMY1.woff2 b/website/blog/_astro/KaTeX_AMS-Regular.BQhdFMY1.woff2 deleted file mode 100644 index 0acaaff..0000000 Binary files a/website/blog/_astro/KaTeX_AMS-Regular.BQhdFMY1.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_AMS-Regular.DMm9YOAa.woff b/website/blog/_astro/KaTeX_AMS-Regular.DMm9YOAa.woff deleted file mode 100644 index b804d7b..0000000 Binary files a/website/blog/_astro/KaTeX_AMS-Regular.DMm9YOAa.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_AMS-Regular.DRggAlZN.ttf b/website/blog/_astro/KaTeX_AMS-Regular.DRggAlZN.ttf deleted file mode 100644 index c6f9a5e..0000000 Binary files a/website/blog/_astro/KaTeX_AMS-Regular.DRggAlZN.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf b/website/blog/_astro/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf deleted file mode 100644 index 9ff4a5e..0000000 Binary files a/website/blog/_astro/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Caligraphic-Bold.BEiXGLvX.woff b/website/blog/_astro/KaTeX_Caligraphic-Bold.BEiXGLvX.woff deleted file mode 100644 index 9759710..0000000 Binary files a/website/blog/_astro/KaTeX_Caligraphic-Bold.BEiXGLvX.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2 b/website/blog/_astro/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2 deleted file mode 100644 index f390922..0000000 Binary files a/website/blog/_astro/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Caligraphic-Regular.CTRA-rTL.woff b/website/blog/_astro/KaTeX_Caligraphic-Regular.CTRA-rTL.woff deleted file mode 100644 index 9bdd534..0000000 Binary files a/website/blog/_astro/KaTeX_Caligraphic-Regular.CTRA-rTL.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2 b/website/blog/_astro/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2 deleted file mode 100644 index 75344a1..0000000 Binary files a/website/blog/_astro/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Caligraphic-Regular.wX97UBjC.ttf b/website/blog/_astro/KaTeX_Caligraphic-Regular.wX97UBjC.ttf deleted file mode 100644 index f522294..0000000 Binary files a/website/blog/_astro/KaTeX_Caligraphic-Regular.wX97UBjC.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Fraktur-Bold.BdnERNNW.ttf b/website/blog/_astro/KaTeX_Fraktur-Bold.BdnERNNW.ttf deleted file mode 100644 index 4e98259..0000000 Binary files a/website/blog/_astro/KaTeX_Fraktur-Bold.BdnERNNW.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Fraktur-Bold.BsDP51OF.woff b/website/blog/_astro/KaTeX_Fraktur-Bold.BsDP51OF.woff deleted file mode 100644 index e7730f6..0000000 Binary files a/website/blog/_astro/KaTeX_Fraktur-Bold.BsDP51OF.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Fraktur-Bold.CL6g_b3V.woff2 b/website/blog/_astro/KaTeX_Fraktur-Bold.CL6g_b3V.woff2 deleted file mode 100644 index 395f28b..0000000 Binary files a/website/blog/_astro/KaTeX_Fraktur-Bold.CL6g_b3V.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Fraktur-Regular.CB_wures.ttf b/website/blog/_astro/KaTeX_Fraktur-Regular.CB_wures.ttf deleted file mode 100644 index b8461b2..0000000 Binary files a/website/blog/_astro/KaTeX_Fraktur-Regular.CB_wures.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Fraktur-Regular.CTYiF6lA.woff2 b/website/blog/_astro/KaTeX_Fraktur-Regular.CTYiF6lA.woff2 deleted file mode 100644 index 735f694..0000000 Binary files a/website/blog/_astro/KaTeX_Fraktur-Regular.CTYiF6lA.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Fraktur-Regular.Dxdc4cR9.woff b/website/blog/_astro/KaTeX_Fraktur-Regular.Dxdc4cR9.woff deleted file mode 100644 index acab069..0000000 Binary files a/website/blog/_astro/KaTeX_Fraktur-Regular.Dxdc4cR9.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Bold.Cx986IdX.woff2 b/website/blog/_astro/KaTeX_Main-Bold.Cx986IdX.woff2 deleted file mode 100644 index ab2ad21..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Bold.Cx986IdX.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Bold.Jm3AIy58.woff b/website/blog/_astro/KaTeX_Main-Bold.Jm3AIy58.woff deleted file mode 100644 index f38136a..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Bold.Jm3AIy58.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Bold.waoOVXN0.ttf b/website/blog/_astro/KaTeX_Main-Bold.waoOVXN0.ttf deleted file mode 100644 index 4060e62..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Bold.waoOVXN0.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2 b/website/blog/_astro/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2 deleted file mode 100644 index 5931794..0000000 Binary files a/website/blog/_astro/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-BoldItalic.DzxPMmG6.ttf b/website/blog/_astro/KaTeX_Main-BoldItalic.DzxPMmG6.ttf deleted file mode 100644 index dc00797..0000000 Binary files a/website/blog/_astro/KaTeX_Main-BoldItalic.DzxPMmG6.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-BoldItalic.SpSLRI95.woff b/website/blog/_astro/KaTeX_Main-BoldItalic.SpSLRI95.woff deleted file mode 100644 index 67807b0..0000000 Binary files a/website/blog/_astro/KaTeX_Main-BoldItalic.SpSLRI95.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Italic.3WenGoN9.ttf b/website/blog/_astro/KaTeX_Main-Italic.3WenGoN9.ttf deleted file mode 100644 index 0e9b0f3..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Italic.3WenGoN9.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Italic.BMLOBm91.woff b/website/blog/_astro/KaTeX_Main-Italic.BMLOBm91.woff deleted file mode 100644 index 6f43b59..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Italic.BMLOBm91.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Italic.NWA7e6Wa.woff2 b/website/blog/_astro/KaTeX_Main-Italic.NWA7e6Wa.woff2 deleted file mode 100644 index b50920e..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Italic.NWA7e6Wa.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Regular.B22Nviop.woff2 b/website/blog/_astro/KaTeX_Main-Regular.B22Nviop.woff2 deleted file mode 100644 index eb24a7b..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Regular.B22Nviop.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Regular.Dr94JaBh.woff b/website/blog/_astro/KaTeX_Main-Regular.Dr94JaBh.woff deleted file mode 100644 index 21f5812..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Regular.Dr94JaBh.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Main-Regular.ypZvNtVU.ttf b/website/blog/_astro/KaTeX_Main-Regular.ypZvNtVU.ttf deleted file mode 100644 index dd45e1e..0000000 Binary files a/website/blog/_astro/KaTeX_Main-Regular.ypZvNtVU.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Math-BoldItalic.B3XSjfu4.ttf b/website/blog/_astro/KaTeX_Math-BoldItalic.B3XSjfu4.ttf deleted file mode 100644 index 728ce7a..0000000 Binary files a/website/blog/_astro/KaTeX_Math-BoldItalic.B3XSjfu4.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2 b/website/blog/_astro/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2 deleted file mode 100644 index 2965702..0000000 Binary files a/website/blog/_astro/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Math-BoldItalic.iY-2wyZ7.woff b/website/blog/_astro/KaTeX_Math-BoldItalic.iY-2wyZ7.woff deleted file mode 100644 index 0ae390d..0000000 Binary files a/website/blog/_astro/KaTeX_Math-BoldItalic.iY-2wyZ7.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Math-Italic.DA0__PXp.woff b/website/blog/_astro/KaTeX_Math-Italic.DA0__PXp.woff deleted file mode 100644 index eb5159d..0000000 Binary files a/website/blog/_astro/KaTeX_Math-Italic.DA0__PXp.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Math-Italic.flOr_0UB.ttf b/website/blog/_astro/KaTeX_Math-Italic.flOr_0UB.ttf deleted file mode 100644 index 70d559b..0000000 Binary files a/website/blog/_astro/KaTeX_Math-Italic.flOr_0UB.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Math-Italic.t53AETM-.woff2 b/website/blog/_astro/KaTeX_Math-Italic.t53AETM-.woff2 deleted file mode 100644 index 215c143..0000000 Binary files a/website/blog/_astro/KaTeX_Math-Italic.t53AETM-.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Bold.CFMepnvq.ttf b/website/blog/_astro/KaTeX_SansSerif-Bold.CFMepnvq.ttf deleted file mode 100644 index 2f65a8a..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Bold.CFMepnvq.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Bold.D1sUS0GD.woff2 b/website/blog/_astro/KaTeX_SansSerif-Bold.D1sUS0GD.woff2 deleted file mode 100644 index cfaa3bd..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Bold.D1sUS0GD.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Bold.DbIhKOiC.woff b/website/blog/_astro/KaTeX_SansSerif-Bold.DbIhKOiC.woff deleted file mode 100644 index 8d47c02..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Bold.DbIhKOiC.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Italic.C3H0VqGB.woff2 b/website/blog/_astro/KaTeX_SansSerif-Italic.C3H0VqGB.woff2 deleted file mode 100644 index 349c06d..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Italic.C3H0VqGB.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Italic.DN2j7dab.woff b/website/blog/_astro/KaTeX_SansSerif-Italic.DN2j7dab.woff deleted file mode 100644 index 7e02df9..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Italic.DN2j7dab.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf b/website/blog/_astro/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf deleted file mode 100644 index d5850df..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Regular.BNo7hRIc.ttf b/website/blog/_astro/KaTeX_SansSerif-Regular.BNo7hRIc.ttf deleted file mode 100644 index 537279f..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Regular.BNo7hRIc.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Regular.CS6fqUqJ.woff b/website/blog/_astro/KaTeX_SansSerif-Regular.CS6fqUqJ.woff deleted file mode 100644 index 31b8482..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Regular.CS6fqUqJ.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2 b/website/blog/_astro/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2 deleted file mode 100644 index a90eea8..0000000 Binary files a/website/blog/_astro/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Script-Regular.C5JkGWo-.ttf b/website/blog/_astro/KaTeX_Script-Regular.C5JkGWo-.ttf deleted file mode 100644 index fd679bf..0000000 Binary files a/website/blog/_astro/KaTeX_Script-Regular.C5JkGWo-.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Script-Regular.D3wIWfF6.woff2 b/website/blog/_astro/KaTeX_Script-Regular.D3wIWfF6.woff2 deleted file mode 100644 index b3048fc..0000000 Binary files a/website/blog/_astro/KaTeX_Script-Regular.D3wIWfF6.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Script-Regular.D5yQViql.woff b/website/blog/_astro/KaTeX_Script-Regular.D5yQViql.woff deleted file mode 100644 index 0e7da82..0000000 Binary files a/website/blog/_astro/KaTeX_Script-Regular.D5yQViql.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size1-Regular.C195tn64.woff b/website/blog/_astro/KaTeX_Size1-Regular.C195tn64.woff deleted file mode 100644 index 7f292d9..0000000 Binary files a/website/blog/_astro/KaTeX_Size1-Regular.C195tn64.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size1-Regular.Dbsnue_I.ttf b/website/blog/_astro/KaTeX_Size1-Regular.Dbsnue_I.ttf deleted file mode 100644 index 871fd7d..0000000 Binary files a/website/blog/_astro/KaTeX_Size1-Regular.Dbsnue_I.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size1-Regular.mCD8mA8B.woff2 b/website/blog/_astro/KaTeX_Size1-Regular.mCD8mA8B.woff2 deleted file mode 100644 index c5a8462..0000000 Binary files a/website/blog/_astro/KaTeX_Size1-Regular.mCD8mA8B.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size2-Regular.B7gKUWhC.ttf b/website/blog/_astro/KaTeX_Size2-Regular.B7gKUWhC.ttf deleted file mode 100644 index 7a212ca..0000000 Binary files a/website/blog/_astro/KaTeX_Size2-Regular.B7gKUWhC.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size2-Regular.Dy4dx90m.woff2 b/website/blog/_astro/KaTeX_Size2-Regular.Dy4dx90m.woff2 deleted file mode 100644 index e1bccfe..0000000 Binary files a/website/blog/_astro/KaTeX_Size2-Regular.Dy4dx90m.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size2-Regular.oD1tc_U0.woff b/website/blog/_astro/KaTeX_Size2-Regular.oD1tc_U0.woff deleted file mode 100644 index d241d9b..0000000 Binary files a/website/blog/_astro/KaTeX_Size2-Regular.oD1tc_U0.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size3-Regular.CTq5MqoE.woff b/website/blog/_astro/KaTeX_Size3-Regular.CTq5MqoE.woff deleted file mode 100644 index e6e9b65..0000000 Binary files a/website/blog/_astro/KaTeX_Size3-Regular.CTq5MqoE.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size3-Regular.DgpXs0kz.ttf b/website/blog/_astro/KaTeX_Size3-Regular.DgpXs0kz.ttf deleted file mode 100644 index 00bff34..0000000 Binary files a/website/blog/_astro/KaTeX_Size3-Regular.DgpXs0kz.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size4-Regular.BF-4gkZK.woff b/website/blog/_astro/KaTeX_Size4-Regular.BF-4gkZK.woff deleted file mode 100644 index e1ec545..0000000 Binary files a/website/blog/_astro/KaTeX_Size4-Regular.BF-4gkZK.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size4-Regular.DWFBv043.ttf b/website/blog/_astro/KaTeX_Size4-Regular.DWFBv043.ttf deleted file mode 100644 index 74f0892..0000000 Binary files a/website/blog/_astro/KaTeX_Size4-Regular.DWFBv043.ttf and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Size4-Regular.Dl5lxZxV.woff2 b/website/blog/_astro/KaTeX_Size4-Regular.Dl5lxZxV.woff2 deleted file mode 100644 index 680c130..0000000 Binary files a/website/blog/_astro/KaTeX_Size4-Regular.Dl5lxZxV.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Typewriter-Regular.C0xS9mPB.woff b/website/blog/_astro/KaTeX_Typewriter-Regular.C0xS9mPB.woff deleted file mode 100644 index 2432419..0000000 Binary files a/website/blog/_astro/KaTeX_Typewriter-Regular.C0xS9mPB.woff and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Typewriter-Regular.CO6r4hn1.woff2 b/website/blog/_astro/KaTeX_Typewriter-Regular.CO6r4hn1.woff2 deleted file mode 100644 index 771f1af..0000000 Binary files a/website/blog/_astro/KaTeX_Typewriter-Regular.CO6r4hn1.woff2 and /dev/null differ diff --git a/website/blog/_astro/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf b/website/blog/_astro/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf deleted file mode 100644 index c83252c..0000000 Binary files a/website/blog/_astro/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf and /dev/null differ diff --git a/website/blog/_astro/Layout.CKPtf-VR.css b/website/blog/_astro/Layout.CKPtf-VR.css deleted file mode 100644 index a848ad2..0000000 --- a/website/blog/_astro/Layout.CKPtf-VR.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * OverlayScrollbars - * Version: 2.15.1 - * - * Copyright (c) Rene Haas | KingSora. - * https://github.com/KingSora - * - * Released under the MIT license. - */.os-size-observer,.os-size-observer-listener{scroll-behavior:auto!important;direction:inherit;pointer-events:none;overflow:hidden;visibility:hidden;box-sizing:border-box}.os-size-observer,.os-size-observer-listener,.os-size-observer-listener-item,.os-size-observer-listener-item-final{writing-mode:horizontal-tb;position:absolute;left:0;top:0}.os-size-observer{z-index:-1;contain:strict;display:flex;flex-direction:row;flex-wrap:nowrap;padding:inherit;border:inherit;box-sizing:inherit;margin:-133px;inset:0;transform:scale(.1)}.os-size-observer:before{content:"";flex:none;box-sizing:inherit;padding:10px;width:10px;height:10px}.os-size-observer-appear{animation:os-size-observer-appear-animation 1ms forwards}.os-size-observer-listener{box-sizing:border-box;position:relative;flex:auto;padding:inherit;border:inherit;margin:-133px;transform:scale(10)}.os-size-observer-listener.ltr{margin-right:-266px;margin-left:0}.os-size-observer-listener.rtl{margin-left:-266px;margin-right:0}.os-size-observer-listener:empty:before{content:"";width:100%;height:100%}.os-size-observer-listener:empty:before,.os-size-observer-listener>.os-size-observer-listener-item{display:block;position:relative;padding:inherit;border:inherit;box-sizing:content-box;flex:auto}.os-size-observer-listener-scroll{box-sizing:border-box;display:flex}.os-size-observer-listener-item{right:0;bottom:0;overflow:hidden;direction:ltr;flex:none}.os-size-observer-listener-item-final{transition:none}@keyframes os-size-observer-appear-animation{0%{cursor:auto}to{cursor:none}}.os-trinsic-observer{flex:none;box-sizing:border-box;position:relative;max-width:0px;max-height:1px;padding:0;margin:0;border:none;overflow:hidden;z-index:-1;height:0;top:calc(100% + 1px);contain:strict}.os-trinsic-observer:not(:empty){height:calc(100% + 1px);top:-1px}.os-trinsic-observer:not(:empty)>.os-size-observer{width:1000%;height:1000%;min-height:1px;min-width:1px}[data-overlayscrollbars-initialize]:not([data-overlayscrollbars-viewport]),[data-overlayscrollbars-viewport~=scrollbarHidden],html[data-overlayscrollbars-viewport~=scrollbarHidden]>body{scrollbar-width:none!important}[data-overlayscrollbars-initialize]:not([data-overlayscrollbars-viewport])::-webkit-scrollbar,[data-overlayscrollbars-initialize]:not([data-overlayscrollbars-viewport])::-webkit-scrollbar-corner,[data-overlayscrollbars-viewport~=scrollbarHidden]::-webkit-scrollbar,[data-overlayscrollbars-viewport~=scrollbarHidden]::-webkit-scrollbar-corner,html[data-overlayscrollbars-viewport~=scrollbarHidden]>body::-webkit-scrollbar,html[data-overlayscrollbars-viewport~=scrollbarHidden]>body::-webkit-scrollbar-corner{-webkit-appearance:none!important;appearance:none!important;display:none!important;width:0!important;height:0!important}[data-overlayscrollbars-initialize]:not([data-overlayscrollbars]):not(html):not(body){overflow:auto}html[data-overlayscrollbars-body]{overflow:hidden}html[data-overlayscrollbars-body],html[data-overlayscrollbars-body]>body{width:100%;height:100%;margin:0}html[data-overlayscrollbars-body]>body{overflow:visible;margin:0}[data-overlayscrollbars]{position:relative}[data-overlayscrollbars~=host],[data-overlayscrollbars-padding]{display:flex;align-items:stretch!important;flex-direction:row!important;flex-wrap:nowrap!important;scroll-behavior:auto!important}[data-overlayscrollbars-padding],[data-overlayscrollbars-viewport]:not([data-overlayscrollbars]){box-sizing:inherit;position:relative;flex:auto;height:auto;width:100%;min-width:0;padding:0;margin:0;border:none;z-index:0}[data-overlayscrollbars-viewport]:not([data-overlayscrollbars]){--os-vaw: 0;--os-vah: 0;outline:none}[data-overlayscrollbars-viewport]:not([data-overlayscrollbars]):focus{outline:none}[data-overlayscrollbars-viewport][data-overlayscrollbars-viewport~=arrange]:before{content:"";position:absolute;pointer-events:none;z-index:-1;min-width:1px;min-height:1px;width:var(--os-vaw);height:var(--os-vah)}[data-overlayscrollbars~=host],[data-overlayscrollbars-padding]{overflow:hidden!important}[data-overlayscrollbars~=host][data-overlayscrollbars~=noClipping],[data-overlayscrollbars-padding~=noClipping]{overflow:visible!important}[data-overlayscrollbars-viewport]{--os-viewport-overflow-x: hidden;--os-viewport-overflow-y: hidden;overflow-x:var(--os-viewport-overflow-x);overflow-y:var(--os-viewport-overflow-y)}[data-overlayscrollbars-viewport~=overflowXVisible]{--os-viewport-overflow-x: visible}[data-overlayscrollbars-viewport~=overflowXHidden]{--os-viewport-overflow-x: hidden}[data-overlayscrollbars-viewport~=overflowXScroll]{--os-viewport-overflow-x: scroll}[data-overlayscrollbars-viewport~=overflowYVisible]{--os-viewport-overflow-y: visible}[data-overlayscrollbars-viewport~=overflowYHidden]{--os-viewport-overflow-y: hidden}[data-overlayscrollbars-viewport~=overflowYScroll]{--os-viewport-overflow-y: scroll}[data-overlayscrollbars-viewport~=overflowImportant]{overflow-x:var(--os-viewport-overflow-x)!important;overflow-y:var(--os-viewport-overflow-y)!important}[data-overlayscrollbars-viewport~=noContent]:not(#osFakeId){font-size:0!important;line-height:0!important}[data-overlayscrollbars-viewport~=noContent]:not(#osFakeId):before,[data-overlayscrollbars-viewport~=noContent]:not(#osFakeId):after,[data-overlayscrollbars-viewport~=noContent]:not(#osFakeId)>*:not(#osFakeId){display:none!important;position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border-width:0!important}[data-overlayscrollbars-viewport~=measuring],[data-overlayscrollbars-viewport~=scrolling]{scroll-behavior:auto!important;scroll-snap-type:none!important}[data-overlayscrollbars-viewport~=measuring][data-overlayscrollbars-viewport~=overflowXVisible]{overflow-x:hidden!important}[data-overlayscrollbars-viewport~=measuring][data-overlayscrollbars-viewport~=overflowYVisible]{overflow-y:hidden!important}[data-overlayscrollbars-content]{box-sizing:inherit}[data-overlayscrollbars-contents]:not(#osFakeId):not([data-overlayscrollbars-padding]):not([data-overlayscrollbars-viewport]):not([data-overlayscrollbars-content]){display:contents}[data-overlayscrollbars-grid],[data-overlayscrollbars-grid] [data-overlayscrollbars-padding]{display:grid;grid-template:1fr/1fr}[data-overlayscrollbars-grid]>[data-overlayscrollbars-padding],[data-overlayscrollbars-grid]>[data-overlayscrollbars-viewport],[data-overlayscrollbars-grid]>[data-overlayscrollbars-padding]>[data-overlayscrollbars-viewport]{height:auto!important;width:auto!important}@property --os-scroll-percent{syntax: ""; inherits: true; initial-value: 0;}@property --os-viewport-percent{syntax: ""; inherits: true; initial-value: 0;}.os-scrollbar{--os-viewport-percent: 0;--os-scroll-percent: 0;--os-scroll-direction: 0;--os-scroll-percent-directional: calc( var(--os-scroll-percent) - (var(--os-scroll-percent) + (1 - var(--os-scroll-percent)) * -1) * var(--os-scroll-direction) );contain:size layout;contain:size layout style;transition:opacity .15s,visibility .15s,top .15s,right .15s,bottom .15s,left .15s;pointer-events:none;position:absolute;opacity:0;visibility:hidden}body>.os-scrollbar{position:fixed;z-index:99999}.os-scrollbar-transitionless{transition:none!important}.os-scrollbar-track{position:relative;padding:0!important;border:none!important}.os-scrollbar-handle{position:absolute}.os-scrollbar-track,.os-scrollbar-handle{pointer-events:none;width:100%;height:100%}.os-scrollbar.os-scrollbar-track-interactive .os-scrollbar-track,.os-scrollbar.os-scrollbar-handle-interactive .os-scrollbar-handle{pointer-events:auto;touch-action:none}.os-scrollbar-horizontal{bottom:0;left:0}.os-scrollbar-vertical{top:0;right:0}.os-scrollbar-rtl.os-scrollbar-horizontal{right:0}.os-scrollbar-rtl.os-scrollbar-vertical{right:auto;left:0}.os-scrollbar-visible{opacity:1;visibility:visible}.os-scrollbar-auto-hide.os-scrollbar-auto-hide-hidden{opacity:0;visibility:hidden}.os-scrollbar-interaction.os-scrollbar-visible{opacity:1;visibility:visible}.os-scrollbar-unusable,.os-scrollbar-unusable *,.os-scrollbar-wheel,.os-scrollbar-wheel *{pointer-events:none!important}.os-scrollbar-unusable .os-scrollbar-handle{opacity:0!important;transition:none!important}.os-scrollbar-horizontal .os-scrollbar-handle{bottom:0;left:calc(var(--os-scroll-percent-directional) * 100%);transform:translate(calc(var(--os-scroll-percent-directional) * -100%));width:calc(var(--os-viewport-percent) * 100%)}.os-scrollbar-vertical .os-scrollbar-handle{right:0;top:calc(var(--os-scroll-percent-directional) * 100%);transform:translateY(calc(var(--os-scroll-percent-directional) * -100%));height:calc(var(--os-viewport-percent) * 100%)}@supports (container-type: size){.os-scrollbar-track{container-type:size}.os-scrollbar-horizontal .os-scrollbar-handle{left:auto;transform:translate(calc(var(--os-scroll-percent-directional) * 100cqw + var(--os-scroll-percent-directional) * -100%))}.os-scrollbar-vertical .os-scrollbar-handle{top:auto;transform:translateY(calc(var(--os-scroll-percent-directional) * 100cqh + var(--os-scroll-percent-directional) * -100%))}.os-scrollbar-rtl.os-scrollbar-horizontal .os-scrollbar-handle{right:auto;left:0}}.os-scrollbar-rtl.os-scrollbar-vertical .os-scrollbar-handle{right:auto;left:0}.os-scrollbar.os-scrollbar-horizontal.os-scrollbar-cornerless,.os-scrollbar.os-scrollbar-horizontal.os-scrollbar-cornerless.os-scrollbar-rtl{left:0;right:0}.os-scrollbar.os-scrollbar-vertical.os-scrollbar-cornerless,.os-scrollbar.os-scrollbar-vertical.os-scrollbar-cornerless.os-scrollbar-rtl{top:0;bottom:0}@media print{.os-scrollbar{display:none}}.os-scrollbar{--os-size: 0;--os-padding-perpendicular: 0;--os-padding-axis: 0;--os-track-border-radius: 0;--os-track-bg: none;--os-track-bg-hover: none;--os-track-bg-active: none;--os-track-border: none;--os-track-border-hover: none;--os-track-border-active: none;--os-handle-border-radius: 0;--os-handle-bg: none;--os-handle-bg-hover: none;--os-handle-bg-active: none;--os-handle-border: none;--os-handle-border-hover: none;--os-handle-border-active: none;--os-handle-min-size: 33px;--os-handle-max-size: none;--os-handle-perpendicular-size: 100%;--os-handle-perpendicular-size-hover: 100%;--os-handle-perpendicular-size-active: 100%;--os-handle-interactive-area-offset: 0}.os-scrollbar-track{border:var(--os-track-border);border-radius:var(--os-track-border-radius);background:var(--os-track-bg);transition:opacity .15s,background-color .15s,border-color .15s}.os-scrollbar-track:hover{border:var(--os-track-border-hover);background:var(--os-track-bg-hover)}.os-scrollbar-track:active{border:var(--os-track-border-active);background:var(--os-track-bg-active)}.os-scrollbar-handle{border:var(--os-handle-border);border-radius:var(--os-handle-border-radius);background:var(--os-handle-bg)}.os-scrollbar-handle:hover{border:var(--os-handle-border-hover);background:var(--os-handle-bg-hover)}.os-scrollbar-handle:active{border:var(--os-handle-border-active);background:var(--os-handle-bg-active)}.os-scrollbar-track:before,.os-scrollbar-handle:before{content:"";position:absolute;inset:0;display:block}.os-scrollbar-horizontal{padding:var(--os-padding-perpendicular) var(--os-padding-axis);right:var(--os-size);height:var(--os-size)}.os-scrollbar-horizontal.os-scrollbar-rtl{left:var(--os-size);right:0}.os-scrollbar-horizontal .os-scrollbar-track:before{top:calc(var(--os-padding-perpendicular) * -1);bottom:calc(var(--os-padding-perpendicular) * -1)}.os-scrollbar-horizontal .os-scrollbar-handle{min-width:var(--os-handle-min-size);max-width:var(--os-handle-max-size);height:var(--os-handle-perpendicular-size);transition:opacity .15s,background-color .15s,border-color .15s,height .15s}.os-scrollbar-horizontal .os-scrollbar-handle:before{top:calc((var(--os-padding-perpendicular) + var(--os-handle-interactive-area-offset)) * -1);bottom:calc(var(--os-padding-perpendicular) * -1)}.os-scrollbar-horizontal:hover .os-scrollbar-handle{height:var(--os-handle-perpendicular-size-hover)}.os-scrollbar-horizontal:active .os-scrollbar-handle{height:var(--os-handle-perpendicular-size-active)}.os-scrollbar-vertical{padding:var(--os-padding-axis) var(--os-padding-perpendicular);bottom:var(--os-size);width:var(--os-size)}.os-scrollbar-vertical .os-scrollbar-track:before{left:calc(var(--os-padding-perpendicular) * -1);right:calc(var(--os-padding-perpendicular) * -1)}.os-scrollbar-vertical .os-scrollbar-handle{min-height:var(--os-handle-min-size);max-height:var(--os-handle-max-size);width:var(--os-handle-perpendicular-size);transition:opacity .15s,background-color .15s,border-color .15s,width .15s}.os-scrollbar-vertical .os-scrollbar-handle:before{left:calc((var(--os-padding-perpendicular) + var(--os-handle-interactive-area-offset)) * -1);right:calc(var(--os-padding-perpendicular) * -1)}.os-scrollbar-vertical.os-scrollbar-rtl .os-scrollbar-handle:before{right:calc((var(--os-padding-perpendicular) + var(--os-handle-interactive-area-offset)) * -1);left:calc(var(--os-padding-perpendicular) * -1)}.os-scrollbar-vertical:hover .os-scrollbar-handle{width:var(--os-handle-perpendicular-size-hover)}.os-scrollbar-vertical:active .os-scrollbar-handle{width:var(--os-handle-perpendicular-size-active)}[data-overlayscrollbars-viewport~=measuring]>.os-scrollbar,.os-theme-none.os-scrollbar{display:none!important}.os-theme-dark,.os-theme-light{box-sizing:border-box;--os-size: 10px;--os-padding-perpendicular: 2px;--os-padding-axis: 2px;--os-track-border-radius: 10px;--os-handle-interactive-area-offset: 4px;--os-handle-border-radius: 10px}.os-theme-dark{--os-handle-bg: rgba(0, 0, 0, .44);--os-handle-bg-hover: rgba(0, 0, 0, .55);--os-handle-bg-active: rgba(0, 0, 0, .66)}.os-theme-light{--os-handle-bg: rgba(255, 255, 255, .44);--os-handle-bg-hover: rgba(255, 255, 255, .55);--os-handle-bg-active: rgba(255, 255, 255, .66)} diff --git a/website/blog/_astro/Layout.DSulWsr7.css b/website/blog/_astro/Layout.DSulWsr7.css deleted file mode 100644 index 1d598b7..0000000 --- a/website/blog/_astro/Layout.DSulWsr7.css +++ /dev/null @@ -1 +0,0 @@ -/*! PhotoSwipe main CSS by Dmytro Semenov | photoswipe.com */.pswp{--pswp-bg: #000;--pswp-placeholder-bg: #222;--pswp-root-z-index: 100000;--pswp-preloader-color: rgba(79, 79, 79, .4);--pswp-preloader-color-secondary: rgba(255, 255, 255, .9);--pswp-icon-color: #fff;--pswp-icon-color-secondary: #4f4f4f;--pswp-icon-stroke-color: #4f4f4f;--pswp-icon-stroke-width: 2px;--pswp-error-text-color: var(--pswp-icon-color)}.pswp{position:fixed;top:0;left:0;width:100%;height:100%;z-index:var(--pswp-root-z-index);display:none;touch-action:none;outline:0;opacity:.003;contain:layout style size;-webkit-tap-highlight-color:rgba(0,0,0,0)}.pswp:focus{outline:0}.pswp *{box-sizing:border-box}.pswp img{max-width:none}.pswp--open{display:block}.pswp,.pswp__bg{transform:translateZ(0);will-change:opacity}.pswp__bg{opacity:.005;background:var(--pswp-bg)}.pswp,.pswp__scroll-wrap{overflow:hidden}.pswp__scroll-wrap,.pswp__bg,.pswp__container,.pswp__item,.pswp__content,.pswp__img,.pswp__zoom-wrap{position:absolute;top:0;left:0;width:100%;height:100%}.pswp__img,.pswp__zoom-wrap{width:auto;height:auto}.pswp--click-to-zoom.pswp--zoom-allowed .pswp__img{cursor:zoom-in}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img{cursor:move;cursor:grab}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img:active{cursor:grabbing}.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img,.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img:active,.pswp__img{cursor:zoom-out}.pswp__container,.pswp__img,.pswp__button,.pswp__counter{-webkit-user-select:none;-moz-user-select:none;user-select:none}.pswp__item{z-index:1;overflow:hidden}.pswp__hidden{display:none!important}.pswp__content{pointer-events:none}.pswp__content>*{pointer-events:auto}.pswp__error-msg-container{display:grid}.pswp__error-msg{margin:auto;font-size:1em;line-height:1;color:var(--pswp-error-text-color)}.pswp .pswp__hide-on-close{opacity:.005;will-change:opacity;transition:opacity var(--pswp-transition-duration) cubic-bezier(.4,0,.22,1);z-index:10;pointer-events:none}.pswp--ui-visible .pswp__hide-on-close{opacity:1;pointer-events:auto}.pswp__button{position:relative;display:block;width:50px;height:60px;padding:0;margin:0;overflow:hidden;cursor:pointer;background:none;border:0;box-shadow:none;opacity:.85;-webkit-appearance:none;-webkit-touch-callout:none}.pswp__button:hover,.pswp__button:active,.pswp__button:focus{transition:none;padding:0;background:none;border:0;box-shadow:none;opacity:1}.pswp__button:disabled{opacity:.3;cursor:auto}.pswp__icn{fill:var(--pswp-icon-color);color:var(--pswp-icon-color-secondary);position:absolute;top:14px;left:9px;width:32px;height:32px;overflow:hidden;pointer-events:none}.pswp__icn-shadow{stroke:var(--pswp-icon-stroke-color);stroke-width:var(--pswp-icon-stroke-width);fill:none}.pswp__icn:focus{outline:0}div.pswp__img--placeholder,.pswp__img--with-bg{background:var(--pswp-placeholder-bg)}.pswp__top-bar{position:absolute;left:0;top:0;width:100%;height:60px;display:flex;flex-direction:row;justify-content:flex-end;z-index:10;pointer-events:none!important}.pswp__top-bar>*{pointer-events:auto;will-change:opacity}.pswp__button--close{margin-right:6px}.pswp__button--arrow{position:absolute;width:75px;height:100px;top:50%;margin-top:-50px}.pswp__button--arrow:disabled{display:none;cursor:default}.pswp__button--arrow .pswp__icn{top:50%;margin-top:-30px;width:60px;height:60px;background:none;border-radius:0}.pswp--one-slide .pswp__button--arrow{display:none}.pswp--touch .pswp__button--arrow{visibility:hidden}.pswp--has_mouse .pswp__button--arrow{visibility:visible}.pswp__button--arrow--prev{right:auto;left:0}.pswp__button--arrow--next{right:0}.pswp__button--arrow--next .pswp__icn{left:auto;right:14px;transform:scaleX(-1)}.pswp__button--zoom{display:none}.pswp--zoom-allowed .pswp__button--zoom{display:block}.pswp--zoomed-in .pswp__zoom-icn-bar-v{display:none}.pswp__preloader{position:relative;overflow:hidden;width:50px;height:60px;margin-right:auto}.pswp__preloader .pswp__icn{opacity:0;transition:opacity .2s linear;animation:pswp-clockwise .6s linear infinite}.pswp__preloader--active .pswp__icn{opacity:.85}@keyframes pswp-clockwise{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.pswp__counter{height:30px;margin-top:15px;margin-inline-start:20px;font-size:14px;line-height:30px;color:var(--pswp-icon-color);text-shadow:1px 1px 3px var(--pswp-icon-color-secondary);opacity:.85}.pswp--one-slide .pswp__counter{display:none} diff --git a/website/blog/_astro/Layout.astro_astro_type_script_index_1_lang.BilWV2C2.js b/website/blog/_astro/Layout.astro_astro_type_script_index_1_lang.BilWV2C2.js deleted file mode 100644 index da7ec29..0000000 --- a/website/blog/_astro/Layout.astro_astro_type_script_index_1_lang.BilWV2C2.js +++ /dev/null @@ -1,4 +0,0 @@ -import{_}from"./preload-helper.DBDNhmf7.js";/*! - * PhotoSwipe Lightbox 5.4.4 - https://photoswipe.com - * (c) 2024 Dmytro Semenov - */function a(n,t,i){const e=document.createElement(t);return n&&(e.className=n),i&&i.appendChild(e),e}function E(n,t,i){let e=`translate3d(${n}px,0px,0)`;return i!==void 0&&(e+=` scale3d(${i},${i},1)`),e}function u(n,t,i){n.style.width=typeof t=="number"?`${t}px`:t,n.style.height=typeof i=="number"?`${i}px`:i}const h={IDLE:"idle",LOADING:"loading",LOADED:"loaded",ERROR:"error"};function S(n){return"button"in n&&n.button===1||n.ctrlKey||n.metaKey||n.altKey||n.shiftKey}function d(n,t,i=document){let e=[];if(n instanceof Element)e=[n];else if(n instanceof NodeList||Array.isArray(n))e=Array.from(n);else{const s=typeof n=="string"?n:t;s&&(e=Array.from(i.querySelectorAll(s)))}return e}function I(n){return typeof n=="function"&&n.prototype&&n.prototype.goTo}function m(){return!!(navigator.vendor&&navigator.vendor.match(/apple/i))}class C{constructor(t,i){this.type=t,this.defaultPrevented=!1,i&&Object.assign(this,i)}preventDefault(){this.defaultPrevented=!0}}class L{constructor(){this._listeners={},this._filters={},this.pswp=void 0,this.options=void 0}addFilter(t,i,e=100){var s,l,r;this._filters[t]||(this._filters[t]=[]),(s=this._filters[t])===null||s===void 0||s.push({fn:i,priority:e}),(l=this._filters[t])===null||l===void 0||l.sort((o,f)=>o.priority-f.priority),(r=this.pswp)===null||r===void 0||r.addFilter(t,i,e)}removeFilter(t,i){this._filters[t]&&(this._filters[t]=this._filters[t].filter(e=>e.fn!==i)),this.pswp&&this.pswp.removeFilter(t,i)}applyFilters(t,...i){var e;return(e=this._filters[t])===null||e===void 0||e.forEach(s=>{i[0]=s.fn.apply(this,i)}),i[0]}on(t,i){var e,s;this._listeners[t]||(this._listeners[t]=[]),(e=this._listeners[t])===null||e===void 0||e.push(i),(s=this.pswp)===null||s===void 0||s.on(t,i)}off(t,i){var e;this._listeners[t]&&(this._listeners[t]=this._listeners[t].filter(s=>i!==s)),(e=this.pswp)===null||e===void 0||e.off(t,i)}dispatch(t,i){var e;if(this.pswp)return this.pswp.dispatch(t,i);const s=new C(t,i);return(e=this._listeners[t])===null||e===void 0||e.forEach(l=>{l.call(this,s)}),s}}class D{constructor(t,i){if(this.element=a("pswp__img pswp__img--placeholder",t?"img":"div",i),t){const e=this.element;e.decoding="async",e.alt="",e.src=t,e.setAttribute("role","presentation")}this.element.setAttribute("aria-hidden","true")}setDisplayedSize(t,i){this.element&&(this.element.tagName==="IMG"?(u(this.element,250,"auto"),this.element.style.transformOrigin="0 0",this.element.style.transform=E(0,0,t/250)):u(this.element,t,i))}destroy(){var t;(t=this.element)!==null&&t!==void 0&&t.parentNode&&this.element.remove(),this.element=null}}class P{constructor(t,i,e){this.instance=i,this.data=t,this.index=e,this.element=void 0,this.placeholder=void 0,this.slide=void 0,this.displayedImageWidth=0,this.displayedImageHeight=0,this.width=Number(this.data.w)||Number(this.data.width)||0,this.height=Number(this.data.h)||Number(this.data.height)||0,this.isAttached=!1,this.hasSlide=!1,this.isDecoding=!1,this.state=h.IDLE,this.data.type?this.type=this.data.type:this.data.src?this.type="image":this.type="html",this.instance.dispatch("contentInit",{content:this})}removePlaceholder(){this.placeholder&&!this.keepPlaceholder()&&setTimeout(()=>{this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0)},1e3)}load(t,i){if(this.slide&&this.usePlaceholder())if(this.placeholder){const e=this.placeholder.element;e&&!e.parentElement&&this.slide.container.prepend(e)}else{const e=this.instance.applyFilters("placeholderSrc",this.data.msrc&&this.slide.isFirstSlide?this.data.msrc:!1,this);this.placeholder=new D(e,this.slide.container)}this.element&&!i||this.instance.dispatch("contentLoad",{content:this,isLazy:t}).defaultPrevented||(this.isImageContent()?(this.element=a("pswp__img","img"),this.displayedImageWidth&&this.loadImage(t)):(this.element=a("pswp__content","div"),this.element.innerHTML=this.data.html||""),i&&this.slide&&this.slide.updateContentSize(!0))}loadImage(t){var i,e;if(!this.isImageContent()||!this.element||this.instance.dispatch("contentLoadImage",{content:this,isLazy:t}).defaultPrevented)return;const s=this.element;this.updateSrcsetSizes(),this.data.srcset&&(s.srcset=this.data.srcset),s.src=(i=this.data.src)!==null&&i!==void 0?i:"",s.alt=(e=this.data.alt)!==null&&e!==void 0?e:"",this.state=h.LOADING,s.complete?this.onLoaded():(s.onload=()=>{this.onLoaded()},s.onerror=()=>{this.onError()})}setSlide(t){this.slide=t,this.hasSlide=!0,this.instance=t.pswp}onLoaded(){this.state=h.LOADED,this.slide&&this.element&&(this.instance.dispatch("loadComplete",{slide:this.slide,content:this}),this.slide.isActive&&this.slide.heavyAppended&&!this.element.parentNode&&(this.append(),this.slide.updateContentSize(!0)),(this.state===h.LOADED||this.state===h.ERROR)&&this.removePlaceholder())}onError(){this.state=h.ERROR,this.slide&&(this.displayError(),this.instance.dispatch("loadComplete",{slide:this.slide,isError:!0,content:this}),this.instance.dispatch("loadError",{slide:this.slide,content:this}))}isLoading(){return this.instance.applyFilters("isContentLoading",this.state===h.LOADING,this)}isError(){return this.state===h.ERROR}isImageContent(){return this.type==="image"}setDisplayedSize(t,i){if(this.element&&(this.placeholder&&this.placeholder.setDisplayedSize(t,i),!this.instance.dispatch("contentResize",{content:this,width:t,height:i}).defaultPrevented&&(u(this.element,t,i),this.isImageContent()&&!this.isError()))){const e=!this.displayedImageWidth&&t;this.displayedImageWidth=t,this.displayedImageHeight=i,e?this.loadImage(!1):this.updateSrcsetSizes(),this.slide&&this.instance.dispatch("imageSizeChange",{slide:this.slide,width:t,height:i,content:this})}}isZoomable(){return this.instance.applyFilters("isContentZoomable",this.isImageContent()&&this.state!==h.ERROR,this)}updateSrcsetSizes(){if(!this.isImageContent()||!this.element||!this.data.srcset)return;const t=this.element,i=this.instance.applyFilters("srcsetSizesWidth",this.displayedImageWidth,this);(!t.dataset.largestUsedSize||i>parseInt(t.dataset.largestUsedSize,10))&&(t.sizes=i+"px",t.dataset.largestUsedSize=String(i))}usePlaceholder(){return this.instance.applyFilters("useContentPlaceholder",this.isImageContent(),this)}lazyLoad(){this.instance.dispatch("contentLazyLoad",{content:this}).defaultPrevented||this.load(!0)}keepPlaceholder(){return this.instance.applyFilters("isKeepingPlaceholder",this.isLoading(),this)}destroy(){this.hasSlide=!1,this.slide=void 0,!this.instance.dispatch("contentDestroy",{content:this}).defaultPrevented&&(this.remove(),this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0),this.isImageContent()&&this.element&&(this.element.onload=null,this.element.onerror=null,this.element=void 0))}displayError(){if(this.slide){var t,i;let e=a("pswp__error-msg","div");e.innerText=(t=(i=this.instance.options)===null||i===void 0?void 0:i.errorMsg)!==null&&t!==void 0?t:"",e=this.instance.applyFilters("contentErrorElement",e,this),this.element=a("pswp__content pswp__error-msg-container","div"),this.element.appendChild(e),this.slide.container.innerText="",this.slide.container.appendChild(this.element),this.slide.updateContentSize(!0),this.removePlaceholder()}}append(){if(this.isAttached||!this.element)return;if(this.isAttached=!0,this.state===h.ERROR){this.displayError();return}if(this.instance.dispatch("contentAppend",{content:this}).defaultPrevented)return;const t="decode"in this.element;this.isImageContent()?t&&this.slide&&(!this.slide.isActive||m())?(this.isDecoding=!0,this.element.decode().catch(()=>{}).finally(()=>{this.isDecoding=!1,this.appendImage()})):this.appendImage():this.slide&&!this.element.parentNode&&this.slide.container.appendChild(this.element)}activate(){this.instance.dispatch("contentActivate",{content:this}).defaultPrevented||!this.slide||(this.isImageContent()&&this.isDecoding&&!m()?this.appendImage():this.isError()&&this.load(!1,!0),this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","false"))}deactivate(){this.instance.dispatch("contentDeactivate",{content:this}),this.slide&&this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","true")}remove(){this.isAttached=!1,!this.instance.dispatch("contentRemove",{content:this}).defaultPrevented&&(this.element&&this.element.parentNode&&this.element.remove(),this.placeholder&&this.placeholder.element&&this.placeholder.element.remove())}appendImage(){this.isAttached&&(this.instance.dispatch("contentAppendImage",{content:this}).defaultPrevented||(this.slide&&this.element&&!this.element.parentNode&&this.slide.container.appendChild(this.element),(this.state===h.LOADED||this.state===h.ERROR)&&this.removePlaceholder()))}}function A(n,t){if(n.getViewportSizeFn){const i=n.getViewportSizeFn(n,t);if(i)return i}return{x:document.documentElement.clientWidth,y:window.innerHeight}}function c(n,t,i,e,s){let l=0;if(t.paddingFn)l=t.paddingFn(i,e,s)[n];else if(t.padding)l=t.padding[n];else{const r="padding"+n[0].toUpperCase()+n.slice(1);t[r]&&(l=t[r])}return Number(l)||0}function T(n,t,i,e){return{x:t.x-c("left",n,t,i,e)-c("right",n,t,i,e),y:t.y-c("top",n,t,i,e)-c("bottom",n,t,i,e)}}const g=4e3;class z{constructor(t,i,e,s){this.pswp=s,this.options=t,this.itemData=i,this.index=e,this.panAreaSize=null,this.elementSize=null,this.fit=1,this.fill=1,this.vFill=1,this.initial=1,this.secondary=1,this.max=1,this.min=1}update(t,i,e){const s={x:t,y:i};this.elementSize=s,this.panAreaSize=e;const l=e.x/s.x,r=e.y/s.y;this.fit=Math.min(1,lr?l:r),this.vFill=Math.min(1,r),this.initial=this._getInitial(),this.secondary=this._getSecondary(),this.max=Math.max(this.initial,this.secondary,this._getMax()),this.min=Math.min(this.fit,this.initial,this.secondary),this.pswp&&this.pswp.dispatch("zoomLevelsUpdate",{zoomLevels:this,slideData:this.itemData})}_parseZoomLevelOption(t){const i=t+"ZoomLevel",e=this.options[i];if(e)return typeof e=="function"?e(this):e==="fill"?this.fill:e==="fit"?this.fit:Number(e)}_getSecondary(){let t=this._parseZoomLevelOption("secondary");return t||(t=Math.min(1,this.fit*3),this.elementSize&&t*this.elementSize.x>g&&(t=g/this.elementSize.x),t)}_getInitial(){return this._parseZoomLevelOption("initial")||this.fit}_getMax(){return this._parseZoomLevelOption("max")||Math.max(1,this.fit*4)}}function w(n,t,i){const e=t.createContentFromData(n,i);let s;const{options:l}=t;if(l){s=new z(l,n,-1);let r;t.pswp?r=t.pswp.viewportSize:r=A(l,t);const o=T(l,r,n,i);s.update(e.width,e.height,o)}return e.lazyLoad(),s&&e.setDisplayedSize(Math.ceil(e.width*s.initial),Math.ceil(e.height*s.initial)),e}function b(n,t){const i=t.getItemData(n);if(!t.dispatch("lazyLoadSlide",{index:n,itemData:i}).defaultPrevented)return w(i,t,n)}class x extends L{getNumItems(){var t;let i=0;const e=(t=this.options)===null||t===void 0?void 0:t.dataSource;e&&"length"in e?i=e.length:e&&"gallery"in e&&(e.items||(e.items=this._getGalleryDOMElements(e.gallery)),e.items&&(i=e.items.length));const s=this.dispatch("numItems",{dataSource:e,numItems:i});return this.applyFilters("numItems",s.numItems,e)}createContentFromData(t,i){return new P(t,this,i)}getItemData(t){var i;const e=(i=this.options)===null||i===void 0?void 0:i.dataSource;let s={};Array.isArray(e)?s=e[t]:e&&"gallery"in e&&(e.items||(e.items=this._getGalleryDOMElements(e.gallery)),s=e.items[t]);let l=s;l instanceof Element&&(l=this._domElementToItemData(l));const r=this.dispatch("itemData",{itemData:l||{},index:t});return this.applyFilters("itemData",r.itemData,t)}_getGalleryDOMElements(t){var i,e;return(i=this.options)!==null&&i!==void 0&&i.children||(e=this.options)!==null&&e!==void 0&&e.childSelector?d(this.options.children,this.options.childSelector,t)||[]:[t]}_domElementToItemData(t){const i={element:t},e=t.tagName==="A"?t:t.querySelector("a");if(e){i.src=e.dataset.pswpSrc||e.href,e.dataset.pswpSrcset&&(i.srcset=e.dataset.pswpSrcset),i.width=e.dataset.pswpWidth?parseInt(e.dataset.pswpWidth,10):0,i.height=e.dataset.pswpHeight?parseInt(e.dataset.pswpHeight,10):0,i.w=i.width,i.h=i.height,e.dataset.pswpType&&(i.type=e.dataset.pswpType);const l=t.querySelector("img");if(l){var s;i.msrc=l.currentSrc||l.src,i.alt=(s=l.getAttribute("alt"))!==null&&s!==void 0?s:""}(e.dataset.pswpCropped||e.dataset.cropped)&&(i.thumbCropped=!0)}return this.applyFilters("domItemData",i,t,e)}lazyLoadData(t,i){return w(t,this,i)}}class O extends x{constructor(t){super(),this.options=t||{},this._uid=0,this.shouldOpen=!1,this._preloadedContent=void 0,this.onThumbnailsClick=this.onThumbnailsClick.bind(this)}init(){d(this.options.gallery,this.options.gallerySelector).forEach(t=>{t.addEventListener("click",this.onThumbnailsClick,!1)})}onThumbnailsClick(t){if(S(t)||window.pswp)return;let i={x:t.clientX,y:t.clientY};!i.x&&!i.y&&(i=null);let e=this.getClickedIndex(t);e=this.applyFilters("clickedIndex",e,t,this);const s={gallery:t.currentTarget};e>=0&&(t.preventDefault(),this.loadAndOpen(e,s,i))}getClickedIndex(t){if(this.options.getClickedIndexFn)return this.options.getClickedIndexFn.call(this,t);const i=t.target,s=d(this.options.children,this.options.childSelector,t.currentTarget).findIndex(l=>l===i||l.contains(i));return s!==-1?s:this.options.children||this.options.childSelector?-1:0}loadAndOpen(t,i,e){if(window.pswp||!this.options)return!1;if(!i&&this.options.gallery&&this.options.children){const s=d(this.options.gallery);s[0]&&(i={gallery:s[0]})}return this.options.index=t,this.options.initialPointerPos=e,this.shouldOpen=!0,this.preload(t,i),!0}preload(t,i){const{options:e}=this;i&&(e.dataSource=i);const s=[],l=typeof e.pswpModule;if(I(e.pswpModule))s.push(Promise.resolve(e.pswpModule));else{if(l==="string")throw new Error("pswpModule as string is no longer supported");if(l==="function")s.push(e.pswpModule());else throw new Error("pswpModule is not valid")}typeof e.openPromise=="function"&&s.push(e.openPromise()),e.preloadFirstSlide!==!1&&t>=0&&(this._preloadedContent=b(t,this));const r=++this._uid;Promise.all(s).then(o=>{if(this.shouldOpen){const f=o[0];this._openPhotoswipe(f,r)}})}_openPhotoswipe(t,i){if(i!==this._uid&&this.shouldOpen||(this.shouldOpen=!1,window.pswp))return;const e=typeof t=="object"?new t.default(this.options):new t(this.options);this.pswp=e,window.pswp=e,Object.keys(this._listeners).forEach(s=>{var l;(l=this._listeners[s])===null||l===void 0||l.forEach(r=>{e.on(s,r)})}),Object.keys(this._filters).forEach(s=>{var l;(l=this._filters[s])===null||l===void 0||l.forEach(r=>{e.addFilter(s,r.fn,r.priority)})}),this._preloadedContent&&(e.contentLoader.addToCache(this._preloadedContent),this._preloadedContent=void 0),e.on("destroy",()=>{this.pswp=void 0,delete window.pswp}),e.init()}destroy(){var t;(t=this.pswp)===null||t===void 0||t.destroy(),this.shouldOpen=!1,this._listeners={},d(this.options.gallery,this.options.gallerySelector).forEach(i=>{i.removeEventListener("click",this.onThumbnailsClick,!1)})}}let p,M=_(()=>import("./photoswipe.esm.CKV1Bsxh.js"),[]);function y(){p=new O({gallery:".custom-md img, #post-cover img, .moment-images img",pswpModule:()=>M,closeSVG:'',zoomSVG:'',padding:{top:20,bottom:20,left:20,right:20},wheelToZoom:!0,arrowPrev:!1,arrowNext:!1,imageClickAction:"close",tapAction:"close",doubleTapAction:"zoom"}),p.addFilter("domItemData",(n,t)=>(t instanceof HTMLImageElement&&(n.src=t.src,n.w=Number(t.naturalWidth||window.innerWidth),n.h=Number(t.naturalHeight||window.innerHeight),n.msrc=t.src),n)),p.init()}const v=()=>{p||y(),window.swup.hooks.on("page:view",()=>{y()}),window.swup.hooks.on("content:replace",()=>{p?.destroy?.()},{before:!0})};window.swup?v():document.addEventListener("swup:enable",v); diff --git a/website/blog/_astro/Layout.astro_astro_type_script_index_2_lang.BTdkr2U1.js b/website/blog/_astro/Layout.astro_astro_type_script_index_2_lang.BTdkr2U1.js deleted file mode 100644 index 7d64a03..0000000 --- a/website/blog/_astro/Layout.astro_astro_type_script_index_2_lang.BTdkr2U1.js +++ /dev/null @@ -1,9 +0,0 @@ -import{B as Zo,g as Go,s as Jo,d as Qo,b as ts,e as nn,f as es}from"./setting-utils.Bem8IX7u.js";import{p as ns,u as os}from"./url-utils.CaIMLrxo.js";import{s as ss}from"./config.B4FKKqOZ.js";import"./zh_TW.CqrCsd4X.js";/*! - * OverlayScrollbars - * Version: 2.15.1 - * - * Copyright (c) Rene Haas | KingSora. - * https://github.com/KingSora - * - * Released under the MIT license. - */const gt=(t,e)=>{const{o:n,i:o,u:s}=t;let c=n,r;const i=(u,p)=>{const v=c,O=u,d=p||(o?!o(v,O):v!==O);return(d||s)&&(c=O,r=v),[c,d,r]};return[e?u=>i(e(c,r),u):i,u=>[c,!!u,r]]},cs=typeof window<"u"&&typeof HTMLElement<"u"&&!!window.document,yt=cs?window:{},eo=Math.max,rs=Math.min,on=Math.round,_t=Math.abs,Bn=Math.sign,no=yt.cancelAnimationFrame,gn=yt.requestAnimationFrame,bn=yt.setTimeout,oo=yt.clearTimeout,ke=t=>typeof yt[t]<"u"?yt[t]:void 0,is=ke("MutationObserver"),zn=ke("IntersectionObserver"),Wt=ke("ResizeObserver"),re=ke("ScrollTimeline"),vn=t=>t===void 0,Me=t=>t===null,Bt=t=>typeof t=="number",Qt=t=>typeof t=="string",De=t=>typeof t=="boolean",Tt=t=>typeof t=="function",Et=t=>Array.isArray(t),Oe=t=>typeof t=="object"&&!Et(t)&&!Me(t),wn=t=>{const e=!!t&&t.length,n=Bt(e)&&e>-1&&e%1==0;return Et(t)||!Tt(t)&&n?e>0&&Oe(t)?e-1 in t:!0:!1},ie=t=>!!t&&t.constructor===Object,Le=t=>t instanceof HTMLElement,Pe=t=>t instanceof Element;function J(t,e){if(wn(t))for(let n=0;ne(t[n],n,t)));return t}const so=(t,e)=>t.indexOf(e)>=0,Gt=(t,e)=>t.concat(e),rt=(t,e,n)=>(!Qt(e)&&wn(e)?Array.prototype.push.apply(t,e):t.push(e),t),Rt=t=>Array.from(t||[]),Sn=t=>Et(t)?t:!Qt(t)&&wn(t)?Rt(t):[t],Ie=t=>!!t&&!t.length,$e=t=>Rt(new Set(t)),vt=(t,e,n)=>{J(t,s=>s?s.apply(void 0,e||[]):!0),n||(t.length=0)},co="paddingTop",ro="paddingRight",io="paddingLeft",lo="paddingBottom",ao="marginLeft",uo="marginRight",fo="marginBottom",xn="overflowX",En="overflowY",_e="width",Be="height",kt="visible",Ct="hidden",Ft="scroll",ls=t=>{const e=String(t||"");return e?e[0].toUpperCase()+e.slice(1):""},ze=(t,e,n,o)=>{if(t&&e){let s=!0;return J(n,(c=>{const r=t[c],i=e[c];r!==i&&(s=!1)})),s}return!1},po=(t,e)=>ze(t,e,["w","h"]),Ee=(t,e)=>ze(t,e,["x","y"]),as=(t,e)=>ze(t,e,["t","r","b","l"]),k=(t,...e)=>t.bind(0,...e),Ut=t=>{let e;const n=t?bn:gn,o=t?oo:no;return[s=>{o(e),e=n((()=>s()),Tt(t)?t():t)},()=>o(e)]},Rn=t=>{const e=Tt(t)?t():t;if(Bt(e)){const n=e?bn:gn,o=e?oo:no;return s=>{const c=n((()=>s()),e);return()=>{o(c)}}}return e&&e._},mo=(t,e)=>{const{p:n,v:o,S:s,m:c}=e||{};let r,i,l,f;const u=function(S){i&&i(),r&&r(),f=i=r=l=void 0,t.apply(this,S)},p=d=>c&&l?c(l,d):d,v=()=>{i&&l&&u(p(l)||l)},O=function(){const S=Rt(arguments),C=Rn(n);if(C){const $=typeof s=="function"?s():s,q=Rn(o),y=p(S)||S,L=u.bind(0,y);i&&i(),$&&!f?(L(),f=!0,i=C((()=>f=void 0))):(i=C(L),q&&!r&&(r=q(v))),l=y}else u(S)};return O.O=v,O},ho=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),mt=t=>t?Object.keys(t):[],K=(t,e,n,o,s,c,r)=>{const i=[e,n,o,s,c,r];return(typeof t!="object"||Me(t))&&!Tt(t)&&(t={}),J(i,(l=>{J(l,((f,u)=>{const p=l[u];if(t===p)return!0;const v=Et(p);if(p&&ie(p)){const O=t[u];let d=O;v&&!Et(O)?d=[]:!v&&!ie(O)&&(d={}),t[u]=K(d,p)}else t[u]=v?p.slice():p}))})),t},yo=(t,e)=>J(K({},t),((n,o,s)=>{n===void 0?delete s[o]:n&&ie(n)&&(s[o]=yo(n))})),Cn=t=>!mt(t).length,le=()=>{},go=(t,e,n)=>eo(t,rs(e,n)),qt=t=>$e((Et(t)?t:(t||"").split(" ")).filter((e=>e))),Tn=(t,e)=>t&&t.getAttribute(e),Nn=(t,e)=>t&&t.hasAttribute(e),At=(t,e,n)=>{J(qt(e),(o=>{t&&t.setAttribute(o,String(n||""))}))},Ot=(t,e)=>{J(qt(e),(n=>t&&t.removeAttribute(n)))},Re=(t,e)=>{const n=qt(Tn(t,e)),o=k(At,t,e),s=(c,r)=>{const i=new Set(n);return J(qt(c),(l=>{i[r](l)})),Rt(i).join(" ")};return{C:c=>o(s(c,"delete")),$:c=>o(s(c,"add")),H:c=>{const r=qt(c);return r.reduce(((i,l)=>i&&n.includes(l)),r.length>0)}}},bo=(t,e,n)=>(Re(t,e).C(n),k(On,t,e,n)),On=(t,e,n)=>(Re(t,e).$(n),k(bo,t,e,n)),Ae=(t,e,n,o)=>(o?On:bo)(t,e,n),Ln=(t,e,n)=>Re(t,e).H(n),vo=t=>Re(t,"class"),wo=(t,e)=>{vo(t).C(e)},In=(t,e)=>(vo(t).$(e),k(wo,t,e)),So=(t,e)=>{const n=e?Pe(e)&&e:document;return n?Rt(n.querySelectorAll(t)):[]},us=(t,e)=>{const n=e?Pe(e)&&e:document;return n&&n.querySelector(t)},sn=(t,e)=>Pe(t)&&t.matches(e),xo=t=>sn(t,"body"),cn=t=>t?Rt(t.childNodes):[],ae=t=>t&&t.parentElement,Kt=(t,e)=>Pe(t)&&t.closest(e),rn=t=>document.activeElement,ds=(t,e,n)=>{const o=Kt(t,e),s=t&&us(n,o),c=Kt(s,e)===o;return o&&s?o===t||s===t||c&&Kt(Kt(t,n),e)!==o:!1},Jt=t=>{J(Sn(t),(e=>{const n=ae(e);e&&n&&n.removeChild(e)}))},ht=(t,e)=>k(Jt,t&&e&&J(Sn(e),(n=>{n&&t.appendChild(n)})));let Eo;const fs=()=>Eo,ps=t=>{Eo=t},Yt=t=>{const e=document.createElement("div");return At(e,"class",t),e},Co=t=>{const e=Yt(),n=fs(),o=t.trim();return e.innerHTML=n?n.createHTML(o):o,J(cn(e),(s=>Jt(s)))},Vn=(t,e)=>t.getPropertyValue(e)||t[e]||"",To=t=>{const e=t||0;return isFinite(e)?e:0},Se=t=>To(parseFloat(t||"")),ln=t=>Math.round(t*1e4)/1e4,Oo=t=>`${ln(To(t))}px`;function ue(t,e){t&&e&&J(e,((n,o)=>{try{const s=t.style,c=Me(n)||De(n)?"":Bt(n)?Oo(n):n;o.indexOf("--")===0?s.setProperty(o,c):s[o]=c}catch{}}))}function It(t,e,n){const o=Qt(e);let s=o?"":{};if(t){const c=yt.getComputedStyle(t,n)||t.style;s=o?Vn(c,e):Rt(e).reduce(((r,i)=>(r[i]=Vn(c,i),r)),s)}return s}const Fn=(t,e,n)=>{const o=e?`${e}-`:"",s=n?`-${n}`:"",c=`${o}top${s}`,r=`${o}right${s}`,i=`${o}bottom${s}`,l=`${o}left${s}`,f=It(t,[c,r,i,l]);return{t:Se(f[c]),r:Se(f[r]),b:Se(f[i]),l:Se(f[l])}},Ke=(t,e)=>`translate${Oe(t)?`(${t.x},${t.y})`:`${e?"X":"Y"}(${t})`}`,ms=t=>!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length),hs={w:0,h:0},Ne=(t,e)=>e?{w:e[`${t}Width`],h:e[`${t}Height`]}:hs,ys=t=>Ne("inner",t||yt),Zt=k(Ne,"offset"),Lo=k(Ne,"client"),He=k(Ne,"scroll"),$n=t=>{const e=parseFloat(It(t,_e))||0,n=parseFloat(It(t,Be))||0;return{w:e-on(e),h:n-on(n)}},Xe=t=>t.getBoundingClientRect(),gs=t=>!!t&&ms(t),an=t=>!!(t&&(t[Be]||t[_e])),Io=(t,e)=>{const n=an(t);return!an(e)&&n},qn=(t,e,n,o)=>{J(qt(e),(s=>{t&&t.removeEventListener(s,n,o)}))},ot=(t,e,n,o)=>{var s;const c=(s=o&&o.D)!=null?s:!0,r=o&&o.I||!1,i=o&&o.A||!1,l={passive:c,capture:r};return k(vt,qt(e).map((f=>{const u=i?p=>{qn(t,f,u,r),n&&n(p)}:n;return t&&t.addEventListener(f,u,l),k(qn,t,f,u,r)})))},$o=t=>t.stopPropagation(),un=t=>t.preventDefault(),Ao=t=>$o(t)||un(t),Lt=(t,e)=>{const{x:n,y:o}=Bt(e)?{x:e,y:e}:e||{};Bt(n)&&(t.scrollLeft=n),Bt(o)&&(t.scrollTop=o)},bt=t=>({x:t.scrollLeft,y:t.scrollTop}),Ho=()=>({T:{x:0,y:0},k:{x:0,y:0}}),bs=(t,e)=>{const{T:n,k:o}=t,{w:s,h:c}=e,r=(p,v,O)=>{let d=Bn(p)*O,S=Bn(v)*O;if(d===S){const C=_t(p),$=_t(v);S=C>$?0:S,d=C<$?0:d}return d=d===S?0:d,[d+0,S+0]},[i,l]=r(n.x,o.x,s),[f,u]=r(n.y,o.y,c);return{T:{x:i,y:f},k:{x:l,y:u}}},Ye=({T:t,k:e})=>{const n=(o,s)=>o===0&&o<=s;return{x:n(t.x,e.x),y:n(t.y,e.y)}},jn=({T:t,k:e},n)=>{const o=(s,c,r)=>go(0,1,(s-r)/(s-c)||0);return{x:o(t.x,e.x,n.x),y:o(t.y,e.y,n.y)}},dn=t=>{t&&t.focus&&t.focus({preventScroll:!0,focusVisible:!1})},Wn=(t,e)=>{J(Sn(e),t)},fn=t=>{const e=new Map,n=(c,r)=>{if(c){const i=e.get(c);Wn((l=>{i&&i[l?"delete":"clear"](l)}),r)}else e.forEach((i=>{i.clear()})),e.clear()},o=(c,r)=>{if(Qt(c)){const f=e.get(c)||new Set;return e.set(c,f),Wn((u=>{Tt(u)&&f.add(u)}),r),k(n,c,r)}De(r)&&r&&n();const i=mt(c),l=[];return J(i,(f=>{const u=c[f];u&&rt(l,o(f,u))})),k(vt,l)},s=(c,r)=>{J(Rt(e.get(c)),(i=>{r&&!Ie(r)?i.apply(0,r):i()}))};return o(t||{}),[o,n,s]},ko={},Mo={},vs=t=>{J(t,(e=>J(e,((n,o)=>{ko[o]=e[o]}))))},Do=(t,e,n)=>mt(t).map((o=>{const{static:s,instance:c}=t[o],[r,i,l]=n||[],f=n?c:s;if(f){const u=n?f(r,i,e):f(e);return(l||Mo)[o]=u}})),ws=(t,e)=>t[e],te=t=>ws(Mo,t),Ss="__osOptionsValidationPlugin",ee="data-overlayscrollbars",Ce="os-environment",xe=`${Ce}-scrollbar-hidden`,Ze=`${ee}-initialize`,Te="noClipping",Un=`${ee}-body`,zt=ee,xs="host",Ht=`${ee}-viewport`,Es=xn,Cs=En,Ts="arrange",Po="measuring",Os="scrolling",_o="scrollbarHidden",Ls="noContent",pn=`${ee}-padding`,Kn=`${ee}-content`,An="os-size-observer",Is=`${An}-appear`,$s=`${An}-listener`,As="os-trinsic-observer",Hs="os-theme-none",wt="os-scrollbar",ks=`${wt}-rtl`,Ms=`${wt}-horizontal`,Ds=`${wt}-vertical`,Bo=`${wt}-track`,Hn=`${wt}-handle`,Ps=`${wt}-visible`,_s=`${wt}-cornerless`,Xn=`${wt}-interaction`,Yn=`${wt}-unusable`,mn=`${wt}-auto-hide`,Bs=`${mn}-hidden`,Zn=`${wt}-wheel`,zs=`${Bo}-interactive`,Rs=`${Hn}-interactive`,Ns="__osSizeObserverPlugin",Vs=(t,e)=>{const{M:n}=e,[o,s]=t("showNativeOverlaidScrollbars");return[o&&n.x&&n.y,s]},Xt=t=>t.indexOf(kt)===0,Fs=t=>t.replace(`${kt}-`,""),hn=(t,e)=>{if(t==="auto")return e?Ft:Ct;const n=t||Ct;return[Ct,Ft,kt].includes(n)?n:Ct},qs=(t,e)=>{const{overflowX:n,overflowY:o}=It(t,[xn,En]);return{x:hn(n,e.x),y:hn(o,e.y)}},kn="__osScrollbarsHidingPlugin",js="__osClickScrollPlugin",Gn=t=>JSON.stringify(t,((e,n)=>{if(Tt(n))throw 0;return n})),Jn=(t,e)=>t?`${e}`.split(".").reduce(((n,o)=>n&&ho(n,o)?n[o]:void 0),t):void 0,Ws=[0,33],zo=[33,99],Ro=[222,666,!0],Us={paddingAbsolute:!1,showNativeOverlaidScrollbars:!1,update:{elementEvents:[["img","load"]],debounce:{mutation:Ws,resize:null,event:zo,env:Ro},attributes:null,ignoreMutation:null,flowDirectionStyles:null},overflow:{x:"scroll",y:"scroll"},scrollbars:{theme:"os-theme-dark",visibility:"auto",autoHide:"never",autoHideDelay:1300,autoHideSuspend:!1,dragScroll:!0,clickScroll:!1,pointers:["mouse","touch","pen"]}},No=(t,e)=>{const n={},o=Gt(mt(e),mt(t));return J(o,(s=>{const c=t[s],r=e[s];if(Oe(c)&&Oe(r))K(n[s]={},No(c,r)),Cn(n[s])&&delete n[s];else if(ho(e,s)&&r!==c){let i=!0;if(Et(c)||Et(r))try{Gn(c)===Gn(r)&&(i=!1)}catch{}i&&(n[s]=r)}})),n},Ge=(t,e,n)=>o=>[Jn(t,o),n||Jn(e,o)!==void 0];let Vo;const Ks=()=>Vo,Xs=t=>{Vo=t};let Je;const Ys=()=>{const t=(y,L,P)=>{ht(document.body,y),ht(document.body,y);const j=Lo(y),_=Zt(y),N=$n(L);return P&&Jt(y),{x:_.h-j.h+N.h,y:_.w-j.w+N.w}},e=y=>{let L=!1;const P=In(y,xe);try{L=It(y,"scrollbar-width")==="none"||It(y,"display","::-webkit-scrollbar")==="none"}catch{}return P(),L},n=`.${Ce}{scroll-behavior:auto!important;position:fixed;opacity:0;visibility:hidden;overflow:scroll;height:200px;width:200px;z-index:-1}.${Ce} div{width:200%;height:200%;margin:10px 0}.${xe}{scrollbar-width:none!important}.${xe}::-webkit-scrollbar,.${xe}::-webkit-scrollbar-corner{appearance:none!important;display:none!important;width:0!important;height:0!important}`,s=Co(`
`)[0],c=s.firstChild,r=s.lastChild,i=Ks();i&&(r.nonce=i);const[l,,f]=fn(),[u,p]=gt({o:t(s,c),i:Ee},k(t,s,c,!0)),[v]=p(),O=e(s),d={x:v.x===0,y:v.y===0},S={elements:{host:null,padding:!O,viewport:y=>O&&xo(y)&&y,content:!1},scrollbars:{slot:!0},cancel:{nativeScrollbarsOverlaid:!1,body:null}},C=K({},Us),$=k(K,{},C),q=k(K,{},S),X={U:v,M:d,P:O,J:!!re,G:k(l,"r"),K:q,Z:y=>K(S,y)&&q(),tt:$,nt:y=>K(C,y)&&$(),ot:K({},S),st:K({},C)};if(Ot(s,"style"),Jt(s),ot(yt,"resize",(()=>{f("r",[])})),Tt(yt.matchMedia)&&!O&&(!d.x||!d.y)){const y=L=>{const P=yt.matchMedia(`(resolution: ${yt.devicePixelRatio}dppx)`);ot(P,"change",(()=>{L(),y(L)}),{A:!0})};y((()=>{const[L,P]=u();K(X.U,L),f("r",[P])}))}return X},$t=()=>(Je||(Je=Ys()),Je),Zs=(t,e,n)=>{let o=!1;const s=n?new WeakMap:!1,c=()=>{o=!0},r=i=>{if(s&&n){const l=n.map((f=>{const[u,p]=f||[];return[p&&u?(i||So)(u,t):[],p]}));J(l,(f=>J(f[0],(u=>{const p=f[1],v=s.get(u)||[];if(t.contains(u)&&p){const d=ot(u,p,(S=>{o?(d(),s.delete(u)):e(S)}));s.set(u,rt(v,d))}else vt(v),s.delete(u)}))))}};return r(),[c,r]},Qn=(t,e,n,o)=>{let s=!1;const{et:c,ct:r,rt:i,it:l,lt:f,ut:u}=o||{},[p,v]=Zs(t,(()=>s&&n(!0)),i),O=c||[],d=r||[],S=Gt(O,d),C=(q,X)=>{if(!Ie(X)){const y=f||le,L=u||le,P=[],j=[];let _=!1,N=!1;if(J(X,(B=>{const{attributeName:w,target:x,type:z,oldValue:E,addedNodes:V,removedNodes:Y}=B,Q=z==="attributes",et=z==="childList",W=t===x,st=Q&&w,I=st&&Tn(x,w||""),A=Qt(I)?I:null,T=st&&E!==A,m=so(d,w)&&T;if(e&&(et||!W)){const g=Q&&T,h=g&&l&&sn(x,l),b=(h?!y(x,w,E,A):!Q||g)&&!L(B,!!h,t,o);J(V,(H=>rt(P,H))),J(Y,(H=>rt(P,H))),N=N||b}!e&&W&&T&&!y(x,w,E,A)&&(rt(j,w),_=_||m)})),v((B=>$e(P).reduce(((w,x)=>(rt(w,So(B,x)),sn(x,B)?rt(w,x):w)),[]))),e)return!q&&N&&n(!1),[!1];if(!Ie(j)||_){const B=[$e(j),_];return q||n.apply(0,B),B}}},$=new is(k(C,!1));return[()=>($.observe(t,{attributes:!0,attributeOldValue:!0,attributeFilter:S,subtree:e,childList:e,characterData:e}),s=!0,()=>{s&&(p(),$.disconnect(),s=!1)}),()=>{if(s)return C(!0,$.takeRecords())}]};let Vt=null;const Fo=(t,e,n)=>{const{ft:o}=n||{},s=te(Ns),[c]=gt({o:!1,u:!0});return()=>{const r=[],l=Co(`
`)[0],f=l.firstChild,u=p=>{const v=Et(p)&&!Ie(p);let O=!1,d=!1;if(v){const S=p[0],[C,,$]=c(S.contentRect),q=an(C);d=Io(C,$),O=!d&&!q}else d=p===!0;O||e({_t:!0,ft:d})};if(Wt){if(!De(Vt)){const d=new Wt(le);d.observe(t,{get box(){Vt=!0}}),Vt=Vt||!1,d.disconnect()}const p=mo(u,{p:0,v:0}),v=d=>p(d),O=new Wt(v);if(O.observe(Vt?t:f),rt(r,[()=>{O.disconnect()},!Vt&&ht(t,l)]),Vt){const d=new Wt(v);d.observe(t,{box:"border-box"}),rt(r,(()=>d.disconnect()))}}else if(s){const[p,v]=s(f,u,o);rt(r,Gt([In(l,Is),ot(l,"animationstart",p),ht(t,l)],v))}else return le;return k(vt,r)}},Gs=(t,e)=>{let n;const o=l=>l.h===0||l.isIntersecting||l.intersectionRatio>0,s=Yt(As),[c]=gt({o:!1}),r=(l,f)=>{if(l){const u=c(o(l)),[,p]=u;return p&&!f&&e(u)&&[u]}},i=(l,f)=>r(f.pop(),l);return[()=>{const l=[];if(zn)n=new zn(k(i,!1),{root:t}),n.observe(s),rt(l,(()=>{n.disconnect()}));else{const f=()=>{const u=Zt(s);r(u)};rt(l,Fo(s,f)()),f()}return k(vt,rt(l,ht(t,s)))},()=>n&&i(!0,n.takeRecords())]},Js=(t,e,n,o)=>{let s,c,r,i,l,f,u,p;const v=`[${zt}]`,O=`[${Ht}]`,d=["id","class","style","open","wrap","cols","rows"],{dt:S,vt:C,L:$,gt:q,ht:X,V:y,bt:L,yt:P,wt:j,St:_}=t,N=a=>It(a,"direction")==="rtl",B=()=>{let a,b,H;const M=mo(o,{p:()=>a,v:()=>b,S:()=>H,m(R,Z){const[D]=R,[G]=Z;return[Gt(mt(D),mt(G)).reduce(((F,it)=>(F[it]=D[it]||G[it],F)),{})]}}),U=(R,Z)=>{if(Et(Z)){const[D,G,F]=Z;a=D,b=G,H=F}else Bt(Z)?(a=Z,b=!1,H=!1):(a=!1,b=!1,H=!1);M(R)};return U.O=M.O,U},w={Ot:!1,B:N(S)},x=$t(),z=te(kn),[E]=gt({i:po,o:{w:0,h:0}},(()=>{const a=z&&z.R(t,e,w,x,n).Y,H=!(L&&y)&&Ln(C,zt,Te),M=!y&&P(Ts),U=M&&bt(q),R=U&&_(),Z=j(Po,H),D=M&&a&&a(),G=He($),F=$n($);return D&&D(),Lt(q,U),R&&R(),H&&Z(),{w:G.w+F.w,h:G.h+F.h}})),V=B(),Y=a=>{const b=N(S);K(a,{Ct:p!==b}),K(w,{B:b}),p=b},Q=(a,b)=>{const[H,M]=a,U={$t:M};return K(w,{Ot:H}),b||o(U),U},et=({_t:a,ft:b})=>{const H=b?o:V,M={_t:a||b,ft:b};Y(M),H(M,c)},W=(a,b)=>{const[,H]=E(),M={xt:H};return Y(M),H&&!b&&V(M,a?r:s),M},st=(a,b,H)=>{const M={Ht:b};return Y(M),b&&!H&&V(M,s),M},[I,A]=X?Gs(C,Q):[],T=!y&&Fo(C,et,{ft:!0}),[m,g]=Qn(C,!1,st,{ct:d,et:d}),h=y&&Wt&&new Wt((a=>{const b=a[a.length-1].contentRect;et({_t:!0,ft:Io(b,u)}),u=b}));return[()=>{h&&h.observe(C);const a=T&&T(),b=I&&I(),H=m(),M=x.G((U=>{const[,R]=E();V({Et:U,xt:R,_t:L},i)}));return()=>{h&&h.disconnect(),a&&a(),b&&b(),f&&f(),H(),M()}},({Dt:a,zt:b,It:H})=>{const M={},[U]=a("update.ignoreMutation"),[R,Z]=a("update.attributes"),[D,G]=a("update.elementEvents"),[F,it]=a("update.debounce"),ut=G||Z,ct=b||H,lt=nt=>Tt(U)&&U(nt);if(ut){l&&l(),f&&f();const[nt,pt]=Qn(X||$,!0,W,{et:Gt(d,R||[]),rt:D,it:v,ut:(at,St)=>{const{target:tt,attributeName:ft}=at;return(!St&&ft&&!y?ds(tt,v,O):!1)||!!Kt(tt,`.${wt}`)||!!lt(at)}});f=nt(),l=pt}if(it&&(V.O(),Et(F)||Bt(F)?(s=F,c=!1,r=zo,i=Ro):ie(F)?(s=F.mutation,c=F.resize,r=F.event,i=F.env):(s=!1,c=!1,r=!1,i=!1)),ct){const nt=g(),pt=A&&A(),at=l&&l();nt&&K(M,st(nt[0],nt[1],ct)),pt&&K(M,Q(pt[0],ct)),at&&K(M,W(at[0],ct))}return Y(M),M},w]},qo=(t,e)=>Tt(e)?e.apply(0,t):e,Qs=(t,e,n,o)=>{const s=vn(o)?n:o;return qo(t,s)||e.apply(0,t)},jo=(t,e,n,o)=>{const s=vn(o)?n:o,c=qo(t,s);return!!c&&(Le(c)?c:e.apply(0,t))},tc=(t,e)=>{const{nativeScrollbarsOverlaid:n,body:o}=e||{},{M:s,P:c,K:r}=$t(),{nativeScrollbarsOverlaid:i,body:l}=r().cancel,f=n??i,u=vn(o)?l:o,p=(s.x||s.y)&&f,v=t&&(Me(u)?!c:u);return!!p||!!v},ec=(t,e,n,o)=>{const s="--os-viewport-percent",c="--os-scroll-percent",r="--os-scroll-direction",{K:i}=$t(),{scrollbars:l}=i(),{slot:f}=l,{dt:u,vt:p,L:v,At:O,gt:d,bt:S,V:C}=e,{scrollbars:$}=O?{}:t,{slot:q}=$||{},X=[],y=[],L=[],P=jo([u,p,v],(()=>C&&S?u:p),f,q),j=I=>{if(re){let A=null,T=[];const m=new re({source:d,axis:I}),g=()=>{A&&A.cancel(),A=null};return{Mt:a=>{const{Tt:b}=n,H=Ye(b)[I],M=I==="x",U=[Ke(0,M),Ke(`calc(-100% + 100cq${M?"w":"h"})`,M)],R=H?U:U.reverse();return T[0]===R[0]&&T[1]===R[1]||(T=R,g(),A=a.kt.animate({clear:["left"],transform:R},{timeline:m})),g}}}},_={x:j("x"),y:j("y")},N=()=>{const{Rt:I,Vt:A}=n,T=(m,g)=>go(0,1,m/(m+g)||0);return{x:T(A.x,I.x),y:T(A.y,I.y)}},B=(I,A,T)=>{const m=T?In:wo;J(I,(g=>{m(g.Lt,A)}))},w=(I,A)=>{J(I,(T=>{const[m,g]=A(T);ue(m,g)}))},x=(I,A,T)=>{const m=De(T),g=m?T:!0,h=m?!T:!0;g&&B(y,I,A),h&&B(L,I,A)},z=()=>{const I=N(),A=T=>m=>[m.Lt,{[s]:ln(T)+""}];w(y,A(I.x)),w(L,A(I.y))},E=()=>{if(!re){const{Tt:I}=n,A=jn(I,bt(d)),T=m=>g=>[g.Lt,{[c]:ln(m)+""}];w(y,T(A.x)),w(L,T(A.y))}},V=()=>{const{Tt:I}=n,A=Ye(I),T=m=>g=>[g.Lt,{[r]:m?"0":"1"}];w(y,T(A.x)),w(L,T(A.y)),re&&(y.forEach(_.x.Mt),L.forEach(_.y.Mt))},Y=()=>{if(C&&!S){const{Rt:I,Tt:A}=n,T=Ye(A),m=jn(A,bt(d)),g=h=>{const{Lt:a}=h,b=ae(a)===v&&a,H=(M,U,R)=>{const Z=U*M;return Oo(R?Z:-Z)};return[b,b&&{transform:Ke({x:H(m.x,I.x,T.x),y:H(m.y,I.y,T.y)})}]};w(y,g),w(L,g)}},Q=I=>{const A=I?"x":"y",m=Yt(`${wt} ${I?Ms:Ds}`),g=Yt(Bo),h=Yt(Hn),a={Lt:m,Pt:g,kt:h},b=_[A];return rt(I?y:L,a),rt(X,[ht(m,g),ht(g,h),k(Jt,m),b&&b.Mt(a),o(a,x,I)]),a},et=k(Q,!0),W=k(Q,!1),st=()=>(ht(P,y[0].Lt),ht(P,L[0].Lt),k(vt,X));return et(),W(),[{Ut:z,Nt:E,qt:V,Bt:Y,Ft:x,jt:{Xt:y,Yt:et,Wt:k(w,y)},Jt:{Xt:L,Yt:W,Wt:k(w,L)}},st]},nc=(t,e,n,o,s)=>(c,r,i)=>{const{vt:l,L:f,V:u,gt:p,Gt:v,St:O}=e,{Lt:d,Pt:S,kt:C}=c,[$,q]=Ut(333),[X,y]=Ut(444),L=_=>{Tt(p.scrollBy)&&p.scrollBy({behavior:"smooth",left:_.x,top:_.y})},P=()=>{const _="pointerup pointercancel lostpointercapture",N=`client${i?"X":"Y"}`,B=i?_e:Be,w=i?"left":"top",x=i?"w":"h",z=i?"x":"y",E=[];return ot(S,"pointerdown",o((V=>{const Y=Kt(V.target,`.${Hn}`)===C,Q=Y?C:S,et=t.scrollbars,W=et[Y?"dragScroll":"clickScroll"],{button:st,isPrimary:I,pointerType:A}=V,{pointers:T}=et;if(st===0&&I&&W&&(T||[]).includes(A)){vt(E),y();const g=!Y&&(V.shiftKey||W==="instant"),h=k(Xe,C),a=k(Xe,S),b=(tt,ft)=>(tt||h())[w]-(ft||a())[w],H=on(Xe(p)[B])/Zt(p)[x]||1,M=bt(p)[z],U=tt=>{Lt(p,{[z]:M+tt})},R=tt=>{const{Rt:ft}=n,dt=Zt(S)[x]-Zt(C)[x],Dt=1/H*tt/dt;U(Dt*ft[z])},Z=V[N],D=h(),G=a(),F=D[B],it=b(D,G)+F/2,ct=Z-G[w]-it,lt=Y?0:ct,nt=tt=>{vt(St),Q.releasePointerCapture(tt.pointerId)},pt=Y||g,at=O(),St=[ot(v,_,nt),ot(v,"selectstart",(tt=>un(tt)),{D:!1}),ot(S,_,nt),pt&&ot(S,"pointermove",(tt=>R(lt+tt[N]-Z))),pt&&(()=>{const tt=bt(p);at();const ft=bt(p),dt={x:ft.x-tt.x,y:ft.y-tt.y};(_t(dt.x)>3||_t(dt.y)>3)&&(O(),Lt(p,tt),L(dt),X(at))})];if(Q.setPointerCapture(V.pointerId),g)R(ct);else if(!Y){const tt=te(js);if(tt){const{Vt:ft}=n,dt=tt(U,R,k(b),ct,ft[z],W,!!i,(Dt=>{Dt?at():rt(St,at)}));rt(St,dt),rt(E,k(dt,!0))}}}})))};let j=!0;return k(vt,[ot(C,"pointermove pointerleave",o(s)),ot(d,"pointerenter",o((()=>{r(Xn,!0)}))),ot(d,"pointerleave pointercancel",o((()=>{r(Xn,!1)}))),ot(d,"wheel",o((_=>{const{deltaX:N,deltaY:B,deltaMode:w}=_;j&&w===0&&ae(d)===l&&L({x:N,y:B}),j=!1,r(Zn,!0),$((()=>{j=!0,r(Zn)})),un(_)})),{D:!1,I:!0}),!u&&ot(d,"mousedown",o((()=>{const _=rn();(Nn(_,Ht)||Nn(_,zt)||_===document.body)&&bn(k(dn,f),25)}))),ot(d,"pointerdown",(()=>{const _=ot(v,"click",(B=>{N(),Ao(B)}),{A:!0,I:!0,D:!1}),N=ot(v,"pointerup pointercancel",(()=>{N(),setTimeout(_,150)}),{I:!0,D:!0})}),{I:!0,D:!0}),P(),q,y])},oc=(t,e,n,o,s,c,r)=>{let i,l,f,u,p,v=le,O=0;const d=["mouse","pen"],S=h=>a=>{n.Kt||h(a)},C=h=>d.includes(h.pointerType),[$,q]=Ut(),[X,y]=Ut(100),[L,P]=Ut(50),[j,_]=Ut((()=>O)),[N,B]=ec(t,c,s,nc(e,c,s,S,(h=>C(h)&&st()))),{vt:w,Qt:x,bt:z}=c,{Ft:E,Ut:V,Nt:Y,qt:Q,Bt:et}=N,W=(h,a)=>{_();const b=H=>{n.Kt||E(Bs,H)};if(h)b();else{const H=f?!i:!0;O>0&&!a?j(k(b,H)):b(H)}},st=()=>{(f?!i:!u)&&(W(!0),X((()=>{W(!1)})))},I=h=>{C(h)&&(i=!0,!n.Kt&&f&&W(!0))},A=h=>{C(h)&&(i=!1,!n.Kt&&f&&W(!1))},T=h=>{E(mn,h,!0),E(mn,h,!1)},m=[_,y,P,q,()=>v(),ot(w,"pointerover",I,{A:!0}),ot(w,"pointerenter",I),ot(w,"pointerleave",A),ot(w,"pointermove",S((h=>{C(h)&&l&&st()}))),ot(x,"scroll",S((h=>{$((()=>{Y(),st()})),r(h),et()})))],g=te(kn);return[()=>k(vt,rt(m,B())),({Dt:h,It:a,Zt:b,tn:H})=>{const{nn:M,sn:U,en:R,cn:Z}=H||{},{Ct:D,ft:G}=b||{},{B:F}=o,{M:it,P:ut}=$t(),{rn:ct,j:lt}=s,[nt,pt]=h("showNativeOverlaidScrollbars"),[at,St]=h("scrollbars.theme"),[tt,ft]=h("scrollbars.visibility"),[dt,Dt]=h("scrollbars.autoHide"),[ne,de]=h("scrollbars.autoHideSuspend"),[fe]=h("scrollbars.autoHideDelay"),[Nt,oe]=h("scrollbars.dragScroll"),[Ve,Fe]=h("scrollbars.clickScroll"),[pe,qe]=h("overflow"),xt=G&&!a,je=M||U||Z||D||a,me=R||ft||qe,We=nt&&it.x&&it.y,jt=!ut&&!g,Ue=We||jt,he=(se,ce,ye)=>{const Pt=se.includes(Ft)&&(tt===kt||tt==="auto"&&ce===Ft);return E(Ps,Pt,ye),Pt};if(O=fe,(pt||jt)&&E(Hs,Ue),St&&(E(p),E(at,!0),p=at),(de||xt)&&(T(!ne),xt&&ne&&(lt.x||lt.y?(v(),L((()=>{v=ot(x,Ft,S(k(T,!0)),{A:!0})}))):T(!0))),Dt&&(l=dt==="move",f=dt==="leave",u=dt==="never",W(u,!0)),oe&&E(Rs,Nt),Fe&&E(zs,!!Ve),me){const se=he(pe.x,ct.x,!0),ce=he(pe.y,ct.y,!1);E(_s,!(se&&ce))}je&&(Y(),V(),et(),Z&&Q(),E(Yn,!lt.x,!0),E(Yn,!lt.y,!1),E(ks,F&&!z))},{},N]},sc=t=>{const e=$t(),{K:n,P:o}=e,{elements:s}=n(),{padding:c,viewport:r,content:i}=s,l=Le(t),f=l?{}:t,{elements:u}=f,{padding:p,viewport:v,content:O}=u||{},d=l?t:f.target,S=xo(d),C=d.ownerDocument,$=C.documentElement,q=()=>C.defaultView||yt,X=k(Qs,[d]),y=k(jo,[d]),L=k(Yt,""),P=k(X,L,r),j=k(y,L,i),_=D=>{const G=Zt(D),F=He(D),it=It(D,xn),ut=It(D,En);return F.w-G.w>0&&!Xt(it)||F.h-G.h>0&&!Xt(ut)},N=P(v),B=N===d,w=B&&S,x=!B&&j(O),z=!B&&N===x,E=w?$:N,V=w?E:d,Y=!B&&y(L,c,p),Q=!z&&x,et=[Q,E,Y,V].map((D=>Le(D)&&!ae(D)&&D)),W=D=>D&&so(et,D),st=!W(E)&&_(E)?E:d,I=w?$:E,T={dt:d,vt:V,L:E,ln:Y,ht:Q,gt:I,Qt:w?C:E,an:S?$:st,Gt:C,bt:S,At:l,V:B,un:q,yt:D=>Ln(E,Ht,D),wt:(D,G)=>Ae(E,Ht,D,G),St:()=>Ae(I,Ht,Os,!0)},{dt:m,vt:g,ln:h,L:a,ht:b}=T,H=[()=>{Ot(g,[zt,Ze]),Ot(m,Ze),S&&Ot($,[Ze,zt])}];let M=cn([b,a,h,g,m].find((D=>D&&!W(D))));const U=w?m:b||a,R=k(vt,H);return[T,()=>{const D=q(),G=rn(),F=nt=>{ht(ae(nt),cn(nt)),Jt(nt)},it=nt=>ot(nt,"focusin focusout focus blur",Ao,{I:!0,D:!1}),ut="tabindex",ct=Tn(a,ut),lt=it(G);return At(g,zt,B?"":xs),At(h,pn,""),At(a,Ht,""),At(b,Kn,""),B||(At(a,ut,ct||"-1"),S&&At($,Un,"")),ht(U,M),ht(g,h),ht(h||g,!B&&a),ht(a,b),rt(H,[lt,()=>{const nt=rn(),pt=W(a),at=pt&&nt===a?m:nt,St=it(at);Ot(h,pn),Ot(b,Kn),Ot(a,Ht),S&&Ot($,Un),ct?At(a,ut,ct):Ot(a,ut),W(b)&&F(b),pt&&F(a),W(h)&&F(h),dn(at),St()}]),o&&!B&&(On(a,Ht,_o),rt(H,k(Ot,a,Ht))),dn(!B&&S&&G===m&&D.top===D?a:G),lt(),M=0,R},R]},cc=({ht:t})=>({Zt:e,fn:n,It:o})=>{const{$t:s}=e||{},{Ot:c}=n;t&&(s||o)&&ue(t,{[Be]:c&&"100%"})},rc=({vt:t,ln:e,L:n,V:o},s)=>{const[c,r]=gt({i:as,o:Fn()},k(Fn,t,"padding",""));return({Dt:i,Zt:l,fn:f,It:u})=>{let[p,v]=r(u);const{P:O}=$t(),{_t:d,xt:S,Ct:C}=l||{},{B:$}=f,[q,X]=i("paddingAbsolute");(d||v||(u||S))&&([p,v]=c(u));const L=!o&&(X||C||v);if(L){const P=!q||!e&&!O,j=p.r+p.l,_=p.t+p.b,N={[uo]:P&&!$?-j:0,[fo]:P?-_:0,[ao]:P&&$?-j:0,top:P?-p.t:0,right:P?$?-p.r:"auto":0,left:P?$?"auto":-p.l:0,[_e]:P&&`calc(100% + ${j}px)`},B={[co]:P?p.t:0,[ro]:P?p.r:0,[lo]:P?p.b:0,[io]:P?p.l:0};ue(e||n,N),ue(n,B),K(s,{ln:p,_n:!P,F:e?B:K({},N,B)})}return{dn:L}}},ic=(t,e)=>{const n=$t(),{vt:o,ln:s,L:c,V:r,Qt:i,gt:l,bt:f,wt:u,un:p}=t,{P:v}=n,O=f&&r,d=k(eo,0),S={display:()=>!1,direction:m=>m!=="ltr",flexDirection:m=>m.endsWith("-reverse"),writingMode:m=>m!=="horizontal-tb"},C=mt(S),$={i:po,o:{w:0,h:0}},q={i:Ee,o:{}},X=m=>{u(Po,!O&&m)},y=()=>It(c,C),L=(m,g)=>{const h=!mt(m).length,a=!g&&C.some((ct=>{const lt=m[ct];return Qt(lt)&&S[ct](lt)}));if(h&&!a||!gs(c))return{T:{x:0,y:0},k:{x:1,y:1}};X(!0);const H=bt(l),M=ot(i,Ft,(ct=>{const lt=bt(l);ct.isTrusted&<.x===H.x&<.y===H.y&&$o(ct)}),{I:!0,A:!0}),U=u(Ls,!0);Lt(l,{x:0,y:0}),U();const R=bt(l),Z=He(l);Lt(l,{x:Z.w,y:Z.h});const D=bt(l),G={x:D.x-R.x,y:D.y-R.y};Lt(l,{x:-Z.w,y:-Z.h});const F=bt(l),it={x:F.x-R.x,y:F.y-R.y},ut={x:_t(G.x)>=_t(it.x)?D.x:F.x,y:_t(G.y)>=_t(it.y)?D.y:F.y};return Lt(l,H),gn((()=>M())),{T:R,k:ut}},P=(m,g)=>{const h=yt.devicePixelRatio%1!==0?1:0,a={w:d(m.w-g.w),h:d(m.h-g.h)};return{w:a.w>h?a.w:0,h:a.h>h?a.h:0}},j=(m,g)=>{const h=(a,b,H,M)=>{const U=a===kt?Ct:Fs(a),R=Xt(a),Z=Xt(H);return!b&&!M?Ct:R&&Z?kt:R?b&&M?U:b?kt:Ct:b?U:Z&&M?kt:Ct};return{x:h(g.x,m.x,g.y,m.y),y:h(g.y,m.y,g.x,m.x)}},_=m=>{const g=a=>[kt,Ct,Ft].map((b=>T(hn(b),a))),h=g(!0).concat(g()).join(" ");u(h),u(mt(m).map((a=>T(m[a],a==="x"))).join(" "),!0)},[N,B]=gt($,k($n,c)),[w,x]=gt($,k(He,c)),[z,E]=gt($),[V]=gt(q),[Y,Q]=gt($),[et]=gt(q),[W]=gt({i:(m,g)=>ze(m,g,$e(Gt(mt(m),mt(g)))),o:{}}),[st,I]=gt({i:(m,g)=>Ee(m.T,g.T)&&Ee(m.k,g.k),o:Ho()}),A=te(kn),T=(m,g)=>`${g?Es:Cs}${ls(m)}`;return({Dt:m,Zt:g,fn:h,It:a},{dn:b})=>{const{_t:H,Ht:M,xt:U,Ct:R,ft:Z,Et:D}=g||{},G=A&&A.R(t,e,h,n,m),{X:F,Y:it,W:ut}=G||{},[ct,lt]=Vs(m,n),[nt,pt]=m("overflow"),at=Xt(nt.x),St=Xt(nt.y),tt=H||b||U||R||D||lt;let ft=B(a),dt=x(a),Dt=E(a),ne=Q(a);if(lt&&v&&u(_o,!ct),tt){Ln(o,zt,Te)&&X(!0);const Pn=it&&it(),[ge]=ft=N(a),[be]=dt=w(a),ve=Lo(c),we=O&&ys(p()),Yo={w:d(be.w+ge.w),h:d(be.h+ge.h)},_n={w:d((we?we.w:ve.w+d(ve.w-be.w))+ge.w),h:d((we?we.h:ve.h+d(ve.h-be.h))+ge.h)};Pn&&Pn(),ne=Y(_n),Dt=z(P(Yo,_n),a)}const[de,fe]=ne,[Nt,oe]=Dt,[Ve,Fe]=dt,[pe,qe]=ft,[xt,je]=V({x:Nt.w>0,y:Nt.h>0}),me=at&&St&&(xt.x||xt.y)||at&&xt.x&&!xt.y||St&&xt.y&&!xt.x,We=b||R||D||qe||Fe||fe||oe||pt||lt||tt||M&&O,[jt]=m("update.flowDirectionStyles"),[Ue,he]=W(jt?jt(c):y(),a),se=R||Z||he||je||a,[ce,ye]=se?st(L(Ue,!!jt),a):I();let Pt=j(xt,nt);X(!1),We&&(_(Pt),Pt=qs(c,xt),ut&&F&&(F(Pt,Ve,pe),ue(c,ut(Pt))));const[Ko,Xo]=et(Pt);return Ae(o,zt,Te,me),Ae(s,pn,Te,me),K(e,{rn:Ko,Vt:{x:de.w,y:de.h},Rt:{x:Nt.w,y:Nt.h},j:xt,Tt:bs(ce,Nt)}),{en:Xo,nn:fe,sn:oe,cn:ye||oe}}},lc=t=>{const[e,n,o]=sc(t),s={ln:{t:0,r:0,b:0,l:0},_n:!1,F:{[uo]:0,[fo]:0,[ao]:0,[co]:0,[ro]:0,[lo]:0,[io]:0},Vt:{x:0,y:0},Rt:{x:0,y:0},rn:{x:Ct,y:Ct},j:{x:!1,y:!1},Tt:Ho()},{dt:c,gt:r,V:i,St:l}=e,{P:f,M:u}=$t(),p=!f&&(u.x||u.y),v=[cc(e),rc(e,s),ic(e,s)];return[n,O=>{const d={},C=p&&bt(r),$=C&&l();return J(v,(q=>{K(d,q(O,d)||{})})),Lt(r,C),$&&$(),i||Lt(c,0),d},s,e,o]},ac=(t,e,n,o)=>{let s=!1;const c={Kt:!1,pn:!1},r=Ge(e,{}),[i,l,f,u,p]=lc(t),[v,O,d]=Js(u,f,r,(y=>{X({},y)})),[S,C,,$]=oc(t,e,c,d,f,u,o),q=y=>mt(y).some((L=>!!y[L])),X=(y,L)=>{const{Kt:P,pn:j}=c;if(j||P&&s)return!1;const{vn:_,It:N,zt:B}=y,w=_||{},x=!!N||!s,z={Dt:Ge(e,w,x),vn:w,It:x},E=L||O(K({},z,{zt:B})),V=l(K({},z,{fn:d,Zt:E}));C(K({},z,{Zt:E,tn:V}));const Y=q(E),Q=q(V),et=Y||Q||!Cn(w)||x;return s=!0,et&&n(y,{Zt:E,tn:V}),et};return[()=>{const{an:y,gt:L,St:P}=u,j=bt(y),_=[v(),i(),S(),()=>{c.pn=!0}],N=P();return Lt(L,j),N(),k(vt,_)},X,y=>{const L=c.Kt;c.Kt=y,!y&&L!==y&&X({It:!0,zt:!0})},()=>{C({Dt:Ge(e,{},!1),vn:{},It:!1})},()=>({gn:c,hn:d,bn:f}),{yn:u,wn:$},p]},Mn=new WeakMap,uc=(t,e)=>{Mn.set(t,e)},dc=t=>{Mn.delete(t)},Wo=t=>Mn.get(t),Mt=(t,e,n)=>{const{tt:o}=$t(),s=Le(t),c=s?t:t.target,r=Wo(c);if(e&&!r){const i=[],l={},f=x=>{const z=yo(x),E=te(Ss);return E?E(z,!0):z},u=K({},o(),f(e)),[p,v,O]=fn(),[d,S,C]=fn(n),$=(x,z)=>{C(x,z),O(x,z)},[q,X,y,L,P,j,_]=ac(t,u,(({vn:x,It:z},{Zt:E,tn:V})=>{const{_t:Y,Ct:Q,$t:et,xt:W,Ht:st,ft:I}=E,{nn:A,sn:T,en:m,cn:g}=V;$("updated",[w,{updateHints:{sizeChanged:!!Y,directionChanged:!!Q,heightIntrinsicChanged:!!et,overflowEdgeChanged:!!A,overflowAmountChanged:!!T,overflowStyleChanged:!!m,scrollCoordinatesChanged:!!g,contentMutation:!!W,hostMutation:!!st,appear:!!I},changedOptions:x||{},force:!!z}])}),(x=>$("scroll",[w,x]))),N=x=>{const{gn:z}=P(),{pn:E}=z;E||(dc(c),vt(i),$("destroyed",[w,x]),v(),S())},w={options(x,z){if(x){const E=z?o():{},V=No(u,K(E,f(x)));Cn(V)||(K(u,V),X({vn:V}))}return K({},u)},on:d,off:(x,z)=>{x&&z&&S(x,z)},state(){const{gn:x,hn:z,bn:E}=P(),{pn:V,Kt:Y}=x,{B:Q}=z,{Vt:et,Rt:W,rn:st,j:I,ln:A,_n:T,Tt:m}=E;return K({},{overflowEdge:et,overflowAmount:W,overflowStyle:st,hasOverflow:I,scrollCoordinates:{start:m.T,end:m.k},padding:A,paddingAbsolute:T,directionRTL:Q,sleeping:Y,destroyed:V})},elements(){const{dt:x,vt:z,ln:E,L:V,ht:Y,gt:Q,Qt:et}=j.yn,{jt:W,Jt:st}=j.wn,I=T=>{const{kt:m,Pt:g,Lt:h}=T;return{scrollbar:h,track:g,handle:m}},A=T=>{const{Xt:m,Yt:g}=T,h=I(m[0]);return K({},h,{clone:()=>{const a=I(g());return L(),a}})};return K({},{target:x,host:z,padding:E||V,viewport:V,content:Y||V,scrollOffsetElement:Q,scrollEventElement:et,scrollbarHorizontal:A(W),scrollbarVertical:A(st)})},update:x=>X({It:x,zt:!0}),destroy:k(N,!1),sleep:y,plugin:x=>l[mt(x)[0]]};return rt(i,[_]),uc(c,w),Do(ko,Mt,[w,p,l]),tc(j.yn.bt,!s&&t.cancel)?(N(!0),w):(rt(i,q()),$("initialized",[w]),w.update(),w)}return r};Mt.plugin=t=>{const e=Et(t),n=e?t:[t],o=n.map((s=>Do(s,Mt)[0]));return vs(n),e?o:o[0]};Mt.valid=t=>{const e=t&&t.elements,n=Tt(e)&&e();return ie(n)&&!!Wo(n.target)};Mt.env=()=>{const{U:t,M:e,P:n,J:o,ot:s,st:c,K:r,Z:i,tt:l,nt:f}=$t();return K({},{scrollbarsSize:t,scrollbarsOverlaid:e,scrollbarsHiding:n,scrollTimeline:o,staticDefaultInitialization:s,staticDefaultOptions:c,getDefaultInitialization:r,setDefaultInitialization:i,getDefaultOptions:l,setDefaultOptions:f})};Mt.nonce=Xs;Mt.trustedTypePolicy=ps;const yn=!!document.getElementById("banner-wrapper");function Dn(t,e){document.addEventListener("click",n=>{let o=document.getElementById(t),s=n.target;if(s instanceof Node){for(let c of e){let r=document.getElementById(c);if(r==s||r?.contains(s))return}o.classList.add("float-panel-closed")}})}Dn("display-setting",["display-setting","display-settings-switch"]);Dn("nav-menu-panel",["nav-menu-panel","nav-menu-switch"]);Dn("search-panel",["search-panel","search-bar","search-switch"]);function fc(){const t=Go();Jo(t)}function pc(){Qo(ts())}function Uo(){requestIdleCallback(()=>{const t=document.querySelector("body");if(!t)return;Mt({target:t,cancel:{nativeScrollbarsOverlaid:!0}},{scrollbars:{theme:"scrollbar-base scrollbar-auto py-1",autoHide:"move",autoHideDelay:100,autoHideSuspend:!0}});const e=document.querySelectorAll(".katex-display");if(e.length===0)return;const n=new IntersectionObserver((o,s)=>{o.forEach(c=>{if(c.isIntersecting){const r=c.target;if(!r.parentNode||r.hasAttribute("data-scrollbar-initialized"))return;const i=document.createElement("div");i.className="katex-display-container",r.parentNode.insertBefore(i,r),i.appendChild(r),Mt(i,{scrollbars:{theme:"scrollbar-base scrollbar-auto",autoHide:"leave",autoHideDelay:800}}),r.setAttribute("data-scrollbar-initialized","true"),s.unobserve(c.target)}})},{root:null,rootMargin:"200px",threshold:.1});e.forEach(o=>{n.observe(o)})})}function mc(){requestAnimationFrame(()=>{const t=document.getElementById("banner");t&&t.classList.remove("opacity-0","scale-105");const e=document.querySelector('.block.lg\\:hidden[alt="Mobile banner image of the blog"]');e&&!document.getElementById("banner-carousel")&&(e.classList.remove("opacity-0","scale-105"),e.classList.add("opacity-100")),document.getElementById("banner-carousel")&&hc()})}function hc(){const t=document.querySelectorAll(".carousel-item"),e=window.innerWidth<1024,n=Array.from(t).filter(o=>e?o.querySelector(".block.lg\\:hidden"):o.querySelector(".hidden.lg\\:block"));if(n.length>1){t.forEach((c,r)=>{c.classList.add("opacity-0","scale-110"),c.classList.remove("opacity-100","scale-100")});const o=Math.floor(Math.random()*n.length),s=n[o];s.classList.add("opacity-100","scale-100"),s.classList.remove("opacity-0","scale-110");return}n.length>1&&ss.banner.carousel?.enable}function yc(){fc(),pc(),Uo(),mc()}yc();const to=()=>{window.swup.hooks.on("link:click",()=>{if(document.documentElement.style.setProperty("--content-delay","0ms"),yn){const t=document.getElementById("navbar-wrapper");if(t&&document.body.classList.contains("lg:is-home")){const e=window.innerHeight*(nn/100)-88;document.documentElement.scrollTop>=e&&t.classList.add("navbar-hidden")}}}),window.swup.hooks.on("content:replace",()=>{Uo();const t=document.querySelector("table-of-contents");t&&typeof t.init=="function"&&setTimeout(()=>{t.init()},100),typeof window.mobileTOCInit=="function"&&setTimeout(()=>{window.mobileTOCInit()},100),setTimeout(()=>{typeof window.translate<"u"&&window.translate.execute()},100);const e=document.getElementById("navbar");e&&e.getAttribute("data-transparent-mode")==="semifull"&&typeof window.initSemifullScrollDetection=="function"&&window.initSemifullScrollDetection()}),window.swup.hooks.on("visit:start",t=>{const e=document.querySelector("body"),n=ns(t.to.url,os("/"));n?e.classList.add("lg:is-home"):e.classList.remove("lg:is-home");const o=document.querySelector(".banner-text-overlay");o&&(n?o.classList.remove("hidden"):o.classList.add("hidden"));const s=document.getElementById("navbar");s&&(s.setAttribute("data-is-home",n.toString()),s.getAttribute("data-transparent-mode")==="semifull"&&typeof window.initSemifullScrollDetection=="function"&&window.initSemifullScrollDetection());const c=document.getElementById("banner-wrapper"),r=document.querySelector(".absolute.w-full.z-30");c&&r&&(n?(setTimeout(()=>{c.classList.remove("mobile-hide-banner")},100),setTimeout(()=>{r.classList.remove("mobile-main-no-banner")},150)):(c.classList.add("mobile-hide-banner"),setTimeout(()=>{r.classList.add("mobile-main-no-banner")},100)));const i=document.getElementById("page-height-extend");i&&i.classList.remove("hidden");let l=document.getElementById("toc-wrapper");l&&l.classList.add("toc-not-ready")}),window.swup.hooks.on("page:view",()=>{const t=document.getElementById("page-height-extend");t&&t.classList.remove("hidden"),window.scrollTo({top:0,behavior:"instant"}),setTimeout(()=>{if(document.getElementById("tcomment")){const e=new CustomEvent("mizuki:page:loaded",{detail:{path:window.location.pathname,timestamp:Date.now()}});document.dispatchEvent(e),console.log("Layout: 触发 mizuki:page:loaded 事件,路径:",window.location.pathname)}},300)}),window.swup.hooks.on("visit:end",t=>{setTimeout(()=>{const e=document.getElementById("page-height-extend");e&&e.classList.add("hidden");const n=document.getElementById("toc-wrapper");n&&n.classList.remove("toc-not-ready")},200)})};window?.swup?.hooks?to():document.addEventListener("swup:enable",to);let Qe=document.getElementById("back-to-top-btn"),tn=document.getElementById("toc-wrapper"),en=document.getElementById("navbar-wrapper");function gc(t,e){let n;return function(){const o=arguments,s=this;n||(t.apply(s,o),n=!0,setTimeout(()=>n=!1,e))}}function bc(){const t=document.documentElement.scrollTop,e=window.innerHeight*(nn/100);requestAnimationFrame(()=>{if(Qe&&(t>e?Qe.classList.remove("hide"):Qe.classList.add("hide")),yn&&tn&&(t>e?tn.classList.remove("toc-hide"):tn.classList.add("toc-hide")),yn&&en){const o=document.body.classList.contains("lg:is-home")&&window.innerWidth>=1024?es:nn,s=window.innerHeight*(o/100)-88;t>=s?en.classList.add("navbar-hidden"):en.classList.remove("navbar-hidden")}})}window.onscroll=gc(bc,16);window.onresize=()=>{let t=Math.floor(window.innerHeight*(Zo/100));t=t-t%4,document.documentElement.style.setProperty("--banner-height-extend",`${t}px`)}; diff --git a/website/blog/_astro/LightDarkSwitch.DQTkCfco.js b/website/blog/_astro/LightDarkSwitch.DQTkCfco.js deleted file mode 100644 index ef76277..0000000 --- a/website/blog/_astro/LightDarkSwitch.DQTkCfco.js +++ /dev/null @@ -1 +0,0 @@ -import{o as S}from"./lifecycle.MLiOCzKC.js";import{t as O,a as A,p as I,b as q,a3 as z,a4 as C,s as b,g as t,e as G,h as s,r as o,i as _}from"./template.CyUWgh-J.js";import{d as H,a as K}from"./utils.DonxBMOE.js";import{a as m}from"./props.h8jPqBEd.js";import{g as P,a as R,A as u,L as y,D as k,s as U}from"./setting-utils.Bem8IX7u.js";import"./config.B4FKKqOZ.js";import"./zh_TW.CqrCsd4X.js";import{I as h}from"./Icon.DAqWeDJZ.js";import"./functions.LP-DBi81.js";var W=G('
');function $(D,T){q(T,!0);const r=[y,k,u];let a=z(C(u));S(()=>{b(a,P(),!0);const e=window.matchMedia("(prefers-color-scheme: dark)"),f=j=>{R(t(a))};return e.addEventListener("change",f),()=>{e.removeEventListener("change",f)}});function w(e){b(a,e,!0),U(e)}function L(){let e=0;for(;e{v=m(i,1,"absolute",null,v,{"opacity-0":t(a)!==y}),p=m(l,1,"absolute",null,p,{"opacity-0":t(a)!==k}),g=m(d,1,"absolute",null,g,{"opacity-0":t(a)!==u})}),K("click",c,L),A(D,n),I()}H(["click"]);export{$ as default}; diff --git a/website/blog/_astro/MobileTOC.DcxBJmw1.js b/website/blog/_astro/MobileTOC.DcxBJmw1.js deleted file mode 100644 index 659edee..0000000 --- a/website/blog/_astro/MobileTOC.DcxBJmw1.js +++ /dev/null @@ -1,2 +0,0 @@ -import{o as ht,i as bt}from"./lifecycle.MLiOCzKC.js";import{f as j,t as C,a as p,p as wt,b as gt,g as o,e as f,s as g,d as L,h as d,i as _,r as l,c as F,n as G}from"./template.CyUWgh-J.js";import{s as A}from"./render.C4NccAY7.js";import{i as x}from"./functions.LP-DBi81.js";import{e as J,i as Q}from"./each.DMYtlFB3.js";import{e as S}from"./utils.DonxBMOE.js";import{a as _t}from"./props.h8jPqBEd.js";import{I as y}from"./Icon.DAqWeDJZ.js";import{I as U}from"./zh_TW.CqrCsd4X.js";import{i as W}from"./translation.BRy61wHY.js";import{n as xt}from"./navigation-utils.Cc6bKnia.js";/* empty css */import"./config.B4FKKqOZ.js";var yt=f('

暂无文章

'),It=f('
'),kt=f(''),Tt=f('
'),Et=f('

当前页面没有目录

'),Ct=f(''),Lt=f('
'),At=f(`

`,1);function Yt(X,Z){gt(Z,!1);let z=L([]),P=L([]),I=L(""),h,k=L(!1),T=!1;const K=()=>{document.getElementById("mobile-toc-panel")?.classList.toggle("float-panel-closed")},R=t=>{const e=document.getElementById("mobile-toc-panel");e&&e.classList.add("float-panel-closed")},$=()=>{const t=document.querySelectorAll("h1, h2, h3, h4, h5, h6"),e=[];t.forEach(a=>{if(a.id){const i=Number.parseInt(a.tagName.charAt(1)),v=a.textContent?.trim()||"";e.push({id:a.id,text:v,level:i})}}),g(z,e)},tt=()=>{const t=document.querySelectorAll(".card-base"),e=[];t.forEach(a=>{const i=a.querySelector('a[href*="/posts/"].transition.group'),v=a.querySelector('a[href*="/categories/"].link-lg'),n=i?.querySelector('svg[data-icon="mdi:pin"]');if(i){const s=i.getAttribute("href"),m=i.textContent?.replace(/\s+/g," ").trim()||"",r=v?.textContent?.trim()||"",c=!!n;s&&m&&e.push({title:m,url:s,category:r,pinned:c})}}),g(P,e)},et=()=>{g(k,window.location.pathname==="/"||window.location.pathname==="")},ot=t=>{const e=document.getElementById(t);if(e){R();const i=e.offsetTop-80;window.scrollTo({top:i,behavior:"smooth"})}},st=t=>{R(),xt(t)},q=()=>{const t=document.querySelectorAll("h1, h2, h3, h4, h5, h6"),e=window.scrollY,a=100;let i="";t.forEach(v=>{if(v.id){const n=v.offsetTop-a;e>=n&&(i=v.id)}}),g(I,i)},at=()=>{const t=document.querySelectorAll("h1, h2, h3, h4, h5, h6");h&&h.disconnect(),h=new IntersectionObserver(e=>{e.forEach(a=>{a.isIntersecting&&g(I,a.target.id)})},{rootMargin:"-80px 0px -80% 0px",threshold:0}),t.forEach(e=>{e.id&&h.observe(e)})},nt=()=>{if(typeof window<"u"&&(T=!!window.swup,!T)){const t=()=>{window.swup&&(T=!0,document.removeEventListener("swup:enable",t))};document.addEventListener("swup:enable",t),setTimeout(()=>{window.swup&&(T=!0,document.removeEventListener("swup:enable",t))},1e3)}},V=()=>{et(),nt(),o(k)?tt():($(),at(),q())};ht(()=>(setTimeout(V,100),window.addEventListener("scroll",q),()=>{h&&h.disconnect(),window.removeEventListener("scroll",q)})),typeof window<"u"&&(window.mobileTOCInit=V),bt();var Y=At(),E=j(Y),it=d(E);y(it,{icon:"material-symbols:format-list-bulleted",class:"text-[1.25rem]"}),l(E);var D=_(E,2),O=d(D),H=d(O),lt=d(H,!0);l(H);var B=_(H,2),rt=d(B);y(rt,{icon:"material-symbols:close",class:"text-[1rem]"}),l(B),l(O);var ct=_(O,2);{var dt=t=>{var e=F(),a=j(e);{var i=n=>{var s=yt(),m=d(s);y(m,{icon:"material-symbols:article-outline",class:"text-2xl mb-2"}),G(2),l(s),p(n,s)},v=n=>{var s=Tt();J(s,5,()=>o(P),Q,(m,r)=>{var c=kt(),b=d(c),w=d(b);{var M=u=>{y(u,{icon:"mdi:pin",class:"pinned-icon"})};x(w,u=>{o(r).pinned&&u(M)})}var mt=_(w);l(b);var pt=_(b,2);{var ft=u=>{var N=It(),ut=d(N,!0);l(N),C(()=>A(ut,o(r).category)),p(u,N)};x(pt,u=>{o(r).category&&u(ft)})}l(c),C(()=>A(mt,` ${o(r).title??""}`)),S("click",c,()=>st(o(r).url)),p(m,c)}),l(s),p(n,s)};x(a,n=>{o(P).length===0?n(i):n(v,-1)})}p(t,e)},vt=t=>{var e=F(),a=j(e);{var i=n=>{var s=Et(),m=d(s);y(m,{icon:"material-symbols:article-outline",class:"text-2xl mb-2"}),G(2),l(s),p(n,s)},v=n=>{var s=Lt();J(s,5,()=>o(z),Q,(m,r)=>{var c=Ct();let b;var w=d(c),M=d(w,!0);l(w),l(c),C(()=>{b=_t(c,1,`toc-item level-${o(r).level??""} ${o(I)===o(r).id?"active":""}`,"svelte-cz3h3s",b,{active:o(I)===o(r).id}),A(M,o(r).text)}),S("click",c,()=>ot(o(r).id)),p(m,c)}),l(s),p(n,s)};x(a,n=>{o(z).length===0?n(i):n(v,-1)})}p(t,e)};x(ct,t=>{o(k)?t(dt):t(vt,-1)})}l(D),C(t=>A(lt,t),[()=>o(k)?W(U.postList):W(U.tableOfContents)]),S("click",E,K),S("click",B,K),p(X,Y),wt()}export{Yt as default}; diff --git a/website/blog/_astro/MusicPlayer.Ckr8jCXu.js b/website/blog/_astro/MusicPlayer.Ckr8jCXu.js deleted file mode 100644 index c75e022..0000000 --- a/website/blog/_astro/MusicPlayer.Ckr8jCXu.js +++ /dev/null @@ -1 +0,0 @@ -import{o as b,a as W,i as _}from"./lifecycle.MLiOCzKC.js";import{c as x,f as I,a as k,p as R,b as j,s as n,m as s,g as e,d as a}from"./template.CyUWgh-J.js";import{i as q}from"./functions.LP-DBi81.js";import"./config.B4FKKqOZ.js";import"./zh_TW.CqrCsd4X.js";function N(B,F){j(F,!1);let o=a(!1),c=a(0),d=a(0),S=a(.7),l=a(!1),m=a(!1),v=a(0),w=a(""),h=a(!1),f=a({title:"示例歌曲",artist:"示例艺术家",cover:"/favicon/favicon-light-192.png",url:"",duration:0}),u=a([]),i=a(0),t=a();function E(){if(e(u).length<=1)return;let r;if(e(m))do r=Math.floor(Math.random()*e(u).length);while(r===e(i)&&e(u).length>1);else r=e(i)=e(u).length)return;const $=e(o);n(i,r),e(t)&&e(t).pause(),T(e(u)[e(i)]),($||!e(o))&&setTimeout(()=>{e(t)&&(e(t).readyState>=2?e(t).play().catch(()=>{}):e(t).addEventListener("canplay",()=>{e(t).play().catch(()=>{})},{once:!0}))},100)}function M(r){return r.startsWith("http://")||r.startsWith("https://")||r.startsWith("/")?r:`/${r}`}function T(r){!r||!e(t)||(n(f,{...r}),r.url?(n(l,!0),e(t).pause(),s(t,e(t).currentTime=0),n(c,0),n(d,r.duration??0),e(t).removeEventListener("loadeddata",p),e(t).removeEventListener("error",g),e(t).removeEventListener("loadstart",L),e(t).addEventListener("loadeddata",p,{once:!0}),e(t).addEventListener("error",g,{once:!0}),e(t).addEventListener("loadstart",L,{once:!0}),s(t,e(t).src=M(r.url)),e(t).load()):n(l,!1))}function p(){n(l,!1),e(t)?.duration&&e(t).duration>1&&(n(d,Math.floor(e(t).duration)),e(u)[e(i)]&&s(u,e(u)[e(i)].duration=e(d)),s(f,e(f).duration=e(d)))}function g(r){n(l,!1),y(`无法播放 "${e(f).title}",正在尝试下一首...`),e(u).length>1?setTimeout(()=>E(),1e3):y("播放列表中没有可用的歌曲")}function L(){}function y(r){n(w,r),n(h,!0),setTimeout(()=>{n(h,!1)},3e3)}function C(){e(t)&&(e(t).addEventListener("play",()=>{n(o,!0)}),e(t).addEventListener("pause",()=>{n(o,!1)}),e(t).addEventListener("timeupdate",()=>{n(c,e(t).currentTime)}),e(t).addEventListener("ended",()=>{e(v)===1?(s(t,e(t).currentTime=0),e(t).play().catch(()=>{})):e(v)===2||e(i){n(l,!1)}),e(t).addEventListener("stalled",()=>{}),e(t).addEventListener("waiting",()=>{}))}b(()=>{n(t,new Audio),s(t,e(t).volume=e(S)),C()}),W(()=>{e(t)&&(e(t).pause(),s(t,e(t).src=""))}),_();var A=x(),P=I(A);q(P,r=>{}),k(B,A),R()}export{N as default}; diff --git a/website/blog/_astro/Search.C4siwRRu.js b/website/blog/_astro/Search.C4siwRRu.js deleted file mode 100644 index f3aa502..0000000 --- a/website/blog/_astro/Search.C4siwRRu.js +++ /dev/null @@ -1,11 +0,0 @@ -import{o as X,i as Z}from"./lifecycle.MLiOCzKC.js";import{l as R,k as $,f as ee,t as z,g as e,a as F,p as te,b as ae,s,i as o,e as q,d as g,h as f,r as c,u as b,j as M}from"./template.CyUWgh-J.js";import{s as re}from"./render.C4NccAY7.js";import{e as ie,i as se}from"./each.DMYtlFB3.js";import{I as w,h as ne}from"./Icon.DAqWeDJZ.js";import{r as j,s as C}from"./props.h8jPqBEd.js";import{e as I}from"./utils.DonxBMOE.js";import{b as K}from"./input.CM2Xh3yk.js";import{I as V}from"./zh_TW.CqrCsd4X.js";import{i as W}from"./translation.BRy61wHY.js";import{u as Y}from"./url-utils.CaIMLrxo.js";import{n as le}from"./navigation-utils.Cc6bKnia.js";/* empty css */import"./functions.LP-DBi81.js";import"./config.B4FKKqOZ.js";var oe=q(`
`),ce=q(`
`,1);function Se(A,D){ae(D,!1);let i=g(""),n=g(""),d=g([]),x=!1,l=g(!1);const de=[{url:Y("/"),meta:{title:"This Is a Fake Search Result"},excerpt:"Because the search cannot work in the dev environment."},{url:Y("/"),meta:{title:"If You Want to Test the Search"},excerpt:"Try running npm build && npm preview instead."}],G=()=>{document.getElementById("search-panel")?.classList.toggle("float-panel-closed")},k=(t,a)=>{const r=document.getElementById("search-panel");!r||!a||(t?r.classList.remove("float-panel-closed"):r.classList.add("float-panel-closed"))},H=()=>{const t=document.getElementById("search-panel");t&&t.classList.add("float-panel-closed"),s(i,""),s(n,""),s(d,[])},J=(t,a)=>{t.preventDefault(),H(),le(a)},p=async(t,a)=>{if(!t){k(!1,a),s(d,[]);return}if(e(l))try{let r=[];if(x&&window.pagefind){const m=await window.pagefind.search(t);r=await Promise.all(m.results.map(v=>v.data()))}else r=[],console.error("Pagefind is not available in production environment.");s(d,r),k(e(d).length>0,a)}catch(r){console.error("Search error:",r),s(d,[]),k(!1,a)}finally{}};X(()=>{const t=()=>{s(l,!0),x=typeof window<"u"&&!!window.pagefind&&typeof window.pagefind.search=="function",console.log("Pagefind status on init:",x),e(i)&&p(e(i),!0),e(n)&&p(e(n),!1)};document.addEventListener("pagefindready",()=>{console.log("Pagefind ready event received."),t()}),document.addEventListener("pagefindloaderror",()=>{console.warn("Pagefind load error event received. Search functionality will be limited."),t()}),setTimeout(()=>{e(l)||(console.log("Fallback: Initializing search after timeout."),t())},2e3)}),R(()=>(e(l),e(i)),()=>{e(l)&&e(i)&&(async()=>await p(e(i),!0))()}),R(()=>(e(l),e(n)),()=>{e(l)&&e(n)&&(async()=>await p(e(n),!1))()}),$(),Z();var P=ce(),y=ee(P),S=f(y);w(S,{icon:"material-symbols:search",class:"absolute text-[1.25rem] pointer-events-none ml-3 transition my-auto text-black/30 dark:text-white/30"});var u=o(S,2);j(u),c(y);var h=o(y,2),N=f(h);w(N,{icon:"material-symbols:search",class:"text-[1.25rem]"}),c(h);var L=o(h,2),_=f(L),E=f(_);w(E,{icon:"material-symbols:search",class:"absolute text-[1.25rem] pointer-events-none ml-3 transition my-auto text-black/30 dark:text-white/30"});var T=o(E,2);j(T),c(_);var O=o(_,2);ie(O,1,()=>e(d),se,(t,a)=>{var r=oe(),m=f(r),v=f(m,!0),Q=o(v);w(Q,{icon:"fa6-solid:chevron-right",class:"transition text-[0.75rem] translate-x-1 my-auto text-[var(--primary)]"}),c(m);var B=o(m,2);ne(B,()=>(e(a),b(()=>e(a).excerpt)),!0),c(B),c(r),z(()=>{C(r,"href",(e(a),b(()=>e(a).url))),re(v,(e(a),b(()=>e(a).meta.title)))}),I("click",r,U=>J(U,e(a).url)),F(t,r)}),c(L),z(t=>C(u,"placeholder",t),[()=>(M(W),M(V),b(()=>W(V.search)))]),K(u,()=>e(i),t=>s(i,t)),I("focus",u,()=>p(e(i),!0)),I("click",h,G),K(T,()=>e(n),t=>s(n,t)),F(A,P),te()}export{Se as default}; diff --git a/website/blog/_astro/SideBar.astro_astro_type_script_index_0_lang.Fy0FqEdY.js b/website/blog/_astro/SideBar.astro_astro_type_script_index_0_lang.Fy0FqEdY.js deleted file mode 100644 index e694623..0000000 --- a/website/blog/_astro/SideBar.astro_astro_type_script_index_0_lang.Fy0FqEdY.js +++ /dev/null @@ -1 +0,0 @@ -import{w as o}from"./widget-manager.B87vf-Ll.js";import"./config.B4FKKqOZ.js";class a{constructor(){this.init()}init(){this.updateResponsiveDisplay(),window.addEventListener("resize",()=>this.updateResponsiveDisplay())}updateResponsiveDisplay(){const i=o.getBreakpoints(),t=window.innerWidth;let e;t{const w=M(g,String(e));if(w){const f=Object.assign(g,{delegateTarget:w});i.call(l,f),r&&(l.removeEventListener(t,h,a),x(!1,l,i,u))}},u=JSON.stringify({selector:e,type:t,capture:c});x(!0,l,i,u)||l.addEventListener(t,h,a),n?.addEventListener("abort",()=>{x(!1,l,i,u)})}function p(){return p=Object.assign?Object.assign.bind():function(e){for(var t=1;tString(e).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||t||"",S=({hash:e}={})=>window.location.pathname+window.location.search+(e?window.location.hash:""),D=(e,t={})=>{const i=p({url:e=e||S({hash:!0}),random:Math.random(),source:"swup"},t);window.history.pushState(i,"",e)},b=(e=null,t={})=>{e=e||S({hash:!0});const i=p({},window.history.state||{},{url:e,random:Math.random(),source:"swup"},t);window.history.replaceState(i,"",e)},j=(e,t,i,s)=>{const n=new AbortController;return s=p({},s,{signal:n.signal}),R(e,t,i,s),{destroy:()=>n.abort()}};class m extends URL{constructor(t,i=document.baseURI){super(t.toString(),i),Object.setPrototypeOf(this,m.prototype)}get url(){return this.pathname+this.search}static fromElement(t){const i=t.getAttribute("href")||t.getAttribute("xlink:href")||"";return new m(i)}static fromUrl(t){return new m(t)}}class E extends Error{constructor(t,i){super(t),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=i.url,this.status=i.status,this.aborted=i.aborted||!1,this.timedOut=i.timedOut||!1}}async function W(e,t={}){var i;e=m.fromUrl(e).url;const{visit:s=this.visit}=t,n=p({},this.options.requestHeaders,t.headers),o=(i=t.timeout)!=null?i:this.options.timeout,r=new AbortController,{signal:a}=r;t=p({},t,{headers:n,signal:a});let l,c=!1,h=null;o&&o>0&&(h=setTimeout(()=>{c=!0,r.abort("timeout")},o));try{l=await this.hooks.call("fetch:request",s,{url:e,options:t},(v,{url:k,options:y})=>fetch(k,y)),h&&clearTimeout(h)}catch(v){throw c?(this.hooks.call("fetch:timeout",s,{url:e}),new E(`Request timed out: ${e}`,{url:e,timedOut:c})):v?.name==="AbortError"||a.aborted?new E(`Request aborted: ${e}`,{url:e,aborted:!0}):v}const{status:u,url:d}=l,g=await l.text();if(u===500)throw this.hooks.call("fetch:error",s,{status:u,response:l,url:d}),new E(`Server error: ${d}`,{status:u,url:d});if(!g)throw new E(`Empty response: ${d}`,{status:u,url:d});const{url:w}=m.fromUrl(d),f={url:w,html:g};return!s.cache.write||t.method&&t.method!=="GET"||e!==w||this.cache.set(f.url,f),f}class B{constructor(t){this.swup=void 0,this.pages=new Map,this.swup=t}get size(){return this.pages.size}get all(){const t=new Map;return this.pages.forEach((i,s)=>{t.set(s,p({},i))}),t}has(t){return this.pages.has(this.resolve(t))}get(t){const i=this.pages.get(this.resolve(t));return i&&p({},i)}set(t,i){i=p({},i,{url:t=this.resolve(t)}),this.pages.set(t,i),this.swup.hooks.callSync("cache:set",void 0,{page:i})}update(t,i){t=this.resolve(t);const s=p({},this.get(t),i,{url:t});this.pages.set(t,s)}delete(t){this.pages.delete(this.resolve(t))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0,void 0)}prune(t){this.pages.forEach((i,s)=>{t(s,i)&&this.delete(s)})}resolve(t){const{url:i}=m.fromUrl(t);return this.swup.resolveUrl(i)}}const $=(e,t=document)=>t.querySelector(e),L=(e,t=document)=>Array.from(t.querySelectorAll(e)),I=()=>new Promise(e=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{e()})})});function N(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function _(e,t=[]){return new Promise((i,s)=>{const n=e(...t);N(n)?n.then(i,s):i(n)})}function H(e,t){const i=e?.closest(`[${t}]`);return i!=null&&i.hasAttribute(t)?i?.getAttribute(t)||!0:void 0}class F{constructor(t){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating","is-leaving"],this.swup=t}get selectors(){const{scope:t}=this.swup.visit.animation;return t==="containers"?this.swup.visit.containers:t==="html"?["html"]:Array.isArray(t)?t:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?L(this.selector):[]}add(...t){this.targets.forEach(i=>i.classList.add(...t))}remove(...t){this.targets.forEach(i=>i.classList.remove(...t))}clear(){this.targets.forEach(t=>{const i=t.className.split(" ").filter(s=>this.isSwupClass(s));t.classList.remove(...i)})}isSwupClass(t){return this.swupClasses.some(i=>t.startsWith(i))}}class q{constructor(t,i){this.id=void 0,this.state=void 0,this.from=void 0,this.to=void 0,this.containers=void 0,this.animation=void 0,this.trigger=void 0,this.cache=void 0,this.history=void 0,this.scroll=void 0,this.meta=void 0;const{to:s,from:n,hash:o,el:r,event:a}=i;this.id=Math.random(),this.state=1,this.from={url:n??t.location.url,hash:t.location.hash},this.to={url:s,hash:o},this.containers=t.options.containers,this.animation={animate:!0,wait:!1,name:void 0,native:t.options.native,scope:t.options.animationScope,selector:t.options.animationSelector},this.trigger={el:r,event:a},this.cache={read:t.options.cache,write:t.options.cache},this.history={action:"push",popstate:!1,direction:void 0},this.scroll={reset:!0,target:void 0},this.meta={}}advance(t){this.state=7}}function z(e){return new q(this,e)}class K{constructor(t){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:abort","visit:end"],this.swup=t,this.init()}init(){this.hooks.forEach(t=>this.create(t))}create(t){this.registry.has(t)||this.registry.set(t,new Map)}exists(t){return this.registry.has(t)}get(t){const i=this.registry.get(t);if(i)return i;console.error(`Unknown hook '${t}'`)}clear(){this.registry.forEach(t=>t.clear())}on(t,i,s={}){const n=this.get(t);if(!n)return console.warn(`Hook '${t}' not found.`),()=>{};const o=p({},s,{id:n.size+1,hook:t,handler:i});return n.set(i,o),()=>this.off(t,i)}before(t,i,s={}){return this.on(t,i,p({},s,{before:!0}))}replace(t,i,s={}){return this.on(t,i,p({},s,{replace:!0}))}once(t,i,s={}){return this.on(t,i,p({},s,{once:!0}))}off(t,i){const s=this.get(t);s&&i?s.delete(i)||console.warn(`Handler for hook '${t}' not found.`):s&&s.clear()}async call(t,i,s,n){const[o,r,a]=this.parseCallArgs(t,i,s,n),{before:l,handler:c,after:h}=this.getHandlers(t,a);await this.run(l,o,r);const[u]=await this.run(c,o,r,!0);return await this.run(h,o,r),this.dispatchDomEvent(t,o,r),u}callSync(t,i,s,n){const[o,r,a]=this.parseCallArgs(t,i,s,n),{before:l,handler:c,after:h}=this.getHandlers(t,a);this.runSync(l,o,r);const[u]=this.runSync(c,o,r,!0);return this.runSync(h,o,r),this.dispatchDomEvent(t,o,r),u}parseCallArgs(t,i,s,n){return i instanceof q||typeof i!="object"&&typeof s!="function"?[i,s,n]:[void 0,i,s]}async run(t,i=this.swup.visit,s,n=!1){const o=[];for(const{hook:r,handler:a,defaultHandler:l,once:c}of t)if(i==null||!i.done){c&&this.off(r,a);try{const h=await _(a,[i,s,l]);o.push(h)}catch(h){if(n)throw h;console.error(`Error in hook '${r}':`,h)}}return o}runSync(t,i=this.swup.visit,s,n=!1){const o=[];for(const{hook:r,handler:a,defaultHandler:l,once:c}of t)if(i==null||!i.done){c&&this.off(r,a);try{const h=a(i,s,l);o.push(h),N(h)&&console.warn(`Swup will not await Promises in handler for synchronous hook '${r}'.`)}catch(h){if(n)throw h;console.error(`Error in hook '${r}':`,h)}}return o}getHandlers(t,i){const s=this.get(t);if(!s)return{found:!1,before:[],handler:[],after:[],replaced:!1};const n=Array.from(s.values()),o=this.sortRegistrations,r=n.filter(({before:u,replace:d})=>u&&!d).sort(o),a=n.filter(({replace:u})=>u).filter(u=>!0).sort(o),l=n.filter(({before:u,replace:d})=>!u&&!d).sort(o),c=a.length>0;let h=[];if(i&&(h=[{id:0,hook:t,handler:i}],c)){const u=a.length-1,{handler:d,once:g}=a[u],w=f=>{const v=a[f-1];return v?(k,y)=>v.handler(k,y,w(f-1)):i};h=[{id:0,hook:t,once:g,handler:d,defaultHandler:w(u)}]}return{found:!0,before:r,handler:h,after:l,replaced:c}}sortRegistrations(t,i){var s,n;return((s=t.priority)!=null?s:0)-((n=i.priority)!=null?n:0)||t.id-i.id||0}dispatchDomEvent(t,i,s){if(i!=null&&i.done)return;const n={hook:t,args:s,visit:i||this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:n,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${t}`,{detail:n,bubbles:!0}))}parseName(t){const[i,...s]=t.split(".");return[i,s.reduce((n,o)=>p({},n,{[o]:!0}),{})]}}const G=e=>{if(e&&e.charAt(0)==="#"&&(e=e.substring(1)),!e)return null;const t=decodeURIComponent(e);let i=document.getElementById(e)||document.getElementById(t)||$(`a[name='${CSS.escape(e)}']`)||$(`a[name='${CSS.escape(t)}']`);return i||e!=="top"||(i=document.body),i},C="transition",A="animation";async function J({selector:e,elements:t}){if(e===!1&&!t)return;let i=[];if(t)i=Array.from(t);else if(e&&(i=L(e,document.body),!i.length))return void console.warn(`[swup] No elements found matching animationSelector \`${e}\``);const s=i.map(n=>(function(o){const{type:r,timeout:a,propCount:l}=(function(c){const h=window.getComputedStyle(c),u=U(h,`${C}Delay`),d=U(h,`${C}Duration`),g=T(u,d),w=U(h,`${A}Delay`),f=U(h,`${A}Duration`),v=T(w,f),k=Math.max(g,v),y=k>0?g>v?C:A:null;return{type:y,timeout:k,propCount:y?y===C?d.length:f.length:0}})(o);return!(!r||!a)&&new Promise(c=>{const h=`${r}end`,u=performance.now();let d=0;const g=()=>{o.removeEventListener(h,w),c()},w=f=>{f.target===o&&((performance.now()-u)/1e3=l&&g())};setTimeout(()=>{d0?await Promise.all(s):e&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${e}\``)}function U(e,t){return(e[t]||"").split(", ")}function T(e,t){for(;e.lengthO(i)+O(e[s])))}function O(e){return 1e3*parseFloat(e)}function X(e,t={},i={}){if(typeof e!="string")throw new Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(e,{el:i.el,event:i.event}))return void window.location.assign(e);const{url:s,hash:n}=m.fromUrl(e),o=this.createVisit(p({},i,{to:s,hash:n}));this.performNavigation(o,t)}async function Q(e,t={}){if(this.navigating){if(this.visit.state>=6)return e.state=2,void(this.onVisitEnd=()=>this.performNavigation(e,t));await this.hooks.call("visit:abort",this.visit,void 0),delete this.visit.to.document,this.visit.state=8}this.navigating=!0,this.visit=e;const{el:i}=e.trigger;t.referrer=t.referrer||this.location.url,t.animate===!1&&(e.animation.animate=!1),e.animation.animate||this.classes.clear();const s=t.history||H(i,"data-swup-history");typeof s=="string"&&["push","replace"].includes(s)&&(e.history.action=s);const n=t.animation||H(i,"data-swup-animation");var o,r;typeof n=="string"&&(e.animation.name=n),e.meta=t.meta||{},typeof t.cache=="object"?(e.cache.read=(o=t.cache.read)!=null?o:e.cache.read,e.cache.write=(r=t.cache.write)!=null?r:e.cache.write):t.cache!==void 0&&(e.cache={read:!!t.cache,write:!!t.cache}),delete t.cache;try{await this.hooks.call("visit:start",e,void 0),e.state=3;const a=this.hooks.call("page:load",e,{options:t},async(c,h)=>{let u;return c.cache.read&&(u=this.cache.get(c.to.url)),h.page=u||await this.fetchPage(c.to.url,h.options),h.cache=!!u,h.page});a.then(({html:c})=>{e.advance(5),e.to.html=c,e.to.document=new DOMParser().parseFromString(c,"text/html")});const l=e.to.url+e.to.hash;if(e.history.popstate||(e.history.action==="replace"||e.to.url===this.location.url?b(l):(this.currentHistoryIndex++,D(l,{index:this.currentHistoryIndex}))),this.location=m.fromUrl(l),e.history.popstate&&this.classes.add("is-popstate"),e.animation.name&&this.classes.add(`to-${V(e.animation.name)}`),e.animation.wait&&await a,e.done||(await this.hooks.call("visit:transition",e,void 0,async()=>{if(!e.animation.animate)return await this.hooks.call("animation:skip",void 0),void await this.renderPage(e,await a);e.advance(4),await this.animatePageOut(e),e.animation.native&&document.startViewTransition?await document.startViewTransition(async()=>await this.renderPage(e,await a)).finished:await this.renderPage(e,await a),await this.animatePageIn(e)}),e.done))return;await this.hooks.call("visit:end",e,void 0,()=>this.classes.clear()),e.state=7,this.navigating=!1,this.onVisitEnd&&(this.onVisitEnd(),this.onVisitEnd=void 0)}catch(a){if(!a||a!=null&&a.aborted)return void(e.state=8);e.state=9,console.error(a),this.options.skipPopStateHandling=()=>(window.location.assign(e.to.url+e.to.hash),!0),window.history.back()}finally{delete e.to.document}}const Y=async function(e){await this.hooks.call("animation:out:start",e,void 0,()=>{this.classes.add("is-changing","is-animating","is-leaving")}),await this.hooks.call("animation:out:await",e,{skip:!1},(t,{skip:i})=>{if(!i)return this.awaitAnimations({selector:t.animation.selector})}),await this.hooks.call("animation:out:end",e,void 0)},Z=function(e){var t;const i=e.to.document;if(!i)return!1;const s=((t=i.querySelector("title"))==null?void 0:t.innerText)||"";document.title=s;const n=L('[data-swup-persist]:not([data-swup-persist=""])'),o=e.containers.map(r=>{const a=document.querySelector(r),l=i.querySelector(r);return a&&l?(a.replaceWith(l.cloneNode(!0)),!0):(a||console.warn(`[swup] Container missing in current document: ${r}`),l||console.warn(`[swup] Container missing in incoming document: ${r}`),!1)}).filter(Boolean);return n.forEach(r=>{const a=r.getAttribute("data-swup-persist"),l=$(`[data-swup-persist="${a}"]`);l&&l!==r&&l.replaceWith(r)}),o.length===e.containers.length},tt=function(e){const t={behavior:"auto"},{target:i,reset:s}=e.scroll,n=i??e.to.hash;let o=!1;return n&&(o=this.hooks.callSync("scroll:anchor",e,{hash:n,options:t},(r,{hash:a,options:l})=>{const c=this.getAnchorElement(a);return c&&c.scrollIntoView(l),!!c})),s&&!o&&(o=this.hooks.callSync("scroll:top",e,{options:t},(r,{options:a})=>(window.scrollTo(p({top:0,left:0},a)),!0))),o},et=async function(e){if(e.done)return;const t=this.hooks.call("animation:in:await",e,{skip:!1},(i,{skip:s})=>{if(!s)return this.awaitAnimations({selector:i.animation.selector})});await I(),await this.hooks.call("animation:in:start",e,void 0,()=>{this.classes.remove("is-animating")}),await t,await this.hooks.call("animation:in:end",e,void 0)},it=async function(e,t){if(e.done)return;e.advance(6);const{url:i}=t;this.isSameResolvedUrl(S(),i)||(b(i),this.location=m.fromUrl(i),e.to.url=this.location.url,e.to.hash=this.location.hash),await this.hooks.call("content:replace",e,{page:t},(s,{})=>{if(this.classes.remove("is-leaving"),s.animation.animate&&this.classes.add("is-rendering"),!this.replaceContent(s))throw new Error("[swup] Container mismatch, aborting");s.animation.animate&&(this.classes.add("is-changing","is-animating","is-rendering"),s.animation.name&&this.classes.add(`to-${V(s.animation.name)}`))}),await this.hooks.call("content:scroll",e,void 0,()=>this.scrollToContent(e)),await this.hooks.call("page:view",e,{url:this.location.url,title:document.title})},st=function(e){var t;if(t=e,!!t?.isSwupPlugin){if(e.swup=this,!e._checkRequirements||e._checkRequirements())return e._beforeMount&&e._beforeMount(),e.mount(),this.plugins.push(e),this.plugins}else console.error("Not a swup plugin instance",e)};function nt(e){const t=this.findPlugin(e);if(t)return t.unmount(),t._afterUnmount&&t._afterUnmount(),this.plugins=this.plugins.filter(i=>i!==t),this.plugins;console.error("No such plugin",t)}function ot(e){return this.plugins.find(t=>t===e||t.name===e||t.name===`Swup${String(e)}`)}function rt(e){if(typeof this.options.resolveUrl!="function")return console.warn("[swup] options.resolveUrl expects a callback function."),e;const t=this.options.resolveUrl(e);return t&&typeof t=="string"?t.startsWith("//")||t.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),e):t:(console.warn("[swup] options.resolveUrl needs to return a url"),e)}function at(e,t){return this.resolveUrl(e)===this.resolveUrl(t)}const lt={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],hooks:{},ignoreVisit:(e,{el:t}={})=>!(t==null||!t.closest("[data-no-swup]")),linkSelector:"a[href]",linkToSelf:"scroll",native:!1,plugins:[],resolveUrl:e=>e,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:e=>{var t;return((t=e.state)==null?void 0:t.source)!=="swup"},timeout:0};class ht{get currentPageUrl(){return this.location.url}constructor(t={}){var i,s;this.version="4.8.3",this.options=void 0,this.defaults=lt,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.location=m.fromUrl(window.location.href),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.onVisitEnd=void 0,this.use=st,this.unuse=nt,this.findPlugin=ot,this.log=()=>{},this.navigate=X,this.performNavigation=Q,this.createVisit=z,this.delegateEvent=j,this.fetchPage=W,this.awaitAnimations=J,this.renderPage=it,this.replaceContent=Z,this.animatePageIn=et,this.animatePageOut=Y,this.scrollToContent=tt,this.getAnchorElement=G,this.getCurrentUrl=S,this.resolveUrl=rt,this.isSameResolvedUrl=at,this.options=p({},this.defaults,t),this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new B(this),this.classes=new F(this),this.hooks=new K(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=(i=(s=window.history.state)==null?void 0:s.index)!=null?i:1,this.enable()}async enable(){var t;const{linkSelector:i}=this.options;this.clickDelegate=this.delegateEvent(i,"click",this.handleLinkClick),window.addEventListener("popstate",this.handlePopState),this.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),this.options.native=this.options.native&&!!document.startViewTransition,this.options.plugins.forEach(s=>this.use(s));for(const[s,n]of Object.entries(this.options.hooks)){const[o,r]=this.hooks.parseName(s);this.hooks.on(o,n,r)}((t=window.history.state)==null?void 0:t.source)!=="swup"&&b(null,{index:this.currentHistoryIndex}),await I(),await this.hooks.call("enable",void 0,void 0,()=>{const s=document.documentElement;s.classList.add("swup-enabled"),s.classList.toggle("swup-native",this.options.native)})}async destroy(){this.clickDelegate.destroy(),window.removeEventListener("popstate",this.handlePopState),this.cache.clear(),this.options.plugins.forEach(t=>this.unuse(t)),await this.hooks.call("disable",void 0,void 0,()=>{const t=document.documentElement;t.classList.remove("swup-enabled"),t.classList.remove("swup-native")}),this.hooks.clear()}shouldIgnoreVisit(t,{el:i,event:s}={}){const{origin:n,url:o,hash:r}=m.fromUrl(t);return n!==window.location.origin||!(!i||!this.triggerWillOpenNewWindow(i))||!!this.options.ignoreVisit(o+r,{el:i,event:s})}handleLinkClick(t){const i=t.delegateTarget,{href:s,url:n,hash:o}=m.fromElement(i);if(this.shouldIgnoreVisit(s,{el:i,event:t}))return;if(this.navigating&&n===this.visit.to.url)return void t.preventDefault();const r=this.createVisit({to:n,hash:o,el:i,event:t});t.metaKey||t.ctrlKey||t.shiftKey||t.altKey?this.hooks.callSync("link:newtab",r,{href:s}):t.button===0&&this.hooks.callSync("link:click",r,{el:i,event:t},()=>{var a;const l=(a=r.from.url)!=null?a:"";t.preventDefault(),n&&n!==l?this.isSameResolvedUrl(n,l)||this.performNavigation(r):o?this.hooks.callSync("link:anchor",r,{hash:o},()=>{b(n+o),this.scrollToContent(r)}):this.hooks.callSync("link:self",r,void 0,()=>{this.options.linkToSelf==="navigate"?this.performNavigation(r):(b(n),this.scrollToContent(r))})})}handlePopState(t){var i,s,n,o;const r=(i=(s=t.state)==null?void 0:s.url)!=null?i:window.location.href;if(this.options.skipPopStateHandling(t)||this.isSameResolvedUrl(S(),this.location.url))return;const{url:a,hash:l}=m.fromUrl(r),c=this.createVisit({to:a,hash:l,event:t});c.history.popstate=!0;const h=(n=(o=t.state)==null?void 0:o.index)!=null?n:0;h&&h!==this.currentHistoryIndex&&(c.history.direction=h-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=h),c.animation.animate=!1,c.scroll.reset=!1,c.scroll.target=!1,this.options.animateHistoryBrowsing&&(c.animation.animate=!0,c.scroll.reset=!0),this.hooks.callSync("history:popstate",c,{event:t},()=>{this.performNavigation(c)})}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}}const ct=Object.freeze(Object.defineProperty({__proto__:null,default:ht},Symbol.toStringTag,{value:"Module"}));export{ct as S,m as l}; diff --git a/website/blog/_astro/SwupA11yPlugin.Fv5HjOXF.js b/website/blog/_astro/SwupA11yPlugin.Fv5HjOXF.js deleted file mode 100644 index 74bdd3e..0000000 --- a/website/blog/_astro/SwupA11yPlugin.Fv5HjOXF.js +++ /dev/null @@ -1 +0,0 @@ -import{e as g}from"./index.modern.D46RI4Wq.js";import{l as y}from"./Swup.DoubZhVr.js";(function(){if(!(typeof window>"u"||typeof document>"u"||typeof HTMLElement>"u")){var s=!1;try{var t=document.createElement("div");t.addEventListener("focus",function(i){i.preventDefault(),i.stopPropagation()},!0),t.focus(Object.defineProperty({},"preventScroll",{get:function(){if(navigator&&typeof navigator.userAgent<"u"&&navigator.userAgent&&navigator.userAgent.match(/Edge\/1[7-8]/))return s=!1;s=!0}}))}catch{}if(HTMLElement.prototype.nativeFocus===void 0&&!s){HTMLElement.prototype.nativeFocus=HTMLElement.prototype.focus;var n=function(i){for(var e=i.parentNode,u=[],a=document.scrollingElement||document.documentElement;e&&e!==a;)(e.offsetHeightn.replace(`{${o}}`,t[o]||""),s||"")}class w{constructor(){var t;this.id="swup-announcer",this.style="position:absolute;top:0;left:0;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden;white-space:nowrap;word-wrap:normal;width:1px;height:1px;",this.region=void 0,this.region=(t=this.getRegion())!=null?t:this.createRegion()}getRegion(){return document.getElementById(this.id)}createRegion(){const t=(function(n){const o=document.createElement("template");return o.innerHTML=n,o.content.children[0]})(`

`);return document.body.appendChild(t),t}announce(t,n=0){return new Promise(o=>{setTimeout(()=>{this.region.textContent===t&&(t=`${t}.`),this.region.textContent="",this.region.textContent=t,o()},n)})}}function m(s){let t;if(t=typeof s=="string"?document.querySelector(s):s,!(t instanceof HTMLElement))return;const n=t.getAttribute("tabindex");t.setAttribute("tabindex","-1"),t.focus({preventScroll:!0}),n!==null&&t.setAttribute("tabindex",n)}class S extends g{constructor(t={}){super(),this.name="SwupA11yPlugin",this.requires={swup:">=4"},this.defaults={headingSelector:"h1",respectReducedMotion:!0,autofocus:!1,announcements:{visit:"Navigated to: {title}",url:"New page at {url}"}},this.options=void 0,this.announcer=void 0,this.announcementDelay=100,this.rootSelector="body",this.handleAnchorScroll=(n,{hash:o})=>{const r=this.swup.getAnchorElement(o);r instanceof HTMLElement&&m(r)},this.options=h({},this.defaults,t),this.announcer=new w}mount(){this.swup.hooks.create("content:announce"),this.swup.hooks.create("content:focus"),this.before("visit:start",this.prepareVisit),this.on("visit:start",this.markAsBusy),this.on("visit:end",this.unmarkAsBusy),this.on("visit:end",this.focusContent),this.on("visit:end",this.announceContent),this.on("scroll:anchor",this.handleAnchorScroll),this.before("visit:start",this.disableAnimations),this.before("link:self",this.disableAnimations),this.before("link:anchor",this.disableAnimations),this.swup.announce=this.announce.bind(this)}unmount(){this.swup.announce=void 0}async announce(t){await this.announcer.announce(t)}markAsBusy(){document.documentElement.setAttribute("aria-busy","true")}unmarkAsBusy(){document.documentElement.removeAttribute("aria-busy")}prepareVisit(t){t.a11y={announce:void 0,focus:this.rootSelector}}announceContent(t){this.swup.hooks.callSync("content:announce",t,void 0,n=>{n.a11y.announce===void 0&&(n.a11y.announce=this.getPageAnnouncement()),n.a11y.announce&&this.announcer.announce(n.a11y.announce,this.announcementDelay)})}focusContent(t){this.swup.hooks.callSync("content:focus",t,void 0,n=>{n.a11y.focus&&(this.options.autofocus&&(function(){const o=(function(){const r=document.querySelector("body [autofocus]");if(r&&!r.closest('[inert], [aria-disabled], [aria-hidden="true"]'))return r})();return!!o&&(o!==document.activeElement&&o.focus(),!0)})()===!0||m(n.a11y.focus))})}getPageAnnouncement(){const{headingSelector:t,announcements:n}=this.options;return(function({headingSelector:o="h1",announcements:r={}}){var i,e;const u=document.documentElement.lang||"*",{href:a,url:d,pathname:f}=y.fromUrl(window.location.href),l=(i=(e=r[u])!=null?e:r["*"])!=null?i:r;if(typeof l!="object")return;const c=document.querySelector(o);c||console.warn(`SwupA11yPlugin: No main heading (${o}) found on new page`);const v=c?.getAttribute("aria-label")||c?.textContent||document.title||p(l.url,{href:a,url:d,path:f});return p(l.visit,{title:v,href:a,url:d,path:f})})({headingSelector:t,announcements:n})}disableAnimations(t){this.options.respectReducedMotion&&window.matchMedia("(prefers-reduced-motion: reduce)").matches&&(t.animation.animate=!1,t.scroll.animate=!1)}}export{S as default}; diff --git a/website/blog/_astro/SwupHeadPlugin.DvOZNxAa.js b/website/blog/_astro/SwupHeadPlugin.DvOZNxAa.js deleted file mode 100644 index e278bf4..0000000 --- a/website/blog/_astro/SwupHeadPlugin.DvOZNxAa.js +++ /dev/null @@ -1 +0,0 @@ -import{e as $}from"./index.modern.D46RI4Wq.js";function w(){return w=Object.assign?Object.assign.bind():function(r){for(var n=1;nn.some(f=>f instanceof RegExp?f.test(i):i===f)):t}function j(r){return r.matches("link[rel=stylesheet][href]")}class B extends ${constructor(n={}){var t;super(),t=this,this.name="SwupHeadPlugin",this.requires={swup:">=4.6"},this.defaults={persistTags:!1,persistAssets:!1,awaitAssets:!1,attributes:["lang","dir"],timeout:3e3},this.options=void 0,this.updateHead=async function(i,{page:{}}){const{awaitAssets:f,attributes:y,timeout:H}=t.options,T=i.to.document,{removed:E,added:b}=(function(s,m,{shouldPersist:c=()=>!1}={}){const a=Array.from(s.children),o=Array.from(m.children),d=(h=a,o.reduce((e,u,g)=>(h.some(v=>P(u,v))||e.push({el:u,index:g}),e),[]));var h;const p=(function(e,u){return e.reduce((g,v)=>(u.some(O=>P(v,O))||g.push({el:v}),g),[])})(a,o);p.reverse().filter(({el:e})=>A(e)).filter(({el:e})=>!c(e)).forEach(({el:e})=>s.removeChild(e));const l=d.filter(({el:e})=>A(e)).map(e=>{let u=e.el.cloneNode(!0);return s.insertBefore(u,s.children[(e.index||0)+1]||null),w({},e,{el:u})});return{removed:p.map(({el:e})=>e),added:l.map(({el:e})=>e)}})(document.head,T.head,{shouldPersist:s=>t.isPersistentTag(s)});if(t.swup.log(`Removed ${E.length} / added ${b.length} tags in head`),y!=null&&y.length&&(function(s,m,c=[]){const a=new Set;for(const{name:o,value:d}of x(m,c))s.setAttribute(o,d),a.add(o);for(const{name:o}of x(s,c))a.has(o)||s.removeAttribute(o)})(document.documentElement,T.documentElement,y),f){const s=(function(m,c=0){return m.filter(j).map(a=>(function(o,d=0){let h;const p=l=>{o.sheet?l():h=setTimeout(()=>p(l),10)};return new Promise(l=>{p(()=>l(o)),d>0&&setTimeout(()=>{h&&clearTimeout(h),l(o)},d)})})(a,c))})(b,H);s.length&&(t.swup.log(`Waiting for ${s.length} assets to load`),await Promise.all(s))}},this.options=w({},this.defaults,n),this.options.persistAssets&&!this.options.persistTags&&(this.options.persistTags="link[rel=stylesheet], script[src], style")}mount(){this.before("content:replace",this.updateHead)}isPersistentTag(n){const{persistTags:t}=this.options;return typeof t=="function"?t(n):typeof t=="string"&&t.length>0?n.matches(t):!!t}}export{B as default}; diff --git a/website/blog/_astro/SwupScriptsPlugin.DeeT9ppa.js b/website/blog/_astro/SwupScriptsPlugin.DeeT9ppa.js deleted file mode 100644 index 765fa8d..0000000 --- a/website/blog/_astro/SwupScriptsPlugin.DeeT9ppa.js +++ /dev/null @@ -1 +0,0 @@ -import{e as a}from"./index.modern.D46RI4Wq.js";function o(){return o=Object.assign?Object.assign.bind():function(n){for(var t=1;t=4"},this.defaults={head:!0,body:!0,optin:!1},this.options=void 0,this.options=o({},this.defaults,t)}mount(){this.on("content:replace",this.runScripts)}runScripts(){const{head:t,body:e,optin:r}=this.options,s=this.getScope({head:t,body:e});if(!s)return;const i=Array.from(s.querySelectorAll(r?"script[data-swup-reload-script]":"script:not([data-swup-ignore-script])"));i.forEach(u=>this.runScript(u)),this.swup.log(`Executed ${i.length} scripts.`)}runScript(t){const e=document.createElement("script");for(const{name:r,value:s}of t.attributes)e.setAttribute(r,s);return e.textContent=t.textContent,t.replaceWith(e),e}getScope({head:t,body:e}){return t&&e?document:t?document.head:e?document.body:null}}export{p as default}; diff --git a/website/blog/_astro/TOC.astro_astro_type_script_index_0_lang.CGKGUlSz.js b/website/blog/_astro/TOC.astro_astro_type_script_index_0_lang.CGKGUlSz.js deleted file mode 100644 index 1a27439..0000000 --- a/website/blog/_astro/TOC.astro_astro_type_script_index_0_lang.CGKGUlSz.js +++ /dev/null @@ -1,6 +0,0 @@ -class l extends HTMLElement{tocEl=null;visibleClass="visible";observer;anchorNavTarget=null;headingIdxMap=new Map;headings=[];sections=[];tocEntries=[];active=[];activeIndicator=null;constructor(){super(),this.observer=new IntersectionObserver(this.markVisibleSection,{threshold:0})}markVisibleSection=t=>{t.forEach(i=>{const e=i.target.children[0]?.getAttribute("id"),s=e?this.headingIdxMap.get(e):void 0;s!=null&&(this.active[s]=i.isIntersecting),i.isIntersecting&&this.anchorNavTarget==i.target.firstChild&&(this.anchorNavTarget=null)}),this.active.includes(!0)||this.fallback(),this.update()};toggleActiveHeading=()=>{let t=this.active.length-1,i=this.active.length-1,e=-1;for(;t>=0&&!this.active[t];)this.tocEntries[t].classList.remove(this.visibleClass),t--;for(;t>=0&&this.active[t];)this.tocEntries[t].classList.add(this.visibleClass),i=Math.min(i,t),e=Math.max(e,t),t--;for(;t>=0;)this.tocEntries[t].classList.remove(this.visibleClass),t--;if(i>e)this.activeIndicator?.setAttribute("style","opacity: 0");else{let s=this.tocEl?.getBoundingClientRect().top||0,o=this.tocEl?.scrollTop||0,r=this.tocEntries[i].getBoundingClientRect().top-s+o,n=this.tocEntries[e].getBoundingClientRect().bottom-s+o;this.activeIndicator?.setAttribute("style",`top: ${r}px; height: ${n-r}px`)}};scrollToActiveHeading=()=>{if(this.anchorNavTarget||!this.tocEl)return;const t=document.querySelectorAll(`#toc .${this.visibleClass}`);if(!t.length)return;const i=t[0],e=t[t.length-1],s=this.tocEl.clientHeight;let o;e.getBoundingClientRect().bottom-i.getBoundingClientRect().top<.9*s?o=i.offsetTop-32:o=e.offsetTop-s*.8,this.tocEl.scrollTo({top:o,left:0,behavior:"smooth"})};update=()=>{requestAnimationFrame(()=>{this.toggleActiveHeading(),this.scrollToActiveHeading()})};fallback=()=>{if(this.sections.length)for(let t=0;twindow.innerHeight)this.markActiveHeading(t);else if(i>window.innerHeight)break}};markActiveHeading=t=>{this.active[t]=!0};handleAnchorClick=t=>{const i=t.composedPath().find(e=>e instanceof HTMLAnchorElement);if(i){t.preventDefault();const e=decodeURIComponent(i.hash?.substring(1)),s=document.getElementById(e);if(s){const n=s.getBoundingClientRect().top+window.pageYOffset-80;window.scrollTo({top:n,behavior:"smooth"})}const o=this.headingIdxMap.get(e);o!==void 0?this.anchorNavTarget=this.headings[o]:this.anchorNavTarget=null}};isInRange(t,i,e){return i{this.init()},{once:!0}):(console.debug("Animation element not found, initializing directly"),setTimeout(()=>this.init(),100))}init(){if(this.regenerateTOC(),this.tocEl=this,this.tocEl.addEventListener("click",this.handleAnchorClick,{capture:!0}),this.activeIndicator=document.getElementById("active-indicator"),this.tocEntries=Array.from(this.querySelectorAll("a[href^='#']")),this.tocEntries.length!==0){this.sections=new Array(this.tocEntries.length),this.headings=new Array(this.tocEntries.length);for(let t=0;tthis.observer.observe(t)),this.fallback(),this.update()}}regenerateTOC(){if(!(window.location.pathname.includes("/posts/")||document.querySelector(".custom-md, .markdown-content")!==null)){this.innerHTML="";return}const i=Array.from(document.querySelectorAll("h1, h2, h3, h4, h5, h6")).filter(n=>n.id).map(n=>({depth:parseInt(n.tagName.substring(1)),slug:n.id,text:n.textContent||""}));if(i.length===0){this.innerHTML="";return}const e=Math.min(...i.map(n=>n.depth)),s=3;let o=1;const r=i.filter(n=>n.depth{const c=n.depth===e?"":n.depth===e+1?"ml-4":"ml-8",a=n.depth===e?o++:n.depth===e+1?'
':'
';return` -
- ${a} -
-
${n.text}
-
`}).join("");this.innerHTML=r+'
'}disconnectedCallback(){this.sections.forEach(t=>this.observer.unobserve(t)),this.observer.disconnect(),this.tocEl?.removeEventListener("click",this.handleAnchorClick)}}customElements.get("table-of-contents")||customElements.define("table-of-contents",l); diff --git a/website/blog/_astro/TranslateButton.gpbH5i1G.js b/website/blog/_astro/TranslateButton.gpbH5i1G.js deleted file mode 100644 index 8b618b0..0000000 --- a/website/blog/_astro/TranslateButton.gpbH5i1G.js +++ /dev/null @@ -1 +0,0 @@ -import{o as G,a as R,i as W}from"./lifecycle.MLiOCzKC.js";import{ap as H,aq as J,a7 as K,u as Q,a8 as U,ar as V,as as X,c as Z,f as aa,a as F,p as ea,b as ta,s as L,d as D,h as p,r as d,i as b,g as a,t as na,e as T}from"./template.CyUWgh-J.js";import{s as j}from"./render.C4NccAY7.js";import{i as C}from"./functions.LP-DBi81.js";import{e as ia,i as ra}from"./each.DMYtlFB3.js";import{e as S}from"./utils.DonxBMOE.js";import{a as B}from"./props.h8jPqBEd.js";import{I as sa}from"./Icon.DAqWeDJZ.js";import{s as oa}from"./config.B4FKKqOZ.js";/* empty css */function I(e,l){return e===l||e?.[X]===l}function la(e={},l,t,n){var c=H.r,x=U;return J(()=>{var u,r;return K(()=>{u=r,r=[],Q(()=>{e!==t(...r)&&(l(e,...r),u&&I(t(...u),e)&&l(null,...u))})}),()=>{let s=x;for(;s!==c&&s.parent!==null&&s.parent.f&V;)s=s.parent;const v=()=>{r&&I(t(...r),e)&&l(null,...r)},g=s.teardown;s.teardown=()=>{v(),g?.()}}}),e}const ca={zh_CN:"chinese_simplified",zh_TW:"chinese_traditional",en:"english",ja:"japanese",ko:"korean",es:"spanish",th:"thai",vi:"vietnamese",tr:"turkish",id:"indonesian",fr:"french",de:"german",ru:"russian",ar:"arabic"};function ua(e){return ca[e]}var da=T('✓'),fa=T(''),pa=T('
选择语言 / Select Language
');function Ea(e,l){ta(l,!1);let t=!1,n=D(),c=D("");const x=[{code:"chinese_simplified",name:"简体中文",icon:"🇨🇳"},{code:"chinese_traditional",name:"繁體中文",icon:"🇹🇼"},{code:"english",name:"English",icon:"🇺🇸"},{code:"japanese",name:"日本語",icon:"🇯🇵"},{code:"korean",name:"한국어",icon:"🇰🇷"},{code:"french",name:"Français",icon:"🇫🇷"},{code:"german",name:"Deutsch",icon:"🇩🇪"},{code:"spanish",name:"Español",icon:"🇪🇸"},{code:"russian",name:"Русский",icon:"🇷🇺"},{code:"arabic",name:"العربية",icon:"🇸🇦"}],u=ua(oa.lang);function r(){t=!t,a(n)&&a(n).classList.toggle("float-panel-closed",!t)}async function s(o){try{if(typeof window.loadTranslateScript=="function"&&await window.loadTranslateScript(),typeof window.translate<"u"&&window.translate.language&&typeof window.translate.language.getLocal=="function"){const i=window.translate.language.getLocal();o==="chinese_simplified"&&i==="chinese_simplified"&&(typeof window.translate.reset=="function"&&window.translate.reset(),window.translate.language&&(window.translate.language.translateLocal=!0)),window.translate.to=o,typeof window.translate.execute=="function"&&window.translate.execute()}else console.warn("translate.js is not fully loaded or language API is not available");L(c,o)}catch(i){console.error("Failed to load or execute translation:",i)}t=!1,a(n)&&a(n).classList.add("float-panel-closed")}function v(o){const i=o.target;!t||!a(n)||!a(n).contains(i)&&!i.closest("#translate-switch")&&(t=!1,a(n).classList.add("float-panel-closed"))}G(()=>{document.addEventListener("click",v),L(c,u),typeof window.translate<"u"&&(window.translate.to=u)}),R(()=>{document.removeEventListener("click",v)}),W();var g=Z(),O=aa(g);{var z=o=>{var i=pa(),w=p(i),M=p(w);sa(M,{icon:"material-symbols:translate",class:"text-[1.25rem] transition text-black/75 dark:text-white/75 hover:text-[var(--primary)]"}),d(w);var _=b(w,2),A=b(p(_),2);ia(A,5,()=>x,ra,(y,f)=>{var m=fa(),E=p(m),P=p(E,!0);d(E);var h=b(E,2),N=p(h,!0);d(h);var Y=b(h,2);{var $=k=>{var q=da();F(k,q)};C(Y,k=>{a(c)===a(f).code&&k($)})}d(m),na(()=>{B(m,1,`flex items-center gap-3 p-2 rounded-lg hover:bg-[var(--btn-plain-bg-hover)] transition-colors text-left w-full ${a(c)===a(f).code?"bg-[var(--btn-plain-bg-hover)] border-1 border-[var(--primary)]":""}`),j(P,a(f).icon),B(h,1,`text-sm transition text-black/75 dark:text-white/75 ${a(c)===a(f).code?"font-medium text-[var(--primary)]":""}`),j(N,a(f).name)}),S("click",m,()=>s(a(f).code)),F(y,m)}),d(A),d(_),la(_,y=>L(n,y),()=>a(n)),d(i),S("click",w,r),F(o,i)};C(O,o=>{o(z)})}F(e,g),ea()}export{Ea as default}; diff --git a/website/blog/_astro/_page_.BQ6XwRvy.css b/website/blog/_astro/_page_.BQ6XwRvy.css deleted file mode 100644 index 075fa43..0000000 --- a/website/blog/_astro/_page_.BQ6XwRvy.css +++ /dev/null @@ -1 +0,0 @@ -.back-to-top-wrapper[data-astro-cid-eymb5ayk]{width:3.75rem;height:3.75rem;position:absolute;right:0;top:0;pointer-events:none}.back-to-top-btn[data-astro-cid-eymb5ayk]{color:var(--primary);font-size:2.25rem;font-weight:700;border:none;position:fixed;bottom:10rem;opacity:1;cursor:pointer;transform:translate(5rem);pointer-events:auto}.back-to-top-btn[data-astro-cid-eymb5ayk] i[data-astro-cid-eymb5ayk]{font-size:1.75rem}.back-to-top-btn[data-astro-cid-eymb5ayk].hide{transform:translate(5rem) scale(.9);opacity:0;pointer-events:none}.back-to-top-btn[data-astro-cid-eymb5ayk]:active{transform:translate(5rem) scale(.9)}.dropdown-container[data-astro-cid-qou34bit]{position:relative}.dropdown-menu[data-astro-cid-qou34bit]{pointer-events:none;visibility:hidden;position:absolute;top:100%;left:0;z-index:50;--tw-translate-y: -8px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));padding-top:.5rem;opacity:0;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}.dropdown-container[data-astro-cid-qou34bit]:hover .dropdown-menu[data-astro-cid-qou34bit],.dropdown-container[data-astro-cid-qou34bit]:focus-within .dropdown-menu[data-astro-cid-qou34bit]{pointer-events:auto;visibility:visible;--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));opacity:1}.dropdown-container[data-astro-cid-qou34bit]:hover .dropdown-arrow[data-astro-cid-qou34bit],.dropdown-container[data-astro-cid-qou34bit]:focus-within .dropdown-arrow[data-astro-cid-qou34bit]{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dropdown-content[data-astro-cid-qou34bit]{min-width:12rem;border-radius:var(--radius-large);border-width:1px;border-color:#0000000d;background-color:var(--float-panel-bg);padding-top:.5rem;padding-bottom:.5rem;--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dropdown-content[data-astro-cid-qou34bit]:is(.dark *){border-color:#ffffff1a;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dropdown-item[data-astro-cid-qou34bit]{display:flex;align-items:center;justify-content:space-between;padding:.625rem 1rem;font-weight:500;color:#000000bf;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.dropdown-item[data-astro-cid-qou34bit]:hover{background-color:var(--btn-plain-bg-hover);color:var(--primary)}.dropdown-item[data-astro-cid-qou34bit]:is(.dark *){color:#ffffffbf}.dropdown-item[data-astro-cid-qou34bit]:first-child{border-top-left-radius:calc(var(--radius-large) - .5rem);border-top-right-radius:calc(var(--radius-large) - .5rem)}.dropdown-item[data-astro-cid-qou34bit]:last-child{border-bottom-right-radius:calc(var(--radius-large) - .5rem);border-bottom-left-radius:calc(var(--radius-large) - .5rem)}@media(max-width:768px){.dropdown-container[data-astro-cid-qou34bit]{display:none}}.mobile-submenu[data-astro-cid-h5lvqo6o]{max-height:0px;overflow:hidden;transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mobile-dropdown[data-astro-cid-h5lvqo6o][data-expanded=true] .mobile-submenu[data-astro-cid-h5lvqo6o]{max-height:24rem}.mobile-dropdown[data-astro-cid-h5lvqo6o][data-expanded=true] .mobile-dropdown-arrow[data-astro-cid-h5lvqo6o]{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@media(max-width:768px){#sidebar[data-astro-cid-gfmxq3pg]{display:var(--sidebar-mobile-display, block)}}@media(min-width:769px)and (max-width:1024px){#sidebar[data-astro-cid-gfmxq3pg]{display:var(--sidebar-tablet-display, block)}}@media(min-width:1025px){#sidebar[data-astro-cid-gfmxq3pg]{display:var(--sidebar-desktop-display, block)}}.typewriter[data-astro-cid-4iv2rnoh]{position:relative}.typewriter[data-astro-cid-4iv2rnoh]:after{content:"|";animation:blink 1s infinite;margin-left:2px}@keyframes blink{0%,50%{opacity:1}51%,to{opacity:0}}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-cyrillic-ext-400-normal.qHufge6k.woff2) format("woff2"),url(/blog/_astro/roboto-cyrillic-ext-400-normal.CaK1767H.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-cyrillic-400-normal.CBPI_iaY.woff2) format("woff2"),url(/blog/_astro/roboto-cyrillic-400-normal.Bjg-1-sg.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAA5gABIAAAAAGsQAAA39AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhQbHhw0BmA/U1RBVF4AXgiBfgmfBhEMCoJ0gnQLFAABNgIkAyQEIAWEYgcgDIVOG3MZIxH2i7OyB/jrA24MgRr6HmlzCaM2go+1uUKrrwjEMmJDDee8Dlpr4LD+LsxoDHtdq5H/CxNGSDJrT+/U5u2uVjIEWQV0gAqsEod8Fwep4BDXSdkFJh8yft1FBMil99se9ONjNt7Um9rENUgrVOQlWCvXvPx/CRRhZlcXSHYmukAgXG1qXUHAbSnx3RSVErGy1NxVitTdOcJhUOMM8t5KgcvowHQSQDkAXJI6OYf3qca/T8Nx5V8ECeZsY4V8I35GFL5GVulKnf4A0lAfHz8/5/v2JG33MgQ1rhqQMKTkjOk5t7fNuTfp68vwtmPKOBnmqQGQEYT4Scgvv9AWUPfDt4fWOtddK5CE+23D2UGZOBKFIGtfFgcBsCMyBM00wY0VsftMmrdgWd6XEiRLmCYBAqd3Ldzl4vddzasRfW6uXhV1eJS3rhW0Cb77C95Au6EAylElA6CEfIy/gZoQQJoCGNtyRJMWLlYuRHzDhLnEENRkRxl0dAoAxFTFB0DHQSBo4ABCc8+SiHVUtdbRKKDjXNdKY0H/CnNHSgfDaOEkOBjYI1uFmEUtEmn3cPYwHK06BlVUwIoaNOVbCiwx/tB4Lbcl/aA7XSxvdQIGag3zX742zz5/yOYFH2cSCEt8CE2deGpHMH+eOOTNfzgOy6M/AXjE407sLR90SI95zdzkYdfQax31lrscCT7HQfdkVwIbBt102nYHPOCKCPu4Hntsc8anY0+4VxKfn3AWMfOYB2vNTkft3nd6yx5H3HCXR4MX6H/5ZqHDVUIH8u6p7Ap8Bmy0zf7J96iuFCFLpU591jO8u+bXedZNb/s0GI0eW+1zwgV3xzsQOF1y5PChg5s3bdywfnDAs66/r7enu6uzH/nm66++/OLzzz795OOPPvzg/euHV9PJOB8F/96777x9OXT24vzBoN/tvPXmG6+3W81GvfbK86WV5XIabeEzPpusVMpJtEZSd/VYJIU0UBFvg5WGYHStbvdsVlVaO8UaBgSydFoYSyXSdRWcVAaQYq7V7nO7O7SUSZlDdL0BRNLUbuNlaTSYmQYLzFz7AgsTwVqUcKXFJFdkAibiHUe44CYbKlLhzor52YWVxjEqDGu2E30karJWHfizq4H9SinVwQwVgcnIz80vuCAXGVrofuoaFZPhAMli/QId/rb8Qh56TgQJHnWsDANdWMFa9ixf/apkGGtyrjCfiG5fiHWlHJmcxhHpTXY00pvcoS0CE+g3efYXpmbO/KmLI/kcA3rKsB0KBLArXZKlabtnByc4VRjylMf2tPtMzgsSeCoItw5JmnlJZfZoZC2WFqUBhyXSWtpmxlqaHbjILRyV4JaPgojeudvxyvzx0vHy8drM+oyKBOZfjsv+RZJYVPKrXa2nFHhSvQkF2Tv0c1VBgg0/lqUH2MK7EZO1hbluyzd+nQetWNE5tL/aZV2pHKrUaXSaSjmLbGR4aOf8aDAQQJO8UwwCztQnwehb+oleaefe21UrZQImZHmi2MXQe9KYYaXhWL7wkjcy0Gh4jebS7oqBo5lzzVMZCDhuwpH8nDwqvEknUqkmkoqeB45PQioy98VI3ovpYXIYyVlYg1VPTmHTp9g2R8mRLUEdA0rZ+hfOOKMnr6WSR0QwOvZKTV2AnsPgAKFPVRRyqrV7Mq2UKYsYmWql3O5G4y3TubQoUGcSb5Vmzb0U8nBeoqoVa0EfO6JadVyRjMR3HHKvcjInRDITd5zPgcYwuhAgYM5pMBzyvctgaMX+4DH3bTSOpZzyoCh3Sly5nSdUK+XUQbLO/Jokg5qZ6Qb5NFi80JOR5xHwwND9bYNXjqfKhA+4pVLkUzRTlnA2VlHqhhHjpmc1jR3l8WVgYicuDEyTCRwKxkngHiRDeOA6gPiuQs1DVUu7eAjcFyEgCV9Do0FhtTNkVwvwjEj0Eu9yRgiw6lBnJYl58gAGyPGHoNVanuxIaQfBXpJRlzsQK2rbH2uN2KswgRZWg6FJUXg65B15z8C0rFVsKRWahgFGi63qtAnDlkNLJkhufYDtzJkIdWHFoyesEYJrZ1vqHVJ/pxYwt0BevCy+dItyrSBGUAjJZhZXrNFwmED3Ol3diB+lnliIJM5QGWtH4kn2JONNKpiMMk+ey4hAKPYGCrYkWPQdyb/FsZQIr5Wfe8OaSlSj7i4HhZAhVNOV3Z7liR0LhAyRrEGsMbF48UVo3g13G4ZGGpcmYGaRRaZVD0qoyYCltwVkgEVoNrQQnRWAk5SbvhaMQCsJkwls4X3xUk12X0FBpKVyka0LdU7ZpGItk5QdLKBNWGsgSiWJUptUkCvKI7IMH3C/qRHYSJ1PWFvxPaAiMHnlvwSpEdCfBCNwehVVmI/PWxie08C5KmhNGXEJ8VrO1Gh6bFwzB2GLiW3TzWYkUNrqtVpv5GWz1leMX7BgtTAft544yxthx3I8mply7kE11HljTn9hFTdE+apS3t3HiFxarVkvKsJiiwdCrpHK9nmPLOu1VgjMVqO0xkkNSoghlQC6kWYmJDpo1IFBxVKMf2GSBnn7CqGFI1OLoNSCdJ3S+ppUslT68ddzuGOBvtqnySBgsSxXJ9oNAws7r+bcxZWo19GtmjkiKgRk8RuUVGsqzdUI3YUDCZJy5Da+xLkHvEsKQdO2RFmcWJF2g0tPb7aTqi2IrDcjnVuePM3rQLzLWyUWb8xSY+cWF74DK3ageqqpsM+sXgNM1GsNKq7BwDbGt3VdHVZJLun138MbIUsFqRUl3Uxhmr+75JCGwEYfXJJESqC3Uj27oWop+0fVXH42YQM7JcmVv6gCLOTrIahlgfRl77FUCSlH6vca2Dk172AllcCxa1OXb1axskwVNQ28ZCvAxol39TuAwuxbiJHsUh4QWwGeD/SZSlm8SzHsBpcwev0ke7p2PU8IOSVmWQ1sZh+Gg1ZZBsES96Hgp//XnR0IGMdWdgCOGfcktLUPrCPdhj9DqMnU1e9bDuxPZC3zP1hsUUWhTln9+4RGMc5HuM3uLf+kDTAoEqO+ia4DhEk5KPNloweqwCUWOiPeQKhQzB+8uE+OoN3bJ75Of2i5ROl+sn8I5PPRxRNYgoDdVzsOdCnMH6LuIh+gnoYGolNpi46Kfgd0xUYzMkIzfC4TJCkxw3u4eGmpBbG1GVnah+BxmLsyeGUUD6t2+bAhUSQjDtIFPvyttkeowIm/01SIodPbVnoF4I/hM068tKsRx1DDz22OCICgTjsm23hGPFBcn4EQ/Q3iS6+FeS3KWnfND76iVJJH7hzym4ZdQPucSIYpTT+5D+jKICz1h6VIClizgEuPrJOAQbwKwYe97+qKAoFBg2YigaiRBU4wxwonj7Of4w/Hjo7pJAZgYIBpxpcJD5fWHviTrSvkAM9deV1PZ+x2o4/bA8/v7bet3nff/ZBo4KP33rNte+edD/Ie913LMe7bWwfA886Z+55Fe6jQhvwd2e7yjDzN8qkHfBO9E2OghOj9px+G2rqZ8NgLRaPCWqe2cVBaS5fPesmi89n8yD3vlm4csBnH73Hy82CHPHbsXmdg41/x0Xtz2KPm7mDmc9Wb984vLtg9v2bzpOcGT+snPV+3Zff8gpI986u2ZDwfEjVyQ1DL7KfCPp3R9b/z0spF42qPL5riTCzcGeyH0ZQFIBVyKGjCwlCn+bOSpbxrWMbI2CDeLC3NcJTpQRmpafcqip/KmIqUMSXwlfSU1LT7OEsOAoKXcEwyQQA4f29LdFxGacD0f4IxGgDg6f9WDwDfPCdcg36vhzS7AC2nrh6yA8pzCgf5O9IQ9WLh21FlOP2XxpQBdETD0FgW3Jrk/pCJJKYTYAiU4iiwbwPawEAA/HAWBwkLgDsDf58l2IllGfzxd5Yj3ZNZgVgXswpG87DkMlXd/TFR8hI0ClaMdNkxsCPSGpuxr5Oor47S29sDi7Uqt1q9SrerVq9WnVYruDVbg0frUq9KK05s4UYtpkrZ2Z2Hq61Vwx35rbIIyi1NJ8sxtXJirvBWKychXI1zm57LFXxb5+YKXS/F6DIqw6nSTDCtc/q5f7qJ22D0JJdZaOV+6AtN05uEJKn13FZxFyNtIevBabvR5aFQXV+NOKsbtwZWV/JUZ2uzl3a37cC6sZar1qqnCrepkKyyqTUYjF13w7O22qbcwq3f3BpVWXNsusXak8fhiIZmNqDKZTeN/vXn753J1+Odz+9n+Hj6eX95e3vkdbP66ub5PuPpmuPx4mHn/tTcJ7fHLjdH7qw+/vdeHVW5PIJysXI+czZrNQsnE8cjR6OqYjzjoGe//1c6sDsoihvbla3CZtZcmfVsc5FYjayEjCyHqiy5XRYdC06V5Znz/1ZYZkxZpo1qqWHSrDJhyjKuGZOMykdGFMPqkSEYFIrZgv6Ovig9XUqf3tUsnS12O62PtLfO0daaktYWRUZjPw31j9TVJimX+smHTF7KFiTbFAlt27Bb0uY9ta1DJBM9kmgP+rcJViUeIOYn6rdSTSGM2MLIzPDYwuizHfG7ExY1M/xiQUhasDMoLdAZ7Ap0+WXanUqmcNpdwpUgSgULEOvEb4IHlPg7bZlWp5opnZQGZ+6yuqRrnaQUuVK6JZ8lS+U6yeFqQSlw+w23ZGpOnsmcmou5ElgpYwFsHfuNcW4YCt1Pu315jqX3q+biUp8lq9BHW3yjcnNvamQX+OQWH5zbwvw7iHa6Nu7YgbjZUt/u3Pw7Oa7LuO5gbG52/h2CCyItrXBwlI4bfaUNjjMFiZSwdWmjh6JLSzjgJl/CJYvSSy/RhZt0NurfVCQAAAA=) format("woff2"),url(data:font/woff;base64,d09GRgABAAAAAAYYAA8AAAAABvAAAQABAAAAAAAAAAAAAAAAAAAAAAAAAABHREVGAAABWAAAABQAAAAUAA8ACEdQT1MAAAFsAAAAHgAAAB5EdEx1R1NVQgAAAYwAAAA0AAAANJMNggJPUy8yAAABwAAAAGAAAABgl4LQ2VNUQVQAAAIgAAAAXgAAAF5fnUM1Y21hcAAAAoAAAABUAAAAVADNH/FnYXNwAAAC1AAAAAwAAAAMAAgAGWdseWYAAALgAAABNgAAATZng0GjaGVhZAAABBgAAAA2AAAANgz5sE5oaGVhAAAEUAAAACQAAAAkCroNqGhtdHgAAAR0AAAAIAAAACAX6f/DbG9jYQAABJQAAAASAAAAEgGEAVltYXhwAAAEqAAAACAAAAAgACgBIW5hbWUAAATIAAABMAAAAmI2jl6RcG9zdAAABfgAAAAgAAAAIP9tAGQAAQAAAAwAAAAAAAAAAQAHAAEAAQABAAAACgAcABwAAURGTFQACAAEAAAAAP//AAAAAAAAAAEAAAAKADIAMgAEREZMVAAeY3lybAAaZ3JlawAabGF0bgAaAAAAAAAEAAAAAP//AAAAAAAEBIcBkAAFAAAFmgUzAAABHwWaBTMAAAPRAGYCAAAAAgAAAAAAAAAAAOAAAv9QACBbAAAAIAAAAABHT09HAEAAAB9NBgD+AABmB5oCACAAAZ8AAAAABDoFsAAAACAAAwABAAEACAADAAAAFAADAAAALAACd2R0aAElAAB3Z2h0ASgAAWl0YWwBMgACAAYAEgAiAAEAAAACAScAZAAAAAMAAQACASwBkAAAArwAAAADAAIAAgEoAAAAAAABAAAAAAAAAAIAAAADAAAAFAADAAEAAAAUAAQAQAAAAAwACAACAAQAAAANACAAoB9N//8AAAAAAA0AIACgH03//wAB//X/4/9m4LoAAQAAAAAAAAAAAAAAAAABAAIACAAI//8ADwAFAGQAAAMoBbAAAwAGAAkADAAPAAABESERBQEBJQkDIQkCAyj9PAKO/u8BEf2oAQ3+8wEq/v4CA/39AQIBAQWw+lAFsFT9fP18DAJ4Anj9RP2iBUT9ogJeAAACAHf/7AUKBcQAFQArAAABFRQCBgYjIiYmAjU1NBI2NjMyFhYSAzU0LgIjIg4CFRUUHgIzMj4CBQpSmteFgdedVlWc14GF15tTvzVmk11akWc4OGmRWl6SZTQDBlyk/vy2YGC2AQSkXKQBA7dgYLf+/f8AXoLIiEZGiMiCXoPJiUZGickAAAIAcARxAskF1wAFAA8AAAE1EzMVAyU1MxUUFhcHJiYBknTD3/6GpyoqSVZcBIQRAUIV/sL+VU9IaC06LY////54/+wFUAXWACYABEYAAAcABf4I//8AAAABAAAAAwPX2FkjvF8PPPUAGwgAAAAAAMTwES4AAAAA5Y1QA/oa/dUJMQhzAAAACQACAAAAAAAAAAEAAAds/gwAAAlK+hr+SgkxCAAAAAAAAAAAAAAAAAAAAAAIA4wAZAAAAAAB/AAAAfwAAAWBAHcDIQBwAfwAAAXH/ngAAAAtAC0ALQAtAHAAjwCPAJsAAAABAAAACACpABUAdgAHAAEAAAAAAAAAAAAAAAAAAwABeJx9kD1Ow0AQRp+TgAQyrikoXPATJDDECIpQIYqIBhBCpA6OcYIgRrZT0HEWCg7AETgTB+DzeiEmSGhk75tvZmdnBljhlSZOawl4dzzLDq7TsNzA49Nyk5APyy3WeLO8wCYvlhelDy17HBFU7GywzLrlLVxWLbfFruWd2VtOKBXOKBjwwJiIPrHOhJG0c1IyHk2sL3UobWQiBU/kdNmTpeKYCXeiiSJVnVLJ9Q9MjYQrnbf6Cn278mJpU+UOFL2Rlyl7bCr4HOjWPh0OOZYXikPNWK/gz1Wo3+hxIeuJ/ntz3ptlnpqJnqV+76HqoSPzuZYSm/fr3VwqO+Vekcjkn6hyuavUzOXT/rO1RNXLjKmqBLqVas+lmsoSdRX/7DOXnv2aJDJd52ZjEdtfVntaWwADAAAAAAAA/2oAZAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("woff");unicode-range:U+1F00-1FFF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-greek-400-normal.ai2Z1K3C.woff2) format("woff2"),url(/blog/_astro/roboto-greek-400-normal.Bb5mj_fZ.woff) format("woff");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-math-400-normal.BEFej5gc.woff2) format("woff2"),url(/blog/_astro/roboto-math-400-normal.C9RxBKAh.woff) format("woff");unicode-range:U+0302-0303,U+0305,U+0307-0308,U+0310,U+0312,U+0315,U+031A,U+0326-0327,U+032C,U+032F-0330,U+0332-0333,U+0338,U+033A,U+0346,U+034D,U+0391-03A1,U+03A3-03A9,U+03B1-03C9,U+03D1,U+03D5-03D6,U+03F0-03F1,U+03F4-03F5,U+2016-2017,U+2034-2038,U+203C,U+2040,U+2043,U+2047,U+2050,U+2057,U+205F,U+2070-2071,U+2074-208E,U+2090-209C,U+20D0-20DC,U+20E1,U+20E5-20EF,U+2100-2112,U+2114-2115,U+2117-2121,U+2123-214F,U+2190,U+2192,U+2194-21AE,U+21B0-21E5,U+21F1-21F2,U+21F4-2211,U+2213-2214,U+2216-22FF,U+2308-230B,U+2310,U+2319,U+231C-2321,U+2336-237A,U+237C,U+2395,U+239B-23B7,U+23D0,U+23DC-23E1,U+2474-2475,U+25AF,U+25B3,U+25B7,U+25BD,U+25C1,U+25CA,U+25CC,U+25FB,U+266D-266F,U+27C0-27FF,U+2900-2AFF,U+2B0E-2B11,U+2B30-2B4C,U+2BFE,U+3030,U+FF5B,U+FF5D,U+1D400-1D7FF,U+1EE00-1EEFF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-symbols-400-normal.CB1Ce4Gk.woff2) format("woff2"),url(/blog/_astro/roboto-symbols-400-normal.DLYbZahX.woff) format("woff");unicode-range:U+0001-000C,U+000E-001F,U+007F-009F,U+20DD-20E0,U+20E2-20E4,U+2150-218F,U+2190,U+2192,U+2194-2199,U+21AF,U+21E6-21F0,U+21F3,U+2218-2219,U+2299,U+22C4-22C6,U+2300-243F,U+2440-244A,U+2460-24FF,U+25A0-27BF,U+2800-28FF,U+2921-2922,U+2981,U+29BF,U+29EB,U+2B00-2BFF,U+4DC0-4DFF,U+FFF9-FFFB,U+10140-1018E,U+10190-1019C,U+101A0,U+101D0-101FD,U+102E0-102FB,U+10E60-10E7E,U+1D2C0-1D2D3,U+1D2E0-1D37F,U+1F000-1F0FF,U+1F100-1F1AD,U+1F1E6-1F1FF,U+1F30D-1F30F,U+1F315,U+1F31C,U+1F31E,U+1F320-1F32C,U+1F336,U+1F378,U+1F37D,U+1F382,U+1F393-1F39F,U+1F3A7-1F3A8,U+1F3AC-1F3AF,U+1F3C2,U+1F3C4-1F3C6,U+1F3CA-1F3CE,U+1F3D4-1F3E0,U+1F3ED,U+1F3F1-1F3F3,U+1F3F5-1F3F7,U+1F408,U+1F415,U+1F41F,U+1F426,U+1F43F,U+1F441-1F442,U+1F444,U+1F446-1F449,U+1F44C-1F44E,U+1F453,U+1F46A,U+1F47D,U+1F4A3,U+1F4B0,U+1F4B3,U+1F4B9,U+1F4BB,U+1F4BF,U+1F4C8-1F4CB,U+1F4D6,U+1F4DA,U+1F4DF,U+1F4E3-1F4E6,U+1F4EA-1F4ED,U+1F4F7,U+1F4F9-1F4FB,U+1F4FD-1F4FE,U+1F503,U+1F507-1F50B,U+1F50D,U+1F512-1F513,U+1F53E-1F54A,U+1F54F-1F5FA,U+1F610,U+1F650-1F67F,U+1F687,U+1F68D,U+1F691,U+1F694,U+1F698,U+1F6AD,U+1F6B2,U+1F6B9-1F6BA,U+1F6BC,U+1F6C6-1F6CF,U+1F6D3-1F6D7,U+1F6E0-1F6EA,U+1F6F0-1F6F3,U+1F6F7-1F6FC,U+1F700-1F7FF,U+1F800-1F80B,U+1F810-1F847,U+1F850-1F859,U+1F860-1F887,U+1F890-1F8AD,U+1F8B0-1F8BB,U+1F8C0-1F8C1,U+1F900-1F90B,U+1F93B,U+1F946,U+1F984,U+1F996,U+1F9E9,U+1FA00-1FA6F,U+1FA70-1FA7C,U+1FA80-1FA89,U+1FA8F-1FAC6,U+1FACE-1FADC,U+1FADF-1FAE9,U+1FAF0-1FAF8,U+1FB00-1FBFF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-vietnamese-400-normal.D2PTxGxD.woff2) format("woff2"),url(/blog/_astro/roboto-vietnamese-400-normal.DnpnVwnf.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-latin-ext-400-normal.C3tdtHj3.woff2) format("woff2"),url(/blog/_astro/roboto-latin-ext-400-normal.scX0fKtV.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:400;src:url(/blog/_astro/roboto-latin-400-normal.BqEyEoaF.woff2) format("woff2"),url(/blog/_astro/roboto-latin-400-normal.DyYNIH4P.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-cyrillic-ext-700-normal.DmFxo5wj.woff2) format("woff2"),url(/blog/_astro/roboto-cyrillic-ext-700-normal.CI7FH63F.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-cyrillic-700-normal.C2o7G-SM.woff2) format("woff2"),url(/blog/_astro/roboto-cyrillic-700-normal.DhZFXDSN.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(data:font/woff2;base64,d09GMgABAAAAAA5cABIAAAAAGqgAAA37AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhQbHhw0BmA/U1RBVFoAXgiBfgmfBhEMCoJ0gnQLFAABNgIkAyQEIAWESgcgDIVOG1cZIwPBxgEIZL0e4K8ObEPUOqx/RlhaxGdLcUECIUjZFAN1lOQYjjf+W38d3tVNMLC3IZYDS3uEJLPwPL1X/bmVqiSNpbOQsyCH6lmwF+qFNXik/97k+Dn9UAHwypCWBwBvW9aOKf2IloVnNTdjpsxHIc/q99s3gWr6ZjcjVpmLiGloZBpDSwxd86OJXugxOtaFfjcd2/zS9PVOKd5XtA2HxWwJUnXIDNGBab53KRcAQfJbRedYS7PumgdVp9IpPo7m/N5OkvZeDkEdVx0KSUqeMZnZbpvZTfrSPdz2mHKcHOYpckdsBMIHZiG//EJbQN2L7R89NuvUFUiC/3iN2Wn+2ILISBxf+yJAlMwKrjmyBcI0PLbI8JHjpzNKs+wXBACJu3Wtw5MaJ60szKZ+WmFKVjQue0ksV/AW5F5fW5nqEQyYE6Y7SBM8Z71JqgKgB/tEd7LvdNSkSaPwoMkEmwqKVOeEwkPOAuh+pgTwsBAEV3p4TayfrgNqeXIsXVrC8rT0mLRBMmJLsqUbimbUxsZCoaRNq5Rg66WzeoSGfLs1yTdQde1a8OGasbYybtc21/6V8DjXZEKLCzSQ44L/8Jvg4Iufv2sxr2yoZUqoCX3dbzwEv6ypiMG/HNfKsz8Dj/IEp/fhD3FUt/5s2coj3ESf6wRvU85x+YIj4Z1dlwgbucM5dnGYB7lOHQ5y065mJ+f5bMVp7tPEl064gJh9nIdq7R5O2GuX8Tb7Oc5tynlMXpT/9dtRHKsSNpAPz2ZPoYQNbGEnh3K+V/W0OkwmiRWsZRPD+2p+nRe4wzt8Jq1YzQ4OcprL3KN3U9Ufe/zY0SPbtm7ZvGnjhvh69LPP+/V83G/Xy/l0POx32816tVzM0zj0XdvUVVnkWZrEURj4nmNbpqFrqiJLIg96pSJFX18PDwQH9rh0irpWRtJQNfbirWELnIpPg0mB4C/Fz1cyHDjv1bGHD40h3Jj2llQZagVXlQa2muear3m+3AoNbXFAtMeGInk6H9fL0jIoyS1GhvPEG4wqJGd0ITTGsDyVCYwssS+Y4Nb5rkjhlY38NQeTgjKWBvYsB32muNqN4ib2r37Rp9U0hhJqq1Y7vyP/yK2EzFbgxaNOKtZhAGCfdUuDfyl/oAgvE8EG7xZiTSEndrThK+Fnn501ZU+qbfBkZvuG2Hc7RWm90rz+MKX49XfaVtqqFbwP0+Wj0g2JPS0t+IABz/NdgxIR3MKkal53V663Wl3ry724a2n9rcvtuED3XHjQF0oqqmrMbYWso0q64Us4uuSW4uU2jutW3etBlFDyqGamlN55NT9sfNcP+VFVSTUoFTKXjSc+JBASyqNSSSiIe1NXPyDxUv2OBg8IJRu+nDi9IF77DlCcqCycs1Ub321GKw6fMXd2eZRK0humMVSpXnaHbmdY1CDw0A78MigQIGujOiaBxdTXwl8L/5rovLpEB/Wfi8CIhA+OtdS8Z/lDTApcllxiDDbQaHgt4+bpysHCNPMoclloOJ7CmXxKEUtjSNdQMzJJy8tJ4isRK8pEEQv1y+plEcOJ/MPq0ENE9WpHvapeuTY4yyExX//CQx7SZ+8siXdE8Bdy5o6a4GX4nKBVzxWt9bzXz+puh4aFQRh0O/Nl8X8Ii7eCgkwkSwxo6wWmnK77Dbxjb9XXNx8MVCozJCt5nXJU+UMVKpmJVxzBifbwl9AgMOXUbLdyn2WzFYveeM9rKf5rW0I5OcrqbE728+pBt1M7qLpdXJNkUsZMt8jHYN/Wq3aRd8SLw4uPXs8CH5WFaHhmUuCebLGxPNyrCIZp5ixZiae9ct5YBiM5aJpT1hEsGFhpVZ9RyoID10Ws5Cx1/KxGcFKExiORDEn5cR6ZDtka2J6VEN+ReQ0/ZUQocMYwZpPk4jlBAfb4Q9CZHUqyc16h2Rs26oKBWN3ahcgNap/BBJmJh0KTsogvKCrFyMA48S52TIuOaYDRYqsWbcJw+FbIJptWb1jPnDVwZiJedmCPEH2Rag/Qfr6ixgxMBaQtwVZSjyZGBTmCIWxOUVy5/MDpAC/aDD0jeZRG5iHSuMUN2avMKPiTnLe2VdoOeefZmifCghhgcGLVzXtisz+xbyrhc+XTGNhTQyPq7iQ5hByhpiHRZ1Zl9kMQOgQ4jsgJZcFlUKthUV4QGODyQAITwWQ27UQwqYIAFX8sIAfsJZOtQHeWgcWSTGMt+MY7DesIahZj/VFT8dhRQZdspZnra/vsRaRhbQMvCiFwk9xgQalkUU6TanpFefHkIAdWXNAIbGQuplrXxJHQ0jh8qn+C1AhYr4WfGD7DtcETI4EfGRrVXdCuMZIS6rVdqdH06tt1B9XWgRvR02YUqnQ4ame/kZfN6mmcX/Nguw2e8J64ygfVrrDwfmbKuQcpkB7tJeNLq7glyqtNeXmMkXkr3rO/7AhH7ZsI04IltS9679lotkJgdgzVI65GMClHrAJqUiOrK4LMJhRUL+X4o9JqTz2+g79nUbr7l9iC9DzNzRu/JLakuP97Ti8EtN1zmhwCISf0bGJZYDCTi+kLegttNFrerZoYMdUSsvgFDcebyg0dBsZzwAabMAp9X5E8C4krBsHVEaBCQaxIZ8Ar7+h8J7Vn0Gh0TjvPPEWa18YSy1urLLg1S22UJ1z6DsJ4AsfTngr/bF0TwMg8u6i8m400Jo50XRPXSW70+u/hjZDjgK0dJz1sGwS/u5SQjsBGP1ySRWqgr3Ii61QjyPFWo1CdTdggSqC48tdNQIhiFwydrJD+7CPWKilJkf5aG7mQvqgIkxpYeOrTkE92sMT6iQa7dA2olZa4/h9AadsnNL86pLwoayM+CKwN3Y4lrkRre71So29eZE933sSpQk6JrWFBRI5hOGlVaBDs9wgGf/6/7pxEwzmuOQmsmpWfwV37ILwkL8iXCanl9K7j8I38Sd6y/0PFjrQMPWT37xMWxThfnBcOb/lPrcFGlRjNTvQuQUutzOJYtl6iClxiobOWSIRKxerJS/jZNPPVMfHzrLfCDdXPq+enQDGfXbwDIWjIc/dEIac2+DGjF0WDMUxtzKPmhM6adwdyxpYwy1ozfQcTbHJihp9FluClFuRuGL9xa2ieh4XXJl+b9dOq0z4WWBTpyENUy4t/8f5ItRz4V0+lGB79JNIE4Kn+l2oJ2lXzc6hFp4IRAwiUW87r8UxdBrI9mQiR32Al9bkNbmbY2+74wFuUGvYKjvk/adgZ2WICLHSef10bqJ1BWNpP23yby54FXCaNb7lPggaV2yW61cv9/GwEhYsbIFXIBoTwq/OBw8B04BBQGYgC3bDJsHaYAq3DE2rXtsOrqSyRlSFX8bwyb65eEYer0Le7mvgH77wTTrz33kciGz5+//3Iznff/XDxHb5nARO+s42D+LuBhe9bdrXMizB7qUQ+ycDpmkO7HC7plejVABOij5/BrRSvYtJtLs9vWSvWr63ExEpPnvrVf3hljnPxga+WJHbYky4/MNe5MuLqHPvSg3eyI2FB/Dbm2p1+Hom1vTtlefGA8eNjAyYvzw+NjSpqWzJlRfFAMPDJpBXtL6VG3emb6ub3f83ydfeWf9evzR7UbP65KVNHNZ+3vXolWmFGIg52RShA4lCxHfxiYuY9P9TabljNKrRDhbRv361a9y5d7zOmkqOUQ+funau+Wujcpev9lupUDarPpH2PHghgWe+3+qa7/aIqA/51G7gAPPPHSQbg290jywK/r2+HUCxPEnCyK6JgXho+007mks0QsnaRzCL5H+bMZmZadZhbFtJKuH9QOmAzAI2iKp05Aeq7KsUoBKjEBSxEh4Ay/osVIcpPFYXLVxWLDtxX0dTmXMXQilVsc+XkqZXpRaf9pCVhWoRKa6LUddqUo90622tKt/bpYQwxlpBNBknMIoUM0kgnxkTyKCSnHm1SBsnE8MSWzqeIfnTeOS9Pp5BLKnlRHNNFVC5qupMem8bUmJd6J2Y7MrQH2uHJzHQKdYa89ehek+5CV3rSH+Fux4XdkFx56+cr8tsRZvbLGaFhS+JFDj2w9ysfIrZZWuX8bn0sorDXlX07ixjzMat3ZNp93PWLvmjJxX3EPNQ+4IgrfZdtMuw0fVbDF8YHZ+ee77jD9RRbwDsHbzXd8eq6OCzZgvCY2uWJvcEz/il5C/i44f1HXT/Dw0YvPGji/WYX3CvJ4G4d79QPoFObAbGGV2W8rN5eVPG8sg5nldw/rbyNk0oajit2OOLxsIAHBc7fLyZ7eftfuJvDndxPuOQOYCuDm5kXcMzievYz7NPYTmEriauJWyGBKwkNLMdxKYYkGoLFaBoWwuswH8a58E8YRXAm8gIGIZwKJmEy+BO6QRwPLsFYMAmjARzx4bBPhCE/DvpFGADs936Gjhd7Pdjjxq7G595fzQYP9ZIWamURquUZqJQDUC59hlqhF/I5EbKZcUgmeiHq4CASjkG46HK0Q04jBCVORzvgQL+vC3xVu7UN9jR4beixotsqA1fR4W7Zeau75by6tt8di6Pb+mXVlDcSQ15PjIJe0PBqIuE5ohY4AbgNjtFxz7n/2tKta4mKVxIZLyV0niKVBaUgFZ5TdFY6I72Qsj3SDelzKUtpZ4ruTF3wHyvEywnLM0QuMAIwGwyjY54z/5XF9vaS9E29D9OTEzdOMJkAocktINvRcop9Un8uBfZ2QOZmMRR5p29378YzdALsm7bytbjekQCVGpiLobbeaeeMJEm2Tz7Qty5I8kpJVkpad3qjl6Jvw6kkuMmPCMWijDLK6tpDBpfqelN2AA==) format("woff2"),url(data:font/woff;base64,d09GRgABAAAAAAYQAA8AAAAABtQAAQABAAAAAAAAAAAAAAAAAAAAAAAAAABHREVGAAABWAAAABQAAAAUAA8ACEdQT1MAAAFsAAAAHgAAAB5EdEx1R1NVQgAAAYwAAAA0AAAANJMNggJPUy8yAAABwAAAAGAAAABgmK7Q0VNUQVQAAAIgAAAAWgAAAFpfnEGhY21hcAAAAnwAAABUAAAAVADNH/FnYXNwAAAC0AAAAAwAAAAMAAgAGWdseWYAAALcAAABNgAAATZveQfraGVhZAAABBQAAAA2AAAANg1psE5oaGVhAAAETAAAACQAAAAkCykN02htdHgAAARwAAAAIAAAACAX6P92bG9jYQAABJAAAAASAAAAEgGEAVltYXhwAAAEpAAAACAAAAAgACgBIW5hbWUAAATEAAABKwAAAkozllu+cG9zdAAABfAAAAAgAAAAIP9tAGQAAQAAAAwAAAAAAAAAAQAHAAEAAQABAAAACgAcABwAAURGTFQACAAEAAAAAP//AAAAAAAAAAEAAAAKADIAMgAEREZMVAAeY3lybAAaZ3JlawAabGF0bgAaAAAAAAAEAAAAAP//AAAAAAAEBJ8CvAAFAAAFmgUzAAABHwWaBTMAAAPRAGYCAAAAAgAAAAAAAAAAAOAAAv9QACBbAAAAIAAAAABHT09HACAAAB9NBgD+AABmB5oCACAAAZ8AAAAABDoFsAAAACAAAwABAAEACAADAAAAFAADAAAALAACd2R0aAElAAB3Z2h0ASgAAWl0YWwBMgACAAYAEgAeAAEAAAACAScAZAAAAAEAAQAAAS8CvAAAAAMAAgACASgAAAAAAAEAAAAAAAAAAgAAAAMAAAAUAAMAAQAAABQABABAAAAADAAIAAIABAAAAA0AIACgH03//wAAAAAADQAgAKAfTf//AAH/9f/j/2bgugABAAAAAAAAAAAAAAAAAAEAAgAIAAj//wAPAAUAZAAAAygFsAADAAYACQAMAA8AAAERIREFAQElCQMhCQIDKP08Ao7+7wER/agBDf7zASr+/gID/f0BAgEBBbD6UAWwVP18/XwMAngCeP1E/aIFRP2iAl4AAAIAVv/sBS4FxAAVACsAAAEVFAIGBiMiJiYCNTU0EjY2MzIWFhIFNTQuAiMiDgIVFRQeAjMyPgIFLlqk44qJ46ZbWqXjiYrjpVv+0SpSdkxMdVEqKlJ2TEx2UCoC+kWm/vi5YmK5AQimRacBB7piYrr++exHdLB4PT14sHRHc7F5Pj55sQAAAgBaBHACxAXXAAUADwAAATUTMxUDJTUzFRQWFwcmJgGFcc7k/nqoIytSSFwEgxgBPBX+wfZeWD5dIVMkif///mL/7AV0BdYAJgAERgAABwAF/gn//wAAAAEAAAADA9fKS6B2Xw889QAbCAAAAAAAxPARLgAAAADljVAD+jH91QmJCHMAAQAJAAIAAAAAAAAAAQAAB2z+DAAACYz6Mf4zCYkIAAAAAAAAAAAAAAAAAAAAAAgDjABkAAAAAAH9AAAB/QAABYQAVgMXAFoB/QAABcr+YgAAAC0ALQAtAC0AcACPAI8AmwAAAAEAAAAIAKkAFQB2AAcAAQAAAAAAAAAAAAAAAAADAAF4nG2Qu07DQBBFj0lAgAIlonTBI0jgECNSQAUUEQ0ghEgdHOMEhRjZTgFfg/gECj6Ikg+g5nq9CY5Ao/Uc33ntDrDCGxWc6hLwzrdlhxpfludY5NNyhV0+LFdZ49XyPFu8WF6Q3rO8SguvYGeTZTYsb6v/uuW6uGa58TvL8aXCORldhgwI6BDKR/SlXRCT8GhiHak9aX0TyXgi5YiGLBaHjLgXjRQp+uRKqq9nekRcy9/pZDp7nOo7VL9bZSTKG5halwPl79PkkGP9+WJfryvXutPacm6bS1lb9P+ciS9Hz8zNnzV/8t5iYlPmciMllJ+dfaXsmAdFApN/wtjsJDavcKn/2U6k7nnGWF08VcXaZ67Gskh3Cqd7S6UnM7cPFO9KT81Gd34AgExWjgAAAwAAAAAAAP9qAGQAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("woff");unicode-range:U+1F00-1FFF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-greek-700-normal.0aHWxGLu.woff2) format("woff2"),url(/blog/_astro/roboto-greek-700-normal.DjRqqLBV.woff) format("woff");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-math-700-normal.B8YqGHVc.woff2) format("woff2"),url(/blog/_astro/roboto-math-700-normal.DVoD5t2k.woff) format("woff");unicode-range:U+0302-0303,U+0305,U+0307-0308,U+0310,U+0312,U+0315,U+031A,U+0326-0327,U+032C,U+032F-0330,U+0332-0333,U+0338,U+033A,U+0346,U+034D,U+0391-03A1,U+03A3-03A9,U+03B1-03C9,U+03D1,U+03D5-03D6,U+03F0-03F1,U+03F4-03F5,U+2016-2017,U+2034-2038,U+203C,U+2040,U+2043,U+2047,U+2050,U+2057,U+205F,U+2070-2071,U+2074-208E,U+2090-209C,U+20D0-20DC,U+20E1,U+20E5-20EF,U+2100-2112,U+2114-2115,U+2117-2121,U+2123-214F,U+2190,U+2192,U+2194-21AE,U+21B0-21E5,U+21F1-21F2,U+21F4-2211,U+2213-2214,U+2216-22FF,U+2308-230B,U+2310,U+2319,U+231C-2321,U+2336-237A,U+237C,U+2395,U+239B-23B7,U+23D0,U+23DC-23E1,U+2474-2475,U+25AF,U+25B3,U+25B7,U+25BD,U+25C1,U+25CA,U+25CC,U+25FB,U+266D-266F,U+27C0-27FF,U+2900-2AFF,U+2B0E-2B11,U+2B30-2B4C,U+2BFE,U+3030,U+FF5B,U+FF5D,U+1D400-1D7FF,U+1EE00-1EEFF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-symbols-700-normal.BiFDindJ.woff2) format("woff2"),url(/blog/_astro/roboto-symbols-700-normal.BoS6HWkc.woff) format("woff");unicode-range:U+0001-000C,U+000E-001F,U+007F-009F,U+20DD-20E0,U+20E2-20E4,U+2150-218F,U+2190,U+2192,U+2194-2199,U+21AF,U+21E6-21F0,U+21F3,U+2218-2219,U+2299,U+22C4-22C6,U+2300-243F,U+2440-244A,U+2460-24FF,U+25A0-27BF,U+2800-28FF,U+2921-2922,U+2981,U+29BF,U+29EB,U+2B00-2BFF,U+4DC0-4DFF,U+FFF9-FFFB,U+10140-1018E,U+10190-1019C,U+101A0,U+101D0-101FD,U+102E0-102FB,U+10E60-10E7E,U+1D2C0-1D2D3,U+1D2E0-1D37F,U+1F000-1F0FF,U+1F100-1F1AD,U+1F1E6-1F1FF,U+1F30D-1F30F,U+1F315,U+1F31C,U+1F31E,U+1F320-1F32C,U+1F336,U+1F378,U+1F37D,U+1F382,U+1F393-1F39F,U+1F3A7-1F3A8,U+1F3AC-1F3AF,U+1F3C2,U+1F3C4-1F3C6,U+1F3CA-1F3CE,U+1F3D4-1F3E0,U+1F3ED,U+1F3F1-1F3F3,U+1F3F5-1F3F7,U+1F408,U+1F415,U+1F41F,U+1F426,U+1F43F,U+1F441-1F442,U+1F444,U+1F446-1F449,U+1F44C-1F44E,U+1F453,U+1F46A,U+1F47D,U+1F4A3,U+1F4B0,U+1F4B3,U+1F4B9,U+1F4BB,U+1F4BF,U+1F4C8-1F4CB,U+1F4D6,U+1F4DA,U+1F4DF,U+1F4E3-1F4E6,U+1F4EA-1F4ED,U+1F4F7,U+1F4F9-1F4FB,U+1F4FD-1F4FE,U+1F503,U+1F507-1F50B,U+1F50D,U+1F512-1F513,U+1F53E-1F54A,U+1F54F-1F5FA,U+1F610,U+1F650-1F67F,U+1F687,U+1F68D,U+1F691,U+1F694,U+1F698,U+1F6AD,U+1F6B2,U+1F6B9-1F6BA,U+1F6BC,U+1F6C6-1F6CF,U+1F6D3-1F6D7,U+1F6E0-1F6EA,U+1F6F0-1F6F3,U+1F6F7-1F6FC,U+1F700-1F7FF,U+1F800-1F80B,U+1F810-1F847,U+1F850-1F859,U+1F860-1F887,U+1F890-1F8AD,U+1F8B0-1F8BB,U+1F8C0-1F8C1,U+1F900-1F90B,U+1F93B,U+1F946,U+1F984,U+1F996,U+1F9E9,U+1FA00-1FA6F,U+1FA70-1FA7C,U+1FA80-1FA89,U+1FA8F-1FAC6,U+1FACE-1FADC,U+1FADF-1FAE9,U+1FAF0-1FAF8,U+1FB00-1FBFF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-vietnamese-700-normal.BEVeWqJt.woff2) format("woff2"),url(/blog/_astro/roboto-vietnamese-700-normal.DsFyXAL4.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-latin-ext-700-normal.DSBUz0N1.woff2) format("woff2"),url(/blog/_astro/roboto-latin-ext-700-normal.BUhwtWwy.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:700;src:url(/blog/_astro/roboto-latin-700-normal.BZpUvMxY.woff2) format("woff2"),url(/blog/_astro/roboto-latin-700-normal.DLgJJpmK.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:KaTeX_AMS;src:url(/blog/_astro/KaTeX_AMS-Regular.BQhdFMY1.woff2) format("woff2"),url(/blog/_astro/KaTeX_AMS-Regular.DMm9YOAa.woff) format("woff"),url(/blog/_astro/KaTeX_AMS-Regular.DRggAlZN.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Caligraphic;src:url(/blog/_astro/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2) format("woff2"),url(/blog/_astro/KaTeX_Caligraphic-Bold.BEiXGLvX.woff) format("woff"),url(/blog/_astro/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf) format("truetype");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Caligraphic;src:url(/blog/_astro/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2) format("woff2"),url(/blog/_astro/KaTeX_Caligraphic-Regular.CTRA-rTL.woff) format("woff"),url(/blog/_astro/KaTeX_Caligraphic-Regular.wX97UBjC.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Fraktur;src:url(/blog/_astro/KaTeX_Fraktur-Bold.CL6g_b3V.woff2) format("woff2"),url(/blog/_astro/KaTeX_Fraktur-Bold.BsDP51OF.woff) format("woff"),url(/blog/_astro/KaTeX_Fraktur-Bold.BdnERNNW.ttf) format("truetype");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Fraktur;src:url(/blog/_astro/KaTeX_Fraktur-Regular.CTYiF6lA.woff2) format("woff2"),url(/blog/_astro/KaTeX_Fraktur-Regular.Dxdc4cR9.woff) format("woff"),url(/blog/_astro/KaTeX_Fraktur-Regular.CB_wures.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Main;src:url(/blog/_astro/KaTeX_Main-Bold.Cx986IdX.woff2) format("woff2"),url(/blog/_astro/KaTeX_Main-Bold.Jm3AIy58.woff) format("woff"),url(/blog/_astro/KaTeX_Main-Bold.waoOVXN0.ttf) format("truetype");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Main;src:url(/blog/_astro/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2) format("woff2"),url(/blog/_astro/KaTeX_Main-BoldItalic.SpSLRI95.woff) format("woff"),url(/blog/_astro/KaTeX_Main-BoldItalic.DzxPMmG6.ttf) format("truetype");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:KaTeX_Main;src:url(/blog/_astro/KaTeX_Main-Italic.NWA7e6Wa.woff2) format("woff2"),url(/blog/_astro/KaTeX_Main-Italic.BMLOBm91.woff) format("woff"),url(/blog/_astro/KaTeX_Main-Italic.3WenGoN9.ttf) format("truetype");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:KaTeX_Main;src:url(/blog/_astro/KaTeX_Main-Regular.B22Nviop.woff2) format("woff2"),url(/blog/_astro/KaTeX_Main-Regular.Dr94JaBh.woff) format("woff"),url(/blog/_astro/KaTeX_Main-Regular.ypZvNtVU.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Math;src:url(/blog/_astro/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2) format("woff2"),url(/blog/_astro/KaTeX_Math-BoldItalic.iY-2wyZ7.woff) format("woff"),url(/blog/_astro/KaTeX_Math-BoldItalic.B3XSjfu4.ttf) format("truetype");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:KaTeX_Math;src:url(/blog/_astro/KaTeX_Math-Italic.t53AETM-.woff2) format("woff2"),url(/blog/_astro/KaTeX_Math-Italic.DA0__PXp.woff) format("woff"),url(/blog/_astro/KaTeX_Math-Italic.flOr_0UB.ttf) format("truetype");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:KaTeX_SansSerif;src:url(/blog/_astro/KaTeX_SansSerif-Bold.D1sUS0GD.woff2) format("woff2"),url(/blog/_astro/KaTeX_SansSerif-Bold.DbIhKOiC.woff) format("woff"),url(/blog/_astro/KaTeX_SansSerif-Bold.CFMepnvq.ttf) format("truetype");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:KaTeX_SansSerif;src:url(/blog/_astro/KaTeX_SansSerif-Italic.C3H0VqGB.woff2) format("woff2"),url(/blog/_astro/KaTeX_SansSerif-Italic.DN2j7dab.woff) format("woff"),url(/blog/_astro/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf) format("truetype");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:KaTeX_SansSerif;src:url(/blog/_astro/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2) format("woff2"),url(/blog/_astro/KaTeX_SansSerif-Regular.CS6fqUqJ.woff) format("woff"),url(/blog/_astro/KaTeX_SansSerif-Regular.BNo7hRIc.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Script;src:url(/blog/_astro/KaTeX_Script-Regular.D3wIWfF6.woff2) format("woff2"),url(/blog/_astro/KaTeX_Script-Regular.D5yQViql.woff) format("woff"),url(/blog/_astro/KaTeX_Script-Regular.C5JkGWo-.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Size1;src:url(/blog/_astro/KaTeX_Size1-Regular.mCD8mA8B.woff2) format("woff2"),url(/blog/_astro/KaTeX_Size1-Regular.C195tn64.woff) format("woff"),url(/blog/_astro/KaTeX_Size1-Regular.Dbsnue_I.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Size2;src:url(/blog/_astro/KaTeX_Size2-Regular.Dy4dx90m.woff2) format("woff2"),url(/blog/_astro/KaTeX_Size2-Regular.oD1tc_U0.woff) format("woff"),url(/blog/_astro/KaTeX_Size2-Regular.B7gKUWhC.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Size3;src:url(data:font/woff2;base64,d09GMgABAAAAAA4oAA4AAAAAHbQAAA3TAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgRQIDgmcDBEICo1oijYBNgIkA14LMgAEIAWJAAeBHAyBHBvbGiMRdnO0IkRRkiYDgr9KsJ1NUAf2kILNxgUmgqIgq1P89vcbIcmsQbRps3vCcXdYOKSWEPEKgZgQkprQQsxIXUgq0DqpGKmIvrgkeVGtEQD9DzAO29fM9jYhxZEsL2FeURH2JN4MIcTdO049NCVdxQ/w9NrSYFEBKTDKpLKfNkCGDc1RwjZLQcm3vqJ2UW9Xfa3tgAHz6ivp6vgC2yD4/6352ndnN0X0TL7seypkjZlMsjmZnf0Mm5Q+JykRWQBKCVCVPbARPXWyQtb5VgLB6Biq7/Uixcj2WGqdI8tGSgkuRG+t910GKP2D7AQH0DB9FMDW/obJZ8giFI3Wg8Cvevz0M+5m0rTh7XDBlvo9Y4vm13EXmfttwI4mBo1EG15fxJhUiCLbiiyCf/ZA6MFAhg3pGIZGdGIVjtPn6UcMk9A/UUr9PhoNsCENw1APAq0gpH73e+M+0ueyHbabc3vkbcdtzcf/fiy+NxQEjf9ud/ELBHAXJ0nk4z+MXH2Ev/kWyV4k7SkvpPc9Qr38F6RPWnM9cN6DJ0AdD1BhtgABtmoRoFCvPsBAumNm6soZG2Gk5GyVTo2sJncSyp0jQTYoR6WDvTwaaEcHsxHfvuWhHA3a6bN7twRKtcGok6NsCi7jYRrM2jExsUFMxMQYuJbMhuWNOumEJy9hi29Dmg5zMp/A5+hhPG19j1vBrq8JTLr8ki5VLPmG/PynJHVul440bxg5xuymHUFPBshC+nA9I1FmwbRBTNHAcik3Oae0cxKoI3MOriM42UrPe51nsaGxJ+WfXubAsP84aabUlQSJ1IiE0iPETLUU4CATgfXSCSpuRFRmCGbO+wSpAnzaeaCYW1VNEysRtuXCEL1kUFUbbtMv3Tilt/1c11jt3Q5bbMa84cpWipp8Elw3MZhOHsOlwwVUQM3lAR35JiFQbaYCRnMF2lxAWoOg2gyoIV4PouX8HytNIfLhqpJtXB4vjiViUI8IJ7bkC4ikkQvKksnOTKICwnqWSZ9YS5f0WCxmpgjbIq7EJcM4aI2nmhLNY2JIUgOjXZFWBHb+x5oh6cwb0Tv1ackHdKi0I9OO2wE9aogIOn540CCCziyhN+IaejtgAONKznHlHyutPrHGwCx9S6B8kfS4Mfi4Eyv7OU730bT1SCBjt834cXsf43zVjPUqqJjgrjeGnBxSG4aYAKFuVbeCfkDIjAqMb6yLNIbCuvXhMH2/+k2vkNpkORhR59N1CkzoOENvneIosjYmuTxlhUzaGEJQ/iWqx4dmwpmKjrwTiTGTCVozNAYqk/zXOndWxuWSmJkQpJw3pK5KX6QrLt5LATMqpmPAQhkhK6PUjzHUn7E0gHE0kPE0iKkolgkUx9SZmVAdDgpffdyJKg3k7VmzYGCwVXGz/tXmkOIp+vcWs+EMuhhvN0h9uhfzWJziBQmCREGSIFmQIkgVpAnSBRmC//6hkLZwaVhwxlrJSOdqlFtOYxlau9F2QN5Y98xmIAsiM1HVp2VFX+DHHGg6Ecjh3vmqtidX3qHI2qycTk/iwxSt5UzTmEP92ZBnEWTk4Mx8Mpl78ZDokxg/KWb+Q0QkvdKVmq3TMW+RXEgrsziSAfNXFMhDc60N5N9jQzjfO0kBKpUZl0ZmwJ41j/B9Hz6wmRaJB84niNmQrzp9eSlQCDDzazGDdVi3P36VZQ+Jy4f9UBNp+3zTjqI4abaFAm+GShVaXlsGdF3FYzZcDI6cori4kMxUECl9IjJZpzkvitAoxKue+90pDMvcKRxLl53TmOKCmV/xRolNKSqqUxc6LStOETmFOiLZZptlZepcKiAzteG8PEdpnQpbOMNcMsR4RR2Bs0cKFEvSmIjAFcnarqwUL4lDhHmnVkwu1IwshbiCcgvOheZuYyOteufZZwlcTlLgnZ3o/WcYdzZHW/WGaqaVfmTZ1aWCceJjkbZqsfbkOtcFlUZM/jy+hXHDbaUobWqqXaeWobbLO99yG5N3U4wxco0rQGGcOLASFMXeJoham8M+/x6O2WywK2l4HGbq1CoUyC/IZikQhdq3SiuNrvAEj0AVu9x2x3lp/xWzahaxidezFVtdcb5uEnzyl0ZmYiuKI0exvCd4Xc9CV1KB0db00z92wDPde0kukbvZIWN6jUWFTmPIC/Y4UPCm8UfDTFZpZNon1qLFTkBhxzB+FjQRA2Q/YRJT8pQigslMaUpFyAG8TMlXigiqmAZX4xgijKjRlGpLE0GdplRfCaJo0JQaSxNBk6ZmMzcya0FmrcisDdn0Q3HI2sWSppYigmlM1XT/kLQZSNpMJG0WkjYbSZuDpM1F0uYhFc1HxU4m1QJjDK6iL0S5uSj5rgXc3RejEigtcRBtqYPQsiTskmO5vosV+q4VGIKbOkDg0jtRrq+Em1YloaTFar3EGr1EUC8R0kus1Uus00usL97ABr2BjXoDm/QGNhuWtMVBKOwg/i78lT7hBsAvDmwHc/ao3vmUbBmhjeYySZNWvGkfZAgISDSaDo1SVpzGDsAEkF8B+gEapViUoZgUWXcRIGFZNm6gWbAKk0bp0k1MHG9fLYtV4iS2SmLEQFARzRcnf9PUS0LVn05/J9MiRRBU3v2IrvW974v4N00L7ZMk0wXP1409CHo/an8zTRHD3eSJ6m8D4YMkZNl3M79sqeuAsr/m3f+8/yl7A50aiAEJgeBeMWzu7ui9UfUBCe2TIqZIoOd/3/udRBOQidQZUERzb2/VwZN1H/Sju82ew2H2Wfr6qvfVf3hqwDvAIpkQVFy4B9Pe9e4/XvPeceu7h3dvO56iJPf0+A6cqA2ip18ER+iFgggiuOkvj24bby0N9j2UHIkgqIt+sVgfodC4YghLSMjSZbH0VR/6dMDrYJeKHilKTemt6v6kvzvn3/RrdWtr0GoN/xL+Sex/cPYLUpepx9cz/D46UPU5KXgAQa+NDps1v6J3xP1i2HtaDB0M9aX2deA7SYff//+gUCovMmIK/qfsFcOk+4Y5ZN97XlG6zebqtMbKgeRFi51vnxTQYBUik2rS/Cn6PC8ADR8FGxsRPB82dzfND90gIcshOcYUkfjherBz53odpm6TP8txlwOZ71xmfHHOvq053qFF/MRlS3jP0ELudrf2OeN8DHvp6ZceLe8qKYvWz/7yp0u4dKPfli3CYq0O13Ih71mylJ80tOi10On8wi+F4+LWgDPeJ30msSQt9/vkmHq9/Lvo2b461mP801v3W4xTcs6CbvF9UDdrSt+A8OUbpSh55qAUFXWznBBfdeJ8a4d7ugT5tvxUza3h9m4H7ptTqiG4z0g5dc0X29OcGlhpGFMpQo9ytTS+NViZpNdvU4kWx+LKxNY10kQ1yqGXrhe4/1nvP7E+nd5A92TtaRplbHSqoIdOqtRWti+fkB5/n1+/VvCmz12pG1kpQWsfi1ftlBobm0bpngs16CHkbIwdLnParxtTV3QYRlfJ0KFskH7pdN/YDn+yRuSd7sNH3aO0DYPggk6uWuXrfOc+fa3VTxFVvKaNxHsiHmsXyCLIE5yuOeN3/Jdf8HBL/5M6shjyhxHx9BjB1O0+4NLOnjLLSxwO7ukN4jMbOIcD879KLSi6Pk61Oqm2377n8079PXEEQ7cy7OKEC9nbpet118fxweTafpt69x/Bt8UqGzNQt7aelpc44dn5cqhwf71+qKp/Zf/+a0zcizOUWpl/iBcSXip0pplkatCchoH5c5aUM8I7/dWxAej8WicPL1URFZ9BDJelUwEwTkGqUhgSlydVes95YdXvhh9Gfz/aeFWvgVb4tuLbcv4+wLdutVZv/cUonwBD/6eDlE0aSiKK/uoH3+J1wDE/jMVqY2ysGufN84oIXB0sPzy8ollX/LegY74DgJXJR57sn+VGza0x3DnuIgABFM15LmajjjsNlYj+JEZGbuRYcAMOWxFkPN2w6Wd46xo4gVWQR/X4lyI/R6K/YK0110GzudPRW7Y+UOBGTfNNzHeYT0fiH0taunBpq9HEW8OKSaBGj21L0MqenEmNRWBAWDWAk4CpNoEZJ2tTaPFgbQYj8HxtFilErs3BTRwT8uO1NXQaWfIotchmPkAF5mMBAliEmZiOGVgCG9LgRzpscMAOOwowlT3JhusdazXGSC/hxR3UlmWVwWHpOIKheqONvjyhSiTHIkVUco5bnji8m//zL7PKaT1Vl5I6UE609f+gkr6MZKVyKc7zJRmCahLsdlyA5fdQkRSan9LgnnLEyGSkaKJCJog0wAgvepWBt80+1yKln1bMVtCljfNWDueKLsWwaEbBSfSPTEmVRsUcYYMnEjcjeyCZzBXK9E9BYBXLKjOSpUDR+nEV3TFSUdQaz+ot98QxgXwx0GQ+EEUAKB2qZPkQQ0GqFD8UPFMqyaCHM24BZmSGic9EYMagKizOw9Hz50DMrDLrqqLkTAhplMictiCAx5S3BIUQdeJeLnBy2CNtMfz6cV4u8XKoFZQesbf9YZiIERiHjaNodDW6LgcirX/mPnJIkBGDUpTBhSa0EIr38D5hCIszhCM8URGBqImoWjpvpt1ebu/v3Gl3qJfMnNM+9V+kiRFyROTPHQWOcs1dNW94/ukKMPZBvDi55i5CttdeJz84DLngLqjcdwEZ87bFFR8CIG35OAkDVN6VRDZ7aq67NteYqZ2lpT8oYB2CytoBd6VuAx4WgiAsnuj3WohG+LugzXiQRDeM3XYXlULv4dp5VFYC) format("woff2"),url(/blog/_astro/KaTeX_Size3-Regular.CTq5MqoE.woff) format("woff"),url(/blog/_astro/KaTeX_Size3-Regular.DgpXs0kz.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Size4;src:url(/blog/_astro/KaTeX_Size4-Regular.Dl5lxZxV.woff2) format("woff2"),url(/blog/_astro/KaTeX_Size4-Regular.BF-4gkZK.woff) format("woff"),url(/blog/_astro/KaTeX_Size4-Regular.DWFBv043.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:KaTeX_Typewriter;src:url(/blog/_astro/KaTeX_Typewriter-Regular.CO6r4hn1.woff2) format("woff2"),url(/blog/_astro/KaTeX_Typewriter-Regular.C0xS9mPB.woff) format("woff"),url(/blog/_astro/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf) format("truetype");font-weight:400;font-style:normal;font-display:block}.katex{font: 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;position:relative;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.45"}.katex .katex-mathml{position:absolute;clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.katex .katex-html>.newline{display:block}.katex .base{position:relative;display:inline-block;white-space:nowrap;width:-moz-min-content;width:min-content}.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-weight:700;font-style:italic}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathsfit,.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{display:inline-table;table-layout:fixed;border-collapse:collapse}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;vertical-align:bottom;position:relative}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;vertical-align:bottom;font-size:1px;width:2px;min-width:2px}.katex .vbox{display:inline-flex;flex-direction:column;align-items:baseline}.katex .hbox{display:inline-flex;flex-direction:row;width:100%}.katex .thinbox{display:inline-flex;flex-direction:row;width:0;max-width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .underline .underline-line,.katex .hline,.katex .hdashline,.katex .rule{min-height:1px}.katex .mspace{display:inline-block}.katex .smash{display:inline;line-height:0}.katex .llap,.katex .rlap,.katex .clap{width:0;position:relative}.katex .llap>.inner,.katex .rlap>.inner,.katex .clap>.inner{position:absolute}.katex .llap>.fix,.katex .rlap>.fix,.katex .clap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .rlap>.inner,.katex .clap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{display:inline-block;border:solid 0;position:relative}.katex .overline .overline-line,.katex .underline .underline-line,.katex .hline{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline{display:inline-block;width:100%;border-bottom-style:dashed}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .sizing.reset-size1.size1,.katex .fontsize-ensurer.reset-size1.size1{font-size:1em}.katex .sizing.reset-size1.size2,.katex .fontsize-ensurer.reset-size1.size2{font-size:1.2em}.katex .sizing.reset-size1.size3,.katex .fontsize-ensurer.reset-size1.size3{font-size:1.4em}.katex .sizing.reset-size1.size4,.katex .fontsize-ensurer.reset-size1.size4{font-size:1.6em}.katex .sizing.reset-size1.size5,.katex .fontsize-ensurer.reset-size1.size5{font-size:1.8em}.katex .sizing.reset-size1.size6,.katex .fontsize-ensurer.reset-size1.size6{font-size:2em}.katex .sizing.reset-size1.size7,.katex .fontsize-ensurer.reset-size1.size7{font-size:2.4em}.katex .sizing.reset-size1.size8,.katex .fontsize-ensurer.reset-size1.size8{font-size:2.88em}.katex .sizing.reset-size1.size9,.katex .fontsize-ensurer.reset-size1.size9{font-size:3.456em}.katex .sizing.reset-size1.size10,.katex .fontsize-ensurer.reset-size1.size10{font-size:4.148em}.katex .sizing.reset-size1.size11,.katex .fontsize-ensurer.reset-size1.size11{font-size:4.976em}.katex .sizing.reset-size2.size1,.katex .fontsize-ensurer.reset-size2.size1{font-size:.8333333333em}.katex .sizing.reset-size2.size2,.katex .fontsize-ensurer.reset-size2.size2{font-size:1em}.katex .sizing.reset-size2.size3,.katex .fontsize-ensurer.reset-size2.size3{font-size:1.1666666667em}.katex .sizing.reset-size2.size4,.katex .fontsize-ensurer.reset-size2.size4{font-size:1.3333333333em}.katex .sizing.reset-size2.size5,.katex .fontsize-ensurer.reset-size2.size5{font-size:1.5em}.katex .sizing.reset-size2.size6,.katex .fontsize-ensurer.reset-size2.size6{font-size:1.6666666667em}.katex .sizing.reset-size2.size7,.katex .fontsize-ensurer.reset-size2.size7{font-size:2em}.katex .sizing.reset-size2.size8,.katex .fontsize-ensurer.reset-size2.size8{font-size:2.4em}.katex .sizing.reset-size2.size9,.katex .fontsize-ensurer.reset-size2.size9{font-size:2.88em}.katex .sizing.reset-size2.size10,.katex .fontsize-ensurer.reset-size2.size10{font-size:3.4566666667em}.katex .sizing.reset-size2.size11,.katex .fontsize-ensurer.reset-size2.size11{font-size:4.1466666667em}.katex .sizing.reset-size3.size1,.katex .fontsize-ensurer.reset-size3.size1{font-size:.7142857143em}.katex .sizing.reset-size3.size2,.katex .fontsize-ensurer.reset-size3.size2{font-size:.8571428571em}.katex .sizing.reset-size3.size3,.katex .fontsize-ensurer.reset-size3.size3{font-size:1em}.katex .sizing.reset-size3.size4,.katex .fontsize-ensurer.reset-size3.size4{font-size:1.1428571429em}.katex .sizing.reset-size3.size5,.katex .fontsize-ensurer.reset-size3.size5{font-size:1.2857142857em}.katex .sizing.reset-size3.size6,.katex .fontsize-ensurer.reset-size3.size6{font-size:1.4285714286em}.katex .sizing.reset-size3.size7,.katex .fontsize-ensurer.reset-size3.size7{font-size:1.7142857143em}.katex .sizing.reset-size3.size8,.katex .fontsize-ensurer.reset-size3.size8{font-size:2.0571428571em}.katex .sizing.reset-size3.size9,.katex .fontsize-ensurer.reset-size3.size9{font-size:2.4685714286em}.katex .sizing.reset-size3.size10,.katex .fontsize-ensurer.reset-size3.size10{font-size:2.9628571429em}.katex .sizing.reset-size3.size11,.katex .fontsize-ensurer.reset-size3.size11{font-size:3.5542857143em}.katex .sizing.reset-size4.size1,.katex .fontsize-ensurer.reset-size4.size1{font-size:.625em}.katex .sizing.reset-size4.size2,.katex .fontsize-ensurer.reset-size4.size2{font-size:.75em}.katex .sizing.reset-size4.size3,.katex .fontsize-ensurer.reset-size4.size3{font-size:.875em}.katex .sizing.reset-size4.size4,.katex .fontsize-ensurer.reset-size4.size4{font-size:1em}.katex .sizing.reset-size4.size5,.katex .fontsize-ensurer.reset-size4.size5{font-size:1.125em}.katex .sizing.reset-size4.size6,.katex .fontsize-ensurer.reset-size4.size6{font-size:1.25em}.katex .sizing.reset-size4.size7,.katex .fontsize-ensurer.reset-size4.size7{font-size:1.5em}.katex .sizing.reset-size4.size8,.katex .fontsize-ensurer.reset-size4.size8{font-size:1.8em}.katex .sizing.reset-size4.size9,.katex .fontsize-ensurer.reset-size4.size9{font-size:2.16em}.katex .sizing.reset-size4.size10,.katex .fontsize-ensurer.reset-size4.size10{font-size:2.5925em}.katex .sizing.reset-size4.size11,.katex .fontsize-ensurer.reset-size4.size11{font-size:3.11em}.katex .sizing.reset-size5.size1,.katex .fontsize-ensurer.reset-size5.size1{font-size:.5555555556em}.katex .sizing.reset-size5.size2,.katex .fontsize-ensurer.reset-size5.size2{font-size:.6666666667em}.katex .sizing.reset-size5.size3,.katex .fontsize-ensurer.reset-size5.size3{font-size:.7777777778em}.katex .sizing.reset-size5.size4,.katex .fontsize-ensurer.reset-size5.size4{font-size:.8888888889em}.katex .sizing.reset-size5.size5,.katex .fontsize-ensurer.reset-size5.size5{font-size:1em}.katex .sizing.reset-size5.size6,.katex .fontsize-ensurer.reset-size5.size6{font-size:1.1111111111em}.katex .sizing.reset-size5.size7,.katex .fontsize-ensurer.reset-size5.size7{font-size:1.3333333333em}.katex .sizing.reset-size5.size8,.katex .fontsize-ensurer.reset-size5.size8{font-size:1.6em}.katex .sizing.reset-size5.size9,.katex .fontsize-ensurer.reset-size5.size9{font-size:1.92em}.katex .sizing.reset-size5.size10,.katex .fontsize-ensurer.reset-size5.size10{font-size:2.3044444444em}.katex .sizing.reset-size5.size11,.katex .fontsize-ensurer.reset-size5.size11{font-size:2.7644444444em}.katex .sizing.reset-size6.size1,.katex .fontsize-ensurer.reset-size6.size1{font-size:.5em}.katex .sizing.reset-size6.size2,.katex .fontsize-ensurer.reset-size6.size2{font-size:.6em}.katex .sizing.reset-size6.size3,.katex .fontsize-ensurer.reset-size6.size3{font-size:.7em}.katex .sizing.reset-size6.size4,.katex .fontsize-ensurer.reset-size6.size4{font-size:.8em}.katex .sizing.reset-size6.size5,.katex .fontsize-ensurer.reset-size6.size5{font-size:.9em}.katex .sizing.reset-size6.size6,.katex .fontsize-ensurer.reset-size6.size6{font-size:1em}.katex .sizing.reset-size6.size7,.katex .fontsize-ensurer.reset-size6.size7{font-size:1.2em}.katex .sizing.reset-size6.size8,.katex .fontsize-ensurer.reset-size6.size8{font-size:1.44em}.katex .sizing.reset-size6.size9,.katex .fontsize-ensurer.reset-size6.size9{font-size:1.728em}.katex .sizing.reset-size6.size10,.katex .fontsize-ensurer.reset-size6.size10{font-size:2.074em}.katex .sizing.reset-size6.size11,.katex .fontsize-ensurer.reset-size6.size11{font-size:2.488em}.katex .sizing.reset-size7.size1,.katex .fontsize-ensurer.reset-size7.size1{font-size:.4166666667em}.katex .sizing.reset-size7.size2,.katex .fontsize-ensurer.reset-size7.size2{font-size:.5em}.katex .sizing.reset-size7.size3,.katex .fontsize-ensurer.reset-size7.size3{font-size:.5833333333em}.katex .sizing.reset-size7.size4,.katex .fontsize-ensurer.reset-size7.size4{font-size:.6666666667em}.katex .sizing.reset-size7.size5,.katex .fontsize-ensurer.reset-size7.size5{font-size:.75em}.katex .sizing.reset-size7.size6,.katex .fontsize-ensurer.reset-size7.size6{font-size:.8333333333em}.katex .sizing.reset-size7.size7,.katex .fontsize-ensurer.reset-size7.size7{font-size:1em}.katex .sizing.reset-size7.size8,.katex .fontsize-ensurer.reset-size7.size8{font-size:1.2em}.katex .sizing.reset-size7.size9,.katex .fontsize-ensurer.reset-size7.size9{font-size:1.44em}.katex .sizing.reset-size7.size10,.katex .fontsize-ensurer.reset-size7.size10{font-size:1.7283333333em}.katex .sizing.reset-size7.size11,.katex .fontsize-ensurer.reset-size7.size11{font-size:2.0733333333em}.katex .sizing.reset-size8.size1,.katex .fontsize-ensurer.reset-size8.size1{font-size:.3472222222em}.katex .sizing.reset-size8.size2,.katex .fontsize-ensurer.reset-size8.size2{font-size:.4166666667em}.katex .sizing.reset-size8.size3,.katex .fontsize-ensurer.reset-size8.size3{font-size:.4861111111em}.katex .sizing.reset-size8.size4,.katex .fontsize-ensurer.reset-size8.size4{font-size:.5555555556em}.katex .sizing.reset-size8.size5,.katex .fontsize-ensurer.reset-size8.size5{font-size:.625em}.katex .sizing.reset-size8.size6,.katex .fontsize-ensurer.reset-size8.size6{font-size:.6944444444em}.katex .sizing.reset-size8.size7,.katex .fontsize-ensurer.reset-size8.size7{font-size:.8333333333em}.katex .sizing.reset-size8.size8,.katex .fontsize-ensurer.reset-size8.size8{font-size:1em}.katex .sizing.reset-size8.size9,.katex .fontsize-ensurer.reset-size8.size9{font-size:1.2em}.katex .sizing.reset-size8.size10,.katex .fontsize-ensurer.reset-size8.size10{font-size:1.4402777778em}.katex .sizing.reset-size8.size11,.katex .fontsize-ensurer.reset-size8.size11{font-size:1.7277777778em}.katex .sizing.reset-size9.size1,.katex .fontsize-ensurer.reset-size9.size1{font-size:.2893518519em}.katex .sizing.reset-size9.size2,.katex .fontsize-ensurer.reset-size9.size2{font-size:.3472222222em}.katex .sizing.reset-size9.size3,.katex .fontsize-ensurer.reset-size9.size3{font-size:.4050925926em}.katex .sizing.reset-size9.size4,.katex .fontsize-ensurer.reset-size9.size4{font-size:.462962963em}.katex .sizing.reset-size9.size5,.katex .fontsize-ensurer.reset-size9.size5{font-size:.5208333333em}.katex .sizing.reset-size9.size6,.katex .fontsize-ensurer.reset-size9.size6{font-size:.5787037037em}.katex .sizing.reset-size9.size7,.katex .fontsize-ensurer.reset-size9.size7{font-size:.6944444444em}.katex .sizing.reset-size9.size8,.katex .fontsize-ensurer.reset-size9.size8{font-size:.8333333333em}.katex .sizing.reset-size9.size9,.katex .fontsize-ensurer.reset-size9.size9{font-size:1em}.katex .sizing.reset-size9.size10,.katex .fontsize-ensurer.reset-size9.size10{font-size:1.2002314815em}.katex .sizing.reset-size9.size11,.katex .fontsize-ensurer.reset-size9.size11{font-size:1.4398148148em}.katex .sizing.reset-size10.size1,.katex .fontsize-ensurer.reset-size10.size1{font-size:.2410800386em}.katex .sizing.reset-size10.size2,.katex .fontsize-ensurer.reset-size10.size2{font-size:.2892960463em}.katex .sizing.reset-size10.size3,.katex .fontsize-ensurer.reset-size10.size3{font-size:.337512054em}.katex .sizing.reset-size10.size4,.katex .fontsize-ensurer.reset-size10.size4{font-size:.3857280617em}.katex .sizing.reset-size10.size5,.katex .fontsize-ensurer.reset-size10.size5{font-size:.4339440694em}.katex .sizing.reset-size10.size6,.katex .fontsize-ensurer.reset-size10.size6{font-size:.4821600771em}.katex .sizing.reset-size10.size7,.katex .fontsize-ensurer.reset-size10.size7{font-size:.5785920926em}.katex .sizing.reset-size10.size8,.katex .fontsize-ensurer.reset-size10.size8{font-size:.6943105111em}.katex .sizing.reset-size10.size9,.katex .fontsize-ensurer.reset-size10.size9{font-size:.8331726133em}.katex .sizing.reset-size10.size10,.katex .fontsize-ensurer.reset-size10.size10{font-size:1em}.katex .sizing.reset-size10.size11,.katex .fontsize-ensurer.reset-size10.size11{font-size:1.1996142719em}.katex .sizing.reset-size11.size1,.katex .fontsize-ensurer.reset-size11.size1{font-size:.2009646302em}.katex .sizing.reset-size11.size2,.katex .fontsize-ensurer.reset-size11.size2{font-size:.2411575563em}.katex .sizing.reset-size11.size3,.katex .fontsize-ensurer.reset-size11.size3{font-size:.2813504823em}.katex .sizing.reset-size11.size4,.katex .fontsize-ensurer.reset-size11.size4{font-size:.3215434084em}.katex .sizing.reset-size11.size5,.katex .fontsize-ensurer.reset-size11.size5{font-size:.3617363344em}.katex .sizing.reset-size11.size6,.katex .fontsize-ensurer.reset-size11.size6{font-size:.4019292605em}.katex .sizing.reset-size11.size7,.katex .fontsize-ensurer.reset-size11.size7{font-size:.4823151125em}.katex .sizing.reset-size11.size8,.katex .fontsize-ensurer.reset-size11.size8{font-size:.578778135em}.katex .sizing.reset-size11.size9,.katex .fontsize-ensurer.reset-size11.size9{font-size:.6945337621em}.katex .sizing.reset-size11.size10,.katex .fontsize-ensurer.reset-size11.size10{font-size:.8336012862em}.katex .sizing.reset-size11.size11,.katex .fontsize-ensurer.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .op-limits>.vlist-t{text-align:center}.katex .accent>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{display:block;position:absolute;width:100%;height:inherit;fill:currentColor;stroke:currentColor}.katex svg path{stroke:none}.katex svg{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img{border-style:none;min-width:0;min-height:0;max-width:none;max-height:none}.katex .stretchy{width:100%;display:block;position:relative;overflow:hidden}.katex .stretchy:before,.katex .stretchy:after{content:""}.katex .hide-tail{width:100%;position:relative;overflow:hidden}.katex .halfarrow-left{position:absolute;left:0;width:50.2%;overflow:hidden}.katex .halfarrow-right{position:absolute;right:0;width:50.2%;overflow:hidden}.katex .brace-left{position:absolute;left:0;width:25.1%;overflow:hidden}.katex .brace-center{position:absolute;left:25%;width:50%;overflow:hidden}.katex .brace-right{position:absolute;right:0;width:25.1%;overflow:hidden}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .x-arrow,.katex .mover,.katex .munder{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{box-sizing:border-box;border:.04em solid}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{box-sizing:border-box;border-top:.049em solid;border-right:.049em solid;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{counter-increment:katexEqnNo;content:"(" counter(katexEqnNo) ")"}.katex .mml-eqn-num:before{counter-increment:mmlEqnNo;content:"(" counter(mmlEqnNo) ")"}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;position:absolute;left:calc(50% + .3em);text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{text-align:left;padding-left:2em}body{counter-reset:katexEqnNo mmlEqnNo}@media(min-width:1024px){#banner-wrapper~* #navbar[data-transparent-mode=semi]>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=semi]>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(max-width:1023px){#banner-wrapper~* #navbar[data-transparent-mode=semi][data-is-home=true]>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=semi][data-is-home=true]>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(min-width:1024px){:root.dark #banner-wrapper~* #navbar[data-transparent-mode=semi]>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=semi]>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(max-width:1023px){:root.dark #banner-wrapper~* #navbar[data-transparent-mode=semi][data-is-home=true]>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=semi][data-is-home=true]>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(min-width:1024px){#banner-wrapper~* #navbar[data-transparent-mode=full]>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=full]>div{backdrop-filter:none!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(min-width:1024px){#banner-wrapper~* #navbar[data-transparent-mode=semifull]>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull]>div{backdrop-filter:none!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}#banner-wrapper~* #navbar[data-transparent-mode=semifull].scrolled>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull].scrolled>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(max-width:1023px){#banner-wrapper~* #navbar[data-transparent-mode=full][data-is-home=true]>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=full][data-is-home=true]>div{backdrop-filter:none!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(max-width:1023px){#banner-wrapper~* #navbar[data-transparent-mode=semifull][data-is-home=true]>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull][data-is-home=true]>div{backdrop-filter:none!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}#banner-wrapper~* #navbar[data-transparent-mode=semifull][data-is-home=true].scrolled>div,body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull][data-is-home=true].scrolled>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(min-width:1024px){:root.dark #banner-wrapper~* #navbar[data-transparent-mode=full]>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=full]>div{background:transparent!important;border:none!important;box-shadow:none!important}}@media(min-width:1024px){:root.dark #banner-wrapper~* #navbar[data-transparent-mode=semifull]>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull]>div{background:transparent!important;border:none!important;box-shadow:none!important}:root.dark #banner-wrapper~* #navbar[data-transparent-mode=semifull].scrolled>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull].scrolled>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(max-width:1023px){:root.dark #banner-wrapper~* #navbar[data-transparent-mode=full][data-is-home=true]>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=full][data-is-home=true]>div{background:transparent!important;border:none!important;box-shadow:none!important}}@media(max-width:1023px){:root.dark #banner-wrapper~* #navbar[data-transparent-mode=semifull][data-is-home=true]>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull][data-is-home=true]>div{background:transparent!important;border:none!important;box-shadow:none!important}:root.dark #banner-wrapper~* #navbar[data-transparent-mode=semifull][data-is-home=true].scrolled>div,:root.dark body:has(#banner-wrapper) #navbar[data-transparent-mode=semifull][data-is-home=true].scrolled>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(min-width:1024px){#banner-wrapper~* .dropdown-content,body:has(#banner-wrapper) .dropdown-content{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}#banner-wrapper~* #display-setting,body:has(#banner-wrapper) #display-setting{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}#banner-wrapper~* #nav-menu-panel,body:has(#banner-wrapper) #nav-menu-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}#banner-wrapper~* #translate-panel,body:has(#banner-wrapper) #translate-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}#banner-wrapper~* #mobile-toc-panel,body:has(#banner-wrapper) #mobile-toc-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}#banner-wrapper~* #search-panel,body:has(#banner-wrapper) #search-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}}@media(max-width:1023px){#banner-wrapper~* #navbar[data-is-home=true] .dropdown-content,body:has(#banner-wrapper) #navbar[data-is-home=true] .dropdown-content{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}#banner-wrapper~* #navbar[data-is-home=true]~* #display-setting,body:has(#banner-wrapper) #navbar[data-is-home=true]~* #display-setting{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}body:has(#banner-wrapper) #navbar[data-is-home=true] #nav-menu-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}body:has(#banner-wrapper) #navbar[data-is-home=true] #translate-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}body:has(#banner-wrapper) #navbar[data-is-home=true] #mobile-toc-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}body:has(#banner-wrapper) #navbar[data-is-home=true] #search-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}body:has(#banner-wrapper) #navbar[data-is-home=true] #display-setting{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}}@media(min-width:1024px){:root.dark #banner-wrapper~* .dropdown-content,:root.dark body:has(#banner-wrapper) .dropdown-content{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark #banner-wrapper~* #display-setting,:root.dark body:has(#banner-wrapper) #display-setting{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark #banner-wrapper~* #nav-menu-panel,:root.dark body:has(#banner-wrapper) #nav-menu-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark #banner-wrapper~* #translate-panel,:root.dark body:has(#banner-wrapper) #translate-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark #banner-wrapper~* #mobile-toc-panel,:root.dark body:has(#banner-wrapper) #mobile-toc-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark #banner-wrapper~* #search-panel,:root.dark body:has(#banner-wrapper) #search-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(max-width:1023px){:root.dark #banner-wrapper~* #navbar[data-is-home=true] .dropdown-content,:root.dark body:has(#banner-wrapper) #navbar[data-is-home=true] .dropdown-content{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark #banner-wrapper~* #navbar[data-is-home=true]~* #display-setting,:root.dark body:has(#banner-wrapper) #navbar[data-is-home=true]~* #display-setting{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body:has(#banner-wrapper) #navbar[data-is-home=true] #nav-menu-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body:has(#banner-wrapper) #navbar[data-is-home=true] #translate-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body:has(#banner-wrapper) #navbar[data-is-home=true] #mobile-toc-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body:has(#banner-wrapper) #navbar[data-is-home=true] #display-setting{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body:has(#banner-wrapper) #navbar[data-is-home=true] #search-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}#navbar>div{background:var(--card-bg);border-radius:var(--radius-large);transition:all .3s cubic-bezier(.4,0,.2,1)}@media(min-width:1024px){body.wallpaper-transparent #navbar[data-transparent-mode=semi]>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(max-width:1023px){body.wallpaper-transparent #navbar[data-transparent-mode=semi][data-is-home=true]>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(min-width:1024px){:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=semi]>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(max-width:1023px){:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=semi][data-is-home=true]>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(min-width:1024px){body.wallpaper-transparent #navbar[data-transparent-mode=full]>div{backdrop-filter:none!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(min-width:1024px){body.wallpaper-transparent #navbar[data-transparent-mode=semifull]>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}body.wallpaper-transparent #navbar[data-transparent-mode=semifull].scrolled>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(max-width:1023px){body.wallpaper-transparent #navbar[data-transparent-mode=full][data-is-home=true]>div{backdrop-filter:none!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(max-width:1023px){body.wallpaper-transparent #navbar[data-transparent-mode=semifull][data-is-home=true]>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}body.wallpaper-transparent #navbar[data-transparent-mode=semifull][data-is-home=true].scrolled>div{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;border-radius:.75rem!important;box-shadow:0 4px 16px #0000001a!important;transition:all .3s cubic-bezier(.4,0,.2,1)!important}}@media(min-width:1024px){:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=full]>div{background:transparent!important;border:none!important;box-shadow:none!important}}@media(min-width:1024px){:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=semifull]>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=semifull].scrolled>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(max-width:1023px){:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=full][data-is-home=true]>div{background:transparent!important;border:none!important;box-shadow:none!important}}@media(max-width:1023px){:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=semifull][data-is-home=true]>div{background:transparent!important;border:none!important;box-shadow:none!important}:root.dark body.wallpaper-transparent #navbar[data-transparent-mode=semifull][data-is-home=true].scrolled>div{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(min-width:768px)and (max-width:1023px){#navbar>div{border-radius:1rem!important}}@media(max-width:480px){#navbar>div{border-radius:.5rem!important;margin:0!important;padding-left:1rem!important;padding-right:1rem!important;max-width:none!important;width:100%!important}}@media(max-width:768px){#navbar>div{max-width:none!important;width:100%!important;margin-left:0!important;margin-right:0!important}}@media(min-width:1024px){body.wallpaper-transparent .dropdown-content,body.wallpaper-transparent #display-setting,body.wallpaper-transparent #nav-menu-panel,body.wallpaper-transparent #translate-panel,body.wallpaper-transparent #mobile-toc-panel,body.wallpaper-transparent #search-panel{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}}@media(max-width:1023px){body.wallpaper-transparent #navbar[data-is-home=true] .dropdown-content{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}body.wallpaper-transparent #navbar[data-is-home=true]~* #display-setting{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}body.wallpaper-transparent #navbar[data-is-home=true] #nav-menu-panel,body.wallpaper-transparent #navbar[data-is-home=true] #translate-panel,body.wallpaper-transparent #navbar[data-is-home=true] #mobile-toc-panel,body.wallpaper-transparent #navbar[data-is-home=true] #search-panel,body.wallpaper-transparent #navbar[data-is-home=true] #display-setting{backdrop-filter:blur(20px)!important;background:#ffffff8c!important;border:1px solid rgba(255,255,255,.55)!important;box-shadow:0 4px 16px #0000001a!important}}@media(min-width:1024px){:root.dark body.wallpaper-transparent .dropdown-content{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #display-setting{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #nav-menu-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #translate-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #mobile-toc-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #search-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}@media(max-width:1023px){:root.dark body.wallpaper-transparent #navbar[data-is-home=true] .dropdown-content{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #navbar[data-is-home=true]~* #display-setting{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #navbar[data-is-home=true] #nav-menu-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #navbar[data-is-home=true] #translate-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #navbar[data-is-home=true] #mobile-toc-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #navbar[data-is-home=true] #search-panel{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}:root.dark body.wallpaper-transparent #navbar[data-is-home=true] #display-setting{background:#0000008c!important;border:1px solid rgba(0,0,0,.55)!important;box-shadow:0 4px 16px #0003!important}}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:"`"}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: rgb(17 24 39 / 10%);--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: rgb(255 255 255 / 10%);--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-base{font-size:1rem;line-height:1.75}.prose-base :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-base :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose-base :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose-base :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose-base :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose-base :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose-base :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose-base :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-base :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose-base :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em}.prose-base :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em}.prose-base :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.9em}.prose-base :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose-base :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose-base :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose-base :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose-base :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-base :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-base :where(.prose-base>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-base :where(.prose-base>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(.prose-base>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-base :where(.prose-base>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(.prose-base>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-base :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-base :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-base :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose-base :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:3em;margin-bottom:3em}.prose-base :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.7142857}.prose-base :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose-base :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-base :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-base :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose-base :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-base :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-base :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-base :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose-base :where(.prose-base>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(.prose-base>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.enable-banner.is-home #banner-wrapper{height:var(--banner-height-home);--tw-translate-y: var(--banner-height-extend);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.enable-banner #banner-wrapper{height:var(--banner-height-home)}.enable-banner.is-home #banner{height:var(--banner-height-home);--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.enable-banner #banner{height:var(--banner-height-home);--tw-translate-y: var(--bannerOffset);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.enable-banner.is-home #main-grid{--tw-translate-y: var(--banner-height-extend);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.enable-banner #top-row{height:calc(var(--banner-height-home) - 4.5rem);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.enable-banner.is-home #sidebar-sticky{top:calc(1rem - var(--banner-height-extend))}.navbar-hidden{--tw-translate-y: -4rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));opacity:0}.waves>.parallax use{animation:wave 25s cubic-bezier(.5,.5,.45,.5) infinite}@keyframes wave{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}.dark\:prose-invert:is(.dark *){--tw-prose-body: var(--tw-prose-invert-body);--tw-prose-headings: var(--tw-prose-invert-headings);--tw-prose-lead: var(--tw-prose-invert-lead);--tw-prose-links: var(--tw-prose-invert-links);--tw-prose-bold: var(--tw-prose-invert-bold);--tw-prose-counters: var(--tw-prose-invert-counters);--tw-prose-bullets: var(--tw-prose-invert-bullets);--tw-prose-hr: var(--tw-prose-invert-hr);--tw-prose-quotes: var(--tw-prose-invert-quotes);--tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);--tw-prose-captions: var(--tw-prose-invert-captions);--tw-prose-kbd: var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);--tw-prose-code: var(--tw-prose-invert-code);--tw-prose-pre-code: var(--tw-prose-invert-pre-code);--tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);--tw-prose-th-borders: var(--tw-prose-invert-th-borders);--tw-prose-td-borders: var(--tw-prose-invert-td-borders)}@media(min-width:1024px){.lg\:is-home.enable-banner #banner-wrapper{height:var(--banner-height-home);--tw-translate-y: var(--banner-height-extend);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:is-home.enable-banner #banner{height:var(--banner-height-home);--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:is-home.enable-banner #main-grid{--tw-translate-y: var(--banner-height-extend);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:is-home.enable-banner #sidebar-sticky{top:calc(1rem - var(--banner-height-extend))}}.banner-title[data-astro-cid-haiuh7kc]{text-shadow:2px 2px 4px rgba(0,0,0,.7);animation:fadeInUp 1s ease-out}.banner-subtitle[data-astro-cid-haiuh7kc]{text-shadow:1px 1px 2px rgba(0,0,0,.6);animation:fadeInUp 1s ease-out .3s both}@keyframes fadeInUp{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}@media(max-width:768px){.mobile-no-sidebar[data-astro-cid-haiuh7kc]{display:block!important;width:100%!important}.mobile-no-sidebar[data-astro-cid-haiuh7kc] main[data-astro-cid-haiuh7kc]{width:100%!important;max-width:100%!important;margin:0!important;padding-left:0!important;padding-right:0!important}.mobile-no-sidebar[data-astro-cid-haiuh7kc] #content-wrapper[data-astro-cid-haiuh7kc]{width:100%!important;max-width:100%!important;margin:0!important}}@media(max-width:480px){#banner-wrapper[data-astro-cid-haiuh7kc]{height:70vh!important;min-height:450px;max-height:none;top:0!important}.absolute[data-astro-cid-haiuh7kc].w-full.z-30{top:70vh!important;min-height:30vh!important}.banner-text-overlay[data-astro-cid-haiuh7kc]{align-items:center!important;justify-content:center!important;padding:1rem!important;text-align:center!important}.banner-text-overlay[data-astro-cid-haiuh7kc]>div[data-astro-cid-haiuh7kc]{margin-bottom:0!important;width:95%!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:3.2rem!important;line-height:1.1!important;margin-bottom:.5rem!important;text-shadow:2px 2px 8px rgba(0,0,0,.8)!important}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:1rem!important;line-height:1.3!important;text-shadow:1px 1px 4px rgba(0,0,0,.7)!important}.waves[data-astro-cid-haiuh7kc]{height:8vh!important;min-height:60px!important;max-height:80px!important}}@media(min-width:481px)and (max-width:640px){#banner-wrapper[data-astro-cid-haiuh7kc]{height:75vh!important;min-height:500px;max-height:none;top:0!important}.absolute[data-astro-cid-haiuh7kc].w-full.z-30{top:75vh!important;min-height:25vh!important}.banner-text-overlay[data-astro-cid-haiuh7kc]{align-items:center!important;justify-content:center!important;padding:1.5rem!important;text-align:center!important}.banner-text-overlay[data-astro-cid-haiuh7kc]>div[data-astro-cid-haiuh7kc]{margin-bottom:0!important;width:90%!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:3.8rem!important;line-height:1.1!important;margin-bottom:.75rem!important;text-shadow:2px 2px 8px rgba(0,0,0,.8)!important}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:1.125rem!important;line-height:1.4!important;text-shadow:1px 1px 4px rgba(0,0,0,.7)!important}.waves[data-astro-cid-haiuh7kc]{height:10vh!important;min-height:70px!important;max-height:100px!important}}@media(min-width:641px)and (max-width:1023px){#banner-wrapper[data-astro-cid-haiuh7kc]{height:70vh!important;min-height:500px;top:0!important}.absolute[data-astro-cid-haiuh7kc].w-full.z-30{top:70vh!important;min-height:30vh!important}.banner-text-overlay[data-astro-cid-haiuh7kc]{align-items:center!important;justify-content:center!important;padding:2rem!important;text-align:center!important}.banner-text-overlay[data-astro-cid-haiuh7kc]>div[data-astro-cid-haiuh7kc]{margin-bottom:0!important;width:85%!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:4rem!important;line-height:1.1!important;margin-bottom:1rem!important;text-shadow:2px 2px 8px rgba(0,0,0,.8)!important}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:1.5rem!important;line-height:1.4!important;text-shadow:1px 1px 4px rgba(0,0,0,.7)!important}.waves[data-astro-cid-haiuh7kc]{height:12vh!important;min-height:80px!important;max-height:120px!important}}@media(min-width:1024px){.banner-text-overlay[data-astro-cid-haiuh7kc]{align-items:center!important;justify-content:center!important;padding:2rem!important;text-align:center!important}.banner-text-overlay[data-astro-cid-haiuh7kc]>div[data-astro-cid-haiuh7kc]{margin-bottom:0!important;width:75%!important;text-align:center!important}.carousel-item[data-astro-cid-haiuh7kc] img[data-astro-cid-haiuh7kc],#banner[data-astro-cid-haiuh7kc] img[data-astro-cid-haiuh7kc]{-o-object-position:center center!important;object-position:center center!important;transition:transform 1s ease-out!important}.carousel-item[data-astro-cid-haiuh7kc]{transition:all .5s ease-out!important;transform-origin:center center!important}.carousel-item[data-astro-cid-haiuh7kc].opacity-100.scale-100{transform:scale(1)!important;opacity:1!important}.carousel-item[data-astro-cid-haiuh7kc].opacity-0.scale-110{transform:scale(1.15)!important;opacity:0!important}#banner-carousel[data-astro-cid-haiuh7kc]{overflow:hidden!important}.waves[data-astro-cid-haiuh7kc]{height:15vh!important;min-height:80px!important;max-height:150px!important}}@media(max-width:1023px){.carousel-item[data-astro-cid-haiuh7kc] img[data-astro-cid-haiuh7kc],#banner[data-astro-cid-haiuh7kc] img[data-astro-cid-haiuh7kc]{-o-object-position:center center!important;object-position:center center!important;transition:transform .5s ease-out!important}.carousel-item[data-astro-cid-haiuh7kc]{transition:all 1s ease-out!important;transform-origin:center center!important}.carousel-item[data-astro-cid-haiuh7kc].opacity-100.scale-100{transform:scale(1)!important;opacity:1!important}.carousel-item[data-astro-cid-haiuh7kc].opacity-0.scale-110{transform:scale(1.15)!important;opacity:0!important}#banner-carousel[data-astro-cid-haiuh7kc]{overflow:hidden!important}.onload-animation-fade-in[data-astro-cid-haiuh7kc]{animation:mobile-fade-in .8s ease-out forwards!important}}@keyframes mobile-fade-in{0%{opacity:0;transform:scale(1.1)}to{opacity:1;transform:scale(1)}}@media(max-width:1023px){#banner-wrapper[data-astro-cid-haiuh7kc]{transition:transform .5s cubic-bezier(.25,.46,.45,.94),opacity .3s ease-out;transform-origin:top center;will-change:transform,opacity;backface-visibility:hidden;-webkit-backface-visibility:hidden;transform:translateZ(0);-webkit-transform:translateZ(0)}.mobile-hide-banner[data-astro-cid-haiuh7kc]{transform:translateY(-100%) translateZ(0)!important;opacity:0!important;pointer-events:none!important;transition:transform .3s ease-in,opacity .2s ease-in!important}.absolute[data-astro-cid-haiuh7kc].w-full.z-30{transition:top .4s cubic-bezier(.25,.46,.45,.94) .1s;will-change:top;transform:translateZ(0);-webkit-transform:translateZ(0)}.absolute[data-astro-cid-haiuh7kc].w-full.z-30.mobile-main-no-banner{top:5.5rem!important;min-height:calc(100vh - 5.5rem)!important;transition:top .3s cubic-bezier(.25,.46,.45,.94) .2s!important}.banner-container[data-astro-cid-haiuh7kc]{transform:translateZ(0);-webkit-transform:translateZ(0);will-change:transform,opacity;contain:layout style paint;backface-visibility:hidden;-webkit-backface-visibility:hidden}.carousel-item[data-astro-cid-haiuh7kc]{transform:translateZ(0);-webkit-transform:translateZ(0);will-change:transform,opacity;touch-action:pan-y;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.banner-text-overlay[data-astro-cid-haiuh7kc]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;contain:layout style}.banner-container[data-astro-cid-haiuh7kc] img[data-astro-cid-haiuh7kc]{image-rendering:-webkit-optimize-contrast;image-rendering:crisp-edges;-webkit-user-drag:none;-khtml-user-drag:none;-moz-user-drag:none;-o-user-drag:none;user-drag:none;pointer-events:none}.carousel-indicators[data-astro-cid-haiuh7kc]{position:absolute;bottom:20px;left:50%;transform:translate(-50%);display:flex;gap:8px;z-index:10}.carousel-indicator[data-astro-cid-haiuh7kc]{width:8px;height:8px;border-radius:50%;background:#ffffff80;transition:all .3s ease;cursor:pointer}.carousel-indicator[data-astro-cid-haiuh7kc].active{background:#ffffffe6;transform:scale(1.2)}}.no-banner-layout[data-astro-cid-haiuh7kc]{top:5.5rem!important;min-height:calc(100vh - 5.5rem)!important}@media(max-width:1023px){.absolute[data-astro-cid-haiuh7kc].w-full.z-30.no-banner-layout{top:5.5rem!important;min-height:calc(100vh - 5.5rem)!important;transition:none!important}}@media(max-width:480px){.absolute[data-astro-cid-haiuh7kc].w-full.z-30.no-banner-layout{top:5.5rem!important;min-height:calc(100vh - 5.5rem)!important;transition:none!important}}@media(min-width:641px)and (max-width:1023px){.absolute[data-astro-cid-haiuh7kc].w-full.z-30.no-banner-layout{top:5.5rem!important;min-height:calc(100vh - 5.5rem)!important;transition:none!important}}@media(max-width:1023px)and (orientation:landscape){#banner-wrapper[data-astro-cid-haiuh7kc]:not(.mobile-hide-banner){top:0!important;height:60vh!important}.absolute[data-astro-cid-haiuh7kc].w-full.z-30:not(.mobile-main-no-banner){top:60vh!important;min-height:40vh!important}.banner-container[data-astro-cid-haiuh7kc]{height:60vh;min-height:300px}.banner-text-overlay[data-astro-cid-haiuh7kc]{padding:1rem 1.5rem;align-items:center!important;justify-content:center!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:2.2rem!important;line-height:1.3}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:.9rem;margin-top:.5rem}}@media(max-width:1023px)and (prefers-color-scheme:dark){.banner-text-overlay[data-astro-cid-haiuh7kc]{background:linear-gradient(to top,rgba(0,0,0,.8) 0%,rgba(0,0,0,.4) 50%,transparent 100%)}.banner-title[data-astro-cid-haiuh7kc]{text-shadow:2px 2px 8px rgba(0,0,0,.8)}.banner-subtitle[data-astro-cid-haiuh7kc]{text-shadow:1px 1px 4px rgba(0,0,0,.7)}}.waves[data-astro-cid-haiuh7kc]{overflow:visible;z-index:5;transform:translateZ(0);will-change:transform;contain:layout style paint}.waves[data-astro-cid-haiuh7kc] svg[data-astro-cid-haiuh7kc]{width:100%;height:100%;display:block;transform:translateZ(0);backface-visibility:hidden}.waves[data-astro-cid-haiuh7kc] use[data-astro-cid-haiuh7kc]{will-change:fill}#header-waves[data-astro-cid-haiuh7kc]{isolation:isolate;contain:layout style paint;margin-bottom:-1px}.theme-changing[data-astro-cid-haiuh7kc] #header-waves[data-astro-cid-haiuh7kc],.theme-changing[data-astro-cid-haiuh7kc] #header-waves[data-astro-cid-haiuh7kc] svg[data-astro-cid-haiuh7kc],.theme-changing[data-astro-cid-haiuh7kc] #header-waves[data-astro-cid-haiuh7kc] use[data-astro-cid-haiuh7kc]{will-change:auto;transform:translateZ(0);backface-visibility:hidden}@media(max-width:1023px){#header-waves[data-astro-cid-haiuh7kc]{overflow:visible;z-index:5;transition:transform .3s ease-in,opacity .2s ease-in}.mobile-hide-banner[data-astro-cid-haiuh7kc] #header-waves[data-astro-cid-haiuh7kc]{transform:translateY(-100%);opacity:0;transition:transform .25s ease-in,opacity .15s ease-in}.waves[data-astro-cid-haiuh7kc] svg[data-astro-cid-haiuh7kc]{min-height:60px}.waves[data-astro-cid-haiuh7kc]{bottom:-1px!important;position:absolute!important}}@media(max-width:360px){.waves[data-astro-cid-haiuh7kc]{height:6vh!important;min-height:50px!important;max-height:70px!important}}@media(max-height:500px){#banner-wrapper[data-astro-cid-haiuh7kc]{height:85vh!important;min-height:350px!important}.banner-text-overlay[data-astro-cid-haiuh7kc]{padding:1rem!important;align-items:center!important;justify-content:center!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:2.8rem!important;line-height:1.1!important;margin-bottom:.5rem!important}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:.9rem!important;line-height:1.2!important}.waves[data-astro-cid-haiuh7kc]{height:5vh!important;min-height:40px!important;max-height:50px!important}}@media(min-height:501px)and (max-height:600px){#banner-wrapper[data-astro-cid-haiuh7kc]{height:80vh!important;min-height:400px!important}.banner-text-overlay[data-astro-cid-haiuh7kc]{padding:1.5rem!important;align-items:center!important;justify-content:center!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:3.2rem!important;line-height:1.1!important;margin-bottom:.75rem!important}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:1rem!important;line-height:1.3!important}.waves[data-astro-cid-haiuh7kc]{height:6vh!important;min-height:50px!important;max-height:60px!important}}@media(min-height:601px)and (max-height:700px){#banner-wrapper[data-astro-cid-haiuh7kc]{height:75vh!important;min-height:450px!important}.banner-text-overlay[data-astro-cid-haiuh7kc]{padding:2rem!important;align-items:center!important;justify-content:center!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:3.8rem!important;line-height:1.1!important;margin-bottom:1rem!important}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:1.125rem!important;line-height:1.4!important}.waves[data-astro-cid-haiuh7kc]{height:8vh!important;min-height:60px!important;max-height:80px!important}}@media(orientation:landscape)and (max-height:500px){#banner-wrapper[data-astro-cid-haiuh7kc]{height:90vh!important;min-height:300px!important}.banner-text-overlay[data-astro-cid-haiuh7kc]{padding:1rem 2rem!important;align-items:center!important;justify-content:center!important;text-align:center!important}.banner-title[data-astro-cid-haiuh7kc]{font-size:2.8rem!important;line-height:1.1!important;margin-bottom:.5rem!important}.banner-subtitle[data-astro-cid-haiuh7kc]{font-size:1rem!important;line-height:1.2!important}.waves[data-astro-cid-haiuh7kc]{height:4vh!important;min-height:30px!important;max-height:40px!important}} diff --git a/website/blog/_astro/_page_.C0I9pl0C.css b/website/blog/_astro/_page_.C0I9pl0C.css deleted file mode 100644 index 5fbb0fe..0000000 --- a/website/blog/_astro/_page_.C0I9pl0C.css +++ /dev/null @@ -1 +0,0 @@ -input.svelte-1wah7ro:focus{outline:0}.search-panel.svelte-1wah7ro{max-height:calc(100vh - 100px);overflow-y:auto}.mobile-toc-panel.svelte-cz3h3s{max-height:calc(100vh - 120px);overflow-y:auto;background:var(--card-bg);border:1px solid var(--line-color);backdrop-filter:blur(10px)}.toc-content.svelte-cz3h3s{display:flex;flex-direction:column;gap:2px}.post-content.svelte-cz3h3s{display:flex;flex-direction:column;gap:4px}.toc-item.svelte-cz3h3s{display:block;width:100%;text-align:left;padding:8px 12px;border-radius:8px;transition:all .2s ease;border:none;background:transparent;cursor:pointer;color:#000000bf;font-size:.9rem;line-height:1.4}.dark .toc-item.svelte-cz3h3s{color:#ffffffbf}.toc-item.svelte-cz3h3s:hover{background:var(--btn-plain-bg-hover);color:var(--primary)}.toc-item.active.svelte-cz3h3s{background:var(--btn-plain-bg-active);color:var(--primary);font-weight:600;border-left:3px solid var(--primary);padding-left:9px}.toc-item.level-1.svelte-cz3h3s{padding-left:12px;font-weight:600;font-size:1rem}.toc-item.level-2.svelte-cz3h3s{padding-left:20px}.toc-item.level-3.svelte-cz3h3s{padding-left:28px;font-size:.85rem}.toc-item.level-4.svelte-cz3h3s{padding-left:36px;font-size:.8rem}.toc-item.level-5.svelte-cz3h3s,.toc-item.level-6.svelte-cz3h3s{padding-left:44px;font-size:.75rem;color:#00000080}.dark .toc-item.level-5.svelte-cz3h3s,.dark .toc-item.level-6.svelte-cz3h3s{color:#ffffff80}.toc-item.level-1.active.svelte-cz3h3s{padding-left:9px}.toc-item.level-2.active.svelte-cz3h3s{padding-left:17px}.toc-item.level-3.active.svelte-cz3h3s{padding-left:25px}.toc-item.level-4.active.svelte-cz3h3s{padding-left:33px}.toc-item.level-5.active.svelte-cz3h3s,.toc-item.level-6.active.svelte-cz3h3s{padding-left:41px}.toc-text.svelte-cz3h3s{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.post-item.svelte-cz3h3s{display:block;width:100%;text-align:left;padding:12px;border-radius:8px;transition:all .2s ease;border:none;background:transparent;cursor:pointer;border:1px solid var(--line-color)}.post-item.svelte-cz3h3s:hover{background:var(--btn-plain-bg-hover);border-color:var(--primary);transform:translateY(-1px);box-shadow:0 2px 8px #0000001a}.post-title.svelte-cz3h3s{font-size:.9rem;font-weight:600;color:#000000bf;margin-bottom:4px;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dark .post-title.svelte-cz3h3s{color:#ffffffbf}.post-category.svelte-cz3h3s{font-size:.75rem;color:#00000080;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dark .post-category.svelte-cz3h3s{color:#ffffff80}.pinned-icon{display:inline;color:var(--primary);font-size:1.25rem;margin-right:.5rem;transform:translateY(-.125rem);vertical-align:middle}.post-item.svelte-cz3h3s:hover .post-title:where(.svelte-cz3h3s){color:var(--primary)}.post-item.svelte-cz3h3s:hover .post-category:where(.svelte-cz3h3s){color:#000000bf}.dark .post-item.svelte-cz3h3s:hover .post-category:where(.svelte-cz3h3s){color:#ffffffbf}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar{width:4px}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar-track{background:transparent}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar-thumb{background:var(--line-color);border-radius:2px}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar-thumb:hover{background:var(--text-color-25)}.float-panel-closed.svelte-1dy47ij{opacity:0;pointer-events:none;transform:translateY(-10px);transition:all .2s ease-out}#translate-panel.svelte-1dy47ij:not(.float-panel-closed){opacity:1;pointer-events:auto;transform:translateY(0)}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar{width:4px}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar-track{background:transparent}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar-thumb{background:var(--scrollbar-bg);border-radius:2px}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-bg-hover)}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k){-webkit-appearance:none;height:1.5rem;background-image:var(--color-selection-bar);transition:background-image .15s ease-in-out}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-webkit-slider-thumb{-webkit-appearance:none;height:1rem;width:.5rem;border-radius:.125rem;background:#ffffffb3;box-shadow:none}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-webkit-slider-thumb:hover{background:#fffc}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-webkit-slider-thumb:active{background:#fff9}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-moz-range-thumb{-webkit-appearance:none;height:1rem;width:.5rem;border-radius:.125rem;border-width:0;background:#ffffffb3;box-shadow:none}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-moz-range-thumb:hover{background:#fffc}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-moz-range-thumb:active{background:#fff9}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-ms-thumb{-webkit-appearance:none;height:1rem;width:.5rem;border-radius:.125rem;background:#ffffffb3;box-shadow:none}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-ms-thumb:hover{background:#fffc}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-ms-thumb:active{background:#fff9} diff --git a/website/blog/_astro/_page_.D6v8Siar.css b/website/blog/_astro/_page_.D6v8Siar.css deleted file mode 100644 index 709ffbd..0000000 --- a/website/blog/_astro/_page_.D6v8Siar.css +++ /dev/null @@ -1 +0,0 @@ -*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Roboto,sans-serif,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:"`"}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: rgb(17 24 39 / 10%);--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: rgb(255 255 255 / 10%);--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-base{font-size:1rem;line-height:1.75}.prose-base :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-base :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose-base :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose-base :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose-base :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose-base :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose-base :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose-base :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-base :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose-base :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em}.prose-base :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em}.prose-base :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.9em}.prose-base :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose-base :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose-base :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose-base :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose-base :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-base :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-base :where(.prose-base>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-base :where(.prose-base>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(.prose-base>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-base :where(.prose-base>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(.prose-base>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-base :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-base :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-base :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose-base :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:3em;margin-bottom:3em}.prose-base :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.7142857}.prose-base :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose-base :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-base :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-base :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose-base :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-base :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-base :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-base :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose-base :where(.prose-base>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(.prose-base>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.-bottom-\[1px\]{bottom:-1px}.-left-\[var\(--toc-width\)\]{left:calc(var(--toc-width) * -1)}.-right-\[var\(--toc-width\)\]{right:calc(var(--toc-width) * -1)}.-top-8{top:-2rem}.-top-\[3\.25rem\]{top:-3.25rem}.bottom-0{bottom:0}.bottom-20{bottom:5rem}.bottom-3{bottom:.75rem}.bottom-4{bottom:1rem}.left-0{left:0}.left-3{left:.75rem}.left-4{left:1rem}.left-6{left:1.5rem}.right-0{right:0}.right-3{right:.75rem}.right-4{right:1rem}.right-6{right:1.5rem}.top-0{top:0}.top-1\/2{top:50%}.top-14{top:3.5rem}.top-20{top:5rem}.top-3{top:.75rem}.top-4{top:1rem}.top-\[3\.5rem\]{top:3.5rem}.top-\[calc\(1rem_-_var\(--banner-height-extend\)\)\]{top:calc(1rem - var(--banner-height-extend))}.top-full{top:100%}.isolate{isolation:isolate}.-z-10{z-index:-10}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[60\]{z-index:60}.col-span-1{grid-column:span 1 / span 1}.col-span-2{grid-column:span 2 / span 2}.row-start-2{grid-row-start:2}.row-end-3{grid-row-end:3}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-1\.5{margin-left:.375rem;margin-right:.375rem}.mx-16{margin-left:4rem;margin-right:4rem}.mx-32{margin-left:8rem;margin-right:8rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-auto{margin-top:auto;margin-bottom:auto}.-mb-2{margin-bottom:-.5rem}.mb-0{margin-bottom:0}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-2\.5{margin-bottom:.625rem}.mb-3{margin-bottom:.75rem}.mb-3\.5{margin-bottom:.875rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-8{margin-left:2rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.\!hidden{display:none!important}.hidden{display:none}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-20{height:5rem}.h-28{height:7rem}.h-3{height:.75rem}.h-4{height:1rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[10vh\]{height:10vh}.h-\[3\.25rem\]{height:3.25rem}.h-\[3\.75rem\]{height:3.75rem}.h-\[300vh\]{height:300vh}.h-\[4\.5rem\]{height:4.5rem}.h-\[calc\(100vh_-_20rem\)\]{height:calc(100vh - 20rem)}.h-\[calc\(var\(--banner-height-home\)_-_4\.5rem\)\]{height:calc(var(--banner-height-home) - 4.5rem)}.h-\[var\(--banner-height-home\)\]{height:var(--banner-height-home)}.h-full{height:100%}.max-h-0{max-height:0px}.max-h-64{max-height:16rem}.max-h-80{max-height:20rem}.max-h-96{max-height:24rem}.max-h-\[20vh\]{max-height:20vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[9\.375rem\]{max-height:9.375rem}.max-h-full{max-height:100%}.min-h-32{min-height:8rem}.min-h-9{min-height:2.25rem}.min-h-96{min-height:24rem}.min-h-\[3\.125rem\]{min-height:3.125rem}.min-h-screen{min-height:100vh}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-28{width:7rem}.w-3{width:.75rem}.w-4{width:1rem}.w-4\/5{width:80%}.w-40{width:10rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-\[15\%\]{width:15%}.w-\[3\.25rem\]{width:3.25rem}.w-\[3\.75rem\]{width:3.75rem}.w-\[70\%\]{width:70%}.w-\[calc\(100vw-2rem\)\]{width:calc(100vw - 2rem)}.w-\[var\(--toc-width\)\]{width:var(--toc-width)}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[12rem\]{min-width:12rem}.min-w-\[2rem\]{min-width:2rem}.\!max-w-none{max-width:none!important}.max-w-4xl{max-width:56rem}.max-w-\[12rem\]{max-width:12rem}.max-w-\[calc\(100\%_-_3rem\)\]{max-width:calc(100% - 3rem)}.max-w-\[var\(\&\#45\;\&\#45\;page-width\)\]{max-width:var(--page-width)}.max-w-\[var\(--page-width\)\]{max-width:var(--page-width)}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-2{--tw-translate-x: -.5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-0\.5{--tw-translate-y: -.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-16{--tw-translate-y: -4rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-\[1px\]{--tw-translate-y: -1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0\.5{--tw-translate-y: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-8px\]{--tw-translate-y: -8px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[var\(--banner-height-extend\)\]{--tw-translate-y: var(--banner-height-extend);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[var\(--bannerOffset\)\]{--tw-translate-y: var(--bannerOffset);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-0{--tw-scale-x: 0;--tw-scale-y: 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-105{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-50{--tw-scale-x: .5;--tw-scale-y: .5;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-90{--tw-scale-x: .9;--tw-scale-y: .9;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-95{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-rows-\[auto_1fr_auto\]{grid-template-rows:auto 1fr auto}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-stretch{align-items:stretch}.\!justify-start{justify-content:flex-start!important}.justify-start{justify-content:flex-start}.\!justify-end{justify-content:flex-end!important}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-2{row-gap:.5rem}.gap-y-8{row-gap:2rem}.space-x-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.125rem * var(--tw-space-x-reverse));margin-left:calc(.125rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.\!overflow-visible{overflow:visible!important}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-scroll{overflow-y:scroll}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.overflow-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[0\.1875rem\]{border-radius:.1875rem}.rounded-\[var\(--radius-large\)\]{border-radius:var(--radius-large)}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.rounded-xl{border-radius:.75rem}.rounded-b-\[calc\(var\(--radius-large\)-0\.5rem\)\]{border-bottom-right-radius:calc(var(--radius-large) - .5rem);border-bottom-left-radius:calc(var(--radius-large) - .5rem)}.rounded-t-\[calc\(var\(--radius-large\)-0\.5rem\)\]{border-top-left-radius:calc(var(--radius-large) - .5rem);border-top-right-radius:calc(var(--radius-large) - .5rem)}.border{border-width:1px}.border-2{border-width:2px}.border-b,.border-b-\[1px\]{border-bottom-width:1px}.border-t,.border-t-\[1px\]{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[oklch\(85\%_0\.01_var\(--hue\)\)\]{border-color:oklch(85% .01 var(--hue))}.border-\[var\(\&\#45\;\&\#45\;primary\)\]{border-color:var(--primary)}.border-\[var\(--line-divider\)\]{border-color:var(--line-divider)}.border-\[var\(--primary\)\]{border-color:var(--primary)}.border-\[var\(--toc-btn-hover\)\]{border-color:var(--toc-btn-hover)}.border-black\/10{border-color:#0000001a}.border-black\/5{border-color:#0000000d}.bg-\[oklch\(0\.5_0\.05_var\(--hue\)\)\]{background-color:oklch(.5 .05 var(--hue))}.bg-\[oklch\(0\.80_0\.10_0\)\]{background-color:#f3a3bb}.bg-\[oklch\(0\.85_0\.1_140\)\]{background-color:#abdea0}.bg-\[oklch\(0\.85_0\.1_240\)\]{background-color:oklch(.85 .1 240)}.bg-\[oklch\(0\.95_0\.025_var\(--hue\)\)\]{background-color:oklch(.95 .025 var(--hue))}.bg-\[oklch\(92\%_0\.01_var\(\&\#45\;\&\#45\;hue\)\)\]{background-color:oklch(92% .01 var(--hue))}.bg-\[var\(--btn-content\)\]{background-color:var(--btn-content)}.bg-\[var\(--btn-plain-bg\)\]{background-color:var(--btn-plain-bg)}.bg-\[var\(--btn-plain-bg-hover\)\]{background-color:var(--btn-plain-bg-hover)}.bg-\[var\(--btn-regular-bg\)\]{background-color:var(--btn-regular-bg)}.bg-\[var\(--card-bg\)\]{background-color:var(--card-bg)}.bg-\[var\(--enter-btn-bg\)\]{background-color:var(--enter-btn-bg)}.bg-\[var\(--float-panel-bg\)\]{background-color:var(--float-panel-bg)}.bg-\[var\(--license-block-bg\)\]{background-color:var(--license-block-bg)}.bg-\[var\(--page-bg\)\]{background-color:var(--page-bg)}.bg-\[var\(--primary\)\]{background-color:var(--primary)}.bg-\[var\(--toc-badge-bg\)\]{background-color:var(--toc-badge-bg)}.bg-\[var\(--toc-btn-hover\)\]{background-color:var(--toc-btn-hover)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/0{background-color:#0000}.bg-black\/20{background-color:#0003}.bg-black\/5{background-color:#0000000d}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-black\/80{background-color:#000c}.bg-black\/90{background-color:#000000e6}.bg-black\/\[0\.04\]{background-color:#0000000a}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-purple-500{--tw-bg-opacity: 1;background-color:rgb(168 85 247 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/5{background-color:#ffffff0d}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1))}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-zinc-200{--tw-bg-opacity: 1;background-color:rgb(228 228 231 / var(--tw-bg-opacity, 1))}.bg-opacity-50{--tw-bg-opacity: .5}.bg-opacity-90{--tw-bg-opacity: .9}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.bg-none{background-image:none}.from-black\/60{--tw-gradient-from: rgb(0 0 0 / .6) var(--tw-gradient-from-position);--tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-50{--tw-gradient-from: #eff6ff var(--tw-gradient-from-position);--tw-gradient-to: rgb(239 246 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-50{--tw-gradient-from: #f0fdf4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(240 253 244 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-50{--tw-gradient-from: #fff7ed var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 247 237 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-50{--tw-gradient-from: #faf5ff var(--tw-gradient-from-position);--tw-gradient-to: rgb(250 245 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-50{--tw-gradient-from: #fef2f2 var(--tw-gradient-from-position);--tw-gradient-to: rgb(254 242 242 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-yellow-50{--tw-gradient-from: #fefce8 var(--tw-gradient-from-position);--tw-gradient-to: rgb(254 252 232 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-blue-100{--tw-gradient-to: #dbeafe var(--tw-gradient-to-position)}.to-green-100{--tw-gradient-to: #dcfce7 var(--tw-gradient-to-position)}.to-orange-100{--tw-gradient-to: #ffedd5 var(--tw-gradient-to-position)}.to-purple-100{--tw-gradient-to: #f3e8ff var(--tw-gradient-to-position)}.to-red-100{--tw-gradient-to: #fee2e2 var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.to-yellow-100{--tw-gradient-to: #fef9c3 var(--tw-gradient-to-position)}.fill-\[var\(--page-bg\)\]{fill:var(--page-bg)}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.object-bottom{-o-object-position:bottom;object-position:bottom}.object-center{-o-object-position:center;object-position:center}.object-top{-o-object-position:top;object-position:top}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-9{padding-left:2.25rem;padding-right:2.25rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pl-10{padding-left:2.5rem}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-6{padding-left:1.5rem}.pr-1{padding-right:.25rem}.pr-4{padding-right:1rem}.pr-6{padding-right:1.5rem}.pr-8{padding-right:2rem}.pt-2{padding-top:.5rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-6xl{font-size:3.75rem;line-height:1}.text-8xl{font-size:6rem;line-height:1}.text-\[0\.75rem\]{font-size:.75rem}.text-\[0\.875rem\]{font-size:.875rem}.text-\[1\.1rem\]{font-size:1.1rem}.text-\[1\.25rem\]{font-size:1.25rem}.text-\[1\.5rem\]{font-size:1.5rem}.text-\[1\.75rem\]{font-size:1.75rem}.text-\[14px\]{font-size:14px}.text-\[15rem\]{font-size:15rem}.text-\[1rem\]{font-size:1rem}.text-\[2rem\]{font-size:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.text-\[oklch\(0\.35_0\.15_140\)\]{color:oklch(.35 .15 140)}.text-\[oklch\(0\.35_0\.15_240\)\]{color:oklch(.35 .15 240)}.text-\[oklch\(0\.65_0\.15_140\)\]{color:#58a547}.text-\[oklch\(0\.65_0\.15_240\)\]{color:oklch(.65 .15 240)}.text-\[oklch\(0\.75_0\.14_var\(--hue\)\)\]{color:oklch(.75 .14 var(--hue))}.text-\[oklch\(0\.75_0\.15_80\)\]{color:#dfa11a}.text-\[var\(--btn-content\)\]{color:var(--btn-content)}.text-\[var\(--content-meta\)\]{color:var(--content-meta)}.text-\[var\(--deep-text\)\]{color:var(--deep-text)}.text-\[var\(--meta-divider\)\]{color:var(--meta-divider)}.text-\[var\(--primary\)\]{color:var(--primary)}.text-black\/25{color:#00000040}.text-black\/30{color:#0000004d}.text-black\/5{color:#0000000d}.text-black\/50{color:#00000080}.text-black\/60{color:#0009}.text-black\/70{color:#000000b3}.text-black\/75{color:#000000bf}.text-black\/80{color:#000c}.text-black\/90{color:#000000e6}.text-black\/\[0\.2\]{color:#0003}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-600\/70{color:#2563ebb3}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-600\/70{color:#16a34ab3}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-600{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.text-neutral-700{--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1))}.text-neutral-900{--tw-text-opacity: 1;color:rgb(23 23 23 / var(--tw-text-opacity, 1))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-orange-600\/70{color:#ea580cb3}.text-orange-700{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-600\/70{color:#9333eab3}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-600\/70{color:#dc2626b3}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/75{color:#ffffffbf}.text-white\/80{color:#fffc}.text-white\/90{color:#ffffffe6}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-600\/70{color:#ca8a04b3}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-10{opacity:.1}.opacity-100{opacity:1}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.outline-0{outline-width:0px}.outline-4{outline-width:4px}.-outline-offset-\[2px\]{outline-offset:-2px}.outline-\[var\(--card-bg\)\]{outline-color:var(--card-bg)}.outline-\[var\(--primary\)\]{outline-color:var(--primary)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-lg{--tw-drop-shadow: drop-shadow(0 10px 8px rgb(0 0 0 / .04)) drop-shadow(0 4px 3px rgb(0 0 0 / .1));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-md{--tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / .07)) drop-shadow(0 2px 2px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale: grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-filter{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-1000{transition-duration:1s}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.duration-700{transition-duration:.7s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.dark\:prose-invert:is(.dark *){--tw-prose-body: var(--tw-prose-invert-body);--tw-prose-headings: var(--tw-prose-invert-headings);--tw-prose-lead: var(--tw-prose-invert-lead);--tw-prose-links: var(--tw-prose-invert-links);--tw-prose-bold: var(--tw-prose-invert-bold);--tw-prose-counters: var(--tw-prose-invert-counters);--tw-prose-bullets: var(--tw-prose-invert-bullets);--tw-prose-hr: var(--tw-prose-invert-hr);--tw-prose-quotes: var(--tw-prose-invert-quotes);--tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);--tw-prose-captions: var(--tw-prose-invert-captions);--tw-prose-kbd: var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);--tw-prose-code: var(--tw-prose-invert-code);--tw-prose-pre-code: var(--tw-prose-invert-pre-code);--tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);--tw-prose-th-borders: var(--tw-prose-invert-th-borders);--tw-prose-td-borders: var(--tw-prose-invert-td-borders)}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:-left-3:before{content:var(--tw-content);left:-.75rem}.before\:left-\[-1\.125rem\]:before{content:var(--tw-content);left:-1.125rem}.before\:left-\[-16px\]:before{content:var(--tw-content);left:-16px}.before\:left-\[18px\]:before{content:var(--tw-content);left:18px}.before\:top-\[0\.33rem\]:before{content:var(--tw-content);top:.33rem}.before\:top-\[0\.75rem\]:before{content:var(--tw-content);top:.75rem}.before\:top-\[35px\]:before{content:var(--tw-content);top:35px}.before\:top-\[5\.5px\]:before{content:var(--tw-content);top:5.5px}.before\:hidden:before{content:var(--tw-content);display:none}.before\:h-4:before{content:var(--tw-content);height:1rem}.before\:h-5:before{content:var(--tw-content);height:1.25rem}.before\:w-1:before{content:var(--tw-content);width:.25rem}.before\:rounded-md:before{content:var(--tw-content);border-radius:.375rem}.before\:bg-\[var\(--primary\)\]:before{content:var(--tw-content);background-color:var(--primary)}.last\:border-t-0:last-child{border-top-width:0px}.first-of-type\:mt-2:first-of-type{margin-top:.5rem}.focus-within\:bg-black\/\[0\.06\]:focus-within{background-color:#0000000f}.hover\:scale-105:hover{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-\[var\(--btn-card-bg-hover\)\]:hover{background-color:var(--btn-card-bg-hover)}.hover\:bg-\[var\(--btn-plain-bg-hover\)\]:hover{background-color:var(--btn-plain-bg-hover)}.hover\:bg-\[var\(--btn-regular-bg\)\]:hover{background-color:var(--btn-regular-bg)}.hover\:bg-\[var\(--enter-btn-bg-hover\)\]:hover{background-color:var(--enter-btn-bg-hover)}.hover\:bg-\[var\(--primary-dark\)\]:hover{background-color:var(--primary-dark)}.hover\:bg-\[var\(--toc-btn-hover\)\]:hover{background-color:var(--toc-btn-hover)}.hover\:bg-black\/70:hover{background-color:#000000b3}.hover\:bg-black\/\[0\.06\]:hover{background-color:#0000000f}.hover\:bg-red-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.hover\:bg-opacity-70:hover{--tw-bg-opacity: .7}.hover\:pl-3:hover{padding-left:.75rem}.hover\:pr-9:hover{padding-right:2.25rem}.hover\:text-\[initial\]:hover{color:initial}.hover\:text-\[var\(--primary\)\]:hover{color:var(--primary)}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:w-60:focus{width:15rem}.active\:w-60:active{width:15rem}.active\:scale-90:active{--tw-scale-x: .9;--tw-scale-y: .9;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-95:active{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-\[0\.85\]:active{--tw-scale-x: .85;--tw-scale-y: .85;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:bg-\[var\(--btn-plain-bg-active\)\]:active{background-color:var(--btn-plain-bg-active)}.active\:bg-\[var\(--enter-btn-bg-active\)\]:active{background-color:var(--enter-btn-bg-active)}.active\:bg-\[var\(--toc-btn-active\)\]:active{background-color:var(--toc-btn-active)}.active\:bg-black\/80:active{background-color:#000c}.active\:text-\[var\(--title-active\)\]:active{color:var(--title-active)}.group:hover .group-hover\:h-5{height:1.25rem}.group:hover .group-hover\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-100{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-105{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:border-\[var\(--toc-btn-active\)\]{border-color:var(--toc-btn-active)}.group:hover .group-hover\:bg-\[var\(--primary\)\]{background-color:var(--primary)}.group:hover .group-hover\:bg-black\/20{background-color:#0003}.group:hover .group-hover\:bg-black\/30{background-color:#0000004d}.group:hover .group-hover\:bg-transparent{background-color:transparent}.group:hover .group-hover\:text-\[var\(--primary\)\]{color:var(--primary)}.group:hover .group-hover\:opacity-100{opacity:1}.group:hover .group-hover\:outline-\[var\(--btn-plain-bg-hover\)\]{outline-color:var(--btn-plain-bg-hover)}.group:active .group-active\:bg-black\/50{background-color:#00000080}.group:active .group-active\:text-\[var\(--primary\)\]{color:var(--primary)}.group:active .group-active\:outline-\[var\(--btn-plain-bg-active\)\]{outline-color:var(--btn-plain-bg-active)}.dark\:border-white\/10:is(.dark *){border-color:#ffffff1a}.dark\:border-white\/15:is(.dark *){border-color:#ffffff26}.dark\:border-white\/\[0\.15\]:is(.dark *){border-color:#ffffff26}.dark\:bg-\[oklch\(0\.25_0\.1_140\)\]:is(.dark *){background-color:oklch(.25 .1 140)}.dark\:bg-\[oklch\(0\.25_0\.1_240\)\]:is(.dark *){background-color:oklch(.25 .1 240)}.dark\:bg-\[oklch\(0\.70_0\.10_0\)\]:is(.dark *){background-color:#d2849c}.dark\:bg-\[var\(--card-bg\)\]:is(.dark *){background-color:var(--card-bg)}.dark\:bg-\[var\(--primary\)\]:is(.dark *){background-color:var(--primary)}.dark\:bg-black:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.dark\:bg-black\/10:is(.dark *){background-color:#0000001a}.dark\:bg-black\/5:is(.dark *){background-color:#0000000d}.dark\:bg-blue-900\/20:is(.dark *){background-color:#1e3a8a33}.dark\:bg-blue-900\/30:is(.dark *){background-color:#1e3a8a4d}.dark\:bg-gray-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-900\/30:is(.dark *){background-color:#1118274d}.dark\:bg-green-900\/30:is(.dark *){background-color:#14532d4d}.dark\:bg-indigo-900\/30:is(.dark *){background-color:#312e814d}.dark\:bg-orange-900\/30:is(.dark *){background-color:#7c2d124d}.dark\:bg-purple-900\/30:is(.dark *){background-color:#581c874d}.dark\:bg-red-900\/30:is(.dark *){background-color:#7f1d1d4d}.dark\:bg-slate-800\/50:is(.dark *){background-color:#1e293b80}.dark\:bg-white\/10:is(.dark *){background-color:#ffffff1a}.dark\:bg-white\/5:is(.dark *){background-color:#ffffff0d}.dark\:bg-yellow-900\/30:is(.dark *){background-color:#713f124d}.dark\:bg-zinc-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.dark\:from-blue-900\/20:is(.dark *){--tw-gradient-from: rgb(30 58 138 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(30 58 138 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-green-900\/20:is(.dark *){--tw-gradient-from: rgb(20 83 45 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(20 83 45 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-orange-900\/20:is(.dark *){--tw-gradient-from: rgb(124 45 18 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(124 45 18 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-purple-900\/20:is(.dark *){--tw-gradient-from: rgb(88 28 135 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(88 28 135 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-red-900\/20:is(.dark *){--tw-gradient-from: rgb(127 29 29 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(127 29 29 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-yellow-900\/20:is(.dark *){--tw-gradient-from: rgb(113 63 18 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(113 63 18 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:to-blue-800\/20:is(.dark *){--tw-gradient-to: rgb(30 64 175 / .2) var(--tw-gradient-to-position)}.dark\:to-green-800\/20:is(.dark *){--tw-gradient-to: rgb(22 101 52 / .2) var(--tw-gradient-to-position)}.dark\:to-orange-800\/20:is(.dark *){--tw-gradient-to: rgb(154 52 18 / .2) var(--tw-gradient-to-position)}.dark\:to-purple-800\/20:is(.dark *){--tw-gradient-to: rgb(107 33 168 / .2) var(--tw-gradient-to-position)}.dark\:to-red-800\/20:is(.dark *){--tw-gradient-to: rgb(153 27 27 / .2) var(--tw-gradient-to-position)}.dark\:to-yellow-800\/20:is(.dark *){--tw-gradient-to: rgb(133 77 14 / .2) var(--tw-gradient-to-position)}.dark\:text-\[oklch\(0\.75_0\.15_140\)\]:is(.dark *){color:#77c566}.dark\:text-\[oklch\(0\.75_0\.15_240\)\]:is(.dark *){color:oklch(.75 .15 240)}.dark\:text-\[oklch\(0\.85_0\.15_80\)\]:is(.dark *){color:oklch(.85 .15 80)}.dark\:text-\[var\(--deep-text\)\]:is(.dark *){color:var(--deep-text)}.dark\:text-black\/70:is(.dark *){color:#000000b3}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-blue-400\/70:is(.dark *){color:#60a5fab3}.dark\:text-gray-300:is(.dark *){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-green-400\/70:is(.dark *){color:#4ade80b3}.dark\:text-indigo-400:is(.dark *){--tw-text-opacity: 1;color:rgb(129 140 248 / var(--tw-text-opacity, 1))}.dark\:text-neutral-100:is(.dark *){--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.dark\:text-neutral-300:is(.dark *){--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.dark\:text-neutral-400:is(.dark *){--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.dark\:text-neutral-50:is(.dark *){--tw-text-opacity: 1;color:rgb(250 250 250 / var(--tw-text-opacity, 1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.dark\:text-orange-400\/70:is(.dark *){color:#fb923cb3}.dark\:text-purple-400:is(.dark *){--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.dark\:text-purple-400\/70:is(.dark *){color:#c084fcb3}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-red-400\/70:is(.dark *){color:#f87171b3}.dark\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.dark\:text-white\/25:is(.dark *){color:#ffffff40}.dark\:text-white\/30:is(.dark *){color:#ffffff4d}.dark\:text-white\/5:is(.dark *){color:#ffffff0d}.dark\:text-white\/50:is(.dark *){color:#ffffff80}.dark\:text-white\/60:is(.dark *){color:#fff9}.dark\:text-white\/70:is(.dark *){color:#ffffffb3}.dark\:text-white\/75:is(.dark *){color:#ffffffbf}.dark\:text-white\/80:is(.dark *){color:#fffc}.dark\:text-white\/90:is(.dark *){color:#ffffffe6}.dark\:text-white\/\[0\.2\]:is(.dark *){color:#fff3}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:text-yellow-400\/70:is(.dark *){color:#facc15b3}.dark\:shadow-none:is(.dark *){--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:focus-within\:bg-white\/10:focus-within:is(.dark *){background-color:#ffffff1a}.dark\:hover\:bg-red-900\/30:hover:is(.dark *){background-color:#7f1d1d4d}.dark\:hover\:bg-white\/10:hover:is(.dark *){background-color:#ffffff1a}.dark\:hover\:text-\[var\(--primary\)\]:hover:is(.dark *){color:var(--primary)}.dark\:active\:text-\[var\(--title-active\)\]:active:is(.dark *){color:var(--title-active)}@media(min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:768px){.md\:absolute{position:absolute}.md\:bottom-3{bottom:.75rem}.md\:left-\[unset\]{left:unset}.md\:right-3{right:.75rem}.md\:top-3{top:.75rem}.md\:col-span-1{grid-column:span 1 / span 1}.md\:col-start-1{grid-column-start:1}.md\:col-start-2{grid-column-start:2}.md\:col-end-2{grid-column-end:2}.md\:col-end-3{grid-column-end:3}.md\:row-start-1{grid-row-start:1}.md\:row-end-2{grid-row-end:2}.md\:mx-0{margin-left:0;margin-right:0}.md\:my-4{margin-top:1rem;margin-bottom:1rem}.md\:mb-0{margin-bottom:0}.md\:mb-4{margin-bottom:1rem}.md\:mt-0{margin-top:0}.md\:mt-8{margin-top:2rem}.md\:line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.md\:block{display:block}.md\:inline{display:inline}.md\:\!flex{display:flex!important}.md\:flex{display:flex}.md\:\!hidden{display:none!important}.md\:hidden{display:none}.md\:h-\[15vh\]{height:15vh}.md\:max-h-none{max-height:none}.md\:w-\[10\%\]{width:10%}.md\:w-\[15\%\]{width:15%}.md\:w-\[20rem\]{width:20rem}.md\:w-\[30rem\]{width:30rem}.md\:w-\[65\%\]{width:65%}.md\:w-\[80\%\]{width:80%}.md\:w-\[calc\(100\%_-_52px_-_12px\)\]{width:calc(100% - 64px)}.md\:w-\[calc\(100\%_-_var\(--coverWidth\)_-_12px\)\]{width:calc(100% - var(--coverWidth) - 12px)}.md\:w-\[var\(--coverWidth\)\]{width:var(--coverWidth)}.md\:max-w-\[17\.5rem\]{max-width:17.5rem}.md\:max-w-\[65\%\]{max-width:65%}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-\[17\.5rem_1fr\]{grid-template-columns:17.5rem 1fr}.md\:grid-cols-\[1fr_17\.5rem\]{grid-template-columns:1fr 17.5rem}.md\:flex-row{flex-direction:row}.md\:flex-col{flex-direction:column}.md\:gap-3{gap:.75rem}.md\:gap-4{gap:1rem}.md\:bg-transparent{background-color:transparent}.md\:p-2{padding:.5rem}.md\:p-6{padding:1.5rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:px-9{padding-left:2.25rem;padding-right:2.25rem}.md\:py-0{padding-top:0;padding-bottom:0}.md\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.md\:pl-9{padding-left:2.25rem}.md\:pr-2{padding-right:.5rem}.md\:pt-7{padding-top:1.75rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-9xl{font-size:8rem;line-height:1}.md\:text-\[16px\]{font-size:16px}.md\:text-\[2\.25rem\]\/\[2\.75rem\]{font-size:2.25rem;line-height:2.75rem}.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-sm{font-size:.875rem;line-height:1.25rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}.md\:before\:block:before{content:var(--tw-content);display:block}.md\:before\:w-1:before{content:var(--tw-content);width:.25rem}}@media(min-width:1024px){.lg\:col-span-1{grid-column:span 1 / span 1}.lg\:col-start-1{grid-column-start:1}.lg\:col-start-2{grid-column-start:2}.lg\:col-end-2{grid-column-end:2}.lg\:col-end-3{grid-column-end:3}.lg\:row-start-1{grid-row-start:1}.lg\:row-end-2{grid-row-end:2}.lg\:mx-0{margin-left:0;margin-right:0}.lg\:mb-4{margin-bottom:1rem}.lg\:mt-0{margin-top:0}.lg\:mt-10{margin-top:2.5rem}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:\!hidden{display:none!important}.lg\:hidden{display:none}.lg\:w-3\/4{width:75%}.lg\:w-full{width:100%}.lg\:max-w-\[17\.5rem\]{max-width:17.5rem}.lg\:max-w-none{max-width:none}.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[17\.5rem_1fr\]{grid-template-columns:17.5rem 1fr}.lg\:grid-cols-\[1fr_17\.5rem\]{grid-template-columns:1fr 17.5rem}.lg\:grid-rows-\[auto\]{grid-template-rows:auto}.lg\:gap-4{gap:1rem}.lg\:p-3{padding:.75rem}.lg\:p-8{padding:2rem}.lg\:text-2xl{font-size:1.5rem;line-height:2rem}.lg\:text-3xl{font-size:1.875rem;line-height:2.25rem}.lg\:text-8xl{font-size:6rem;line-height:1}.lg\:text-base{font-size:1rem;line-height:1.5rem}.lg\:text-lg{font-size:1.125rem;line-height:1.75rem}.lg\:first-of-type\:mt-0:first-of-type{margin-top:0}}@media(min-width:1280px){.xl\:block{display:block}}.card-base[data-astro-cid-zetdm5md]{animation:fadeInUp .6s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}a[data-astro-cid-zetdm5md]:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(var(--primary-rgb),.3)} diff --git a/website/blog/_astro/_page_.QUsIdifj.css b/website/blog/_astro/_page_.QUsIdifj.css deleted file mode 100644 index 2df722c..0000000 --- a/website/blog/_astro/_page_.QUsIdifj.css +++ /dev/null @@ -1 +0,0 @@ -.collapsed[data-astro-cid-ucso7hve]{height:var(--collapsedHeight)}.icon-loading[data-astro-cid-qpfihmil]{min-width:1em;min-height:1em;display:inline-flex;align-items:center;justify-content:center}.icon-content[data-astro-cid-qpfihmil]{display:inline-flex;align-items:center;justify-content:center}[data-astro-cid-qpfihmil][data-icon-container]{position:relative;display:inline-flex;align-items:center;justify-content:center;min-width:1em;min-height:1em}[data-astro-cid-qpfihmil][data-icon-container] .icon-loading[data-astro-cid-qpfihmil],[data-astro-cid-qpfihmil][data-icon-container] .icon-content[data-astro-cid-qpfihmil]{position:absolute;top:0;left:0;width:100%;height:100%}.mobile-toc-panel.svelte-cz3h3s{max-height:calc(100vh - 120px);overflow-y:auto;background:var(--card-bg);border:1px solid var(--line-color);backdrop-filter:blur(10px)}.toc-content.svelte-cz3h3s{display:flex;flex-direction:column;gap:2px}.post-content.svelte-cz3h3s{display:flex;flex-direction:column;gap:4px}.toc-item.svelte-cz3h3s{display:block;width:100%;text-align:left;padding:8px 12px;border-radius:8px;transition:all .2s ease;border:none;background:transparent;cursor:pointer;color:#000000bf;font-size:.9rem;line-height:1.4}.dark .toc-item.svelte-cz3h3s{color:#ffffffbf}.toc-item.svelte-cz3h3s:hover{background:var(--btn-plain-bg-hover);color:var(--primary)}.toc-item.active.svelte-cz3h3s{background:var(--btn-plain-bg-active);color:var(--primary);font-weight:600;border-left:3px solid var(--primary);padding-left:9px}.toc-item.level-1.svelte-cz3h3s{padding-left:12px;font-weight:600;font-size:1rem}.toc-item.level-2.svelte-cz3h3s{padding-left:20px}.toc-item.level-3.svelte-cz3h3s{padding-left:28px;font-size:.85rem}.toc-item.level-4.svelte-cz3h3s{padding-left:36px;font-size:.8rem}.toc-item.level-5.svelte-cz3h3s,.toc-item.level-6.svelte-cz3h3s{padding-left:44px;font-size:.75rem;color:#00000080}.dark .toc-item.level-5.svelte-cz3h3s,.dark .toc-item.level-6.svelte-cz3h3s{color:#ffffff80}.toc-item.level-1.active.svelte-cz3h3s{padding-left:9px}.toc-item.level-2.active.svelte-cz3h3s{padding-left:17px}.toc-item.level-3.active.svelte-cz3h3s{padding-left:25px}.toc-item.level-4.active.svelte-cz3h3s{padding-left:33px}.toc-item.level-5.active.svelte-cz3h3s,.toc-item.level-6.active.svelte-cz3h3s{padding-left:41px}.toc-text.svelte-cz3h3s{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.post-item.svelte-cz3h3s{display:block;width:100%;text-align:left;padding:12px;border-radius:8px;transition:all .2s ease;border:none;background:transparent;cursor:pointer;border:1px solid var(--line-color)}.post-item.svelte-cz3h3s:hover{background:var(--btn-plain-bg-hover);border-color:var(--primary);transform:translateY(-1px);box-shadow:0 2px 8px #0000001a}.post-title.svelte-cz3h3s{font-size:.9rem;font-weight:600;color:#000000bf;margin-bottom:4px;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dark .post-title.svelte-cz3h3s{color:#ffffffbf}.post-category.svelte-cz3h3s{font-size:.75rem;color:#00000080;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dark .post-category.svelte-cz3h3s{color:#ffffff80}.pinned-icon{display:inline;color:var(--primary);font-size:1.25rem;margin-right:.5rem;transform:translateY(-.125rem);vertical-align:middle}.post-item.svelte-cz3h3s:hover .post-title:where(.svelte-cz3h3s){color:var(--primary)}.post-item.svelte-cz3h3s:hover .post-category:where(.svelte-cz3h3s){color:#000000bf}.dark .post-item.svelte-cz3h3s:hover .post-category:where(.svelte-cz3h3s){color:#ffffffbf}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar{width:4px}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar-track{background:transparent}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar-thumb{background:var(--line-color);border-radius:2px}.mobile-toc-panel.svelte-cz3h3s::-webkit-scrollbar-thumb:hover{background:var(--text-color-25)}input.svelte-1wah7ro:focus{outline:0}.search-panel.svelte-1wah7ro{max-height:calc(100vh - 100px);overflow-y:auto}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k){-webkit-appearance:none;height:1.5rem;background-image:var(--color-selection-bar);transition:background-image .15s ease-in-out}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-webkit-slider-thumb{-webkit-appearance:none;height:1rem;width:.5rem;border-radius:.125rem;background:#ffffffb3;box-shadow:none}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-webkit-slider-thumb:hover{background:#fffc}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-webkit-slider-thumb:active{background:#fff9}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-moz-range-thumb{-webkit-appearance:none;height:1rem;width:.5rem;border-radius:.125rem;border-width:0;background:#ffffffb3;box-shadow:none}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-moz-range-thumb:hover{background:#fffc}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-moz-range-thumb:active{background:#fff9}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-ms-thumb{-webkit-appearance:none;height:1rem;width:.5rem;border-radius:.125rem;background:#ffffffb3;box-shadow:none}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-ms-thumb:hover{background:#fffc}#display-setting.svelte-d7tq3k input[type=range]:where(.svelte-d7tq3k)::-ms-thumb:active{background:#fff9}#dynamic-sidebar[data-astro-cid-7fqntumn]{--sidebar-gap: 1rem;--sidebar-animation-duration: .3s}.widget-container[data-astro-cid-7fqntumn]{transition:all var(--sidebar-animation-duration) ease}@media(max-width:768px){#dynamic-sidebar[data-astro-cid-7fqntumn]{display:var(--sidebar-mobile-display, block)}.sidebar-top-section[data-astro-cid-7fqntumn],.sidebar-sticky-section[data-astro-cid-7fqntumn]{gap:calc(var(--sidebar-gap) * .75)}}@media(min-width:769px)and (max-width:1024px){#dynamic-sidebar[data-astro-cid-7fqntumn]{display:var(--sidebar-tablet-display, block)}}@media(min-width:1025px){#dynamic-sidebar[data-astro-cid-7fqntumn]{display:var(--sidebar-desktop-display, block)}}.widget-container[data-astro-cid-7fqntumn]{opacity:0;transform:translateY(20px);animation:slideInUp .6s ease forwards}@keyframes slideInUp{to{opacity:1;transform:translateY(0)}}.sidebar-placeholder[data-astro-cid-7fqntumn]{border:2px dashed currentColor;border-radius:.5rem;opacity:.5}.line-clamp-1[data-astro-cid-fimizifw]{display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}.line-clamp-2[data-astro-cid-fimizifw]{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.line-clamp-3[data-astro-cid-fimizifw]{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.line-clamp-2[data-astro-cid-dbsui7p7]{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.line-clamp-3[data-astro-cid-dbsui7p7]{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.group[data-astro-cid-asphmpkf]{position:relative}.float-panel-closed.svelte-1dy47ij{opacity:0;pointer-events:none;transform:translateY(-10px);transition:all .2s ease-out}#translate-panel.svelte-1dy47ij:not(.float-panel-closed){opacity:1;pointer-events:auto;transform:translateY(0)}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar{width:4px}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar-track{background:transparent}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar-thumb{background:var(--scrollbar-bg);border-radius:2px}.overflow-y-auto.svelte-1dy47ij::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-bg-hover)}.expressive-code .frame{--tw-shadow: 0 0 #0000 !important;--tw-shadow-colored: 0 0 #0000 !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.expressive-code .title{font-family:JetBrains Mono Variable,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}@keyframes slideInUp{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}.gallery-container{animation:fadeIn .6s ease-out}.stats-card{animation:slideInUp .6s ease-out;transition:all .3s cubic-bezier(.4,0,.2,1)}.stats-card:nth-child(1){animation-delay:.1s}.stats-card:nth-child(2){animation-delay:.2s}.stats-card:nth-child(3){animation-delay:.3s}.stats-card:hover{transform:translateY(-4px) scale(1.02);box-shadow:0 10px 25px #00000026}.gallery-group-card{animation:scaleIn .5s ease-out;transition:all .3s cubic-bezier(.4,0,.2,1)}.gallery-group-card:nth-child(odd){animation-delay:.1s}.gallery-group-card:nth-child(2n){animation-delay:.2s}.gallery-group-card:hover{transform:translateY(-8px) scale(1.03);box-shadow:0 15px 35px #0000001a}.gallery-content{transition:all .5s cubic-bezier(.25,.46,.45,.94);max-height:0;overflow:hidden;opacity:0;transform:translateY(-20px) scale(.95);padding-top:0;padding-bottom:0}.gallery-group.expanded .gallery-content{max-height:3000px!important;opacity:1!important;transform:translateY(0) scale(1)!important;padding-top:1.5rem;padding-bottom:1.5rem}.gallery-content.hidden{max-height:0!important;opacity:0!important;transform:translateY(-20px) scale(.95)!important;padding-top:0!important;padding-bottom:0!important}.expand-icon{transition:transform .4s cubic-bezier(.25,.46,.45,.94);transform-origin:center}.gallery-group.expanded .expand-icon{transform:rotate(180deg)!important}.masonry-grid{-moz-column-count:2;column-count:2;-moz-column-gap:.5rem;column-gap:.5rem;-moz-column-fill:balance;column-fill:balance}@media(min-width:768px){.masonry-grid{-moz-column-count:2;column-count:2;-moz-column-gap:.75rem;column-gap:.75rem}}@media(min-width:1024px){.masonry-grid{-moz-column-count:3;column-count:3;-moz-column-gap:1rem;column-gap:1rem}}@media(min-width:1280px){.masonry-grid{-moz-column-count:3;column-count:3;-moz-column-gap:1rem;column-gap:1rem}}@media(min-width:1536px){.masonry-grid{-moz-column-count:4;column-count:4;-moz-column-gap:1.25rem;column-gap:1.25rem}}.gallery-image{transition:all .4s cubic-bezier(.4,0,.2,1);overflow:hidden;-moz-column-break-inside:avoid;break-inside:avoid;display:inline-block;width:100%;vertical-align:top}.gallery-image:hover{transform:translateY(-2px);filter:brightness(1.1) contrast(1.1);box-shadow:0 8px 25px #00000026}.gallery-image img{transition:transform .4s cubic-bezier(.4,0,.2,1);width:100%;height:auto;display:block}.gallery-image:hover img{transform:scale(1.05)}.btn-animated{position:relative;overflow:hidden;transition:all .3s ease}.btn-animated:before{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent);transition:left .5s}.btn-animated:hover:before{left:100%}.btn-animated:hover{transform:translateY(-2px);box-shadow:0 8px 20px #00000026}.loading-skeleton{background:linear-gradient(90deg,var(--btn-regular-bg) 25%,var(--btn-regular-bg-hover) 50%,var(--btn-regular-bg) 75%);background-size:200px 100%;animation:shimmer 1.5s infinite}.modal-overlay{animation:fadeIn .3s ease-out}.modal-content{animation:scaleIn .3s ease-out}.gallery-grid{display:grid;gap:1.5rem;grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}@media(max-width:640px){.gallery-grid{grid-template-columns:1fr;gap:1rem}}@media(min-width:641px)and (max-width:1024px){.gallery-grid{grid-template-columns:repeat(2,1fr)}}@media(min-width:1025px){.gallery-grid{grid-template-columns:repeat(3,1fr)}}@media(min-width:1280px){.gallery-grid{grid-template-columns:repeat(4,1fr)}}.image-viewer{max-width:90vw;max-height:90vh}@media(max-width:768px){.image-viewer{max-width:95vw;max-height:85vh}}.upload-zone{min-height:200px}@media(max-width:640px){.upload-zone{min-height:150px;padding:1.5rem}}.preview-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}@media(max-width:640px){.preview-grid{grid-template-columns:repeat(2,1fr)}}@media(min-width:641px)and (max-width:1024px){.preview-grid{grid-template-columns:repeat(3,1fr)}}@media(min-width:1025px){.preview-grid{grid-template-columns:repeat(4,1fr)}}.tag{transition:all .2s ease}.tag:hover{transform:translateY(-1px);box-shadow:0 2px 8px #0000001a}.tooltip{position:relative}.tooltip:after{content:attr(data-tooltip);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:var(--card-bg);color:var(--deep-text);border:1px solid var(--line-divider);padding:.5rem;border-radius:var(--radius-large);font-size:.75rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .2s;z-index:1000;box-shadow:0 4px 12px #0000001a}.tooltip:hover:after{opacity:1}.custom-scrollbar{scrollbar-width:thin;scrollbar-color:var(--btn-regular-bg-hover) transparent}.custom-scrollbar::-webkit-scrollbar{width:6px}.custom-scrollbar::-webkit-scrollbar-track{background:transparent}.custom-scrollbar::-webkit-scrollbar-thumb{background:var(--btn-regular-bg-hover);border-radius:3px}.custom-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--btn-regular-bg-active)}.focus-ring{transition:box-shadow .2s}.focus-ring:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--primary) 50%,transparent)}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@media(prefers-contrast:high){.gallery-group-card,.btn-primary{border:2px solid}}@media print{.gallery-container{-webkit-print-color-adjust:exact;print-color-adjust:exact}.btn-primary,.btn-secondary{display:none}.gallery-grid{grid-template-columns:repeat(2,1fr);gap:1rem}}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Roboto,sans-serif,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:"`"}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body: #374151;--tw-prose-headings: #111827;--tw-prose-lead: #4b5563;--tw-prose-links: #111827;--tw-prose-bold: #111827;--tw-prose-counters: #6b7280;--tw-prose-bullets: #d1d5db;--tw-prose-hr: #e5e7eb;--tw-prose-quotes: #111827;--tw-prose-quote-borders: #e5e7eb;--tw-prose-captions: #6b7280;--tw-prose-kbd: #111827;--tw-prose-kbd-shadows: rgb(17 24 39 / 10%);--tw-prose-code: #111827;--tw-prose-pre-code: #e5e7eb;--tw-prose-pre-bg: #1f2937;--tw-prose-th-borders: #d1d5db;--tw-prose-td-borders: #e5e7eb;--tw-prose-invert-body: #d1d5db;--tw-prose-invert-headings: #fff;--tw-prose-invert-lead: #9ca3af;--tw-prose-invert-links: #fff;--tw-prose-invert-bold: #fff;--tw-prose-invert-counters: #9ca3af;--tw-prose-invert-bullets: #4b5563;--tw-prose-invert-hr: #374151;--tw-prose-invert-quotes: #f3f4f6;--tw-prose-invert-quote-borders: #374151;--tw-prose-invert-captions: #9ca3af;--tw-prose-invert-kbd: #fff;--tw-prose-invert-kbd-shadows: rgb(255 255 255 / 10%);--tw-prose-invert-code: #fff;--tw-prose-invert-pre-code: #d1d5db;--tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);--tw-prose-invert-th-borders: #4b5563;--tw-prose-invert-td-borders: #374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-base{font-size:1rem;line-height:1.75}.prose-base :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-base :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose-base :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose-base :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose-base :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose-base :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose-base :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose-base :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-base :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose-base :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em}.prose-base :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em}.prose-base :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.9em}.prose-base :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose-base :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose-base :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose-base :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose-base :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-base :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-base :where(.prose-base>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-base :where(.prose-base>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(.prose-base>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-base :where(.prose-base>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(.prose-base>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-base :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-base :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-base :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-base :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose-base :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:3em;margin-bottom:3em}.prose-base :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.7142857}.prose-base :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose-base :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-base :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-base :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose-base :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-base :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-base :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-base :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-base :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose-base :where(.prose-base>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-base :where(.prose-base>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.is-theme-transitioning *,.is-theme-transitioning *:before,.is-theme-transitioning *:after{transition:none!important}.is-theme-transitioning svg use{transition:none;fill:currentColor}.is-theme-transitioning #navbar>div,.is-theme-transitioning #navbar[data-transparent-mode]>div,.is-theme-transitioning #navbar[data-transparent-mode].scrolled>div,.is-theme-transitioning body.wallpaper-transparent #navbar>div,.is-theme-transitioning body.wallpaper-transparent #navbar[data-transparent-mode]>div,.is-theme-transitioning body.wallpaper-transparent #navbar[data-transparent-mode].scrolled>div,.is-theme-transitioning #banner-wrapper~* #navbar>div,.is-theme-transitioning #banner-wrapper~* #navbar[data-transparent-mode]>div,.is-theme-transitioning body:has(#banner-wrapper) #navbar>div,.is-theme-transitioning body:has(#banner-wrapper) #navbar[data-transparent-mode]>div{transition:none!important;backdrop-filter:none!important}.is-theme-transitioning .dropdown-content,.is-theme-transitioning .float-panel,.is-theme-transitioning #display-setting,.is-theme-transitioning #nav-menu-panel,.is-theme-transitioning #translate-panel,.is-theme-transitioning #mobile-toc-panel,.is-theme-transitioning #search-panel{transition:none!important;backdrop-filter:none!important}.is-theme-transitioning #header-waves{color:var(--page-bg);isolation:isolate;contain:layout style paint;transform:translateZ(0);background:transparent}.is-theme-transitioning #header-waves use{will-change:transform;transform:translateZ(0)}.card-base{overflow:hidden;border-radius:var(--radius-large);background-color:var(--card-bg);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.wallpaper-transparent .card-base,.wallpaper-transparent .float-panel{background-color:var(--card-bg-transparent);--tw-backdrop-blur: blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.wallpaper-transparent #navbar>div{background-color:var(--card-bg-transparent);--tw-backdrop-blur: blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.wallpaper-transparent .btn-card{background-color:var(--card-bg-transparent);--tw-backdrop-blur: blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.wallpaper-transparent~* .music-player .mini-player,.wallpaper-transparent~* .music-player .expanded-player,.wallpaper-transparent~* .music-player .playlist-panel,body.wallpaper-transparent .music-player .mini-player,body.wallpaper-transparent .music-player .expanded-player,body.wallpaper-transparent .music-player .playlist-panel{background-color:var(--card-bg-transparent)!important;backdrop-filter:blur(8px)!important}h1,h2,h3,h4,h5,h6,p,a,span,li,ul,ol,blockquote,code,pre,table,th,td,strong{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.\!link{position:relative;z-index:0}.\!link:before{position:absolute;inset:0;z-index:-10;--tw-scale-x: .85;--tw-scale-y: .85;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:inherit;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;content:var(--tw-content);transition-timing-function:cubic-bezier(0,0,.2,1)}.\!link:hover:before{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));content:var(--tw-content);background-color:var(--btn-plain-bg-hover)}.\!link:active{background-image:none}.\!link:active:before{content:var(--tw-content);background-color:var(--btn-plain-bg-active)}.\!link{margin:-.25rem;border-radius:.375rem;padding:.25rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.link{position:relative;z-index:0}.link:before{position:absolute;inset:0;z-index:-10;--tw-scale-x: .85;--tw-scale-y: .85;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:inherit;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;content:var(--tw-content);transition-timing-function:cubic-bezier(0,0,.2,1)}.link:hover:before{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));content:var(--tw-content);background-color:var(--btn-plain-bg-hover)}.link:active{background-image:none}.link:active:before{content:var(--tw-content);background-color:var(--btn-plain-bg-active)}.link{margin:-.25rem;border-radius:.375rem;padding:.25rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.link-lg{position:relative;z-index:0}.link-lg:before{position:absolute;inset:0;z-index:-10;--tw-scale-x: .85;--tw-scale-y: .85;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:inherit;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;content:var(--tw-content);transition-timing-function:cubic-bezier(0,0,.2,1)}.link-lg:hover:before{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));content:var(--tw-content);background-color:var(--btn-plain-bg-hover)}.link-lg:active{background-image:none}.link-lg:active:before{content:var(--tw-content);background-color:var(--btn-plain-bg-active)}.link-lg{margin:-.375rem;border-radius:.375rem;padding:.375rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.float-panel{top:5.25rem;overflow:hidden;border-radius:var(--radius-large);background-color:var(--float-panel-bg);--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.float-panel:is(.dark *){--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.float-panel-closed{pointer-events:none;--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));opacity:0}.search-panel mark{background-color:transparent;color:var(--primary)}.btn-card{display:flex;align-items:center;justify-content:center;background-color:var(--card-bg);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-card:hover{background-color:var(--btn-card-bg-hover)}.btn-card:active{background-color:var(--btn-card-bg-active)}.btn-card.disabled{pointer-events:none;color:#0000001a}.btn-card.disabled:is(.dark *){color:#ffffff1a}.btn-plain{position:relative;display:flex;align-items:center;justify-content:center;background-image:none;color:#000000bf;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-plain:hover{color:var(--primary)}.btn-plain:is(.dark *){color:#ffffffbf}.btn-plain:hover:is(.dark *){color:var(--primary)}.btn-plain:not(.scale-animation):hover{background-color:var(--btn-plain-bg-hover)}.btn-plain:not(.scale-animation):active{background-color:var(--btn-plain-bg-active)}.btn-plain.scale-animation{position:relative;z-index:0}.btn-plain.scale-animation:before{position:absolute;inset:0;z-index:-10;--tw-scale-x: .85;--tw-scale-y: .85;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:inherit;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;content:var(--tw-content);transition-timing-function:cubic-bezier(0,0,.2,1)}.btn-plain.scale-animation:hover:before{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));content:var(--tw-content);background-color:var(--btn-plain-bg-hover)}.btn-plain.scale-animation:active{background-image:none}.btn-plain.scale-animation:active:before{content:var(--tw-content);background-color:var(--btn-plain-bg-active)}.btn-regular{display:flex;align-items:center;justify-content:center;background-color:var(--btn-regular-bg);color:var(--btn-content);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-regular:hover{background-color:var(--btn-regular-bg-hover)}.btn-regular:active{background-color:var(--btn-regular-bg-active)}.btn-regular:is(.dark *){color:#ffffffbf}.toc-hide,.toc-not-ready{pointer-events:none;opacity:0}#toc-inner-wrapper{-webkit-mask-image:linear-gradient(to bottom,transparent 0%,black 2rem,black calc(100% - 2rem),transparent 100%);mask-image:linear-gradient(to bottom,transparent 0%,black 2rem,black calc(100% - 2rem),transparent 100%)}.hide-scrollbar{scrollbar-width:none;-ms-overflow-style:none}.hide-scrollbar::-webkit-scrollbar{display:none}.text-90{color:#000000e6}.text-90:is(.dark *){color:#ffffffe6}.text-75{color:#000000bf}.text-75:is(.dark *){color:#ffffffbf}.text-50{color:#00000080}.text-50:is(.dark *){color:#ffffff80}.text-30{color:#0000004d}.text-30:is(.dark *){color:#ffffff4d}.dropdown-container{position:relative}.dropdown-menu{pointer-events:none;visibility:hidden;position:absolute;top:100%;left:0;z-index:50;--tw-translate-y: -8px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));padding-top:.5rem;opacity:0;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}.dropdown-container:hover .dropdown-menu,.dropdown-container:focus-within .dropdown-menu{pointer-events:auto;visibility:visible;--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));opacity:1}.dropdown-container:hover .dropdown-arrow,.dropdown-container:focus-within .dropdown-arrow{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dropdown-content{min-width:12rem;border-radius:var(--radius-large);border-width:1px;border-color:#0000000d;background-color:var(--float-panel-bg);padding-top:.5rem;padding-bottom:.5rem;--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dropdown-content:is(.dark *){border-color:#ffffff1a;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dropdown-item{display:flex;align-items:center;justify-content:space-between;padding:.625rem 1rem;font-weight:500;color:#000000bf;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.dropdown-item:hover{background-color:var(--btn-plain-bg-hover);color:var(--primary)}.dropdown-item:is(.dark *){color:#ffffffbf}.dropdown-item:first-child{border-top-left-radius:calc(var(--radius-large) - .5rem);border-top-right-radius:calc(var(--radius-large) - .5rem)}.dropdown-item:last-child{border-bottom-right-radius:calc(var(--radius-large) - .5rem);border-bottom-left-radius:calc(var(--radius-large) - .5rem)}.mobile-submenu{max-height:0px;overflow:hidden;transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.mobile-dropdown[data-expanded=true] .mobile-submenu{max-height:24rem}.mobile-dropdown[data-expanded=true] .mobile-dropdown-arrow{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@media(max-width:768px){.dropdown-container{display:none}}.dropdown-container:focus-within .dropdown-menu{pointer-events:auto;visibility:visible;--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));opacity:1}.dropdown-item:focus{outline:2px solid transparent;outline-offset:2px}.mobile-dropdown button:focus{outline:2px solid transparent;outline-offset:2px}.meta-icon{margin-right:.5rem;display:flex;height:2rem;width:2rem;align-items:center;justify-content:center;border-radius:.375rem;background-color:var(--btn-regular-bg);color:var(--btn-content);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-regular-dark.success{background-color:oklch(.75 .14 var(--hue))}.btn-regular-dark.success:is(.dark *){background-color:oklch(.75 .14 var(--hue))}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.-bottom-\[1px\]{bottom:-1px}.-left-\[var\(--toc-width\)\]{left:calc(var(--toc-width) * -1)}.-right-\[var\(--toc-width\)\]{right:calc(var(--toc-width) * -1)}.-top-8{top:-2rem}.-top-\[3\.25rem\]{top:-3.25rem}.bottom-0{bottom:0}.bottom-20{bottom:5rem}.bottom-3{bottom:.75rem}.bottom-4{bottom:1rem}.left-0{left:0}.left-3{left:.75rem}.left-4{left:1rem}.left-6{left:1.5rem}.right-0{right:0}.right-3{right:.75rem}.right-4{right:1rem}.right-6{right:1.5rem}.top-0{top:0}.top-1\/2{top:50%}.top-14{top:3.5rem}.top-20{top:5rem}.top-3{top:.75rem}.top-4{top:1rem}.top-\[3\.5rem\]{top:3.5rem}.top-\[calc\(1rem_-_var\(--banner-height-extend\)\)\]{top:calc(1rem - var(--banner-height-extend))}.top-full{top:100%}.isolate{isolation:isolate}.-z-10{z-index:-10}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[60\]{z-index:60}.col-span-1{grid-column:span 1 / span 1}.col-span-2{grid-column:span 2 / span 2}.row-start-2{grid-row-start:2}.row-end-3{grid-row-end:3}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-1\.5{margin-left:.375rem;margin-right:.375rem}.mx-16{margin-left:4rem;margin-right:4rem}.mx-32{margin-left:8rem;margin-right:8rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-auto{margin-top:auto;margin-bottom:auto}.-mb-2{margin-bottom:-.5rem}.mb-0{margin-bottom:0}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-2\.5{margin-bottom:.625rem}.mb-3{margin-bottom:.75rem}.mb-3\.5{margin-bottom:.875rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-8{margin-left:2rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.\!hidden{display:none!important}.hidden{display:none}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-20{height:5rem}.h-28{height:7rem}.h-3{height:.75rem}.h-4{height:1rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[10vh\]{height:10vh}.h-\[3\.25rem\]{height:3.25rem}.h-\[3\.75rem\]{height:3.75rem}.h-\[300vh\]{height:300vh}.h-\[4\.5rem\]{height:4.5rem}.h-\[calc\(100vh_-_20rem\)\]{height:calc(100vh - 20rem)}.h-\[calc\(var\(--banner-height-home\)_-_4\.5rem\)\]{height:calc(var(--banner-height-home) - 4.5rem)}.h-\[var\(--banner-height-home\)\]{height:var(--banner-height-home)}.h-full{height:100%}.max-h-0{max-height:0px}.max-h-64{max-height:16rem}.max-h-80{max-height:20rem}.max-h-96{max-height:24rem}.max-h-\[20vh\]{max-height:20vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[9\.375rem\]{max-height:9.375rem}.max-h-full{max-height:100%}.min-h-32{min-height:8rem}.min-h-9{min-height:2.25rem}.min-h-96{min-height:24rem}.min-h-\[3\.125rem\]{min-height:3.125rem}.min-h-screen{min-height:100vh}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-28{width:7rem}.w-3{width:.75rem}.w-4{width:1rem}.w-4\/5{width:80%}.w-40{width:10rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-\[15\%\]{width:15%}.w-\[3\.25rem\]{width:3.25rem}.w-\[3\.75rem\]{width:3.75rem}.w-\[70\%\]{width:70%}.w-\[calc\(100vw-2rem\)\]{width:calc(100vw - 2rem)}.w-\[var\(--toc-width\)\]{width:var(--toc-width)}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[12rem\]{min-width:12rem}.min-w-\[2rem\]{min-width:2rem}.\!max-w-none{max-width:none!important}.max-w-4xl{max-width:56rem}.max-w-\[12rem\]{max-width:12rem}.max-w-\[calc\(100\%_-_3rem\)\]{max-width:calc(100% - 3rem)}.max-w-\[var\(\&\#45\;\&\#45\;page-width\)\]{max-width:var(--page-width)}.max-w-\[var\(--page-width\)\]{max-width:var(--page-width)}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-2{--tw-translate-x: -.5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-0\.5{--tw-translate-y: -.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-16{--tw-translate-y: -4rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-\[1px\]{--tw-translate-y: -1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0\.5{--tw-translate-y: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[-8px\]{--tw-translate-y: -8px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[var\(--banner-height-extend\)\]{--tw-translate-y: var(--banner-height-extend);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-\[var\(--bannerOffset\)\]{--tw-translate-y: var(--bannerOffset);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-0{--tw-scale-x: 0;--tw-scale-y: 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-105{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-50{--tw-scale-x: .5;--tw-scale-y: .5;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-90{--tw-scale-x: .9;--tw-scale-y: .9;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-95{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-rows-\[auto_1fr_auto\]{grid-template-rows:auto 1fr auto}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-stretch{align-items:stretch}.\!justify-start{justify-content:flex-start!important}.justify-start{justify-content:flex-start}.\!justify-end{justify-content:flex-end!important}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-2{row-gap:.5rem}.gap-y-8{row-gap:2rem}.space-x-0\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.125rem * var(--tw-space-x-reverse));margin-left:calc(.125rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.25rem * var(--tw-space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.\!overflow-visible{overflow:visible!important}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-scroll{overflow-y:scroll}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.overflow-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[0\.1875rem\]{border-radius:.1875rem}.rounded-\[var\(--radius-large\)\]{border-radius:var(--radius-large)}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.rounded-xl{border-radius:.75rem}.rounded-b-\[calc\(var\(--radius-large\)-0\.5rem\)\]{border-bottom-right-radius:calc(var(--radius-large) - .5rem);border-bottom-left-radius:calc(var(--radius-large) - .5rem)}.rounded-t-\[calc\(var\(--radius-large\)-0\.5rem\)\]{border-top-left-radius:calc(var(--radius-large) - .5rem);border-top-right-radius:calc(var(--radius-large) - .5rem)}.border{border-width:1px}.border-2{border-width:2px}.border-b,.border-b-\[1px\]{border-bottom-width:1px}.border-t,.border-t-\[1px\]{border-top-width:1px}.border-dashed{border-style:dashed}.border-\[oklch\(85\%_0\.01_var\(--hue\)\)\]{border-color:oklch(85% .01 var(--hue))}.border-\[var\(\&\#45\;\&\#45\;primary\)\]{border-color:var(--primary)}.border-\[var\(--line-divider\)\]{border-color:var(--line-divider)}.border-\[var\(--primary\)\]{border-color:var(--primary)}.border-\[var\(--toc-btn-hover\)\]{border-color:var(--toc-btn-hover)}.border-black\/10{border-color:#0000001a}.border-black\/5{border-color:#0000000d}.bg-\[oklch\(0\.5_0\.05_var\(--hue\)\)\]{background-color:oklch(.5 .05 var(--hue))}.bg-\[oklch\(0\.80_0\.10_0\)\]{background-color:#f3a3bb}.bg-\[oklch\(0\.85_0\.1_140\)\]{background-color:#abdea0}.bg-\[oklch\(0\.85_0\.1_240\)\]{background-color:oklch(.85 .1 240)}.bg-\[oklch\(0\.95_0\.025_var\(--hue\)\)\]{background-color:oklch(.95 .025 var(--hue))}.bg-\[oklch\(92\%_0\.01_var\(\&\#45\;\&\#45\;hue\)\)\]{background-color:oklch(92% .01 var(--hue))}.bg-\[var\(--btn-content\)\]{background-color:var(--btn-content)}.bg-\[var\(--btn-plain-bg\)\]{background-color:var(--btn-plain-bg)}.bg-\[var\(--btn-plain-bg-hover\)\]{background-color:var(--btn-plain-bg-hover)}.bg-\[var\(--btn-regular-bg\)\]{background-color:var(--btn-regular-bg)}.bg-\[var\(--card-bg\)\]{background-color:var(--card-bg)}.bg-\[var\(--enter-btn-bg\)\]{background-color:var(--enter-btn-bg)}.bg-\[var\(--float-panel-bg\)\]{background-color:var(--float-panel-bg)}.bg-\[var\(--license-block-bg\)\]{background-color:var(--license-block-bg)}.bg-\[var\(--page-bg\)\]{background-color:var(--page-bg)}.bg-\[var\(--primary\)\]{background-color:var(--primary)}.bg-\[var\(--toc-badge-bg\)\]{background-color:var(--toc-badge-bg)}.bg-\[var\(--toc-btn-hover\)\]{background-color:var(--toc-btn-hover)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/0{background-color:#0000}.bg-black\/20{background-color:#0003}.bg-black\/5{background-color:#0000000d}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-black\/80{background-color:#000c}.bg-black\/90{background-color:#000000e6}.bg-black\/\[0\.04\]{background-color:#0000000a}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-purple-500{--tw-bg-opacity: 1;background-color:rgb(168 85 247 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/5{background-color:#ffffff0d}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1))}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-zinc-200{--tw-bg-opacity: 1;background-color:rgb(228 228 231 / var(--tw-bg-opacity, 1))}.bg-opacity-50{--tw-bg-opacity: .5}.bg-opacity-90{--tw-bg-opacity: .9}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.bg-none{background-image:none}.from-black\/60{--tw-gradient-from: rgb(0 0 0 / .6) var(--tw-gradient-from-position);--tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-blue-50{--tw-gradient-from: #eff6ff var(--tw-gradient-from-position);--tw-gradient-to: rgb(239 246 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-green-50{--tw-gradient-from: #f0fdf4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(240 253 244 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-50{--tw-gradient-from: #fff7ed var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 247 237 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-50{--tw-gradient-from: #faf5ff var(--tw-gradient-from-position);--tw-gradient-to: rgb(250 245 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-red-50{--tw-gradient-from: #fef2f2 var(--tw-gradient-from-position);--tw-gradient-to: rgb(254 242 242 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-yellow-50{--tw-gradient-from: #fefce8 var(--tw-gradient-from-position);--tw-gradient-to: rgb(254 252 232 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-blue-100{--tw-gradient-to: #dbeafe var(--tw-gradient-to-position)}.to-green-100{--tw-gradient-to: #dcfce7 var(--tw-gradient-to-position)}.to-orange-100{--tw-gradient-to: #ffedd5 var(--tw-gradient-to-position)}.to-purple-100{--tw-gradient-to: #f3e8ff var(--tw-gradient-to-position)}.to-red-100{--tw-gradient-to: #fee2e2 var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.to-yellow-100{--tw-gradient-to: #fef9c3 var(--tw-gradient-to-position)}.fill-\[var\(--page-bg\)\]{fill:var(--page-bg)}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.object-bottom{-o-object-position:bottom;object-position:bottom}.object-center{-o-object-position:center;object-position:center}.object-top{-o-object-position:top;object-position:top}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0{padding-left:0;padding-right:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-9{padding-left:2.25rem;padding-right:2.25rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pl-10{padding-left:2.5rem}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-6{padding-left:1.5rem}.pr-1{padding-right:.25rem}.pr-4{padding-right:1rem}.pr-6{padding-right:1.5rem}.pr-8{padding-right:2rem}.pt-2{padding-top:.5rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-6xl{font-size:3.75rem;line-height:1}.text-8xl{font-size:6rem;line-height:1}.text-\[0\.75rem\]{font-size:.75rem}.text-\[0\.875rem\]{font-size:.875rem}.text-\[1\.1rem\]{font-size:1.1rem}.text-\[1\.25rem\]{font-size:1.25rem}.text-\[1\.5rem\]{font-size:1.5rem}.text-\[1\.75rem\]{font-size:1.75rem}.text-\[14px\]{font-size:14px}.text-\[15rem\]{font-size:15rem}.text-\[1rem\]{font-size:1rem}.text-\[2rem\]{font-size:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.text-\[oklch\(0\.35_0\.15_140\)\]{color:oklch(.35 .15 140)}.text-\[oklch\(0\.35_0\.15_240\)\]{color:oklch(.35 .15 240)}.text-\[oklch\(0\.65_0\.15_140\)\]{color:#58a547}.text-\[oklch\(0\.65_0\.15_240\)\]{color:oklch(.65 .15 240)}.text-\[oklch\(0\.75_0\.14_var\(--hue\)\)\]{color:oklch(.75 .14 var(--hue))}.text-\[oklch\(0\.75_0\.15_80\)\]{color:#dfa11a}.text-\[var\(--btn-content\)\]{color:var(--btn-content)}.text-\[var\(--content-meta\)\]{color:var(--content-meta)}.text-\[var\(--deep-text\)\]{color:var(--deep-text)}.text-\[var\(--meta-divider\)\]{color:var(--meta-divider)}.text-\[var\(--primary\)\]{color:var(--primary)}.text-black\/25{color:#00000040}.text-black\/30{color:#0000004d}.text-black\/5{color:#0000000d}.text-black\/50{color:#00000080}.text-black\/60{color:#0009}.text-black\/70{color:#000000b3}.text-black\/75{color:#000000bf}.text-black\/80{color:#000c}.text-black\/90{color:#000000e6}.text-black\/\[0\.2\]{color:#0003}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-600\/70{color:#2563ebb3}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-600\/70{color:#16a34ab3}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-600{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.text-neutral-700{--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1))}.text-neutral-900{--tw-text-opacity: 1;color:rgb(23 23 23 / var(--tw-text-opacity, 1))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-orange-600\/70{color:#ea580cb3}.text-orange-700{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-600\/70{color:#9333eab3}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-600\/70{color:#dc2626b3}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/75{color:#ffffffbf}.text-white\/80{color:#fffc}.text-white\/90{color:#ffffffe6}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-600\/70{color:#ca8a04b3}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-10{opacity:.1}.opacity-100{opacity:1}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.outline-0{outline-width:0px}.outline-4{outline-width:4px}.-outline-offset-\[2px\]{outline-offset:-2px}.outline-\[var\(--card-bg\)\]{outline-color:var(--card-bg)}.outline-\[var\(--primary\)\]{outline-color:var(--primary)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-lg{--tw-drop-shadow: drop-shadow(0 10px 8px rgb(0 0 0 / .04)) drop-shadow(0 4px 3px rgb(0 0 0 / .1));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-md{--tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / .07)) drop-shadow(0 2px 2px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale: grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-filter{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-1000{transition-duration:1s}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.duration-700{transition-duration:.7s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}html{scroll-behavior:smooth}.top-gradient-highlight{position:fixed;top:0;left:0;right:0;height:180px;background:linear-gradient(to bottom,rgba(255,255,255,.5) 0%,rgba(255,255,255,.3) 30%,rgba(255,255,255,.15) 60%,rgba(255,255,255,.05) 80%,transparent 100%);pointer-events:none;z-index:20;transition:all .3s cubic-bezier(.4,0,.2,1)}:root.dark .top-gradient-highlight{background:linear-gradient(to bottom,rgba(0,0,0,.5) 0%,rgba(0,0,0,.3) 30%,rgba(0,0,0,.15) 60%,rgba(0,0,0,.05) 80%,transparent 100%)}.custom-md img,#post-cover img{cursor:zoom-in}::-moz-selection{background-color:var(--selection-bg)}::selection{background-color:var(--selection-bg)}.dash-line{position:relative}.dash-line:before{content:"";position:absolute;width:10%;height:100%;left:calc(50% - 1px);border-left:2px dashed var(--line-color);pointer-events:none;transition:all .3s;transform:translateY(-50%)}.collapsed{height:var(--collapsedHeight)}.dark\:prose-invert:is(.dark *){--tw-prose-body: var(--tw-prose-invert-body);--tw-prose-headings: var(--tw-prose-invert-headings);--tw-prose-lead: var(--tw-prose-invert-lead);--tw-prose-links: var(--tw-prose-invert-links);--tw-prose-bold: var(--tw-prose-invert-bold);--tw-prose-counters: var(--tw-prose-invert-counters);--tw-prose-bullets: var(--tw-prose-invert-bullets);--tw-prose-hr: var(--tw-prose-invert-hr);--tw-prose-quotes: var(--tw-prose-invert-quotes);--tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);--tw-prose-captions: var(--tw-prose-invert-captions);--tw-prose-kbd: var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);--tw-prose-code: var(--tw-prose-invert-code);--tw-prose-pre-code: var(--tw-prose-invert-pre-code);--tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);--tw-prose-th-borders: var(--tw-prose-invert-th-borders);--tw-prose-td-borders: var(--tw-prose-invert-td-borders)}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:-left-3:before{content:var(--tw-content);left:-.75rem}.before\:left-\[-1\.125rem\]:before{content:var(--tw-content);left:-1.125rem}.before\:left-\[-16px\]:before{content:var(--tw-content);left:-16px}.before\:left-\[18px\]:before{content:var(--tw-content);left:18px}.before\:top-\[0\.33rem\]:before{content:var(--tw-content);top:.33rem}.before\:top-\[0\.75rem\]:before{content:var(--tw-content);top:.75rem}.before\:top-\[35px\]:before{content:var(--tw-content);top:35px}.before\:top-\[5\.5px\]:before{content:var(--tw-content);top:5.5px}.before\:hidden:before{content:var(--tw-content);display:none}.before\:h-4:before{content:var(--tw-content);height:1rem}.before\:h-5:before{content:var(--tw-content);height:1.25rem}.before\:w-1:before{content:var(--tw-content);width:.25rem}.before\:rounded-md:before{content:var(--tw-content);border-radius:.375rem}.before\:bg-\[var\(--primary\)\]:before{content:var(--tw-content);background-color:var(--primary)}.last\:border-t-0:last-child{border-top-width:0px}.first-of-type\:mt-2:first-of-type{margin-top:.5rem}.focus-within\:bg-black\/\[0\.06\]:focus-within{background-color:#0000000f}.hover\:scale-105:hover{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:bg-\[var\(--btn-card-bg-hover\)\]:hover{background-color:var(--btn-card-bg-hover)}.hover\:bg-\[var\(--btn-plain-bg-hover\)\]:hover{background-color:var(--btn-plain-bg-hover)}.hover\:bg-\[var\(--btn-regular-bg\)\]:hover{background-color:var(--btn-regular-bg)}.hover\:bg-\[var\(--enter-btn-bg-hover\)\]:hover{background-color:var(--enter-btn-bg-hover)}.hover\:bg-\[var\(--primary-dark\)\]:hover{background-color:var(--primary-dark)}.hover\:bg-\[var\(--toc-btn-hover\)\]:hover{background-color:var(--toc-btn-hover)}.hover\:bg-black\/70:hover{background-color:#000000b3}.hover\:bg-black\/\[0\.06\]:hover{background-color:#0000000f}.hover\:bg-red-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.hover\:bg-opacity-70:hover{--tw-bg-opacity: .7}.hover\:pl-3:hover{padding-left:.75rem}.hover\:pr-9:hover{padding-right:2.25rem}.hover\:text-\[initial\]:hover{color:initial}.hover\:text-\[var\(--primary\)\]:hover{color:var(--primary)}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:w-60:focus{width:15rem}.active\:w-60:active{width:15rem}.active\:scale-90:active{--tw-scale-x: .9;--tw-scale-y: .9;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-95:active{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-\[0\.85\]:active{--tw-scale-x: .85;--tw-scale-y: .85;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:bg-\[var\(--btn-plain-bg-active\)\]:active{background-color:var(--btn-plain-bg-active)}.active\:bg-\[var\(--enter-btn-bg-active\)\]:active{background-color:var(--enter-btn-bg-active)}.active\:bg-\[var\(--toc-btn-active\)\]:active{background-color:var(--toc-btn-active)}.active\:bg-black\/80:active{background-color:#000c}.active\:text-\[var\(--title-active\)\]:active{color:var(--title-active)}.group:hover .group-hover\:h-5{height:1.25rem}.group:hover .group-hover\:translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-100{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-105{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:border-\[var\(--toc-btn-active\)\]{border-color:var(--toc-btn-active)}.group:hover .group-hover\:bg-\[var\(--primary\)\]{background-color:var(--primary)}.group:hover .group-hover\:bg-black\/20{background-color:#0003}.group:hover .group-hover\:bg-black\/30{background-color:#0000004d}.group:hover .group-hover\:bg-transparent{background-color:transparent}.group:hover .group-hover\:text-\[var\(--primary\)\]{color:var(--primary)}.group:hover .group-hover\:opacity-100{opacity:1}.group:hover .group-hover\:outline-\[var\(--btn-plain-bg-hover\)\]{outline-color:var(--btn-plain-bg-hover)}.group:active .group-active\:bg-black\/50{background-color:#00000080}.group:active .group-active\:text-\[var\(--primary\)\]{color:var(--primary)}.group:active .group-active\:outline-\[var\(--btn-plain-bg-active\)\]{outline-color:var(--btn-plain-bg-active)}.dark\:border-white\/10:is(.dark *){border-color:#ffffff1a}.dark\:border-white\/15:is(.dark *){border-color:#ffffff26}.dark\:border-white\/\[0\.15\]:is(.dark *){border-color:#ffffff26}.dark\:bg-\[oklch\(0\.25_0\.1_140\)\]:is(.dark *){background-color:oklch(.25 .1 140)}.dark\:bg-\[oklch\(0\.25_0\.1_240\)\]:is(.dark *){background-color:oklch(.25 .1 240)}.dark\:bg-\[oklch\(0\.70_0\.10_0\)\]:is(.dark *){background-color:#d2849c}.dark\:bg-\[var\(--card-bg\)\]:is(.dark *){background-color:var(--card-bg)}.dark\:bg-\[var\(--primary\)\]:is(.dark *){background-color:var(--primary)}.dark\:bg-black:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.dark\:bg-black\/10:is(.dark *){background-color:#0000001a}.dark\:bg-black\/5:is(.dark *){background-color:#0000000d}.dark\:bg-blue-900\/20:is(.dark *){background-color:#1e3a8a33}.dark\:bg-blue-900\/30:is(.dark *){background-color:#1e3a8a4d}.dark\:bg-gray-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-900\/30:is(.dark *){background-color:#1118274d}.dark\:bg-green-900\/30:is(.dark *){background-color:#14532d4d}.dark\:bg-indigo-900\/30:is(.dark *){background-color:#312e814d}.dark\:bg-orange-900\/30:is(.dark *){background-color:#7c2d124d}.dark\:bg-purple-900\/30:is(.dark *){background-color:#581c874d}.dark\:bg-red-900\/30:is(.dark *){background-color:#7f1d1d4d}.dark\:bg-slate-800\/50:is(.dark *){background-color:#1e293b80}.dark\:bg-white\/10:is(.dark *){background-color:#ffffff1a}.dark\:bg-white\/5:is(.dark *){background-color:#ffffff0d}.dark\:bg-yellow-900\/30:is(.dark *){background-color:#713f124d}.dark\:bg-zinc-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.dark\:from-blue-900\/20:is(.dark *){--tw-gradient-from: rgb(30 58 138 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(30 58 138 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-green-900\/20:is(.dark *){--tw-gradient-from: rgb(20 83 45 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(20 83 45 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-orange-900\/20:is(.dark *){--tw-gradient-from: rgb(124 45 18 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(124 45 18 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-purple-900\/20:is(.dark *){--tw-gradient-from: rgb(88 28 135 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(88 28 135 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-red-900\/20:is(.dark *){--tw-gradient-from: rgb(127 29 29 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(127 29 29 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:from-yellow-900\/20:is(.dark *){--tw-gradient-from: rgb(113 63 18 / .2) var(--tw-gradient-from-position);--tw-gradient-to: rgb(113 63 18 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.dark\:to-blue-800\/20:is(.dark *){--tw-gradient-to: rgb(30 64 175 / .2) var(--tw-gradient-to-position)}.dark\:to-green-800\/20:is(.dark *){--tw-gradient-to: rgb(22 101 52 / .2) var(--tw-gradient-to-position)}.dark\:to-orange-800\/20:is(.dark *){--tw-gradient-to: rgb(154 52 18 / .2) var(--tw-gradient-to-position)}.dark\:to-purple-800\/20:is(.dark *){--tw-gradient-to: rgb(107 33 168 / .2) var(--tw-gradient-to-position)}.dark\:to-red-800\/20:is(.dark *){--tw-gradient-to: rgb(153 27 27 / .2) var(--tw-gradient-to-position)}.dark\:to-yellow-800\/20:is(.dark *){--tw-gradient-to: rgb(133 77 14 / .2) var(--tw-gradient-to-position)}.dark\:text-\[oklch\(0\.75_0\.15_140\)\]:is(.dark *){color:#77c566}.dark\:text-\[oklch\(0\.75_0\.15_240\)\]:is(.dark *){color:oklch(.75 .15 240)}.dark\:text-\[oklch\(0\.85_0\.15_80\)\]:is(.dark *){color:oklch(.85 .15 80)}.dark\:text-\[var\(--deep-text\)\]:is(.dark *){color:var(--deep-text)}.dark\:text-black\/70:is(.dark *){color:#000000b3}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-blue-400\/70:is(.dark *){color:#60a5fab3}.dark\:text-gray-300:is(.dark *){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-green-400\/70:is(.dark *){color:#4ade80b3}.dark\:text-indigo-400:is(.dark *){--tw-text-opacity: 1;color:rgb(129 140 248 / var(--tw-text-opacity, 1))}.dark\:text-neutral-100:is(.dark *){--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.dark\:text-neutral-300:is(.dark *){--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.dark\:text-neutral-400:is(.dark *){--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.dark\:text-neutral-50:is(.dark *){--tw-text-opacity: 1;color:rgb(250 250 250 / var(--tw-text-opacity, 1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.dark\:text-orange-400\/70:is(.dark *){color:#fb923cb3}.dark\:text-purple-400:is(.dark *){--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.dark\:text-purple-400\/70:is(.dark *){color:#c084fcb3}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-red-400\/70:is(.dark *){color:#f87171b3}.dark\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.dark\:text-white\/25:is(.dark *){color:#ffffff40}.dark\:text-white\/30:is(.dark *){color:#ffffff4d}.dark\:text-white\/5:is(.dark *){color:#ffffff0d}.dark\:text-white\/50:is(.dark *){color:#ffffff80}.dark\:text-white\/60:is(.dark *){color:#fff9}.dark\:text-white\/70:is(.dark *){color:#ffffffb3}.dark\:text-white\/75:is(.dark *){color:#ffffffbf}.dark\:text-white\/80:is(.dark *){color:#fffc}.dark\:text-white\/90:is(.dark *){color:#ffffffe6}.dark\:text-white\/\[0\.2\]:is(.dark *){color:#fff3}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.dark\:text-yellow-400\/70:is(.dark *){color:#facc15b3}.dark\:shadow-none:is(.dark *){--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:focus-within\:bg-white\/10:focus-within:is(.dark *){background-color:#ffffff1a}.dark\:hover\:bg-red-900\/30:hover:is(.dark *){background-color:#7f1d1d4d}.dark\:hover\:bg-white\/10:hover:is(.dark *){background-color:#ffffff1a}.dark\:hover\:text-\[var\(--primary\)\]:hover:is(.dark *){color:var(--primary)}.dark\:active\:text-\[var\(--title-active\)\]:active:is(.dark *){color:var(--title-active)}@media(min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:768px){.md\:absolute{position:absolute}.md\:bottom-3{bottom:.75rem}.md\:left-\[unset\]{left:unset}.md\:right-3{right:.75rem}.md\:top-3{top:.75rem}.md\:col-span-1{grid-column:span 1 / span 1}.md\:col-start-1{grid-column-start:1}.md\:col-start-2{grid-column-start:2}.md\:col-end-2{grid-column-end:2}.md\:col-end-3{grid-column-end:3}.md\:row-start-1{grid-row-start:1}.md\:row-end-2{grid-row-end:2}.md\:mx-0{margin-left:0;margin-right:0}.md\:my-4{margin-top:1rem;margin-bottom:1rem}.md\:mb-0{margin-bottom:0}.md\:mb-4{margin-bottom:1rem}.md\:mt-0{margin-top:0}.md\:mt-8{margin-top:2rem}.md\:line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.md\:block{display:block}.md\:inline{display:inline}.md\:\!flex{display:flex!important}.md\:flex{display:flex}.md\:\!hidden{display:none!important}.md\:hidden{display:none}.md\:h-\[15vh\]{height:15vh}.md\:max-h-none{max-height:none}.md\:w-\[10\%\]{width:10%}.md\:w-\[15\%\]{width:15%}.md\:w-\[20rem\]{width:20rem}.md\:w-\[30rem\]{width:30rem}.md\:w-\[65\%\]{width:65%}.md\:w-\[80\%\]{width:80%}.md\:w-\[calc\(100\%_-_52px_-_12px\)\]{width:calc(100% - 64px)}.md\:w-\[calc\(100\%_-_var\(--coverWidth\)_-_12px\)\]{width:calc(100% - var(--coverWidth) - 12px)}.md\:w-\[var\(--coverWidth\)\]{width:var(--coverWidth)}.md\:max-w-\[17\.5rem\]{max-width:17.5rem}.md\:max-w-\[65\%\]{max-width:65%}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-\[17\.5rem_1fr\]{grid-template-columns:17.5rem 1fr}.md\:grid-cols-\[1fr_17\.5rem\]{grid-template-columns:1fr 17.5rem}.md\:flex-row{flex-direction:row}.md\:flex-col{flex-direction:column}.md\:gap-3{gap:.75rem}.md\:gap-4{gap:1rem}.md\:bg-transparent{background-color:transparent}.md\:p-2{padding:.5rem}.md\:p-6{padding:1.5rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:px-9{padding-left:2.25rem;padding-right:2.25rem}.md\:py-0{padding-top:0;padding-bottom:0}.md\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.md\:pl-9{padding-left:2.25rem}.md\:pr-2{padding-right:.5rem}.md\:pt-7{padding-top:1.75rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-9xl{font-size:8rem;line-height:1}.md\:text-\[16px\]{font-size:16px}.md\:text-\[2\.25rem\]\/\[2\.75rem\]{font-size:2.25rem;line-height:2.75rem}.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-sm{font-size:.875rem;line-height:1.25rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}.md\:before\:block:before{content:var(--tw-content);display:block}.md\:before\:w-1:before{content:var(--tw-content);width:.25rem}}@media(min-width:1024px){.lg\:col-span-1{grid-column:span 1 / span 1}.lg\:col-start-1{grid-column-start:1}.lg\:col-start-2{grid-column-start:2}.lg\:col-end-2{grid-column-end:2}.lg\:col-end-3{grid-column-end:3}.lg\:row-start-1{grid-row-start:1}.lg\:row-end-2{grid-row-end:2}.lg\:mx-0{margin-left:0;margin-right:0}.lg\:mb-4{margin-bottom:1rem}.lg\:mt-0{margin-top:0}.lg\:mt-10{margin-top:2.5rem}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:\!hidden{display:none!important}.lg\:hidden{display:none}.lg\:w-3\/4{width:75%}.lg\:w-full{width:100%}.lg\:max-w-\[17\.5rem\]{max-width:17.5rem}.lg\:max-w-none{max-width:none}.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[17\.5rem_1fr\]{grid-template-columns:17.5rem 1fr}.lg\:grid-cols-\[1fr_17\.5rem\]{grid-template-columns:1fr 17.5rem}.lg\:grid-rows-\[auto\]{grid-template-rows:auto}.lg\:gap-4{gap:1rem}.lg\:p-3{padding:.75rem}.lg\:p-8{padding:2rem}.lg\:text-2xl{font-size:1.5rem;line-height:2rem}.lg\:text-3xl{font-size:1.875rem;line-height:2.25rem}.lg\:text-8xl{font-size:6rem;line-height:1}.lg\:text-base{font-size:1rem;line-height:1.5rem}.lg\:text-lg{font-size:1.125rem;line-height:1.75rem}.lg\:first-of-type\:mt-0:first-of-type{margin-top:0}}@media(min-width:1280px){.xl\:block{display:block}}.custom-md blockquote.admonition .bdm-title{display:flex;align-items:center;margin-bottom:-.9rem;font-weight:700}.custom-md blockquote.admonition .bdm-title:before{content:" ";display:inline-block;font-size:inherit;overflow:visible;margin-right:.6rem;height:1em;width:1em;vertical-align:-.126em;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;transform:translateY(-.0625rem)}.custom-md blockquote.admonition.bdm-tip .bdm-title{color:var(--admonitions-color-tip)}.custom-md blockquote.admonition.bdm-tip .bdm-title:before{background:var(--admonitions-color-tip);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z'%3E%3C/path%3E%3C/svg%3E")}.custom-md blockquote.admonition.bdm-tip:before{background:var(--admonitions-color-tip)}.custom-md blockquote.admonition.bdm-note .bdm-title{color:var(--admonitions-color-note)}.custom-md blockquote.admonition.bdm-note .bdm-title:before{background:var(--admonitions-color-note);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath fill='var(--admonitions-color-tip)' d='M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath fill='var(--admonitions-color-tip)' d='M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E")}.custom-md blockquote.admonition.bdm-note:before{background:var(--admonitions-color-note)}.custom-md blockquote.admonition.bdm-important .bdm-title{color:var(--admonitions-color-important)}.custom-md blockquote.admonition.bdm-important .bdm-title:before{background:var(--admonitions-color-important);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'%3E%3C/path%3E%3C/svg%3E")}.custom-md blockquote.admonition.bdm-important:before{background:var(--admonitions-color-important)}.custom-md blockquote.admonition.bdm-warning .bdm-title{color:var(--admonitions-color-warning)}.custom-md blockquote.admonition.bdm-warning .bdm-title:before{background:var(--admonitions-color-warning);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'%3E%3C/path%3E%3C/svg%3E")}.custom-md blockquote.admonition.bdm-warning:before{background:var(--admonitions-color-warning)}.custom-md blockquote.admonition.bdm-caution .bdm-title{color:var(--admonitions-color-caution)}.custom-md blockquote.admonition.bdm-caution .bdm-title:before{background:var(--admonitions-color-caution);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath d='M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E")}.custom-md blockquote.admonition.bdm-caution:before{background:var(--admonitions-color-caution)}.custom-md img{border-radius:.75rem}.custom-md hr{border-color:var(--line-divider);border-style:dashed}.custom-md iframe{border-radius:.75rem;margin-left:auto;margin-right:auto;max-width:100%}a.card-github{display:block;background:var(--license-block-bg);position:relative;margin:.5rem 0;padding:1.1rem 1.5rem;color:var(--tw-prose-body);border-radius:var(--radius-large);text-decoration-thickness:0px;text-decoration-line:none}a.card-github:hover{background-color:var(--btn-regular-bg-hover)}a.card-github:hover .gc-titlebar{color:var(--btn-content)}a.card-github:hover .gc-stars,a.card-github:hover .gc-forks,a.card-github:hover .gc-license,a.card-github:hover .gc-description{color:var(--tw-prose-headings)}a.card-github:hover .gc-stars:before,a.card-github:hover .gc-forks:before,a.card-github:hover .gc-license:before,a.card-github:hover .gc-description:before{background-color:var(--tw-prose-headings)}a.card-github:active{scale:.98;background-color:var(--btn-regular-bg-active)}a.card-github .gc-titlebar{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem;color:var(--tw-prose-headings);font-size:1.25rem;font-weight:500}a.card-github .gc-titlebar .gc-titlebar-left{display:flex;flex-flow:row nowrap;gap:.5rem}a.card-github .gc-titlebar .gc-repo{font-weight:700}a.card-github .gc-titlebar .gc-owner{font-weight:300;position:relative;display:flex;flex-flow:row nowrap;gap:.5rem;align-items:center}a.card-github .gc-titlebar .gc-avatar{display:block;overflow:hidden;width:1.5rem;height:1.5rem;margin-top:-.1rem;background-color:var(--primary);background-size:cover;border-radius:50%}a.card-github .gc-description{margin-bottom:.7rem;font-size:1rem;font-weight:300;line-height:1.5rem;color:var(--tw-prose-body)}a.card-github .gc-infobar{display:flex;flex-flow:row nowrap;gap:1.5rem;color:var(--tw-prose-body);width:-moz-fit-content;width:fit-content}a.card-github .gc-language{display:none}a.card-github .gc-stars,a.card-github .gc-forks,a.card-github .gc-license,a.card-github .github-logo{font-weight:500;font-size:.875rem;opacity:.9}a.card-github .gc-stars:before,a.card-github .gc-forks:before,a.card-github .gc-license:before,a.card-github .github-logo:before{content:" ";display:inline-block;height:1.3em;width:1.3em;margin-right:.4rem;vertical-align:-.24em;font-size:inherit;background-color:var(--tw-prose-body);overflow:visible;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;transition-property:background-color,background;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}a.card-github .gc-stars:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z'%3E%3C/path%3E%3C/svg%3E")}a.card-github .gc-license:before{margin-right:.5rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z'%3E%3C/path%3E%3C/svg%3E")}a.card-github .gc-forks:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z'%3E%3C/path%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z'%3E%3C/path%3E%3C/svg%3E")}a.card-github .github-logo{font-size:1.25rem}a.card-github .github-logo:before{background-color:var(--tw-prose-headings);margin-right:0;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='31' height='32' viewBox='0 0 496 512'%3E%3Cpath fill='%23a1f7cb' d='M165.9 397.4c0 2-2.3 3.6-5.2 3.6c-3.3.3-5.6-1.3-5.6-3.6c0-2 2.3-3.6 5.2-3.6c3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9c2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9c.3 2 2.9 3.3 5.9 2.6c2.9-.7 4.9-2.6 4.6-4.6c-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2c12.8 2.3 17.3-5.6 17.3-12.1c0-6.2-.3-40.4-.3-61.4c0 0-70 15-84.7-29.8c0 0-11.4-29.1-27.8-36.6c0 0-22.9-15.7 1.6-15.4c0 0 24.9 2 38.6 25.8c21.9 38.6 58.6 27.5 72.9 20.9c2.3-16 8.8-27.1 16-33.7c-55.9-6.2-112.3-14.3-112.3-110.5c0-27.5 7.6-41.3 23.6-58.9c-2.6-6.5-11.1-33.3 2.6-67.9c20.9-6.5 69 27 69 27c20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27c13.7 34.7 5.2 61.4 2.6 67.9c16 17.7 25.8 31.5 25.8 58.9c0 96.5-58.9 104.2-114.8 110.5c9.2 7.9 17 22.9 17 46.4c0 33.7-.3 75.4-.3 83.6c0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252C496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2c1.6 1.6 3.9 2.3 5.2 1c1.3-1 1-3.3-.7-5.2c-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9c1.6 1 3.6.7 4.3-.7c.7-1.3-.3-2.9-2.3-3.9c-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2c2.3 2.3 5.2 2.6 6.5 1c1.3-1.3.7-4.3-1.3-6.2c-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9c1.6 2.3 4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2c-1.4-2.3-4-3.3-5.6-2'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='31' height='32' viewBox='0 0 496 512'%3E%3Cpath fill='%23a1f7cb' d='M165.9 397.4c0 2-2.3 3.6-5.2 3.6c-3.3.3-5.6-1.3-5.6-3.6c0-2 2.3-3.6 5.2-3.6c3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9c2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9c.3 2 2.9 3.3 5.9 2.6c2.9-.7 4.9-2.6 4.6-4.6c-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2c12.8 2.3 17.3-5.6 17.3-12.1c0-6.2-.3-40.4-.3-61.4c0 0-70 15-84.7-29.8c0 0-11.4-29.1-27.8-36.6c0 0-22.9-15.7 1.6-15.4c0 0 24.9 2 38.6 25.8c21.9 38.6 58.6 27.5 72.9 20.9c2.3-16 8.8-27.1 16-33.7c-55.9-6.2-112.3-14.3-112.3-110.5c0-27.5 7.6-41.3 23.6-58.9c-2.6-6.5-11.1-33.3 2.6-67.9c20.9-6.5 69 27 69 27c20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27c13.7 34.7 5.2 61.4 2.6 67.9c16 17.7 25.8 31.5 25.8 58.9c0 96.5-58.9 104.2-114.8 110.5c9.2 7.9 17 22.9 17 46.4c0 33.7-.3 75.4-.3 83.6c0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252C496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2c1.6 1.6 3.9 2.3 5.2 1c1.3-1 1-3.3-.7-5.2c-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9c1.6 1 3.6.7 4.3-.7c.7-1.3-.3-2.9-2.3-3.9c-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2c2.3 2.3 5.2 2.6 6.5 1c1.3-1.3.7-4.3-1.3-6.2c-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9c1.6 2.3 4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2c-1.4-2.3-4-3.3-5.6-2'/%3E%3C/svg%3E")}a.card-github.fetch-waiting{pointer-events:none;opacity:.7;transition:opacity .15s ease-in-out}a.card-github.fetch-waiting .gc-description,a.card-github.fetch-waiting .gc-infobar,a.card-github.fetch-waiting .gc-avatar{background-color:var(--tw-prose-body);color:transparent;opacity:.5;animation:pulsate 2s infinite linear;-webkit-user-select:none;-moz-user-select:none;user-select:none}a.card-github.fetch-waiting .gc-description:before,a.card-github.fetch-waiting .gc-infobar:before,a.card-github.fetch-waiting .gc-avatar:before{background-color:transparent}a.card-github.fetch-waiting .gc-repo{margin-left:-.1rem}a.card-github.fetch-waiting .gc-description,a.card-github.fetch-waiting .gc-infobar{border-radius:.5rem}a.card-github.fetch-error{pointer-events:all;opacity:1}.card-github,.gc-description,.gc-titlebar,.gc-stars,.gc-forks,.gc-license,.gc-avatar,.github-logo{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.mermaid-diagram-container{margin:1rem 0;border-radius:.75rem;overflow:hidden;background:var(--card-bg);transition:all .3s ease}.mermaid-diagram-container:hover{box-shadow:0 4px 12px #0000001a}.mermaid-wrapper{padding:1.5rem;text-align:center}.mermaid{display:flex;justify-content:center;align-items:center;min-height:100px;font-family:inherit}.mermaid svg{max-width:100%;height:auto;border-radius:.5rem}.mermaid-error{color:var(--admonitions-color-warning);background:var(--admonitions-color-warning);background:#ef44441a;border:1px solid var(--admonitions-color-warning);border-radius:.5rem;padding:1rem;margin:1rem 0;text-align:center;font-weight:500}.dark .mermaid-diagram-container{background:var(--card-bg)}.dark .mermaid-diagram-container svg{filter:brightness(.9) contrast(1.1)}@media(max-width:768px){.mermaid-wrapper{padding:1rem}.mermaid svg{max-height:400px}}@keyframes pulsate{0%{opacity:.15}50%{opacity:.25}to{opacity:.15}}.custom-md h1{font-size:1.875rem;line-height:2.25rem}.custom-md h1 .anchor,.custom-md h2 .anchor,.custom-md h3 .anchor,.custom-md h4 .anchor,.custom-md h5 .anchor,.custom-md h6 .anchor{margin:-.125rem!important;margin-left:.2ch!important;-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important;padding:.125rem!important;text-decoration-line:none!important;opacity:0!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.custom-md h1 .anchor .anchor-icon,.custom-md h2 .anchor .anchor-icon,.custom-md h3 .anchor .anchor-icon,.custom-md h4 .anchor .anchor-icon,.custom-md h5 .anchor .anchor-icon,.custom-md h6 .anchor .anchor-icon{margin-left:.45ch!important;margin-right:.45ch!important}.custom-md h1:hover .anchor,.custom-md h2:hover .anchor,.custom-md h3:hover .anchor,.custom-md h4:hover .anchor,.custom-md h5:hover .anchor,.custom-md h6:hover .anchor{opacity:1!important}.custom-md a:not(.no-styling){position:relative;background-image:none;font-weight:500;color:var(--primary);text-decoration-line:underline;text-decoration-color:var(--link-underline);text-decoration-style:dashed;text-decoration-thickness:1px;text-underline-offset:4px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.custom-md a:not(.no-styling):hover,.custom-md a:not(.no-styling):active{text-decoration-color:transparent;background:var(--btn-plain-bg-hover);border-bottom:1px dashed var(--link-hover);text-decoration:none}.custom-md code{overflow:hidden;border-radius:.375rem;background-color:var(--inline-code-bg);padding:.125rem .25rem;color:var(--inline-code-color);font-family:JetBrains Mono Variable,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.custom-md code:before{content:none}.custom-md code:after{content:none}.custom-md code{counter-reset:line}.custom-md code span.line:before{margin-right:1rem;display:inline-block;width:1rem;color:#ffffff40;content:counter(line);counter-increment:line;direction:rtl}.custom-md code span.line:last-child:empty,.custom-md code span.line:last-child:has(>span:empty:only-child){display:none}.custom-md .copy-btn{all:initial;position:absolute;top:.75rem;right:.75rem;z-index:20;height:2rem;width:2rem;cursor:pointer;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;opacity:0;--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);--tw-shadow-color: rgb(0 0 0 / .5);--tw-shadow: var(--tw-shadow-colored);transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.custom-md .copy-btn:hover{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.custom-md .copy-btn:active{--tw-scale-x: .9;--tw-scale-y: .9;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.custom-md .frame:hover .copy-btn{opacity:1}.custom-md .copy-btn-icon{pointer-events:none;position:absolute;top:50%;left:50%;height:1rem;width:1rem;--tw-translate-x: -50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));fill:#fff;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.custom-md .copy-btn .copy-icon{fill:#fff;opacity:1}.custom-md .copy-btn .copy-icon:is(.dark *){fill:#ffffffbf}.custom-md .copy-btn.success .copy-icon{fill:var(--deep-text);opacity:0}.custom-md .copy-btn .success-icon{fill:#fff;opacity:0}.custom-md .copy-btn.success .success-icon{opacity:1}.custom-md .expressive-code{margin-top:1rem;margin-bottom:1rem}.custom-md .expressive-code ::-moz-selection{background-color:var(--codeblock-selection)}.custom-md .expressive-code ::selection{background-color:var(--codeblock-selection)}.custom-md ul li::marker,.custom-md ol li::marker{color:var(--primary)}.custom-md blockquote{position:relative;border-color:transparent;font-style:normal;font-weight:inherit}.custom-md blockquote:before{position:absolute;left:-.25rem;display:block;height:100%;width:.25rem;border-radius:9999px;background-color:var(--btn-regular-bg);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;--tw-content: "";content:var(--tw-content)}.custom-md blockquote p:before,.custom-md blockquote p:after{--tw-content: none;content:var(--tw-content)}.custom-md .katex-display-container{max-width:100%;overflow-x:auto;margin:1em 0}.pswp__button{margin-right:0!important;display:flex!important;height:3rem!important;width:3rem!important;align-items:center!important;justify-content:center!important;background-color:#0006!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.pswp__button:hover{background-color:#00000080!important}.pswp__button:active{background-color:#0009!important}.pswp__button--zoom,.pswp__button--close{margin-top:1rem!important;border-radius:.75rem!important}.pswp__button--zoom:active,.pswp__button--close:active{--tw-scale-x: .9 !important;--tw-scale-y: .9 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.pswp__button--zoom{margin-right:.625rem!important}.pswp__button--close{margin-right:1rem!important}.scrollbar-base.os-scrollbar{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;pointer-events:unset}.scrollbar-base.os-scrollbar.os-scrollbar-horizontal{height:1rem;padding:.25rem .5rem}.scrollbar-base.os-scrollbar.os-scrollbar-horizontal .os-scrollbar-track .os-scrollbar-handle{height:.25rem;border-radius:9999px}.scrollbar-base.os-scrollbar.os-scrollbar-horizontal:hover .os-scrollbar-track .os-scrollbar-handle{height:.5rem}.scrollbar-base.os-scrollbar.os-scrollbar-vertical{width:1rem;padding:.25rem}.scrollbar-base.os-scrollbar.os-scrollbar-vertical .os-scrollbar-track .os-scrollbar-handle{width:.25rem;border-radius:9999px}.scrollbar-base.os-scrollbar.os-scrollbar-vertical:hover .os-scrollbar-track .os-scrollbar-handle{width:.5rem}.os-scrollbar.scrollbar-auto{--os-handle-bg: var(--scrollbar-bg);--os-handle-bg-hover: var(--scrollbar-bg-hover);--os-handle-bg-active: var(--scrollbar-bg-active)}.os-scrollbar.scrollbar-dark{--os-handle-bg: var(--scrollbar-bg-dark);--os-handle-bg-hover: var(--scrollbar-bg-hover-dark);--os-handle-bg-active: var(--scrollbar-bg-active-dark)}.os-scrollbar.scrollbar-light{--os-handle-bg: var(--scrollbar-bg-light);--os-handle-bg-hover: var(--scrollbar-bg-hover-light);--os-handle-bg-active: var(--scrollbar-bg-active-light)}html.is-changing .transition-swup-fade{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}html.is-animating .transition-swup-fade{--tw-translate-y: 1rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));opacity:0}@keyframes fade-in-up{0%{transform:translateY(2rem);opacity:0}to{transform:translateY(0);opacity:1}}.onload-animation{opacity:0;animation:.15s fade-in-up;animation-fill-mode:forwards}#navbar{animation-delay:20ms}#sidebar{animation-delay:40ms}#swup-container{outline:none}#content-wrapper{animation-delay:60ms}.footer{animation-delay:80ms}#banner-credit{animation-delay:.1s}#post-container :nth-child(1){animation-delay:0ms}#post-container :nth-child(2){animation-delay:20ms}#post-container :nth-child(3){animation-delay:40ms}#post-container :nth-child(4){animation-delay:60ms}#post-container :nth-child(5){animation-delay:80ms}#post-container :nth-child(6){animation-delay:.1s}:root{--tk-text: black;--code-block-text: #d1d5db}html.dark{--tk-text: #d1d5db}.tk-comments{color:var(--tk-text)}.tk-submit .tk-avatar{display:none}.tk-row .tk-col{flex-direction:column-reverse}.tk-row .tk-col .tk-input textarea{min-height:150px!important;border-radius:var(--radius-large);padding:1rem 1.5rem}.tk-row .tk-col .tk-input textarea:focus{border-color:var(--primary)}.tk-meta-input{position:relative;margin-top:.75rem}.tk-meta-input div{min-height:2.5rem}.tk-meta-input div .el-input-group__prepend{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem;background-color:inherit!important;min-height:inherit}.tk-meta-input div input{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem;padding-left:1rem;padding-right:1rem}.tk-meta-input div input:focus{border-color:var(--primary)!important}.tk-meta-input div input{min-height:inherit}.tk-row.actions{margin-left:0!important;margin-top:0!important;width:100%}.tk-row.actions .__markdown{display:none!important}.tk-row.actions .tk-preview,.tk-row.actions .tk-send,.tk-row.actions .tk-cancel{height:2rem;border-radius:.5rem;border-style:none;background-color:var(--btn-regular-bg-active)!important;padding-left:.75rem;padding-right:.75rem;padding-top:0;padding-bottom:0;color:var(--btn-content)!important}.tk-row.actions .tk-preview:disabled,.tk-row.actions .tk-send:disabled,.tk-row.actions .tk-cancel:disabled{background-color:var(--btn-regular-bg)!important;color:#ffffffa1!important}.tk-comments-title .__comments svg{fill:var(--primary)}.tk-comment{border-radius:1rem;border-width:1px;border-color:#9093994f;padding:1rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.tk-comment:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.tk-comment .tk-action-icon svg{fill:var(--primary)}.tk-action .tk-action-count{color:var(--btn-content)}.tk-meta .tk-tag{border-radius:.5rem;border-style:none;color:var(--btn-content)}.tk-meta .tk-tag-green{background-color:var(--btn-regular-bg)}.tk-meta .tk-tag-green:is(.dark *){background-color:var(--primary);color:var(--deep-text)}.tk-content img,.tk-preview-container img{display:inline;vertical-align:bottom!important}.tk-content a,.tk-preview-container a{position:relative;z-index:0}.tk-content a:before,.tk-preview-container a:before{position:absolute;inset:0;z-index:-10;--tw-scale-x: .85;--tw-scale-y: .85;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:inherit;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;content:var(--tw-content);transition-timing-function:cubic-bezier(0,0,.2,1)}.tk-content a:hover:before,.tk-preview-container a:hover:before{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));content:var(--tw-content);background-color:var(--btn-plain-bg-hover)}.tk-content a:active,.tk-preview-container a:active{background-image:none}.tk-content a:active:before,.tk-preview-container a:active:before{content:var(--tw-content);background-color:var(--btn-plain-bg-active)}.tk-content a,.tk-preview-container a{margin:-.25rem;border-radius:.375rem;padding:.25rem;text-decoration-line:underline;text-decoration-color:var(--link-underline);text-decoration-style:dashed;text-decoration-thickness:2px;text-underline-offset:.25rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.tk-content a:hover,.tk-preview-container a:hover{text-decoration-color:var(--link-hover)}.tk-content a:active,.tk-preview-container a:active{text-decoration-color:var(--link-active)}.tk-content a,.tk-preview-container a{font-weight:500;color:var(--primary)}.tk-content .tk-ruser,.tk-preview-container .tk-ruser{text-decoration-line:none}.tk-content :not(pre)>code,.tk-preview-container :not(pre)>code{border-radius:.375rem;background-color:var(--inline-code-bg);padding:.125rem .25rem;font-weight:600;color:var(--inline-code-color)}.tk-content li:before,.tk-preview-container li:before{color:var(--primary);--tw-content: "•";content:var(--tw-content)}.tk-replies .tk-comment{background-color:var(--page-bg)}.tk-replies .tk-comment .tk-content>span:first-of-type{font-size:.75rem;line-height:1rem}.twikoo .code-block pre{border-radius:.75rem!important}.twikoo .code-block pre:not([class]){overflow:auto;--tw-bg-opacity: 1;background-color:rgb(45 45 45 / var(--tw-bg-opacity, 1));padding:.5rem;color:var(--code-block-text)}.twikoo .code-block .copy-btn-icon{width:inherit!important;height:inherit!important}.tk-expand-wrap .tk-expand,.tk-collapse-wrap .tk-expand{margin-top:.25rem}.tk-expand-wrap .tk-expand:hover,.tk-collapse-wrap .tk-expand:hover{border-radius:.5rem;background-color:var(--btn-plain-bg-hover)}.card-base{overflow:visible}.tk-action-icon,.tk-owo,.tk-submit,.tk-cancel,.tk-preview,.tk-admin,.tk-delete,.tk-edit{cursor:pointer;transition:all .2s ease}.tk-action{min-height:24px;display:flex;align-items:center}.tk-submit-wrapper{position:relative}.tk-admin-panel{position:relative;z-index:100}:root{--radius-large: 1rem;--content-delay: .15s}:root{--primary: oklch(.7 .14 var(--hue));--page-bg: oklch(.95 .01 var(--hue));--card-bg: white;--card-bg-transparent: rgba(255,255,255,.8);--btn-content: oklch(.55 .12 var(--hue));--btn-regular-bg: oklch(.95 .025 var(--hue));--btn-regular-bg-hover: oklch(.9 .05 var(--hue));--btn-regular-bg-active: oklch(.85 .08 var(--hue));--btn-plain-bg-hover: oklch(.95 .025 var(--hue));--btn-plain-bg-active: oklch(.98 .01 var(--hue));--btn-card-bg-hover: oklch(.98 .005 var(--hue));--btn-card-bg-active: oklch(.9 .03 var(--hue));--enter-btn-bg: var(--btn-regular-bg);--enter-btn-bg-hover: var(--btn-regular-bg-hover);--enter-btn-bg-active: var(--btn-regular-bg-active);--deep-text: oklch(.25 .02 var(--hue));--title-active: oklch(.6 .1 var(--hue));--line-divider: rgba(0,0,0,.08);--line-color: rgba(0,0,0,.1);--meta-divider: rgba(0,0,0,.2);--content-meta: rgba(0,0,0,.5);--inline-code-bg: var(--btn-regular-bg);--inline-code-color: var(--btn-content);--selection-bg: oklch(.9 .05 var(--hue));--codeblock-selection: oklch(.4 .08 var(--hue));--codeblock-bg: oklch(.17 .015 var(--hue));--codeblock-topbar-bg: oklch(.3 .02 var(--hue));--license-block-bg: rgba(0,0,0,.03);--link-underline: oklch(.93 .04 var(--hue));--link-hover: oklch(.95 .025 var(--hue));--link-active: oklch(.9 .05 var(--hue));--float-panel-bg: white;--scrollbar-bg-light: rgba(0,0,0,.4);--scrollbar-bg-hover-light: rgba(0,0,0,.5);--scrollbar-bg-active-light: rgba(0,0,0,.6);--scrollbar-bg-dark: rgba(255,255,255,.4);--scrollbar-bg-hover-dark: rgba(255,255,255,.5);--scrollbar-bg-active-dark: rgba(255,255,255,.6);--scrollbar-bg: var(--scrollbar-bg-light);--scrollbar-bg-hover: var(--scrollbar-bg-hover-light);--scrollbar-bg-active: var(--scrollbar-bg-active-light);--color-selection-bar: linear-gradient(to right, oklch(.8 .1 0), oklch(.8 .1 30), oklch(.8 .1 60), oklch(.8 .1 90), oklch(.8 .1 120), oklch(.8 .1 150), oklch(.8 .1 180), oklch(.8 .1 210), oklch(.8 .1 240), oklch(.8 .1 270), oklch(.8 .1 300), oklch(.8 .1 330), oklch(.8 .1 360));--display-light-icon: 1;--display-dark-icon: 0;--admonitions-color-tip: oklch(.7 .14 180);--admonitions-color-note: oklch(.7 .14 250);--admonitions-color-important: oklch(.7 .14 310);--admonitions-color-warning: oklch(.7 .14 60);--admonitions-color-caution: oklch(.6 .2 25);--toc-badge-bg: oklch(.9 .045 var(--hue));--toc-btn-hover: oklch(.92 .015 var(--hue));--toc-btn-active: oklch(.9 .015 var(--hue));--toc-width: calc((100vw - var(--page-width)) / 2 - 1rem);--toc-item-active: oklch(.7 .13 var(--hue))}:root.dark{--primary: oklch(.75 .14 var(--hue));--page-bg: oklch(.16 .014 var(--hue));--card-bg: oklch(.23 .015 var(--hue));--card-bg-transparent: rgba(23,23,23,.8);--btn-content: oklch(.75 .1 var(--hue));--btn-regular-bg: oklch(.33 .035 var(--hue));--btn-regular-bg-hover: oklch(.38 .04 var(--hue));--btn-regular-bg-active: oklch(.43 .045 var(--hue));--btn-plain-bg-hover: oklch(.3 .035 var(--hue));--btn-plain-bg-active: oklch(.27 .025 var(--hue));--btn-card-bg-hover: oklch(.3 .03 var(--hue));--btn-card-bg-active: oklch(.35 .035 var(--hue));--line-divider: rgba(255,255,255,.08);--line-color: rgba(255,255,255,.1);--meta-divider: rgba(255,255,255,.2);--content-meta: rgba(255,255,255,.6);--selection-bg: oklch(.4 .08 var(--hue));--codeblock-bg: oklch(.17 .015 var(--hue));--codeblock-topbar-bg: oklch(.12 .015 var(--hue));--license-block-bg: var(--codeblock-bg);--link-underline: oklch(.4 .08 var(--hue));--link-hover: oklch(.4 .08 var(--hue));--link-active: oklch(.35 .07 var(--hue));--float-panel-bg: oklch(.19 .015 var(--hue));--scrollbar-bg: var(--scrollbar-bg-dark);--scrollbar-bg-hover: var(--scrollbar-bg-hover-dark);--scrollbar-bg-active: var(--scrollbar-bg-active-dark);--color-selection-bar: linear-gradient(to right, oklch(.7 .1 0), oklch(.7 .1 30), oklch(.7 .1 60), oklch(.7 .1 90), oklch(.7 .1 120), oklch(.7 .1 150), oklch(.7 .1 180), oklch(.7 .1 210), oklch(.7 .1 240), oklch(.7 .1 270), oklch(.7 .1 300), oklch(.7 .1 330), oklch(.7 .1 360));--display-light-icon: 0;--display-dark-icon: 1;--admonitions-color-tip: oklch(.75 .14 180);--admonitions-color-note: oklch(.75 .14 250);--admonitions-color-important: oklch(.75 .14 310);--admonitions-color-warning: oklch(.75 .14 60);--admonitions-color-caution: oklch(.65 .2 25);--toc-badge-bg: var(--btn-regular-bg);--toc-btn-hover: oklch(.22 .02 var(--hue));--toc-btn-active: oklch(.25 .02 var(--hue));--toc-item-active: oklch(.35 .07 var(--hue))}:root{--breakpoint-mobile: 768px;--breakpoint-tablet: 1024px;--breakpoint-desktop: 1025px;--widget-gap-mobile: .75rem;--widget-gap-tablet: 1rem;--widget-gap-desktop: 1.25rem;--widget-animation-duration: .3s;--widget-animation-timing: ease-in-out;--sidebar-width-mobile: 100%;--sidebar-width-tablet: 280px;--sidebar-width-desktop: 320px;--widget-min-height: 60px;--widget-max-height-mobile: 200px;--widget-max-height-tablet: 300px;--widget-max-height-desktop: 400px}#dynamic-sidebar{width:var(--sidebar-width-desktop);transition:all var(--widget-animation-duration) var(--widget-animation-timing);position:relative}.widget-container{min-height:var(--widget-min-height);transition:all var(--widget-animation-duration) var(--widget-animation-timing);overflow:hidden}.widget-container:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000001a}.widget-container.widget-hover{transform:translateY(-2px);box-shadow:0 4px 12px #00000026}@media(max-width:767px){#dynamic-sidebar{width:var(--sidebar-width-mobile);padding:.5rem}.sidebar-top-section,.sidebar-sticky-section{gap:var(--widget-gap-mobile)}.widget-container{max-height:var(--widget-max-height-mobile)}.widget-container[data-mobile-hidden=true]{display:none}.sidebar-sticky-section{position:static!important;top:auto!important}.widget-container[data-widget-type=announcement]{order:-1}.widget-container[data-widget-type=categories],.widget-container[data-widget-type=tags]{max-height:120px;overflow-y:auto}}@media(min-width:768px)and (max-width:1024px){#dynamic-sidebar{width:var(--sidebar-width-tablet);padding:.75rem}.sidebar-top-section,.sidebar-sticky-section{gap:var(--widget-gap-tablet)}.widget-container{max-height:var(--widget-max-height-tablet)}.widget-container[data-tablet-hidden=true]{display:none}.widget-container[data-widget-type=music-player]{transform:scale(.95)}}@media(min-width:1025px){#dynamic-sidebar{width:var(--sidebar-width-desktop);padding:1rem}.sidebar-top-section,.sidebar-sticky-section{gap:var(--widget-gap-desktop)}.widget-container{max-height:var(--widget-max-height-desktop)}.widget-container[data-desktop-hidden=true]{display:none}.widget-container:hover{transform:translateY(-4px);box-shadow:0 8px 24px #0000001f}}@media(min-width:1441px){#dynamic-sidebar{width:360px}.widget-container{max-height:500px}}.sidebar-top-section{margin-bottom:1rem}.sidebar-sticky-section{position:sticky;top:1rem;z-index:10}.widget-container[data-widget-type=profile]{min-height:120px}@media(max-width:767px){.widget-container[data-widget-type=profile]{min-height:100px}}.widget-container[data-widget-type=announcement]{min-height:80px}@media(max-width:767px){.widget-container[data-widget-type=announcement]{min-height:60px;font-size:.875rem}}.widget-container[data-widget-type=categories],.widget-container[data-widget-type=tags]{overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(156,163,175,.5) transparent}.widget-container[data-widget-type=categories]::-webkit-scrollbar,.widget-container[data-widget-type=tags]::-webkit-scrollbar{width:4px}.widget-container[data-widget-type=categories]::-webkit-scrollbar-track,.widget-container[data-widget-type=tags]::-webkit-scrollbar-track{background:transparent}.widget-container[data-widget-type=categories]::-webkit-scrollbar-thumb,.widget-container[data-widget-type=tags]::-webkit-scrollbar-thumb{background-color:#9ca3af80;border-radius:2px}.widget-container[data-widget-type=toc]{max-height:400px;overflow-y:auto}@media(max-width:767px){.widget-container[data-widget-type=toc]{display:none}}.widget-container[data-widget-type=music-player]{min-height:100px;max-height:150px}@media(max-width:767px){.widget-container[data-widget-type=music-player]{min-height:80px;max-height:120px}}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes slideIn{0%{opacity:0;transform:translate(-30px)}to{opacity:1;transform:translate(0)}}@keyframes scaleIn{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.widget-animation-fade{animation:fadeIn var(--widget-animation-duration) var(--widget-animation-timing) forwards}.widget-animation-slide{animation:slideIn var(--widget-animation-duration) var(--widget-animation-timing) forwards}.widget-animation-scale{animation:scaleIn var(--widget-animation-duration) var(--widget-animation-timing) forwards}.widget-container{opacity:0}.widget-container.widget-animated{opacity:1}.widget-loading{position:relative;overflow:hidden}.widget-loading:before{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent);animation:shimmer 1.5s infinite}@keyframes shimmer{0%{left:-100%}to{left:100%}}.widget-error{border:2px dashed #ef4444;background-color:#fef2f2;color:#dc2626;display:flex;align-items:center;justify-content:center;min-height:80px;text-align:center;font-size:.875rem}.widget-empty{border:2px dashed #d1d5db;background-color:#f9fafb;color:#6b7280;display:flex;align-items:center;justify-content:center;min-height:80px;text-align:center;font-size:.875rem}@media(prefers-color-scheme:dark){.widget-container:hover{box-shadow:0 4px 12px #0000004d}.widget-container.widget-hover{box-shadow:0 4px 12px #0006}.widget-error{border-color:#f87171;background-color:#450a0a;color:#fca5a5}.widget-empty{border-color:#4b5563;background-color:#111827;color:#9ca3af}.widget-loading:before{background:linear-gradient(90deg,transparent,rgba(255,255,255,.1),transparent)}}@media(prefers-contrast:high){.widget-container{border:2px solid currentColor}.widget-container:hover{border-width:3px}}@media(prefers-reduced-motion:reduce){.widget-container,.widget-animation-fade,.widget-animation-slide,.widget-animation-scale{animation:none;transition:none}.widget-container{opacity:1;transform:none}.widget-container:hover{transform:none}}@media print{#dynamic-sidebar{display:none}}@supports (container-type: inline-size){#dynamic-sidebar{container-type:inline-size}@container (max-width: 280px){.widget-container{font-size:.875rem}.widget-container[data-widget-type=categories],.widget-container[data-widget-type=tags]{max-height:150px}}@container (min-width: 360px){.widget-container{padding:1.25rem}}}.widget-hidden{display:none!important}.widget-visible{display:block!important}.widget-compact{padding:.5rem!important;font-size:.875rem!important}.widget-expanded{padding:1.5rem!important;font-size:1rem!important}[data-debug=true] .widget-container{border:1px solid #3b82f6;position:relative}[data-debug=true] .widget-container:before{content:attr(data-widget-type) " [" attr(data-widget-order) "]";position:absolute;top:-1px;left:-1px;background:#3b82f6;color:#fff;font-size:10px;padding:2px 4px;z-index:1000} diff --git a/website/blog/_astro/about.DhJwTaWu.css b/website/blog/_astro/about.DhJwTaWu.css deleted file mode 100644 index 79cfeec..0000000 --- a/website/blog/_astro/about.DhJwTaWu.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAfsABQAAAAAEAwAAAeCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoP0hWQVJbBmA/U1RBVIFiJyYAdC9qEQgKhGSEAAsgADCGCAE2AiQDOgQgBYlMB4EUDAcbLQ4onoexrSC/2ZyLAa8p8VHB8/x3Vue+V0hVJalMJg2nx/TCrQXxBeqLjQG7FyM1WEa/X1tEXN7cFz9EJEMmMUz3RihWSSKeQCbcIou0izz/C8v+fq3VfajEa9gDD11CImXS7qL/RJFVzC1qiB6KmKeD6TZdQ6IRGv78dL6uSVVCfgni5mzu7kcgQBgAEAQTQRCoL++STTYybkJxNfQxAAIAGu8OdEB9teW2jh4BpgDqFjAeSEByW3zFP0CBBgNMsMCGEDjgggdhiEAUAeIIED7ABTDUEnkIE9Q9ahFgKttcVhApo4ACB4qobHaccgDfEjFO6aaWUhjMLt2SyIvHKoDqoA4CSUwEIYQCEjhAO9R1G6keDeDZGjNo+AhxOjCEGTr1WeIF3kYBiLAOKvkJSMiKX0VdAyQt3SDJClCkxJCHkCzfqyVTriJZLcolS32JZHUekq2TYNkYtCtjYHMQXSxGjXDz2t/yLWXzDzxz+o3zFwDEaN23F+13pyMdQAEaSKAR9vcGq4A4MTSKCElGW+M7UcY7xqkggITb28ZJhlqc9q2twYKTt0NjixBgYvO9BIihEBLYuOFXQzfIQ7dXGUEEEgFDooBfAzqiQbpJrhiWSuKJCRFKYbHCyJKI2G5GiZbNAvgAu5pc3vwx4G+g3aDkhklABiSz0BICXrYghtYhx/cdJ+44rY2oZ0aMNRFz3VZjb6W33F3gzltqtOCV8tTHSpOeXuItfvr5lCdfzFpqtEitvqdcdGGFd28ZqqC0tPbeChGXgrIlnhSWu/eUso4uKWFLugyDzQJhflY4659+WjQ++6x72WUMv9G8mw6QJl7BVxX5fe/kpUsOvnZwee9uQ0cGXYd0o89XB2748sDSnt8d2VphdOTTgceDVvOds0v9P/s7HPq15aGun/6Vllb56f1dl0t1LejqrNkpdRZsG8TOnM5vkBG5oiVyVGnS8LHps5cfNWJs6qKPfaNSxiQNBUm3cKNWROr0GSur7Za31k1vieq7LH11VF+jXdRIasRKflc7jkobm1Z9te1IyZA0pDkhLR98+H37Zf1c/8at+dB7x+7GfVyTfJMPiYztsnl59Y5l4j+0n1RXlpHnF3Tq7HecmNF/CJodEMAikruxiyJaGLvHOdAfoA+oDvpjBm2b91cHGRZMU9n25xEU0A8fgEEAdKI3Q1iDtc034sug5YVMkE2jsE+BIkwSoQ3gxXMqz9tELp48bd0cFKOKS7xYjEuXBnZP5ia7DyiO/X/YI+PQSbt2uSdqAkWL9nQbV1XB94/+uPfdZz8dnXYFBYrcTl2SIR/ybxJNJPz/Gupb0JaZeens2ekC7EKr8t+Ls/P5VJPYJdHKyqfg2nqU6bhlidzcddQV/7MmecTzJ5VPcKXkNKSEogHjYFx6QZ7rQ+FSe8njaiNuOnXS8H2ScQ619c2mC3VTtauL0rRbXd/CkSOP37FY9Zkjz8+GibYUMOEWF+RdrFS8Ecv1SHOpPUPZGEIpjPvFyU5cXKjd6OXqorTqy9GwRd++HVufPGnVsW+aO3vggKZ18jR9sXaTC1PWTEsVUaK0FkNySbTQDqlm2PfDjZcu4aalnSLKjnOoYQ0nUlqqXcGpPu/4VgV/xU2pAqW4BW3qzhQ8/hFKhV2qE3+BKAtDqBXjfgnVdH4y0wg5tbVNRenNdTWOrenWLcupQdmsbq5b+18piTe/xRdp1xbILxNPJGInm2z6hoB21Lal0i+ePTtd7B45+3XhFJ329evskXm7qurUVREotqSluSo/L29d3qDhI4YOQqWhI4YNvBNfsMHeXKemXrxQfKeuPOGRVayA3JtkJKEgbPp+dXUDluddutRYLFoXGXWX6N3WFaGLbQtRSitVYNacTNSdy7AaG/HSaUEANcBoGXNdcZvZsOqQ1icBDv21/gzAoYPHH/WDW0qNR3QTYKEAEHig6o13NXbND06CQPlRtYjGNnSktRc09k1mAMDvAlDKfQjgy6fssInlfzmNAjKkDxoxHOBLdVRAIVt9j4qo+hA1w9T1aNBNTUOTTNUHLbqokE+UAfJXCIGw/IxCSL5GRUJeR40rL/UxTm4Q08H6MbCs70ObuNyIIXrINHQYInF06UUlevTjbQzTh5upiDMzMMogUtEnjPs/Y7jAHCJeB0GBHh04tC6FiB6ZFB1oArUSIoFoqhzCeAN6lHwm0T4C3VVPWvjpSMXReuWesMEcoqrmgtNBGd2noWeV0hNAz9rFeShNJxHGsPa3HXeKTk8b55hahySYHaYKKFFLpCfN8rsoaJn01CR04Gkc+5k7KVTCmClX8Q10HCrUEkVlSX+XO33oQR9609tJ516H497WSobWs5Up6TLaS10/dessIskgJSLiDlWvHVUywpkQ7hdPZqGyiEF0uVQerVcPamT1A3eKXdyI1vG9OoflrSXihZ1qqGE3nhmAgiIbRCQgPLEPtOM3UQwTLYaYYomNlpA44opnjV6jkD6id80OOrzf6BzmMD6eEa1zKyeYG1fzfEf16V6jw9XYOaar1/b2kP/IYX8oR2mcFvv2GtBV3JXgd437AQAA) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/blog/_astro/jetbrains-mono-cyrillic-wght-normal.D73BlboJ.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/blog/_astro/jetbrains-mono-greek-wght-normal.Bw9x6K1M.woff2) format("woff2-variations");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/blog/_astro/jetbrains-mono-vietnamese-wght-normal.Bt-aOZkq.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/blog/_astro/jetbrains-mono-latin-ext-wght-normal.DBQx-q_a.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/blog/_astro/jetbrains-mono-latin-wght-normal.B9CIFXIH.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} diff --git a/website/blog/_astro/avatar.DslDo0tY_Z2tanD.webp b/website/blog/_astro/avatar.DslDo0tY_Z2tanD.webp deleted file mode 100644 index 5b2da87..0000000 Binary files a/website/blog/_astro/avatar.DslDo0tY_Z2tanD.webp and /dev/null differ diff --git a/website/blog/_astro/banner.D0rEZ1wm.webp b/website/blog/_astro/banner.D0rEZ1wm.webp deleted file mode 100644 index 0ea86dd..0000000 Binary files a/website/blog/_astro/banner.D0rEZ1wm.webp and /dev/null differ diff --git a/website/blog/_astro/client.svelte.9vP7DkWT.js b/website/blog/_astro/client.svelte.9vP7DkWT.js deleted file mode 100644 index 97e4876..0000000 --- a/website/blog/_astro/client.svelte.9vP7DkWT.js +++ /dev/null @@ -1 +0,0 @@ -import{ai as u,a9 as m,aj as v,v as y,C as _,y as h,x as $,a4 as g}from"./template.CyUWgh-J.js";import{u as b,h as x,m as j}from"./render.C4NccAY7.js";import"./utils.DonxBMOE.js";function c(e){return(a,...l)=>{var n=e(...l),t;if(y)t=_,h();else{var i=n.render().trim(),o=u(i);t=$(o),a.before(t)}const s=n.setup?.(t);m(t,t),typeof s=="function"&&v(s)}}const p=new WeakMap;var L=e=>async(a,l,n,{client:t})=>{if(!e.hasAttribute("ssr"))return;let i,o,s={};for(const[r,f]of Object.entries(n))o??={},r==="default"?(o.default=!0,i=c(()=>({render:()=>`${f}`}))):o[r]=c(()=>({render:()=>`${f}`})),r==="default"?s.children=c(()=>({render:()=>`${f}`})):s[r]=c(()=>({render:()=>`${f}`}));const d={...l,children:i,$$slots:o,...s};if(p.has(e))p.get(e).setProps(d);else{const r=k(a,e,d,t!=="only");p.set(e,r),e.addEventListener("astro:unmount",()=>r.destroy(),{once:!0})}};function k(e,a,l,n){let t=g(l);const i=n?x:j;n||(a.innerHTML="");const o=i(e,{target:a,props:t});return{setProps(s){Object.assign(t,s);for(const d in t)d in s||delete t[d]},destroy(){b(o)}}}export{L as default}; diff --git a/website/blog/_astro/config.B4FKKqOZ.js b/website/blog/_astro/config.B4FKKqOZ.js deleted file mode 100644 index fe8ca3e..0000000 --- a/website/blog/_astro/config.B4FKKqOZ.js +++ /dev/null @@ -1 +0,0 @@ -var e=(a=>(a[a.Home=0]="Home",a[a.Archive=1]="Archive",a[a.About=2]="About",a[a.Friends=3]="Friends",a[a.Anime=4]="Anime",a[a.Diary=5]="Diary",a[a.Gallery=6]="Gallery",a[a.Projects=7]="Projects",a[a.Skills=8]="Skills",a[a.Timeline=9]="Timeline",a))(e||{});const o="zh_CN",i={lang:o,banner:{carousel:{enable:!1}}};e.Home,e.Archive;const t={theme:"github-dark"},l={enable:!0,position:"left",components:[{type:"profile",enable:!0,order:1,position:"top",class:"onload-animation",animationDelay:0},{type:"announcement",enable:!0,order:2,position:"top",class:"onload-animation",animationDelay:50},{type:"categories",enable:!0,order:3,position:"sticky",class:"onload-animation",animationDelay:150,responsive:{collapseThreshold:5}},{type:"tags",enable:!0,order:4,position:"sticky",class:"onload-animation",animationDelay:200,responsive:{collapseThreshold:20}}],defaultAnimation:{enable:!0,baseDelay:0,increment:50},responsive:{breakpoints:{mobile:768,tablet:1024,desktop:1280},layout:{mobile:"sidebar",tablet:"sidebar",desktop:"sidebar"}}};export{l as a,t as e,i as s}; diff --git a/website/blog/_astro/demo-banner.WD4SMgz_.png b/website/blog/_astro/demo-banner.WD4SMgz_.png deleted file mode 100644 index f8c0310..0000000 Binary files a/website/blog/_astro/demo-banner.WD4SMgz_.png and /dev/null differ diff --git a/website/blog/_astro/each.DMYtlFB3.js b/website/blog/_astro/each.DMYtlFB3.js deleted file mode 100644 index 1166b58..0000000 --- a/website/blog/_astro/each.DMYtlFB3.js +++ /dev/null @@ -1 +0,0 @@ -import{o as b,q as $,E as K,v as R,w as z,x as j,y as ee,g as U,z as ne,H as re,A as X,B as L,C as F,D as fe,F as ae,G as y,I as ie,J as w,K as q,L as le,M as se,N as ue,O as oe,P as V,Q as te,R as de,d as ve,S as G,T as ce,U as pe,V as P,W as Q,X as Y,Y as ge,Z as _e,_ as he,$ as Ee,a0 as me,a1 as Te,a2 as we}from"./template.CyUWgh-J.js";function Ne(e,r){return r}function Ae(e,r,s){for(var o=[],c=r.length,l,i=r.length,p=0;p{if(l){if(l.pending.delete(h),l.done.add(h),l.pending.size===0){var t=e.outrogroups;B(e,V(l.done)),t.delete(l),t.size===0&&(e.outrogroups=null)}}else i-=1},!1)}if(i===0){var a=o.length===0&&s!==null;if(a){var v=s,f=v.parentNode;Ee(f),f.append(v),e.items.clear()}B(e,r,!a)}else l={pending:new Set(r),done:new Set},(e.outrogroups??=new Set).add(l)}function B(e,r,s=!0){var o;if(e.pending.size>0){o=new Set;for(const i of e.pending.values())for(const p of i)o.add(e.items.get(p).e)}for(var c=0;c{var d=s();return oe(d)?d:d==null?[]:V(d)}),t,E=new Map,m=!0;function x(d){(C.effect.f&pe)===0&&(C.pending.delete(d),C.fallback=f,Ce(C,t,i,r,o),f!==null&&(t.length===0?(f.f&w)===0?P(f):(f.f^=w,k(f,null,i)):Q(f,()=>{f=null})))}function n(d){C.pending.delete(d)}var u=$(()=>{t=U(h);var d=t.length;let _=!1;if(R){var H=ne(i)===re;H!==(d===0)&&(i=X(),z(i),L(!1),_=!0)}for(var S=new Set,g=ie,D=se(),I=0;Il(i)):(f=q(()=>l(J??=b())),f.f|=w)),d>S.size&&le(),R&&d>0&&z(X()),!m)if(E.set(g,S),D){for(const[W,Z]of p)S.has(W)||g.skip_effect(Z.e);g.oncommit(x),g.ondiscard(n)}else x(g);_&&L(!0),U(h)}),C={effect:u,items:p,pending:E,outrogroups:null,fallback:f};m=!1,R&&(i=F)}function M(e){for(;e!==null&&(e.f&_e)===0;)e=e.next;return e}function Ce(e,r,s,o,c){var l=(o&he)!==0,i=r.length,p=e.items,a=M(e.effect.first),v,f=null,h,t=[],E=[],m,x,n,u;if(l)for(u=0;u0){var I=(o&K)!==0&&i===0?s:null;if(l){for(u=0;u{if(h!==void 0)for(n of h)n.nodes?.a?.apply()})}function Se(e,r,s,o,c,l,i,p){var a=(i&te)!==0?(i&de)===0?ve(s,!1,!1):G(s):null,v=(i&ce)!==0?G(c):null;return{v:a,i:v,e:q(()=>(l(r,a??s,v??c,p),()=>{e.delete(o)}))}}function k(e,r,s){if(e.nodes)for(var o=e.nodes.start,c=e.nodes.end,l=r&&(r.f&w)===0?r.nodes.start:s;o!==null;){var i=we(o);if(l.before(o),o===c)return;o=i}}function N(e,r,s){r===null?e.effect.first=s:r.next=s,s===null?e.effect.last=r:s.prev=r}export{xe as e,Ne as i}; diff --git a/website/blog/_astro/ec.4fsv9.css b/website/blog/_astro/ec.4fsv9.css deleted file mode 100644 index 5dcd3e5..0000000 --- a/website/blog/_astro/ec.4fsv9.css +++ /dev/null @@ -1 +0,0 @@ -.expressive-code{font-family:var(--ec-uiFontFml);font-size:var(--ec-uiFontSize);font-weight:var(--ec-uiFontWg);line-height:var(--ec-uiLineHt);text-size-adjust:none;-webkit-text-size-adjust:none}.expressive-code *:not(:is(svg, svg *)){all:revert;box-sizing:border-box}.expressive-code pre{display:flex;margin:0;padding:0;border:var(--ec-brdWd) solid var(--ec-brdCol);border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));background:var(--ec-codeBg)}.expressive-code pre:focus-visible{outline:3px solid var(--ec-focusBrd);outline-offset:-3px}.expressive-code pre > code{all:unset;display:block;flex:1 0 100%;padding:var(--ec-codePadBlk) 0;color:var(--ec-codeFg);font-family:var(--ec-codeFontFml);font-size:var(--ec-codeFontSize);font-weight:var(--ec-codeFontWg);line-height:var(--ec-codeLineHt)}.expressive-code pre{overflow-x:auto}.expressive-code pre.wrap .ec-line .code{white-space:pre-wrap;overflow-wrap:break-word;min-width:min(20ch, var(--ecMaxLine, 20ch))}.expressive-code pre.wrap .ec-line .code span.indent{white-space:pre}.expressive-code pre::-webkit-scrollbar,.expressive-code pre::-webkit-scrollbar-track{background-color:inherit;border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));border-top-left-radius:0;border-top-right-radius:0}.expressive-code pre::-webkit-scrollbar-thumb{background-color:var(--ec-sbThumbCol);border:4px solid transparent;background-clip:content-box;border-radius:10px}.expressive-code pre::-webkit-scrollbar-thumb:hover{background-color:var(--ec-sbThumbHoverCol)}.expressive-code .ec-line{direction:ltr;unicode-bidi:isolate;display:grid;grid-template-areas:'gutter code';grid-template-columns:auto 1fr;position:relative}.expressive-code .ec-line .gutter{grid-area:gutter;color:var(--ec-gtrFg)}.expressive-code .ec-line .gutter > *{pointer-events:none;user-select:none;-webkit-user-select:none}.expressive-code .ec-line .gutter ~ .code{--ecLineBrdCol:var(--ec-gtrBrdCol)}.expressive-code .ec-line.highlight .gutter{color:var(--ec-gtrHlFg)}.expressive-code .ec-line .code{grid-area:code;position:relative;box-sizing:content-box;padding-inline-start:calc(var(--ecIndent, 0ch) + var(--ec-codePadInl) - var(--ecGtrBrdWd));padding-inline-end:var(--ec-codePadInl);text-indent:calc(var(--ecIndent, 0ch) * -1)}.expressive-code .ec-line .code::before,.expressive-code .ec-line .code::after,.expressive-code .ec-line .code :where(*){text-indent:0}.expressive-code .ec-line .code{--ecGtrBrdWd:var(--ec-gtrBrdWd);border-inline-start:var(--ecGtrBrdWd) solid var(--ecLineBrdCol, transparent)}.expressive-code .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0}.expressive-code .ec-line.mark{--tmLineBgCol:var(--ec-tm-markBg)}.expressive-code .ec-line.mark .code{--ecLineBrdCol:var(--ec-tm-markBrdCol)}.expressive-code .ec-line.ins{--tmLineBgCol:var(--ec-tm-insBg);--tmLabel:var(--ec-tm-insDiffIndContent)}.expressive-code .ec-line.ins .code{--ecLineBrdCol:var(--ec-tm-insBrdCol)}.expressive-code .ec-line.ins .code::before{color:var(--ec-tm-insDiffIndCol)}.expressive-code .ec-line.del{--tmLineBgCol:var(--ec-tm-delBg);--tmLabel:var(--ec-tm-delDiffIndContent)}.expressive-code .ec-line.del .code{--ecLineBrdCol:var(--ec-tm-delBrdCol)}.expressive-code .ec-line.del .code::before{color:var(--ec-tm-delDiffIndCol)}.expressive-code .ec-line.mark,.expressive-code .ec-line.ins,.expressive-code .ec-line.del{background:var(--tmLineBgCol)}.expressive-code .ec-line.mark .code,.expressive-code .ec-line.ins .code,.expressive-code .ec-line.del .code{--ecGtrBrdWd:var(--ec-tm-lineMarkerAccentWd)}.expressive-code .ec-line.mark .code::before,.expressive-code .ec-line.ins .code::before,.expressive-code .ec-line.del .code::before{display:block;position:absolute;left:0;box-sizing:border-box;content:var(--tmLabel, ' ');padding-inline-start:var(--ec-tm-lineDiffIndMargLeft);text-align:center;white-space:pre}.expressive-code .ec-line.mark.tm-label .code::before,.expressive-code .ec-line.ins.tm-label .code::before,.expressive-code .ec-line.del.tm-label .code::before{background:var(--ecLineBrdCol);padding:0 calc(var(--ec-tm-lineMarkerLabelPadInl) + var(--ec-tm-lineMarkerAccentWd)) 0 var(--ec-tm-lineMarkerLabelPadInl);color:var(--ec-tm-lineMarkerLabelCol)}.expressive-code .ec-line mark{--tmInlineBgCol:var(--ec-tm-markBg);--tmInlineBrdCol:var(--ec-tm-markBrdCol)}.expressive-code .ec-line ins{--tmInlineBgCol:var(--ec-tm-insBg);--tmInlineBrdCol:var(--ec-tm-insBrdCol)}.expressive-code .ec-line del{--tmInlineBgCol:var(--ec-tm-delBg);--tmInlineBrdCol:var(--ec-tm-delBrdCol)}.expressive-code .ec-line mark,.expressive-code .ec-line ins,.expressive-code .ec-line del{all:unset;display:inline-block;position:relative;--tmBrdL:var(--ec-tm-inlMarkerBrdWd);--tmBrdR:var(--ec-tm-inlMarkerBrdWd);--tmRadL:var(--ec-tm-inlMarkerBrdRad);--tmRadR:var(--ec-tm-inlMarkerBrdRad);margin-inline:0.025rem;padding-inline:var(--ec-tm-inlMarkerPad);border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);background:var(--tmInlineBgCol);background-clip:padding-box}.expressive-code .ec-line mark.open-start,.expressive-code .ec-line ins.open-start,.expressive-code .ec-line del.open-start{margin-inline-start:0;padding-inline-start:0;--tmBrdL:0px;--tmRadL:0}.expressive-code .ec-line mark.open-end,.expressive-code .ec-line ins.open-end,.expressive-code .ec-line del.open-end{margin-inline-end:0;padding-inline-end:0;--tmBrdR:0px;--tmRadR:0}.expressive-code .ec-line mark::before,.expressive-code .ec-line ins::before,.expressive-code .ec-line del::before{content:'';position:absolute;pointer-events:none;display:inline-block;inset:0;border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);border:var(--ec-tm-inlMarkerBrdWd) solid var(--tmInlineBrdCol);border-inline-width:var(--tmBrdL) var(--tmBrdR)}.expressive-code .frame{all:unset;position:relative;display:block;--header-border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));--tab-border-radius:calc(var(--ec-frm-edTabBrdRad) + var(--ec-brdWd));--button-spacing:0.4rem;--code-background:var(--ec-frm-edBg);border-radius:var(--header-border-radius);box-shadow:var(--ec-frm-frameBoxShdCssVal)}.expressive-code .frame .header{display:none;z-index:1;position:relative;border-radius:var(--header-border-radius) var(--header-border-radius) 0 0}.expressive-code .frame.has-title pre,.expressive-code .frame.has-title code,.expressive-code .frame.is-terminal pre,.expressive-code .frame.is-terminal code{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.expressive-code .frame .title:empty:before{content:'\a0'}.expressive-code .frame.has-title:not(.is-terminal){--button-spacing:calc(1.9rem + 2 * (var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)))}.expressive-code .frame.has-title:not(.is-terminal) .title{position:relative;color:var(--ec-frm-edActTabFg);background:var(--ec-frm-edActTabBg);background-clip:padding-box;margin-block-start:var(--ec-frm-edTabsMargBlkStart);padding:calc(var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)) var(--ec-uiPadInl);border:var(--ec-brdWd) solid var(--ec-frm-edActTabBrdCol);border-radius:var(--tab-border-radius) var(--tab-border-radius) 0 0;border-bottom:none;overflow:hidden}.expressive-code .frame.has-title:not(.is-terminal) .title::after{content:'';position:absolute;pointer-events:none;inset:0;border-top:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndTopCol);border-bottom:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndBtmCol)}.expressive-code .frame.has-title:not(.is-terminal) .header{display:flex;background:linear-gradient(to top, var(--ec-frm-edTabBarBrdBtmCol) var(--ec-brdWd), transparent var(--ec-brdWd)),linear-gradient(var(--ec-frm-edTabBarBg), var(--ec-frm-edTabBarBg));background-repeat:no-repeat;padding-inline-start:var(--ec-frm-edTabsMargInlStart)}.expressive-code .frame.has-title:not(.is-terminal) .header::before{content:'';position:absolute;pointer-events:none;inset:0;border:var(--ec-brdWd) solid var(--ec-frm-edTabBarBrdCol);border-radius:inherit;border-bottom:none}.expressive-code .frame.is-terminal{--button-spacing:calc(1.9rem + var(--ec-brdWd) + 2 * var(--ec-uiPadBlk));--code-background:var(--ec-frm-trmBg)}.expressive-code .frame.is-terminal .header{display:flex;align-items:center;justify-content:center;padding-block:var(--ec-uiPadBlk);padding-block-end:calc(var(--ec-uiPadBlk) + var(--ec-brdWd));position:relative;font-weight:500;letter-spacing:0.025ch;color:var(--ec-frm-trmTtbFg);background:var(--ec-frm-trmTtbBg);border:var(--ec-brdWd) solid var(--ec-brdCol);border-bottom:none}.expressive-code .frame.is-terminal .header::before{content:'';position:absolute;pointer-events:none;left:var(--ec-uiPadInl);width:2.1rem;height:0.56rem;line-height:0;background-color:var(--ec-frm-trmTtbDotsFg);opacity:var(--ec-frm-trmTtbDotsOpa);-webkit-mask-image:var(--ec-frm-trmIcon);-webkit-mask-repeat:no-repeat;mask-image:var(--ec-frm-trmIcon);mask-repeat:no-repeat}.expressive-code .frame.is-terminal .header::after{content:'';position:absolute;pointer-events:none;inset:0;border-bottom:var(--ec-brdWd) solid var(--ec-frm-trmTtbBrdBtmCol)}.expressive-code .frame pre{background:var(--code-background)}.expressive-code .ec-section{position:relative}.expressive-code .ec-section summary{position:relative;font-family:var(--ec-cs-closedFontFml);font-size:var(--ec-cs-closedFontSize);line-height:var(--ec-cs-closedLineHt);user-select:none;-webkit-user-select:none;cursor:pointer;color:var(--ec-cs-closedTextCol);background-color:var(--ec-cs-closedBgCol);--border-color:var(--ec-cs-closedBrdCol);--border-width:var(--ec-cs-closedBrdWd);box-shadow:inset 0 calc(-1 * var(--border-width)) var(--border-color), inset 0 var(--border-width) var(--border-color);margin:var(--ec-cs-closedMarg);padding:0}.expressive-code .ec-section summary::marker{display:inline-block;content:"";width:16px;height:16px}.expressive-code .ec-section summary::-webkit-details-marker{display:none}.expressive-code .ec-section summary :is(.expand, .collapse){position:relative;display:inline-block;width:16px;height:16px;vertical-align:text-bottom;opacity:0.75}.expressive-code .ec-section summary :is(.expand, .collapse)::after{content:'';position:absolute;pointer-events:none;inset:0;background-color:var(--ec-cs-closedTextCol);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;line-height:0}.expressive-code .ec-section summary .expand::after{-webkit-mask-image:var(--ec-cs-expandIcon);mask-image:var(--ec-cs-expandIcon);-webkit-print-color-adjust:exact;print-color-adjust:exact}.expressive-code .ec-section summary .collapse{display:none}.expressive-code .ec-section summary .collapse::after{-webkit-mask-image:var(--ec-cs-collapseIcon);mask-image:var(--ec-cs-collapseIcon)}.expressive-code .ec-section summary .text{margin-left:1em}.expressive-code .ec-section summary .ec-line .code{padding-block:var(--ec-cs-closedPadBlk);text-indent:0}.expressive-code .ec-section[open],.expressive-code .ec-section details[open] + .content-lines{--border-color:var(--ec-cs-openBrdCol);--border-width:var(--ec-cs-openBrdWd);box-shadow:inset 0 calc(-1 * var(--border-width)) var(--border-color), inset 0 var(--border-width) var(--border-color);padding-inline:var(--ec-cs-openPad);margin-inline:var(--ec-cs-openMarg)}.expressive-code .ec-section.github[open] summary{display:none}.expressive-code .ec-section.github[open]{background-color:var(--ec-cs-openBgCol)}.expressive-code .ec-section:is(.collapsible-start, .collapsible-end){display:flex;flex-direction:column}.expressive-code .ec-section:is(.collapsible-start, .collapsible-end) .content-lines{display:none}.expressive-code .ec-section:is(.collapsible-start, .collapsible-end) details[open] .collapse{display:inline-block}.expressive-code .ec-section:is(.collapsible-start, .collapsible-end) details[open] :is(.expand, .text){display:none}.expressive-code .ec-section:is(.collapsible-start, .collapsible-end) details[open] + .content-lines{display:block;background-color:var(--ec-cs-openBgColCollapsible)}@media print{.expressive-code .ec-section:is(.collapsible-start, .collapsible-end) details[open]{display:none}}.expressive-code .ec-section.collapsible-end{flex-direction:column-reverse}.expressive-code .gutter .ln{display:inline-flex;justify-content:flex-end;align-items:flex-start;box-sizing:content-box;min-width:var(--lnWidth, 2ch);padding-inline:2ch;color:var(--ec-lineNumbers-fg)}.highlight .expressive-code .gutter .ln{color:var(--ec-lineNumbers-hlFg)}.expressive-code [data-language]::before{position:absolute;z-index:2;right:0.5rem;top:0.5rem;padding:0.1rem 0.5rem;content:attr(data-language);font-family:"JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-size:0.75rem;font-weight:bold;text-transform:uppercase;color:oklch(0.75 0.1 var(--hue));background:oklch(0.33 0.035 var(--hue));border-radius:0.5rem;pointer-events:none;transition:opacity 0.3s;opacity:0}@media (hover: none){.expressive-code .frame:not(.has-title):not(.is-terminal) [data-language]::before{opacity:1;margin-right:3rem}.expressive-code .frame:not(.has-title):not(.is-terminal) [data-language]:active::before{opacity:0}}@media (hover: hover){.expressive-code .frame:not(.has-title):not(.is-terminal) [data-language]::before{opacity:1}.expressive-code .frame:not(.has-title):not(.is-terminal):hover [data-language]::before{opacity:0}}:root,:root:not([data-theme='github-dark']) .expressive-code[data-theme='github-dark']{--ec-brdRad:0.75rem;--ec-brdWd:1.5px;--ec-brdCol:none;--ec-codeFontFml:'JetBrains Mono Variable', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;--ec-codeFontSize:0.875rem;--ec-codeFontWg:400;--ec-codeLineHt:1.5rem;--ec-codePadBlk:1rem;--ec-codePadInl:1.35rem;--ec-codeBg:var(--codeblock-bg);--ec-codeFg:#e1e4e8;--ec-codeSelBg:#3392ff44;--ec-gtrFg:#444d56;--ec-gtrBrdCol:#444d5633;--ec-gtrBrdWd:1.5px;--ec-gtrHlFg:#e1e4e8;--ec-uiFontFml:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';--ec-uiFontSize:0.9rem;--ec-uiFontWg:400;--ec-uiLineHt:1.65;--ec-uiPadBlk:0.25rem;--ec-uiPadInl:1rem;--ec-uiSelBg:#39414a;--ec-uiSelFg:#e1e4e8;--ec-focusBrd:#005cc5;--ec-sbThumbCol:#6a737d33;--ec-sbThumbHoverCol:#6a737d44;--ec-tm-lineMarkerAccentMarg:0rem;--ec-tm-lineMarkerAccentWd:0.15rem;--ec-tm-lineMarkerLabelPadInl:0.2rem;--ec-tm-lineMarkerLabelCol:white;--ec-tm-lineDiffIndMargLeft:0.3rem;--ec-tm-inlMarkerBrdWd:1.5px;--ec-tm-inlMarkerBrdRad:0.2rem;--ec-tm-inlMarkerPad:0.15rem;--ec-tm-insDiffIndContent:'+';--ec-tm-delDiffIndContent:'-';--ec-tm-markBg:#00548680;--ec-tm-markBrdCol:#007cb1d0;--ec-tm-insBg:#005a4a80;--ec-tm-insBrdCol:#008371d0;--ec-tm-insDiffIndCol:#2fb6a2d0;--ec-tm-delBg:#822c4d80;--ec-tm-delBrdCol:#af5573d0;--ec-tm-delDiffIndCol:#e686a4d0;--ec-frm-shdCol:#0000005b;--ec-frm-frameBoxShdCssVal:0.1rem 0.1rem 0.2rem #0000005b;--ec-frm-edActTabBg:none;--ec-frm-edActTabFg:#e1e4e8;--ec-frm-edActTabBrdCol:transparent;--ec-frm-edActTabIndHt:1.5px;--ec-frm-edActTabIndTopCol:none;--ec-frm-edActTabIndBtmCol:var(--primary);--ec-frm-edTabsMargInlStart:0;--ec-frm-edTabsMargBlkStart:0;--ec-frm-edTabBrdRad:0.75rem;--ec-frm-edTabBarBg:var(--codeblock-topbar-bg);--ec-frm-edTabBarBrdCol:none;--ec-frm-edTabBarBrdBtmCol:var(--codeblock-topbar-bg);--ec-frm-edBg:var(--codeblock-bg);--ec-frm-trmTtbFg:#e1e4e8;--ec-frm-trmTtbDotsFg:#e1e4e8;--ec-frm-trmTtbDotsOpa:0.15;--ec-frm-trmTtbBg:var(--codeblock-topbar-bg);--ec-frm-trmTtbBrdBtmCol:none;--ec-frm-trmBg:var(--codeblock-bg);--ec-frm-inlBtnFg:#e1e4e8;--ec-frm-inlBtnBg:#e1e4e8;--ec-frm-inlBtnBgIdleOpa:0;--ec-frm-inlBtnBgHoverOrFocusOpa:0.2;--ec-frm-inlBtnBgActOpa:0.3;--ec-frm-inlBtnBrd:#e1e4e8;--ec-frm-inlBtnBrdOpa:0.4;--ec-frm-tooltipSuccessBg:#228739;--ec-frm-tooltipSuccessFg:white;--ec-frm-copyIcon:url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'1.75'%3E%3Cpath%20d%3D'M3%2019a2%202%200%200%201-1-2V2a2%202%200%200%201%201-1h13a2%202%200%200%201%202%201'%2F%3E%3Crect%20x%3D'6'%20y%3D'5'%20width%3D'16'%20height%3D'18'%20rx%3D'1.5'%20ry%3D'1.5'%2F%3E%3C%2Fsvg%3E");--ec-frm-trmIcon:url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2060%2016'%20preserveAspectRatio%3D'xMidYMid%20meet'%3E%3Ccircle%20cx%3D'8'%20cy%3D'8'%20r%3D'8'%2F%3E%3Ccircle%20cx%3D'30'%20cy%3D'8'%20r%3D'8'%2F%3E%3Ccircle%20cx%3D'52'%20cy%3D'8'%20r%3D'8'%2F%3E%3C%2Fsvg%3E");--ec-cs-closedBrdWd:0px;--ec-cs-closedPadBlk:4px;--ec-cs-closedMarg:0;--ec-cs-closedFontFml:inherit;--ec-cs-closedFontSize:inherit;--ec-cs-closedLineHt:inherit;--ec-cs-closedTextCol:#e1e4e8;--ec-cs-closedBgCol:#58606933;--ec-cs-closedBrdCol:#58606980;--ec-cs-openBrdWd:1px;--ec-cs-openPad:0;--ec-cs-openMarg:0;--ec-cs-openBgCol:transparent;--ec-cs-openBgColCollapsible:#5860691a;--ec-cs-openBrdCol:transparent;--ec-cs-expandIcon:url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2016%2016'%3E%3Cpath%20d%3D'm8.177.677%202.896%202.896a.25.25%200%200%201-.177.427H8.75v1.25a.75.75%200%200%201-1.5%200V4H5.104a.25.25%200%200%201-.177-.427L7.823.677a.25.25%200%200%201%20.354%200ZM7.25%2010.75a.75.75%200%200%201%201.5%200V12h2.146a.25.25%200%200%201%20.177.427l-2.896%202.896a.25.25%200%200%201-.354%200l-2.896-2.896A.25.25%200%200%201%205.104%2012H7.25v-1.25Zm-5-2a.75.75%200%200%200%200-1.5h-.5a.75.75%200%200%200%200%201.5h.5ZM6%208a.75.75%200%200%201-.75.75h-.5a.75.75%200%200%201%200-1.5h.5A.75.75%200%200%201%206%208Zm2.25.75a.75.75%200%200%200%200-1.5h-.5a.75.75%200%200%200%200%201.5h.5ZM12%208a.75.75%200%200%201-.75.75h-.5a.75.75%200%200%201%200-1.5h.5A.75.75%200%200%201%2012%208Zm2.25.75a.75.75%200%200%200%200-1.5h-.5a.75.75%200%200%200%200%201.5h.5Z'%2F%3E%3C%2Fsvg%3E");--ec-cs-collapseIcon:url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2016%2016'%3E%3Cpath%20d%3D'M10.896%202H8.75V.75a.75.75%200%200%200-1.5%200V2H5.104a.25.25%200%200%200-.177.427l2.896%202.896a.25.25%200%200%200%20.354%200l2.896-2.896A.25.25%200%200%200%2010.896%202ZM8.75%2015.25a.75.75%200%200%201-1.5%200V14H5.104a.25.25%200%200%201-.177-.427l2.896-2.896a.25.25%200%200%201%20.354%200l2.896%202.896a.25.25%200%200%201-.177.427H8.75v1.25Zm-6.5-6.5a.75.75%200%200%200%200-1.5h-.5a.75.75%200%200%200%200%201.5h.5ZM6%208a.75.75%200%200%201-.75.75h-.5a.75.75%200%200%201%200-1.5h.5A.75.75%200%200%201%206%208Zm2.25.75a.75.75%200%200%200%200-1.5h-.5a.75.75%200%200%200%200%201.5h.5ZM12%208a.75.75%200%200%201-.75.75h-.5a.75.75%200%200%201%200-1.5h.5A.75.75%200%200%201%2012%208Zm2.25.75a.75.75%200%200%200%200-1.5h-.5a.75.75%200%200%200%200%201.5h.5Z'%2F%3E%3C%2Fsvg%3E");--ec-lineNumbers-fg:inherit;--ec-lineNumbers-hlFg:inherit}.expressive-code .ec-line :where(span[style^='--']:not([class])),:root:not([data-theme='github-dark']) .expressive-code[data-theme='github-dark'] .ec-line :where(span[style^='--']:not([class])){color:var(--0, inherit);background-color:var(--0bg, transparent);font-style:var(--0fs, inherit);font-weight:var(--0fw, inherit);text-decoration:var(--0td, inherit)}:root[data-theme='github-dark'] .expressive-code:not([data-theme='github-dark']) .ec-line :where(span[style^='--']:not([class])),.expressive-code[data-theme='github-dark'] .ec-line :where(span[style^='--']:not([class])){color:var(--1, inherit);background-color:var(--1bg, transparent);font-style:var(--1fs, inherit);font-weight:var(--1fw, inherit);text-decoration:var(--1td, inherit)} \ No newline at end of file diff --git a/website/blog/_astro/ec.g1fg5.js b/website/blog/_astro/ec.g1fg5.js deleted file mode 100644 index 6124c46..0000000 --- a/website/blog/_astro/ec.g1fg5.js +++ /dev/null @@ -1 +0,0 @@ -try{(()=>{function a(e){if(!e)return;let t=e.getAttribute("tabindex")!==null,r=e.scrollWidth>e.clientWidth;r&&!t?(e.setAttribute("tabindex","0"),e.setAttribute("role","region")):!r&&t&&(e.removeAttribute("tabindex"),e.removeAttribute("role"))}var u=window.requestIdleCallback||(e=>setTimeout(e,1)),s=window.cancelIdleCallback||clearTimeout;function l(e){let t=new Set,r,n;return new ResizeObserver(c=>{c.forEach(o=>t.add(o.target)),r&&clearTimeout(r),n&&s(n),r=setTimeout(()=>{n&&s(n),n=u(()=>{t.forEach(o=>e(o)),t.clear()})},250)})}function i(e,t){e.querySelectorAll?.(".expressive-code pre > code").forEach(r=>{let n=r.parentElement;n&&t.observe(n)})}var d=l(a);i(document,d);var b=new MutationObserver(e=>e.forEach(t=>t.addedNodes.forEach(r=>{i(r,d)})));b.observe(document.body,{childList:!0,subtree:!0});document.addEventListener("astro:page-load",()=>{i(document,d)});})();}catch(e){console.error("[EC] tabindex-js-module failed:",e)} \ No newline at end of file diff --git a/website/blog/_astro/functions.LP-DBi81.js b/website/blog/_astro/functions.LP-DBi81.js deleted file mode 100644 index 9017c60..0000000 --- a/website/blog/_astro/functions.LP-DBi81.js +++ /dev/null @@ -1 +0,0 @@ -import{V as be,a1 as N,W as xe,o as G,K,I as ve,v as z,C as re,a0 as we,M as Ie,q as ke,y as Se,at as Te,z as Ce,A as Pe,w as Ee,B as W}from"./template.CyUWgh-J.js";class je{anchor;#t=new Map;#n=new Map;#e=new Map;#s=new Set;#o=!0;constructor(t,s=!0){this.anchor=t,this.#o=s}#i=t=>{if(this.#t.has(t)){var s=this.#t.get(t),o=this.#n.get(s);if(o)be(o),this.#s.delete(s);else{var n=this.#e.get(s);n&&(this.#n.set(s,n.effect),this.#e.delete(s),n.fragment.lastChild.remove(),this.anchor.before(n.fragment),o=n.effect)}for(const[i,r]of this.#t){if(this.#t.delete(i),i===t)break;const c=this.#e.get(r);c&&(N(c.effect),this.#e.delete(r))}for(const[i,r]of this.#n){if(i===s||this.#s.has(i))continue;const c=()=>{if(Array.from(this.#t.values()).includes(i)){var f=document.createDocumentFragment();we(r,f),f.append(G()),this.#e.set(i,{effect:r,fragment:f})}else N(r);this.#s.delete(i),this.#n.delete(i)};this.#o||!o?(this.#s.add(i),xe(r,c,!1)):c()}}};#r=t=>{this.#t.delete(t);const s=Array.from(this.#t.values());for(const[o,n]of this.#e)s.includes(o)||(N(n.effect),this.#e.delete(o))};ensure(t,s){var o=ve,n=Ie();if(s&&!this.#n.has(t)&&!this.#e.has(t))if(n){var i=document.createDocumentFragment(),r=G();i.append(r),this.#e.set(t,{effect:K(()=>s(r)),fragment:i})}else this.#n.set(t,K(()=>s(this.anchor)));if(this.#t.set(o,t),n){for(const[c,l]of this.#n)c===t?o.unskip_effect(l):o.skip_effect(l);for(const[c,l]of this.#e)c===t?o.unskip_effect(l.effect):o.skip_effect(l.effect);o.oncommit(this.#i),o.ondiscard(this.#r)}else z&&(this.anchor=re),this.#i(o)}}function Ot(e,t,s=!1){var o;z&&(o=re,Se());var n=new je(e),i=s?Te:0;function r(c,l){if(z){var f=Ce(o);if(c!==parseInt(f.substring(1))){var u=Pe();Ee(u),n.anchor=u,W(!1),n.ensure(c,l),W(!0);return}}n.ensure(c,l)}ke(()=>{var c=!1;t((l,f=0)=>{c=!0,r(f,l)}),c||r(-1,null)},i)}const ce=/^[a-z0-9]+(-[a-z0-9]+)*$/,_=(e,t,s,o="")=>{const n=e.split(":");if(e.slice(0,1)==="@"){if(n.length<2||n.length>3)return null;o=n.shift().slice(1)}if(n.length>3||!n.length)return null;if(n.length>1){const c=n.pop(),l=n.pop(),f={provider:n.length>0?n[0]:o,prefix:l,name:c};return t&&!F(f)?null:f}const i=n[0],r=i.split("-");if(r.length>1){const c={provider:o,prefix:r.shift(),name:r.join("-")};return t&&!F(c)?null:c}if(s&&o===""){const c={provider:o,prefix:"",name:i};return t&&!F(c,s)?null:c}return null},F=(e,t)=>e?!!((t&&e.prefix===""||e.prefix)&&e.name):!1,le=Object.freeze({left:0,top:0,width:16,height:16}),A=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),L=Object.freeze({...le,...A}),q=Object.freeze({...L,body:"",hidden:!1});function Fe(e,t){const s={};!e.hFlip!=!t.hFlip&&(s.hFlip=!0),!e.vFlip!=!t.vFlip&&(s.vFlip=!0);const o=((e.rotate||0)+(t.rotate||0))%4;return o&&(s.rotate=o),s}function J(e,t){const s=Fe(e,t);for(const o in q)o in A?o in e&&!(o in s)&&(s[o]=A[o]):o in t?s[o]=t[o]:o in e&&(s[o]=e[o]);return s}function Oe(e,t){const s=e.icons,o=e.aliases||Object.create(null),n=Object.create(null);function i(r){if(s[r])return n[r]=[];if(!(r in n)){n[r]=null;const c=o[r]&&o[r].parent,l=c&&i(c);l&&(n[r]=[c].concat(l))}return n[r]}return Object.keys(s).concat(Object.keys(o)).forEach(i),n}function Ae(e,t,s){const o=e.icons,n=e.aliases||Object.create(null);let i={};function r(c){i=J(o[c]||n[c],i)}return r(t),s.forEach(r),J(e,i)}function fe(e,t){const s=[];if(typeof e!="object"||typeof e.icons!="object")return s;e.not_found instanceof Array&&e.not_found.forEach(n=>{t(n,null),s.push(n)});const o=Oe(e);for(const n in o){const i=o[n];i&&(t(n,Ae(e,n,i)),s.push(n))}return s}const _e={provider:"",aliases:{},not_found:{},...le};function D(e,t){for(const s in t)if(s in e&&typeof e[s]!=typeof t[s])return!1;return!0}function ue(e){if(typeof e!="object"||e===null)return null;const t=e;if(typeof t.prefix!="string"||!e.icons||typeof e.icons!="object"||!D(e,_e))return null;const s=t.icons;for(const n in s){const i=s[n];if(!n||typeof i.body!="string"||!D(i,q))return null}const o=t.aliases||Object.create(null);for(const n in o){const i=o[n],r=i.parent;if(!n||typeof r!="string"||!s[r]&&!o[r]||!D(i,q))return null}return t}const X=Object.create(null);function Le(e,t){return{provider:e,prefix:t,icons:Object.create(null),missing:new Set}}function S(e,t){const s=X[e]||(X[e]=Object.create(null));return s[t]||(s[t]=Le(e,t))}function ae(e,t){return ue(t)?fe(t,(s,o)=>{o?e.icons[s]=o:e.missing.add(s)}):[]}function Me(e,t,s){try{if(typeof s.body=="string")return e.icons[t]={...s},!0}catch{}return!1}let E=!1;function de(e){return typeof e=="boolean"&&(E=e),E}function Ne(e){const t=typeof e=="string"?_(e,!0,E):e;if(t){const s=S(t.provider,t.prefix),o=t.name;return s.icons[o]||(s.missing.has(o)?null:void 0)}}function De(e,t){const s=_(e,!0,E);if(!s)return!1;const o=S(s.provider,s.prefix);return t?Me(o,s.name,t):(o.missing.add(s.name),!0)}function Re(e,t){if(typeof e!="object")return!1;if(typeof t!="string"&&(t=e.provider||""),E&&!t&&!e.prefix){let n=!1;return ue(e)&&(e.prefix="",fe(e,(i,r)=>{De(i,r)&&(n=!0)})),n}const s=e.prefix;if(!F({prefix:s,name:"a"}))return!1;const o=S(t,s);return!!ae(o,e)}const he=Object.freeze({width:null,height:null}),pe=Object.freeze({...he,...A}),ze=/(-?[0-9.]*[0-9]+[0-9.]*)/g,qe=/^-?[0-9.]*[0-9]+[0-9.]*$/g;function Y(e,t,s){if(t===1)return e;if(s=s||100,typeof e=="number")return Math.ceil(e*t*s)/s;if(typeof e!="string")return e;const o=e.split(ze);if(o===null||!o.length)return e;const n=[];let i=o.shift(),r=qe.test(i);for(;;){if(r){const c=parseFloat(i);isNaN(c)?n.push(i):n.push(Math.ceil(c*t*s)/s)}else n.push(i);if(i=o.shift(),i===void 0)return n.join("");r=!r}}function Qe(e,t="defs"){let s="";const o=e.indexOf("<"+t);for(;o>=0;){const n=e.indexOf(">",o),i=e.indexOf("",i);if(r===-1)break;s+=e.slice(n+1,i).trim(),e=e.slice(0,o).trim()+e.slice(r+1)}return{defs:s,content:e}}function Ue(e,t){return e?""+e+""+t:t}function $e(e,t,s){const o=Qe(e);return Ue(o.defs,t+o.content+s)}const Ve=e=>e==="unset"||e==="undefined"||e==="none";function Be(e,t){const s={...L,...e},o={...pe,...t},n={left:s.left,top:s.top,width:s.width,height:s.height};let i=s.body;[s,o].forEach(I=>{const m=[],g=I.hFlip,a=I.vFlip;let w=I.rotate;g?a?w+=2:(m.push("translate("+(n.width+n.left).toString()+" "+(0-n.top).toString()+")"),m.push("scale(-1 1)"),n.top=n.left=0):a&&(m.push("translate("+(0-n.left).toString()+" "+(n.height+n.top).toString()+")"),m.push("scale(1 -1)"),n.top=n.left=0);let x;switch(w<0&&(w-=Math.floor(w/4)*4),w=w%4,w){case 1:x=n.height/2+n.top,m.unshift("rotate(90 "+x.toString()+" "+x.toString()+")");break;case 2:m.unshift("rotate(180 "+(n.width/2+n.left).toString()+" "+(n.height/2+n.top).toString()+")");break;case 3:x=n.width/2+n.left,m.unshift("rotate(-90 "+x.toString()+" "+x.toString()+")");break}w%2===1&&(n.left!==n.top&&(x=n.left,n.left=n.top,n.top=x),n.width!==n.height&&(x=n.width,n.width=n.height,n.height=x)),m.length&&(i=$e(i,'',""))});const r=o.width,c=o.height,l=n.width,f=n.height;let u,d;r===null?(d=c===null?"1em":c==="auto"?f:c,u=Y(d,l/f)):(u=r==="auto"?l:r,d=c===null?Y(u,f/l):c==="auto"?f:c);const p={},y=(I,m)=>{Ve(m)||(p[I]=m.toString())};y("width",u),y("height",d);const b=[n.left,n.top,l,f];return p.viewBox=b.join(" "),{attributes:p,viewBox:b,body:i}}const He=/\sid="(\S+)"/g,Ge="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16);let Ke=0;function We(e,t=Ge){const s=[];let o;for(;o=He.exec(e);)s.push(o[1]);if(!s.length)return e;const n="suffix"+(Math.random()*16777216|Date.now()).toString(16);return s.forEach(i=>{const r=typeof t=="function"?t(i):t+(Ke++).toString(),c=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");e=e.replace(new RegExp('([#;"])('+c+')([")]|\\.[a-z])',"g"),"$1"+r+n+"$3")}),e=e.replace(new RegExp(n,"g"),""),e}const Q=Object.create(null);function Je(e,t){Q[e]=t}function U(e){return Q[e]||Q[""]}function V(e){let t;if(typeof e.resources=="string")t=[e.resources];else if(t=e.resources,!(t instanceof Array)||!t.length)return null;return{resources:t,path:e.path||"/",maxURL:e.maxURL||500,rotate:e.rotate||750,timeout:e.timeout||5e3,random:e.random===!0,index:e.index||0,dataAfterTimeout:e.dataAfterTimeout!==!1}}const B=Object.create(null),C=["https://api.simplesvg.com","https://api.unisvg.com"],O=[];for(;C.length>0;)C.length===1||Math.random()>.5?O.push(C.shift()):O.push(C.pop());B[""]=V({resources:["https://api.iconify.design"].concat(O)});function Xe(e,t){const s=V(t);return s===null?!1:(B[e]=s,!0)}function H(e){return B[e]}const Ye=()=>{let e;try{if(e=fetch,typeof e=="function")return e}catch{}};let Z=Ye();function Ze(e,t){const s=H(e);if(!s)return 0;let o;if(!s.maxURL)o=0;else{let n=0;s.resources.forEach(r=>{n=Math.max(n,r.length)});const i=t+".json?icons=";o=s.maxURL-n-s.path.length-i.length}return o}function et(e){return e===404}const tt=(e,t,s)=>{const o=[],n=Ze(e,t),i="icons";let r={type:i,provider:e,prefix:t,icons:[]},c=0;return s.forEach((l,f)=>{c+=l.length+1,c>=n&&f>0&&(o.push(r),r={type:i,provider:e,prefix:t,icons:[]},c=l.length),r.icons.push(l)}),o.push(r),o};function nt(e){if(typeof e=="string"){const t=H(e);if(t)return t.path}return"/"}const st=(e,t,s)=>{if(!Z){s("abort",424);return}let o=nt(t.provider);switch(t.type){case"icons":{const i=t.prefix,c=t.icons.join(","),l=new URLSearchParams({icons:c});o+=i+".json?"+l.toString();break}case"custom":{const i=t.uri;o+=i.slice(0,1)==="/"?i.slice(1):i;break}default:s("abort",400);return}let n=503;Z(e+o).then(i=>{const r=i.status;if(r!==200){setTimeout(()=>{s(et(r)?"abort":"next",r)});return}return n=501,i.json()}).then(i=>{if(typeof i!="object"||i===null){setTimeout(()=>{i===404?s("abort",i):s("next",n)});return}setTimeout(()=>{s("success",i)})}).catch(()=>{s("next",n)})},ot={prepare:tt,send:st};function it(e){const t={loaded:[],missing:[],pending:[]},s=Object.create(null);e.sort((n,i)=>n.provider!==i.provider?n.provider.localeCompare(i.provider):n.prefix!==i.prefix?n.prefix.localeCompare(i.prefix):n.name.localeCompare(i.name));let o={provider:"",prefix:"",name:""};return e.forEach(n=>{if(o.name===n.name&&o.prefix===n.prefix&&o.provider===n.provider)return;o=n;const i=n.provider,r=n.prefix,c=n.name,l=s[i]||(s[i]=Object.create(null)),f=l[r]||(l[r]=S(i,r));let u;c in f.icons?u=t.loaded:r===""||f.missing.has(c)?u=t.missing:u=t.pending;const d={provider:i,prefix:r,name:c};u.push(d)}),t}function ge(e,t){e.forEach(s=>{const o=s.loaderCallbacks;o&&(s.loaderCallbacks=o.filter(n=>n.id!==t))})}function rt(e){e.pendingCallbacksFlag||(e.pendingCallbacksFlag=!0,setTimeout(()=>{e.pendingCallbacksFlag=!1;const t=e.loaderCallbacks?e.loaderCallbacks.slice(0):[];if(!t.length)return;let s=!1;const o=e.provider,n=e.prefix;t.forEach(i=>{const r=i.icons,c=r.pending.length;r.pending=r.pending.filter(l=>{if(l.prefix!==n)return!0;const f=l.name;if(e.icons[f])r.loaded.push({provider:o,prefix:n,name:f});else if(e.missing.has(f))r.missing.push({provider:o,prefix:n,name:f});else return s=!0,!0;return!1}),r.pending.length!==c&&(s||ge([e],i.id),i.callback(r.loaded.slice(0),r.missing.slice(0),r.pending.slice(0),i.abort))})}))}let ct=0;function lt(e,t,s){const o=ct++,n=ge.bind(null,s,o);if(!t.pending.length)return n;const i={id:o,icons:t,callback:e,abort:n};return s.forEach(r=>{(r.loaderCallbacks||(r.loaderCallbacks=[])).push(i)}),n}function ft(e,t=!0,s=!1){const o=[];return e.forEach(n=>{const i=typeof n=="string"?_(n,t,s):n;i&&o.push(i)}),o}var ut={resources:[],index:0,timeout:2e3,rotate:750,random:!1,dataAfterTimeout:!1};function at(e,t,s,o){const n=e.resources.length,i=e.random?Math.floor(Math.random()*n):e.index;let r;if(e.random){let h=e.resources.slice(0);for(r=[];h.length>1;){const v=Math.floor(Math.random()*h.length);r.push(h[v]),h=h.slice(0,v).concat(h.slice(v+1))}r=r.concat(h)}else r=e.resources.slice(i).concat(e.resources.slice(0,i));const c=Date.now();let l="pending",f=0,u,d=null,p=[],y=[];typeof o=="function"&&y.push(o);function b(){d&&(clearTimeout(d),d=null)}function I(){l==="pending"&&(l="aborted"),b(),p.forEach(h=>{h.status==="pending"&&(h.status="aborted")}),p=[]}function m(h,v){v&&(y=[]),typeof h=="function"&&y.push(h)}function g(){return{startTime:c,payload:t,status:l,queriesSent:f,queriesPending:p.length,subscribe:m,abort:I}}function a(){l="failed",y.forEach(h=>{h(void 0,u)})}function w(){p.forEach(h=>{h.status==="pending"&&(h.status="aborted")}),p=[]}function x(h,v,T){const j=v!=="success";switch(p=p.filter(k=>k!==h),l){case"pending":break;case"failed":if(j||!e.dataAfterTimeout)return;break;default:return}if(v==="abort"){u=T,a();return}if(j){u=T,p.length||(r.length?M():a());return}if(b(),w(),!e.random){const k=e.resources.indexOf(h.resource);k!==-1&&k!==e.index&&(e.index=k)}l="completed",y.forEach(k=>{k(T)})}function M(){if(l!=="pending")return;b();const h=r.shift();if(h===void 0){if(p.length){d=setTimeout(()=>{b(),l==="pending"&&(w(),a())},e.timeout);return}a();return}const v={status:"pending",resource:h,callback:(T,j)=>{x(v,T,j)}};p.push(v),f++,d=setTimeout(M,e.rotate),s(h,t,v.callback)}return setTimeout(M),g}function me(e){const t={...ut,...e};let s=[];function o(){s=s.filter(c=>c().status==="pending")}function n(c,l,f){const u=at(t,c,l,(d,p)=>{o(),f&&f(d,p)});return s.push(u),u}function i(c){return s.find(l=>c(l))||null}return{query:n,find:i,setIndex:c=>{t.index=c},getIndex:()=>t.index,cleanup:o}}function ee(){}const R=Object.create(null);function dt(e){if(!R[e]){const t=H(e);if(!t)return;const s=me(t),o={config:t,redundancy:s};R[e]=o}return R[e]}function ht(e,t,s){let o,n;if(typeof e=="string"){const i=U(e);if(!i)return s(void 0,424),ee;n=i.send;const r=dt(e);r&&(o=r.redundancy)}else{const i=V(e);if(i){o=me(i);const r=e.resources?e.resources[0]:"",c=U(r);c&&(n=c.send)}}return!o||!n?(s(void 0,424),ee):o.query(t,n,s)().abort}function te(){}function pt(e){e.iconsLoaderFlag||(e.iconsLoaderFlag=!0,setTimeout(()=>{e.iconsLoaderFlag=!1,rt(e)}))}function gt(e){const t=[],s=[];return e.forEach(o=>{(o.match(ce)?t:s).push(o)}),{valid:t,invalid:s}}function P(e,t,s){function o(){const n=e.pendingIcons;t.forEach(i=>{n&&n.delete(i),e.icons[i]||e.missing.add(i)})}if(s&&typeof s=="object")try{if(!ae(e,s).length){o();return}}catch(n){console.error(n)}o(),pt(e)}function ne(e,t){e instanceof Promise?e.then(s=>{t(s)}).catch(()=>{t(null)}):t(e)}function mt(e,t){e.iconsToLoad?e.iconsToLoad=e.iconsToLoad.concat(t).sort():e.iconsToLoad=t,e.iconsQueueFlag||(e.iconsQueueFlag=!0,setTimeout(()=>{e.iconsQueueFlag=!1;const{provider:s,prefix:o}=e,n=e.iconsToLoad;if(delete e.iconsToLoad,!n||!n.length)return;const i=e.loadIcon;if(e.loadIcons&&(n.length>1||!i)){ne(e.loadIcons(n,o,s),u=>{P(e,n,u)});return}if(i){n.forEach(u=>{const d=i(u,o,s);ne(d,p=>{const y=p?{prefix:o,icons:{[u]:p}}:null;P(e,[u],y)})});return}const{valid:r,invalid:c}=gt(n);if(c.length&&P(e,c,null),!r.length)return;const l=o.match(ce)?U(s):null;if(!l){P(e,r,null);return}l.prepare(s,o,r).forEach(u=>{ht(s,u,d=>{P(e,u.icons,d)})})}))}const yt=(e,t)=>{const s=ft(e,!0,de()),o=it(s);if(!o.pending.length){let l=!0;return t&&setTimeout(()=>{l&&t(o.loaded,o.missing,o.pending,te)}),()=>{l=!1}}const n=Object.create(null),i=[];let r,c;return o.pending.forEach(l=>{const{provider:f,prefix:u}=l;if(u===c&&f===r)return;r=f,c=u,i.push(S(f,u));const d=n[f]||(n[f]=Object.create(null));d[u]||(d[u]=[])}),o.pending.forEach(l=>{const{provider:f,prefix:u,name:d}=l,p=S(f,u),y=p.pendingIcons||(p.pendingIcons=new Set);y.has(d)||(y.add(d),n[f][u].push(d))}),i.forEach(l=>{const f=n[l.provider][l.prefix];f.length&&mt(l,f)}),t?lt(t,o,i):te};function bt(e,t){const s={...e};for(const o in t){const n=t[o],i=typeof n;o in he?(n===null||n&&(i==="string"||i==="number"))&&(s[o]=n):i===typeof s[o]&&(s[o]=o==="rotate"?n%4:n)}return s}const xt=/[\s,]+/;function vt(e,t){t.split(xt).forEach(s=>{switch(s.trim()){case"horizontal":e.hFlip=!0;break;case"vertical":e.vFlip=!0;break}})}function wt(e,t=0){const s=e.replace(/^-?[0-9.]*/,"");function o(n){for(;n<0;)n+=4;return n%4}if(s===""){const n=parseInt(e);return isNaN(n)?0:o(n)}else if(s!==e){let n=0;switch(s){case"%":n=25;break;case"deg":n=90}if(n){let i=parseFloat(e.slice(0,e.length-s.length));return isNaN(i)?0:(i=i/n,i%1===0?o(i):0)}}return t}function It(e,t){let s=e.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(const o in t)s+=" "+o+'="'+t[o]+'"';return'"+e+""}function kt(e){return e.replace(/"/g,"'").replace(/%/g,"%25").replace(/#/g,"%23").replace(//g,"%3E").replace(/\s+/g," ")}function St(e){return"data:image/svg+xml,"+kt(e)}function Tt(e){return'url("'+St(e)+'")'}const se={...pe,inline:!1},Ct={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":!0,role:"img"},Pt={display:"inline-block"},$={"background-color":"currentColor"},ye={"background-color":"transparent"},oe={image:"var(--svg)",repeat:"no-repeat",size:"100% 100%"},ie={"-webkit-mask":$,mask:$,background:ye};for(const e in ie){const t=ie[e];for(const s in oe)t[e+"-"+s]=oe[s]}function Et(e){return e+(e.match(/^[-0-9.]+$/)?"px":"")}function jt(e,t){const s=bt(se,t),o=t.mode||"svg",n=o==="svg"?{...Ct}:{};e.body.indexOf("xlink:")===-1&&delete n["xmlns:xlink"];let i=typeof t.style=="string"?t.style:"";for(let g in t){const a=t[g];if(a!==void 0)switch(g){case"icon":case"style":case"onLoad":case"mode":case"ssr":break;case"inline":case"hFlip":case"vFlip":s[g]=a===!0||a==="true"||a===1;break;case"flip":typeof a=="string"&&vt(s,a);break;case"color":i=i+(i.length>0&&i.trim().slice(-1)!==";"?";":"")+"color: "+a+"; ";break;case"rotate":typeof a=="string"?s[g]=wt(a):typeof a=="number"&&(s[g]=a);break;case"ariaHidden":case"aria-hidden":a!==!0&&a!=="true"&&delete n["aria-hidden"];break;default:if(g.slice(0,3)==="on:")break;se[g]===void 0&&(n[g]=a)}}const r=Be(e,s),c=r.attributes;if(s.inline&&(i="vertical-align: -0.125em; "+i),o==="svg"){Object.assign(n,c),i!==""&&(n.style=i);let g=0,a=t.id;return typeof a=="string"&&(a=a.replace(/-/g,"_")),{svg:!0,attributes:n,body:We(r.body,a?()=>a+"ID"+g++:"iconifySvelte")}}const{body:l,width:f,height:u}=e,d=o==="mask"||(o==="bg"?!1:l.indexOf("currentColor")!==-1),p=It(l,{...c,width:f+"",height:u+""}),b={"--svg":Tt(p)},I=g=>{const a=c[g];a&&(b[g]=Et(a))};I("width"),I("height"),Object.assign(b,Pt,d?$:ye);let m="";for(const g in b)m+=g+": "+b[g]+";";return n.style=m+i,{svg:!1,attributes:n}}de(!0);Je("",ot);if(typeof document<"u"&&typeof window<"u"){const e=window;if(e.IconifyPreload!==void 0){const t=e.IconifyPreload,s="Invalid IconifyPreload syntax.";typeof t=="object"&&t!==null&&(t instanceof Array?t:[t]).forEach(o=>{try{(typeof o!="object"||o===null||o instanceof Array||typeof o.icons!="object"||typeof o.prefix!="string"||!Re(o))&&console.error(s)}catch{console.error(s)}})}if(e.IconifyProviders!==void 0){const t=e.IconifyProviders;if(typeof t=="object"&&t!==null)for(let s in t){const o="IconifyProviders["+s+"] is invalid.";try{const n=t[s];if(typeof n!="object"||!n||n.resources===void 0)continue;Xe(s,n)||console.error(o)}catch{console.error(o)}}}}function At(e,t,s,o,n){function i(){t.loading&&(t.loading.abort(),t.loading=null)}if(typeof e=="object"&&e!==null&&typeof e.body=="string")return t.name="",i(),{data:{...L,...e}};let r;if(typeof e!="string"||(r=_(e,!1,!0))===null)return i(),null;const c=Ne(r);if(!c)return s&&(!t.loading||t.loading.name!==e)&&(i(),t.name="",t.loading={name:e,abort:yt([r],o)}),null;i(),t.name!==e&&(t.name=e,n&&!t.destroyed&&n(e));const l=["iconify"];return r.prefix!==""&&l.push("iconify--"+r.prefix),r.provider!==""&&l.push("iconify--"+r.provider),{data:c,classes:l}}function _t(e,t){return e?jt({...L,...e},t):null}export{At as c,_t as g,Ot as i}; diff --git a/website/blog/_astro/index.modern.D46RI4Wq.js b/website/blog/_astro/index.modern.D46RI4Wq.js deleted file mode 100644 index 86c9567..0000000 --- a/website/blog/_astro/index.modern.D46RI4Wq.js +++ /dev/null @@ -1 +0,0 @@ -function o(){return o=Object.assign?Object.assign.bind():function(s){for(var t=1;tString(s).split(".").map(t=>String(parseInt(t||"0",10))).concat(["0","0"]).slice(0,3).join(".");class y{constructor(){this.isSwupPlugin=!0,this.swup=void 0,this.version=void 0,this.requires={},this.handlersToUnregister=[]}mount(){}unmount(){this.handlersToUnregister.forEach(t=>t()),this.handlersToUnregister=[]}_beforeMount(){if(!this.name)throw new Error("You must define a name of plugin when creating a class.")}_afterUnmount(){}_checkRequirements(){return typeof this.requires!="object"||Object.entries(this.requires).forEach(([t,r])=>{if(!(function(e,i,u){const g=(function(a,h){var c;if(a==="swup")return(c=h.version)!=null?c:"";{var l;const p=h.findPlugin(a);return(l=p?.version)!=null?l:""}})(e,u);return!!g&&((a,h)=>h.every(c=>{const[,l,p]=c.match(/^([\D]+)?(.*)$/)||[];var m,f;return((w,b)=>{const v={"":n=>n===0,">":n=>n>0,">=":n=>n>=0,"<":n=>n<0,"<=":n=>n<=0};return(v[b]||v[""])(w)})((f=p,m=d(m=a),f=d(f),m.localeCompare(f,void 0,{numeric:!0})),l||">=")}))(g,i)})(t,r=Array.isArray(r)?r:[r],this.swup)){const e=`${t} ${r.join(", ")}`;throw new Error(`Plugin version mismatch: ${this.name} requires ${e}`)}}),!0}on(t,r,e={}){var i;r=!(i=r).name.startsWith("bound ")||i.hasOwnProperty("prototype")?r.bind(this):r;const u=this.swup.hooks.on(t,r,e);return this.handlersToUnregister.push(u),u}once(t,r,e={}){return this.on(t,r,o({},e,{once:!0}))}before(t,r,e={}){return this.on(t,r,o({},e,{before:!0}))}replace(t,r,e={}){return this.on(t,r,o({},e,{replace:!0}))}off(t,r){return this.swup.hooks.off(t,r)}}export{y as e}; diff --git a/website/blog/_astro/input.CM2Xh3yk.js b/website/blog/_astro/input.CM2Xh3yk.js deleted file mode 100644 index 029da9d..0000000 --- a/website/blog/_astro/input.CM2Xh3yk.js +++ /dev/null @@ -1 +0,0 @@ -import{a5 as m,I as v,a6 as _,u as b,a7 as i,v as y}from"./template.CyUWgh-J.js";function E(a,l,u=l){var s=new WeakSet;m(a,"input",async r=>{var e=r?a.defaultValue:a.value;if(e=t(a)?o(e):e,u(e),v!==null&&s.add(v),await _(),e!==(e=l())){var d=a.selectionStart,f=a.selectionEnd,n=a.value.length;if(a.value=e??"",f!==null){var c=a.value.length;d===f&&f===n&&c>n?(a.selectionStart=c,a.selectionEnd=c):(a.selectionStart=d,a.selectionEnd=Math.min(f,c))}}}),(y&&a.defaultValue!==a.value||b(l)==null&&a.value)&&(u(t(a)?o(a.value):a.value),v!==null&&s.add(v)),i(()=>{var r=l();if(a===document.activeElement){var e=v;if(s.has(e))return}t(a)&&r===o(a.value)||a.type==="date"&&!r&&!a.value||r!==a.value&&(a.value=r??"")})}function t(a){var l=a.type;return l==="number"||l==="range"}function o(a){return a===""?null:+a}export{E as b}; diff --git a/website/blog/_astro/jetbrains-mono-cyrillic-wght-normal.D73BlboJ.woff2 b/website/blog/_astro/jetbrains-mono-cyrillic-wght-normal.D73BlboJ.woff2 deleted file mode 100644 index 8ee2d70..0000000 Binary files a/website/blog/_astro/jetbrains-mono-cyrillic-wght-normal.D73BlboJ.woff2 and /dev/null differ diff --git a/website/blog/_astro/jetbrains-mono-greek-wght-normal.Bw9x6K1M.woff2 b/website/blog/_astro/jetbrains-mono-greek-wght-normal.Bw9x6K1M.woff2 deleted file mode 100644 index 6084d39..0000000 Binary files a/website/blog/_astro/jetbrains-mono-greek-wght-normal.Bw9x6K1M.woff2 and /dev/null differ diff --git a/website/blog/_astro/jetbrains-mono-latin-ext-wght-normal.DBQx-q_a.woff2 b/website/blog/_astro/jetbrains-mono-latin-ext-wght-normal.DBQx-q_a.woff2 deleted file mode 100644 index 01769d9..0000000 Binary files a/website/blog/_astro/jetbrains-mono-latin-ext-wght-normal.DBQx-q_a.woff2 and /dev/null differ diff --git a/website/blog/_astro/jetbrains-mono-latin-wght-normal.B9CIFXIH.woff2 b/website/blog/_astro/jetbrains-mono-latin-wght-normal.B9CIFXIH.woff2 deleted file mode 100644 index cd5102a..0000000 Binary files a/website/blog/_astro/jetbrains-mono-latin-wght-normal.B9CIFXIH.woff2 and /dev/null differ diff --git a/website/blog/_astro/jetbrains-mono-vietnamese-wght-normal.Bt-aOZkq.woff2 b/website/blog/_astro/jetbrains-mono-vietnamese-wght-normal.Bt-aOZkq.woff2 deleted file mode 100644 index b6a3fa1..0000000 Binary files a/website/blog/_astro/jetbrains-mono-vietnamese-wght-normal.Bt-aOZkq.woff2 and /dev/null differ diff --git a/website/blog/_astro/laxxx.Xs7RCgIr_JQ7Ta.webp b/website/blog/_astro/laxxx.Xs7RCgIr_JQ7Ta.webp deleted file mode 100644 index 04caefb..0000000 Binary files a/website/blog/_astro/laxxx.Xs7RCgIr_JQ7Ta.webp and /dev/null differ diff --git a/website/blog/_astro/lifecycle.MLiOCzKC.js b/website/blog/_astro/lifecycle.MLiOCzKC.js deleted file mode 100644 index 057af0f..0000000 --- a/website/blog/_astro/lifecycle.MLiOCzKC.js +++ /dev/null @@ -1 +0,0 @@ -import{aK as g,ap as c,aL as y,aM as u,u as _,O as b,aN as w,aO as d,aP as h,g as m,j as k,aQ as x}from"./template.CyUWgh-J.js";const E="5";typeof window<"u"&&((window.__svelte??={}).v??=new Set).add(E);g();function p(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function O(e){c===null&&p(),y&&c.l!==null?C(c).m.push(e):u(()=>{const n=_(e);if(typeof n=="function")return n})}function I(e){c===null&&p(),O(()=>()=>_(e))}function P(e,n,{bubbles:t=!1,cancelable:s=!1}={}){return new CustomEvent(e,{detail:n,bubbles:t,cancelable:s})}function L(){const e=c;return e===null&&p(),(n,t,s)=>{const o=e.s.$$events?.[n];if(o){const a=b(o)?o.slice():[o],f=P(n,t,s);for(const l of a)l.call(e.x,f);return!f.defaultPrevented}return!0}}function C(e){var n=e.l;return n.u??={a:[],b:[],m:[]}}function M(e=!1){const n=c,t=n.l.u;if(!t)return;let s=()=>k(n.s);if(e){let o=0,a={};const f=x(()=>{let l=!1;const i=n.s;for(const r in i)i[r]!==a[r]&&(a[r]=i[r],l=!0);return l&&o++,o});s=()=>m(f)}t.b.length&&w(()=>{v(n,s),d(t.b)}),u(()=>{const o=_(()=>t.m.map(h));return()=>{for(const a of o)typeof a=="function"&&a()}}),t.a.length&&u(()=>{v(n,s),d(t.a)})}function v(e,n){if(e.l.s)for(const t of e.l.s)m(t);n()}export{I as a,L as c,M as i,O as o}; diff --git a/website/blog/_astro/lkls.CJGvbgjc_Z1Wduyz.webp b/website/blog/_astro/lkls.CJGvbgjc_Z1Wduyz.webp deleted file mode 100644 index 3931ce8..0000000 Binary files a/website/blog/_astro/lkls.CJGvbgjc_Z1Wduyz.webp and /dev/null differ diff --git a/website/blog/_astro/navigation-utils.Cc6bKnia.js b/website/blog/_astro/navigation-utils.Cc6bKnia.js deleted file mode 100644 index 2ee0ef1..0000000 --- a/website/blog/_astro/navigation-utils.Cc6bKnia.js +++ /dev/null @@ -1 +0,0 @@ -function o(t,n){if(!t||typeof t!="string"){console.warn("navigateToPage: Invalid URL provided");return}if(t.startsWith("http://")||t.startsWith("https://")||t.startsWith("//")){window.open(t,"_blank");return}if(t.startsWith("#")){const e=document.getElementById(t.slice(1));e&&e.scrollIntoView({behavior:"smooth"});return}if(typeof window<"u"&&window.swup)try{n?.replace||window.swup.navigate(t)}catch(e){console.error("Swup navigation failed:",e),i(t)}else i(t)}function i(t,n){window.location.href=t}export{o as n}; diff --git a/website/blog/_astro/page.OjjRkIOC.js b/website/blog/_astro/page.OjjRkIOC.js deleted file mode 100644 index 7633202..0000000 --- a/website/blog/_astro/page.OjjRkIOC.js +++ /dev/null @@ -1,2 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["_astro/SwupA11yPlugin.Fv5HjOXF.js","_astro/index.modern.D46RI4Wq.js","_astro/Swup.DoubZhVr.js","_astro/SwupHeadPlugin.DvOZNxAa.js","_astro/SwupScriptsPlugin.DeeT9ppa.js"])))=>i.map(i=>d[i]); -import{_ as r}from"./preload-helper.DBDNhmf7.js";function u(t){return JSON.parse(t,w)}function w(t,e){if(Array.isArray(e)&&e.length===2&&typeof e[1]=="string"){const i=e[0];if(e=e[1],i===":regex:"){const o=e.match(/\/(.*?)\/([a-z]*)?$/i)||[];return new RegExp(o[1],o[2]||"")}if(i===":function:")return new Function(`return (${e}).apply(this, arguments);`)}return e}function p(t,{timeoutFallback:e=1e3}={}){"requestIdleCallback"in window?window.requestIdleCallback(()=>t()):setTimeout(()=>t(),e)}function c(t){document.readyState==="complete"?setTimeout(()=>t(),0):window.addEventListener("load",()=>t())}function f(t,{delayAfterLoad:e=0}={}){c(()=>{e>0?setTimeout(()=>p(t),e):p(t)})}async function _(){const[t,e,i,o]=await Promise.all([r(()=>import("./Swup.DoubZhVr.js").then(n=>n.S),[]).then(n=>n.default),r(()=>import("./SwupA11yPlugin.Fv5HjOXF.js"),__vite__mapDeps([0,1,2])).then(n=>n.default),r(()=>import("./SwupHeadPlugin.DvOZNxAa.js"),__vite__mapDeps([3,1])).then(n=>n.default),r(()=>import("./SwupScriptsPlugin.DeeT9ppa.js"),__vite__mapDeps([4,1])).then(n=>n.default)]),s=new t({ignoreVisit:(n,{el:d,event:l}={})=>d?.closest("[data-no-swup]"),animationSelector:'[class*="transition-swup-"]',containers:["main"],cache:!0,native:!1,plugins:[new e(u("{}")),new i(u('{"awaitAssets":true,"persistAssets":false,"persistTags":false}')),new o(u("{}"))]}),a=n=>document.dispatchEvent(new Event(n));s.hooks.before("content:replace",()=>a("astro:before-swap")),s.hooks.on("content:replace",()=>a("astro:after-swap")),s.hooks.on("page:view",()=>a("astro:page-load")),window.swup=s}f(_); diff --git a/website/blog/_astro/photoswipe.esm.CKV1Bsxh.js b/website/blog/_astro/photoswipe.esm.CKV1Bsxh.js deleted file mode 100644 index 229d613..0000000 --- a/website/blog/_astro/photoswipe.esm.CKV1Bsxh.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * PhotoSwipe 5.4.4 - https://photoswipe.com - * (c) 2024 Dmytro Semenov - */function f(r,t,i){const e=document.createElement(t);return r&&(e.className=r),i&&i.appendChild(e),e}function p(r,t){return r.x=t.x,r.y=t.y,t.id!==void 0&&(r.id=t.id),r}function M(r){r.x=Math.round(r.x),r.y=Math.round(r.y)}function A(r,t){const i=Math.abs(r.x-t.x),e=Math.abs(r.y-t.y);return Math.sqrt(i*i+e*e)}function x(r,t){return r.x===t.x&&r.y===t.y}function b(r,t,i){return Math.min(Math.max(r,t),i)}function I(r,t,i){let e=`translate3d(${r}px,${t||0}px,0)`;return i!==void 0&&(e+=` scale3d(${i},${i},1)`),e}function y(r,t,i,e){r.style.transform=I(t,i,e)}const $="cubic-bezier(.4,0,.22,1)";function R(r,t,i,e){r.style.transition=t?`${t} ${i}ms ${e||$}`:"none"}function L(r,t,i){r.style.width=typeof t=="number"?`${t}px`:t,r.style.height=typeof i=="number"?`${i}px`:i}function U(r){R(r)}function q(r){return"decode"in r?r.decode().catch(()=>{}):r.complete?Promise.resolve(r):new Promise((t,i)=>{r.onload=()=>t(r),r.onerror=i})}const _={IDLE:"idle",LOADING:"loading",LOADED:"loaded",ERROR:"error"};function G(r){return"button"in r&&r.button===1||r.ctrlKey||r.metaKey||r.altKey||r.shiftKey}function K(r,t,i=document){let e=[];if(r instanceof Element)e=[r];else if(r instanceof NodeList||Array.isArray(r))e=Array.from(r);else{const s=typeof r=="string"?r:t;s&&(e=Array.from(i.querySelectorAll(s)))}return e}function C(){return!!(navigator.vendor&&navigator.vendor.match(/apple/i))}let F=!1;try{window.addEventListener("test",null,Object.defineProperty({},"passive",{get:()=>{F=!0}}))}catch{}class X{constructor(){this._pool=[]}add(t,i,e,s){this._toggleListener(t,i,e,s)}remove(t,i,e,s){this._toggleListener(t,i,e,s,!0)}removeAll(){this._pool.forEach(t=>{this._toggleListener(t.target,t.type,t.listener,t.passive,!0,!0)}),this._pool=[]}_toggleListener(t,i,e,s,n,o){if(!t)return;const a=n?"removeEventListener":"addEventListener";i.split(" ").forEach(l=>{if(l){o||(n?this._pool=this._pool.filter(d=>d.type!==l||d.listener!==e||d.target!==t):this._pool.push({target:t,type:l,listener:e,passive:s}));const c=F?{passive:s||!1}:!1;t[a](l,e,c)}})}}function B(r,t){if(r.getViewportSizeFn){const i=r.getViewportSizeFn(r,t);if(i)return i}return{x:document.documentElement.clientWidth,y:window.innerHeight}}function S(r,t,i,e,s){let n=0;if(t.paddingFn)n=t.paddingFn(i,e,s)[r];else if(t.padding)n=t.padding[r];else{const o="padding"+r[0].toUpperCase()+r.slice(1);t[o]&&(n=t[o])}return Number(n)||0}function N(r,t,i,e){return{x:t.x-S("left",r,t,i,e)-S("right",r,t,i,e),y:t.y-S("top",r,t,i,e)-S("bottom",r,t,i,e)}}class Y{constructor(t){this.slide=t,this.currZoomLevel=1,this.center={x:0,y:0},this.max={x:0,y:0},this.min={x:0,y:0}}update(t){this.currZoomLevel=t,this.slide.width?(this._updateAxis("x"),this._updateAxis("y"),this.slide.pswp.dispatch("calcBounds",{slide:this.slide})):this.reset()}_updateAxis(t){const{pswp:i}=this.slide,e=this.slide[t==="x"?"width":"height"]*this.currZoomLevel,n=S(t==="x"?"left":"top",i.options,i.viewportSize,this.slide.data,this.slide.index),o=this.slide.panAreaSize[t];this.center[t]=Math.round((o-e)/2)+n,this.max[t]=e>o?Math.round(o-e)+n:this.center[t],this.min[t]=e>o?n:this.center[t]}reset(){this.center.x=0,this.center.y=0,this.max.x=0,this.max.y=0,this.min.x=0,this.min.y=0}correctPan(t,i){return b(i,this.max[t],this.min[t])}}const T=4e3;class k{constructor(t,i,e,s){this.pswp=s,this.options=t,this.itemData=i,this.index=e,this.panAreaSize=null,this.elementSize=null,this.fit=1,this.fill=1,this.vFill=1,this.initial=1,this.secondary=1,this.max=1,this.min=1}update(t,i,e){const s={x:t,y:i};this.elementSize=s,this.panAreaSize=e;const n=e.x/s.x,o=e.y/s.y;this.fit=Math.min(1,no?n:o),this.vFill=Math.min(1,o),this.initial=this._getInitial(),this.secondary=this._getSecondary(),this.max=Math.max(this.initial,this.secondary,this._getMax()),this.min=Math.min(this.fit,this.initial,this.secondary),this.pswp&&this.pswp.dispatch("zoomLevelsUpdate",{zoomLevels:this,slideData:this.itemData})}_parseZoomLevelOption(t){const i=t+"ZoomLevel",e=this.options[i];if(e)return typeof e=="function"?e(this):e==="fill"?this.fill:e==="fit"?this.fit:Number(e)}_getSecondary(){let t=this._parseZoomLevelOption("secondary");return t||(t=Math.min(1,this.fit*3),this.elementSize&&t*this.elementSize.x>T&&(t=T/this.elementSize.x),t)}_getInitial(){return this._parseZoomLevelOption("initial")||this.fit}_getMax(){return this._parseZoomLevelOption("max")||Math.max(1,this.fit*4)}}class j{constructor(t,i,e){this.data=t,this.index=i,this.pswp=e,this.isActive=i===e.currIndex,this.currentResolution=0,this.panAreaSize={x:0,y:0},this.pan={x:0,y:0},this.isFirstSlide=this.isActive&&!e.opener.isOpen,this.zoomLevels=new k(e.options,t,i,e),this.pswp.dispatch("gettingData",{slide:this,data:this.data,index:i}),this.content=this.pswp.contentLoader.getContentBySlide(this),this.container=f("pswp__zoom-wrap","div"),this.holderElement=null,this.currZoomLevel=1,this.width=this.content.width,this.height=this.content.height,this.heavyAppended=!1,this.bounds=new Y(this),this.prevDisplayedWidth=-1,this.prevDisplayedHeight=-1,this.pswp.dispatch("slideInit",{slide:this})}setIsActive(t){t&&!this.isActive?this.activate():!t&&this.isActive&&this.deactivate()}append(t){this.holderElement=t,this.container.style.transformOrigin="0 0",this.data&&(this.calculateSize(),this.load(),this.updateContentSize(),this.appendHeavy(),this.holderElement.appendChild(this.container),this.zoomAndPanToInitial(),this.pswp.dispatch("firstZoomPan",{slide:this}),this.applyCurrentZoomPan(),this.pswp.dispatch("afterSetContent",{slide:this}),this.isActive&&this.activate())}load(){this.content.load(!1),this.pswp.dispatch("slideLoad",{slide:this})}appendHeavy(){const{pswp:t}=this;this.heavyAppended||!t.opener.isOpen||t.mainScroll.isShifted()||!this.isActive&&!1||this.pswp.dispatch("appendHeavy",{slide:this}).defaultPrevented||(this.heavyAppended=!0,this.content.append(),this.pswp.dispatch("appendHeavyContent",{slide:this}))}activate(){this.isActive=!0,this.appendHeavy(),this.content.activate(),this.pswp.dispatch("slideActivate",{slide:this})}deactivate(){this.isActive=!1,this.content.deactivate(),this.currZoomLevel!==this.zoomLevels.initial&&this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize(),this.pswp.dispatch("slideDeactivate",{slide:this})}destroy(){this.content.hasSlide=!1,this.content.remove(),this.container.remove(),this.pswp.dispatch("slideDestroy",{slide:this})}resize(){this.currZoomLevel===this.zoomLevels.initial||!this.isActive?(this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize()):(this.calculateSize(),this.bounds.update(this.currZoomLevel),this.panTo(this.pan.x,this.pan.y))}updateContentSize(t){const i=this.currentResolution||this.zoomLevels.initial;if(!i)return;const e=Math.round(this.width*i)||this.pswp.viewportSize.x,s=Math.round(this.height*i)||this.pswp.viewportSize.y;!this.sizeChanged(e,s)&&!t||this.content.setDisplayedSize(e,s)}sizeChanged(t,i){return t!==this.prevDisplayedWidth||i!==this.prevDisplayedHeight?(this.prevDisplayedWidth=t,this.prevDisplayedHeight=i,!0):!1}getPlaceholderElement(){var t;return(t=this.content.placeholder)===null||t===void 0?void 0:t.element}zoomTo(t,i,e,s){const{pswp:n}=this;if(!this.isZoomable()||n.mainScroll.isShifted())return;n.dispatch("beforeZoomTo",{destZoomLevel:t,centerPoint:i,transitionDuration:e}),n.animations.stopAllPan();const o=this.currZoomLevel;s||(t=b(t,this.zoomLevels.min,this.zoomLevels.max)),this.setZoomLevel(t),this.pan.x=this.calculateZoomToPanOffset("x",i,o),this.pan.y=this.calculateZoomToPanOffset("y",i,o),M(this.pan);const a=()=>{this._setResolution(t),this.applyCurrentZoomPan()};e?n.animations.startTransition({isPan:!0,name:"zoomTo",target:this.container,transform:this.getCurrentTransform(),onComplete:a,duration:e,easing:n.options.easing}):a()}toggleZoom(t){this.zoomTo(this.currZoomLevel===this.zoomLevels.initial?this.zoomLevels.secondary:this.zoomLevels.initial,t,this.pswp.options.zoomAnimationDuration)}setZoomLevel(t){this.currZoomLevel=t,this.bounds.update(this.currZoomLevel)}calculateZoomToPanOffset(t,i,e){if(this.bounds.max[t]-this.bounds.min[t]===0)return this.bounds.center[t];i||(i=this.pswp.getViewportCenterPoint()),e||(e=this.zoomLevels.initial);const n=this.currZoomLevel/e;return this.bounds.correctPan(t,(this.pan[t]-i[t])*n+i[t])}panTo(t,i){this.pan.x=this.bounds.correctPan("x",t),this.pan.y=this.bounds.correctPan("y",i),this.applyCurrentZoomPan()}isPannable(){return!!this.width&&this.currZoomLevel>this.zoomLevels.fit}isZoomable(){return!!this.width&&this.content.isZoomable()}applyCurrentZoomPan(){this._applyZoomTransform(this.pan.x,this.pan.y,this.currZoomLevel),this===this.pswp.currSlide&&this.pswp.dispatch("zoomPanUpdate",{slide:this})}zoomAndPanToInitial(){this.currZoomLevel=this.zoomLevels.initial,this.bounds.update(this.currZoomLevel),p(this.pan,this.bounds.center),this.pswp.dispatch("initialZoomPan",{slide:this})}_applyZoomTransform(t,i,e){e/=this.currentResolution||this.zoomLevels.initial,y(this.container,t,i,e)}calculateSize(){const{pswp:t}=this;p(this.panAreaSize,N(t.options,t.viewportSize,this.data,this.index)),this.zoomLevels.update(this.width,this.height,this.panAreaSize),t.dispatch("calcSlideSize",{slide:this})}getCurrentTransform(){const t=this.currZoomLevel/(this.currentResolution||this.zoomLevels.initial);return I(this.pan.x,this.pan.y,t)}_setResolution(t){t!==this.currentResolution&&(this.currentResolution=t,this.updateContentSize(),this.pswp.dispatch("resolutionChanged"))}}const Q=.35,J=.6,z=.4,E=.5;function tt(r,t){return r*t/(1-t)}class it{constructor(t){this.gestures=t,this.pswp=t.pswp,this.startPan={x:0,y:0}}start(){this.pswp.currSlide&&p(this.startPan,this.pswp.currSlide.pan),this.pswp.animations.stopAll()}change(){const{p1:t,prevP1:i,dragAxis:e}=this.gestures,{currSlide:s}=this.pswp;if(e==="y"&&this.pswp.options.closeOnVerticalDrag&&s&&s.currZoomLevel<=s.zoomLevels.fit&&!this.gestures.isMultitouch){const n=s.pan.y+(t.y-i.y);if(!this.pswp.dispatch("verticalDrag",{panY:n}).defaultPrevented){this._setPanWithFriction("y",n,J);const o=1-Math.abs(this._getVerticalDragRatio(s.pan.y));this.pswp.applyBgOpacity(o),s.applyCurrentZoomPan()}}else this._panOrMoveMainScroll("x")||(this._panOrMoveMainScroll("y"),s&&(M(s.pan),s.applyCurrentZoomPan()))}end(){const{velocity:t}=this.gestures,{mainScroll:i,currSlide:e}=this.pswp;let s=0;if(this.pswp.animations.stopAll(),i.isShifted()){const o=(i.x-i.getCurrSlideX())/this.pswp.viewportSize.x;t.x<-E&&o<0||t.x<.1&&o<-.5?(s=1,t.x=Math.min(t.x,0)):(t.x>E&&o>0||t.x>-.1&&o>.5)&&(s=-1,t.x=Math.max(t.x,0)),i.moveIndexBy(s,!0,t.x)}e&&e.currZoomLevel>e.zoomLevels.max||this.gestures.isMultitouch?this.gestures.zoomLevels.correctZoomPan(!0):(this._finishPanGestureForAxis("x"),this._finishPanGestureForAxis("y"))}_finishPanGestureForAxis(t){const{velocity:i}=this.gestures,{currSlide:e}=this.pswp;if(!e)return;const{pan:s,bounds:n}=e,o=s[t],a=this.pswp.bgOpacity<1&&t==="y",l=o+tt(i[t],.995);if(a){const v=this._getVerticalDragRatio(o),w=this._getVerticalDragRatio(l);if(v<0&&w<-z||v>0&&w>z){this.pswp.close();return}}const c=n.correctPan(t,l);if(o===c)return;const d=c===l?1:.82,u=this.pswp.bgOpacity,m=c-o;this.pswp.animations.startSpring({name:"panGesture"+t,isPan:!0,start:o,end:c,velocity:i[t],dampingRatio:d,onUpdate:v=>{if(a&&this.pswp.bgOpacity<1){const w=1-(c-v)/m;this.pswp.applyBgOpacity(b(u+(1-u)*w,0,1))}s[t]=Math.floor(v),e.applyCurrentZoomPan()}})}_panOrMoveMainScroll(t){const{p1:i,dragAxis:e,prevP1:s,isMultitouch:n}=this.gestures,{currSlide:o,mainScroll:a}=this.pswp,h=i[t]-s[t],l=a.x+h;if(!h||!o)return!1;if(t==="x"&&!o.isPannable()&&!n)return a.moveTo(l,!0),!0;const{bounds:c}=o,d=o.pan[t]+h;if(this.pswp.options.allowPanToNext&&e==="x"&&t==="x"&&!n){const u=a.getCurrSlideX(),m=a.x-u,v=h>0,w=!v;if(d>c.min[t]&&v){if(c.min[t]<=this.startPan[t])return a.moveTo(l,!0),!0;this._setPanWithFriction(t,d)}else if(d0)return a.moveTo(Math.max(l,u),!0),!0;if(m<0)return a.moveTo(Math.min(l,u),!0),!0}else this._setPanWithFriction(t,d)}else t==="y"?!a.isShifted()&&c.min.y!==c.max.y&&this._setPanWithFriction(t,d):this._setPanWithFriction(t,d);return!1}_getVerticalDragRatio(t){var i,e;return(t-((i=(e=this.pswp.currSlide)===null||e===void 0?void 0:e.bounds.center.y)!==null&&i!==void 0?i:0))/(this.pswp.viewportSize.y/3)}_setPanWithFriction(t,i,e){const{currSlide:s}=this.pswp;if(!s)return;const{pan:n,bounds:o}=s;if(o.correctPan(t,i)!==i||e){const h=Math.round(i-n[t]);n[t]+=h*(e||Q)}else n[t]=i}}const et=.05,st=.15;function O(r,t,i){return r.x=(t.x+i.x)/2,r.y=(t.y+i.y)/2,r}class nt{constructor(t){this.gestures=t,this._startPan={x:0,y:0},this._startZoomPoint={x:0,y:0},this._zoomPoint={x:0,y:0},this._wasOverFitZoomLevel=!1,this._startZoomLevel=1}start(){const{currSlide:t}=this.gestures.pswp;t&&(this._startZoomLevel=t.currZoomLevel,p(this._startPan,t.pan)),this.gestures.pswp.animations.stopAllPan(),this._wasOverFitZoomLevel=!1}change(){const{p1:t,startP1:i,p2:e,startP2:s,pswp:n}=this.gestures,{currSlide:o}=n;if(!o)return;const a=o.zoomLevels.min,h=o.zoomLevels.max;if(!o.isZoomable()||n.mainScroll.isShifted())return;O(this._startZoomPoint,i,s),O(this._zoomPoint,t,e);let l=1/A(i,s)*A(t,e)*this._startZoomLevel;if(l>o.zoomLevels.initial+o.zoomLevels.initial/15&&(this._wasOverFitZoomLevel=!0),lh&&(l=h+(l-h)*et);o.pan.x=this._calculatePanForZoomLevel("x",l),o.pan.y=this._calculatePanForZoomLevel("y",l),o.setZoomLevel(l),o.applyCurrentZoomPan()}end(){const{pswp:t}=this.gestures,{currSlide:i}=t;(!i||i.currZoomLevele.zoomLevels.max?n=e.zoomLevels.max:(o=!1,n=s);const a=i.bgOpacity,h=i.bgOpacity<1,l=p({x:0,y:0},e.pan);let c=p({x:0,y:0},l);t&&(this._zoomPoint.x=0,this._zoomPoint.y=0,this._startZoomPoint.x=0,this._startZoomPoint.y=0,this._startZoomLevel=s,p(this._startPan,l)),o&&(c={x:this._calculatePanForZoomLevel("x",n),y:this._calculatePanForZoomLevel("y",n)}),e.setZoomLevel(n),c={x:e.bounds.correctPan("x",c.x),y:e.bounds.correctPan("y",c.y)},e.setZoomLevel(s);const d=!x(c,l);if(!d&&!o&&!h){e._setResolution(n),e.applyCurrentZoomPan();return}i.animations.stopAllPan(),i.animations.startSpring({isPan:!0,start:0,end:1e3,velocity:0,dampingRatio:1,naturalFrequency:40,onUpdate:u=>{if(u/=1e3,d||o){if(d&&(e.pan.x=l.x+(c.x-l.x)*u,e.pan.y=l.y+(c.y-l.y)*u),o){const m=s+(n-s)*u;e.setZoomLevel(m)}e.applyCurrentZoomPan()}h&&i.bgOpacity<1&&i.applyBgOpacity(b(a+(1-a)*u,0,1))},onComplete:()=>{e._setResolution(n),e.applyCurrentZoomPan()}})}}function Z(r){return!!r.target.closest(".pswp__container")}class ot{constructor(t){this.gestures=t}click(t,i){const e=i.target.classList,s=e.contains("pswp__img"),n=e.contains("pswp__item")||e.contains("pswp__zoom-wrap");s?this._doClickOrTapAction("imageClick",t,i):n&&this._doClickOrTapAction("bgClick",t,i)}tap(t,i){Z(i)&&this._doClickOrTapAction("tap",t,i)}doubleTap(t,i){Z(i)&&this._doClickOrTapAction("doubleTap",t,i)}_doClickOrTapAction(t,i,e){var s;const{pswp:n}=this.gestures,{currSlide:o}=n,a=t+"Action",h=n.options[a];if(!n.dispatch(a,{point:i,originalEvent:e}).defaultPrevented){if(typeof h=="function"){h.call(n,i,e);return}switch(h){case"close":case"next":n[h]();break;case"zoom":o?.toggleZoom(i);break;case"zoom-or-close":o!=null&&o.isZoomable()&&o.zoomLevels.secondary!==o.zoomLevels.initial?o.toggleZoom(i):n.options.clickToCloseNonZoomable&&n.close();break;case"toggle-controls":(s=this.gestures.pswp.element)===null||s===void 0||s.classList.toggle("pswp--ui-visible");break}}}}const rt=10,at=300,ht=25;class lt{constructor(t){this.pswp=t,this.dragAxis=null,this.p1={x:0,y:0},this.p2={x:0,y:0},this.prevP1={x:0,y:0},this.prevP2={x:0,y:0},this.startP1={x:0,y:0},this.startP2={x:0,y:0},this.velocity={x:0,y:0},this._lastStartP1={x:0,y:0},this._intervalP1={x:0,y:0},this._numActivePoints=0,this._ongoingPointers=[],this._touchEventEnabled="ontouchstart"in window,this._pointerEventEnabled=!!window.PointerEvent,this.supportsTouch=this._touchEventEnabled||this._pointerEventEnabled&&navigator.maxTouchPoints>1,this._numActivePoints=0,this._intervalTime=0,this._velocityCalculated=!1,this.isMultitouch=!1,this.isDragging=!1,this.isZooming=!1,this.raf=null,this._tapTimer=null,this.supportsTouch||(t.options.allowPanToNext=!1),this.drag=new it(this),this.zoomLevels=new nt(this),this.tapHandler=new ot(this),t.on("bindEvents",()=>{t.events.add(t.scrollWrap,"click",this._onClick.bind(this)),this._pointerEventEnabled?this._bindEvents("pointer","down","up","cancel"):this._touchEventEnabled?(this._bindEvents("touch","start","end","cancel"),t.scrollWrap&&(t.scrollWrap.ontouchmove=()=>{},t.scrollWrap.ontouchend=()=>{})):this._bindEvents("mouse","down","up")})}_bindEvents(t,i,e,s){const{pswp:n}=this,{events:o}=n,a=s?t+s:"";o.add(n.scrollWrap,t+i,this.onPointerDown.bind(this)),o.add(window,t+"move",this.onPointerMove.bind(this)),o.add(window,t+e,this.onPointerUp.bind(this)),a&&o.add(n.scrollWrap,a,this.onPointerUp.bind(this))}onPointerDown(t){const i=t.type==="mousedown"||t.pointerType==="mouse";if(i&&t.button>0)return;const{pswp:e}=this;if(!e.opener.isOpen){t.preventDefault();return}e.dispatch("pointerDown",{originalEvent:t}).defaultPrevented||(i&&(e.mouseDetected(),this._preventPointerEventBehaviour(t,"down")),e.animations.stopAll(),this._updatePoints(t,"down"),this._numActivePoints===1&&(this.dragAxis=null,p(this.startP1,this.p1)),this._numActivePoints>1?(this._clearTapTimer(),this.isMultitouch=!0):this.isMultitouch=!1)}onPointerMove(t){this._preventPointerEventBehaviour(t,"move"),this._numActivePoints&&(this._updatePoints(t,"move"),!this.pswp.dispatch("pointerMove",{originalEvent:t}).defaultPrevented&&(this._numActivePoints===1&&!this.isDragging?(this.dragAxis||this._calculateDragDirection(),this.dragAxis&&!this.isDragging&&(this.isZooming&&(this.isZooming=!1,this.zoomLevels.end()),this.isDragging=!0,this._clearTapTimer(),this._updateStartPoints(),this._intervalTime=Date.now(),this._velocityCalculated=!1,p(this._intervalP1,this.p1),this.velocity.x=0,this.velocity.y=0,this.drag.start(),this._rafStopLoop(),this._rafRenderLoop())):this._numActivePoints>1&&!this.isZooming&&(this._finishDrag(),this.isZooming=!0,this._updateStartPoints(),this.zoomLevels.start(),this._rafStopLoop(),this._rafRenderLoop())))}_finishDrag(){this.isDragging&&(this.isDragging=!1,this._velocityCalculated||this._updateVelocity(!0),this.drag.end(),this.dragAxis=null)}onPointerUp(t){this._numActivePoints&&(this._updatePoints(t,"up"),!this.pswp.dispatch("pointerUp",{originalEvent:t}).defaultPrevented&&(this._numActivePoints===0&&(this._rafStopLoop(),this.isDragging?this._finishDrag():!this.isZooming&&!this.isMultitouch&&this._finishTap(t)),this._numActivePoints<2&&this.isZooming&&(this.isZooming=!1,this.zoomLevels.end(),this._numActivePoints===1&&(this.dragAxis=null,this._updateStartPoints()))))}_rafRenderLoop(){(this.isDragging||this.isZooming)&&(this._updateVelocity(),this.isDragging?x(this.p1,this.prevP1)||this.drag.change():(!x(this.p1,this.prevP1)||!x(this.p2,this.prevP2))&&this.zoomLevels.change(),this._updatePrevPoints(),this.raf=requestAnimationFrame(this._rafRenderLoop.bind(this)))}_updateVelocity(t){const i=Date.now(),e=i-this._intervalTime;e<50&&!t||(this.velocity.x=this._getVelocity("x",e),this.velocity.y=this._getVelocity("y",e),this._intervalTime=i,p(this._intervalP1,this.p1),this._velocityCalculated=!0)}_finishTap(t){const{mainScroll:i}=this.pswp;if(i.isShifted()){i.moveIndexBy(0,!0);return}if(t.type.indexOf("cancel")>0)return;if(t.type==="mouseup"||t.pointerType==="mouse"){this.tapHandler.click(this.startP1,t);return}const e=this.pswp.options.doubleTapAction?at:0;this._tapTimer?(this._clearTapTimer(),A(this._lastStartP1,this.startP1){this.tapHandler.tap(this.startP1,t),this._clearTapTimer()},e))}_clearTapTimer(){this._tapTimer&&(clearTimeout(this._tapTimer),this._tapTimer=null)}_getVelocity(t,i){const e=this.p1[t]-this._intervalP1[t];return Math.abs(e)>1&&i>5?e/i:0}_rafStopLoop(){this.raf&&(cancelAnimationFrame(this.raf),this.raf=null)}_preventPointerEventBehaviour(t,i){this.pswp.applyFilters("preventPointerEvent",!0,t,i)&&t.preventDefault()}_updatePoints(t,i){if(this._pointerEventEnabled){const e=t,s=this._ongoingPointers.findIndex(n=>n.id===e.pointerId);i==="up"&&s>-1?this._ongoingPointers.splice(s,1):i==="down"&&s===-1?this._ongoingPointers.push(this._convertEventPosToPoint(e,{x:0,y:0})):s>-1&&this._convertEventPosToPoint(e,this._ongoingPointers[s]),this._numActivePoints=this._ongoingPointers.length,this._numActivePoints>0&&p(this.p1,this._ongoingPointers[0]),this._numActivePoints>1&&p(this.p2,this._ongoingPointers[1])}else{const e=t;this._numActivePoints=0,e.type.indexOf("touch")>-1?e.touches&&e.touches.length>0&&(this._convertEventPosToPoint(e.touches[0],this.p1),this._numActivePoints++,e.touches.length>1&&(this._convertEventPosToPoint(e.touches[1],this.p2),this._numActivePoints++)):(this._convertEventPosToPoint(t,this.p1),i==="up"?this._numActivePoints=0:this._numActivePoints++)}}_updatePrevPoints(){p(this.prevP1,this.p1),p(this.prevP2,this.p2)}_updateStartPoints(){p(this.startP1,this.p1),p(this.startP2,this.p2),this._updatePrevPoints()}_calculateDragDirection(){if(this.pswp.mainScroll.isShifted())this.dragAxis="x";else{const t=Math.abs(this.p1.x-this.startP1.x)-Math.abs(this.p1.y-this.startP1.y);if(t!==0){const i=t>0?"x":"y";Math.abs(this.p1[i]-this.startP1[i])>=rt&&(this.dragAxis=i)}}}_convertEventPosToPoint(t,i){return i.x=t.pageX-this.pswp.offset.x,i.y=t.pageY-this.pswp.offset.y,"pointerId"in t?i.id=t.pointerId:t.identifier!==void 0&&(i.id=t.identifier),i}_onClick(t){this.pswp.mainScroll.isShifted()&&(t.preventDefault(),t.stopPropagation())}}const ct=.35;class dt{constructor(t){this.pswp=t,this.x=0,this.slideWidth=0,this._currPositionIndex=0,this._prevPositionIndex=0,this._containerShiftIndex=-1,this.itemHolders=[]}resize(t){const{pswp:i}=this,e=Math.round(i.viewportSize.x+i.viewportSize.x*i.options.spacing),s=e!==this.slideWidth;s&&(this.slideWidth=e,this.moveTo(this.getCurrSlideX())),this.itemHolders.forEach((n,o)=>{s&&y(n.el,(o+this._containerShiftIndex)*this.slideWidth),t&&n.slide&&n.slide.resize()})}resetPosition(){this._currPositionIndex=0,this._prevPositionIndex=0,this.slideWidth=0,this._containerShiftIndex=-1}appendHolders(){this.itemHolders=[];for(let t=0;t<3;t++){const i=f("pswp__item","div",this.pswp.container);i.setAttribute("role","group"),i.setAttribute("aria-roledescription","slide"),i.setAttribute("aria-hidden","true"),i.style.display=t===1?"block":"none",this.itemHolders.push({el:i})}}canBeSwiped(){return this.pswp.getNumItems()>1}moveIndexBy(t,i,e){const{pswp:s}=this;let n=s.potentialIndex+t;const o=s.getNumItems();if(s.canLoop()){n=s.getLoopedIndex(n);const h=(t+o)%o;h<=o/2?t=h:t=h-o}else n<0?n=0:n>=o&&(n=o-1),t=n-s.potentialIndex;s.potentialIndex=n,this._currPositionIndex-=t,s.animations.stopMainScroll();const a=this.getCurrSlideX();if(!i)this.moveTo(a),this.updateCurrItem();else{s.animations.startSpring({isMainScroll:!0,start:this.x,end:a,velocity:e||0,naturalFrequency:30,dampingRatio:1,onUpdate:l=>{this.moveTo(l)},onComplete:()=>{this.updateCurrItem(),s.appendHeavy()}});let h=s.potentialIndex-s.currIndex;if(s.canLoop()){const l=(h+o)%o;l<=o/2?h=l:h=l-o}Math.abs(h)>1&&this.updateCurrItem()}return!!t}getCurrSlideX(){return this.slideWidth*this._currPositionIndex}isShifted(){return this.x!==this.getCurrSlideX()}updateCurrItem(){var t;const{pswp:i}=this,e=this._prevPositionIndex-this._currPositionIndex;if(!e)return;this._prevPositionIndex=this._currPositionIndex,i.currIndex=i.potentialIndex;let s=Math.abs(e),n;s>=3&&(this._containerShiftIndex+=e+(e>0?-3:3),s=3,this.itemHolders.forEach(o=>{var a;(a=o.slide)===null||a===void 0||a.destroy(),o.slide=void 0}));for(let o=0;o0?(n=this.itemHolders.shift(),n&&(this.itemHolders[2]=n,this._containerShiftIndex++,y(n.el,(this._containerShiftIndex+2)*this.slideWidth),i.setContent(n,i.currIndex-s+o+2))):(n=this.itemHolders.pop(),n&&(this.itemHolders.unshift(n),this._containerShiftIndex--,y(n.el,this._containerShiftIndex*this.slideWidth),i.setContent(n,i.currIndex+s-o-2)));Math.abs(this._containerShiftIndex)>50&&!this.isShifted()&&(this.resetPosition(),this.resize()),i.animations.stopAllPan(),this.itemHolders.forEach((o,a)=>{o.slide&&o.slide.setIsActive(a===1)}),i.currSlide=(t=this.itemHolders[1])===null||t===void 0?void 0:t.slide,i.contentLoader.updateLazy(e),i.currSlide&&i.currSlide.applyCurrentZoomPan(),i.dispatch("change")}moveTo(t,i){if(!this.pswp.canLoop()&&i){let e=(this.slideWidth*this._currPositionIndex-t)/this.slideWidth;e+=this.pswp.currIndex;const s=Math.round(t-this.x);(e<0&&s>0||e>=this.pswp.getNumItems()-1&&s<0)&&(t=this.x+s*ct)}this.x=t,this.pswp.container&&y(this.pswp.container,t),this.pswp.dispatch("moveMainScroll",{x:t,dragging:i??!1})}}const pt={Escape:27,z:90,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,Tab:9},g=(r,t)=>t?r:pt[r];class ut{constructor(t){this.pswp=t,this._wasFocused=!1,t.on("bindEvents",()=>{t.options.trapFocus&&(t.options.initialPointerPos||this._focusRoot(),t.events.add(document,"focusin",this._onFocusIn.bind(this))),t.events.add(document,"keydown",this._onKeyDown.bind(this))});const i=document.activeElement;t.on("destroy",()=>{t.options.returnFocus&&i&&this._wasFocused&&i.focus()})}_focusRoot(){!this._wasFocused&&this.pswp.element&&(this.pswp.element.focus(),this._wasFocused=!0)}_onKeyDown(t){const{pswp:i}=this;if(i.dispatch("keydown",{originalEvent:t}).defaultPrevented||G(t))return;let e,s,n=!1;const o="key"in t;switch(o?t.key:t.keyCode){case g("Escape",o):i.options.escKey&&(e="close");break;case g("z",o):e="toggleZoom";break;case g("ArrowLeft",o):s="x";break;case g("ArrowUp",o):s="y";break;case g("ArrowRight",o):s="x",n=!0;break;case g("ArrowDown",o):n=!0,s="y";break;case g("Tab",o):this._focusRoot();break}if(s){t.preventDefault();const{currSlide:a}=i;i.options.arrowKeys&&s==="x"&&i.getNumItems()>1?e=n?"next":"prev":a&&a.currZoomLevel>a.zoomLevels.fit&&(a.pan[s]+=n?-80:80,a.panTo(a.pan.x,a.pan.y))}e&&(t.preventDefault(),i[e]())}_onFocusIn(t){const{template:i}=this.pswp;i&&document!==t.target&&i!==t.target&&!i.contains(t.target)&&i.focus()}}const mt="cubic-bezier(.4,0,.22,1)";class ft{constructor(t){var i;this.props=t;const{target:e,onComplete:s,transform:n,onFinish:o=()=>{},duration:a=333,easing:h=mt}=t;this.onFinish=o;const l=n?"transform":"opacity",c=(i=t[l])!==null&&i!==void 0?i:"";this._target=e,this._onComplete=s,this._finished=!1,this._onTransitionEnd=this._onTransitionEnd.bind(this),this._helperTimeout=setTimeout(()=>{R(e,l,a,h),this._helperTimeout=setTimeout(()=>{e.addEventListener("transitionend",this._onTransitionEnd,!1),e.addEventListener("transitioncancel",this._onTransitionEnd,!1),this._helperTimeout=setTimeout(()=>{this._finalizeAnimation()},a+500),e.style[l]=c},30)},0)}_onTransitionEnd(t){t.target===this._target&&this._finalizeAnimation()}_finalizeAnimation(){this._finished||(this._finished=!0,this.onFinish(),this._onComplete&&this._onComplete())}destroy(){this._helperTimeout&&clearTimeout(this._helperTimeout),U(this._target),this._target.removeEventListener("transitionend",this._onTransitionEnd,!1),this._target.removeEventListener("transitioncancel",this._onTransitionEnd,!1),this._finished||this._finalizeAnimation()}}const _t=12,vt=.75;class gt{constructor(t,i,e){this.velocity=t*1e3,this._dampingRatio=i||vt,this._naturalFrequency=e||_t,this._dampedFrequency=this._naturalFrequency,this._dampingRatio<1&&(this._dampedFrequency*=Math.sqrt(1-this._dampingRatio*this._dampingRatio))}easeFrame(t,i){let e=0,s;i/=1e3;const n=Math.E**(-this._dampingRatio*this._naturalFrequency*i);if(this._dampingRatio===1)s=this.velocity+this._naturalFrequency*t,e=(t+s*i)*n,this.velocity=e*-this._naturalFrequency+s*n;else if(this._dampingRatio<1){s=1/this._dampedFrequency*(this._dampingRatio*this._naturalFrequency*t+this.velocity);const o=Math.cos(this._dampedFrequency*i),a=Math.sin(this._dampedFrequency*i);e=n*(t*o+s*a),this.velocity=e*-this._naturalFrequency*this._dampingRatio+n*(-this._dampedFrequency*t*a+this._dampedFrequency*s*o)}return e}}class yt{constructor(t){this.props=t,this._raf=0;const{start:i,end:e,velocity:s,onUpdate:n,onComplete:o,onFinish:a=()=>{},dampingRatio:h,naturalFrequency:l}=t;this.onFinish=a;const c=new gt(s,h,l);let d=Date.now(),u=i-e;const m=()=>{this._raf&&(u=c.easeFrame(u,Date.now()-d),Math.abs(u)<1&&Math.abs(c.velocity)<50?(n(e),o&&o(),this.onFinish()):(d=Date.now(),n(u+e),this._raf=requestAnimationFrame(m)))};this._raf=requestAnimationFrame(m)}destroy(){this._raf>=0&&cancelAnimationFrame(this._raf),this._raf=0}}class wt{constructor(){this.activeAnimations=[]}startSpring(t){this._start(t,!0)}startTransition(t){this._start(t)}_start(t,i){const e=i?new yt(t):new ft(t);return this.activeAnimations.push(e),e.onFinish=()=>this.stop(e),e}stop(t){t.destroy();const i=this.activeAnimations.indexOf(t);i>-1&&this.activeAnimations.splice(i,1)}stopAll(){this.activeAnimations.forEach(t=>{t.destroy()}),this.activeAnimations=[]}stopAllPan(){this.activeAnimations=this.activeAnimations.filter(t=>t.props.isPan?(t.destroy(),!1):!0)}stopMainScroll(){this.activeAnimations=this.activeAnimations.filter(t=>t.props.isMainScroll?(t.destroy(),!1):!0)}isPanRunning(){return this.activeAnimations.some(t=>t.props.isPan)}}class Pt{constructor(t){this.pswp=t,t.events.add(t.element,"wheel",this._onWheel.bind(this))}_onWheel(t){t.preventDefault();const{currSlide:i}=this.pswp;let{deltaX:e,deltaY:s}=t;if(i&&!this.pswp.dispatch("wheel",{originalEvent:t}).defaultPrevented)if(t.ctrlKey||this.pswp.options.wheelToZoom){if(i.isZoomable()){let n=-s;t.deltaMode===1?n*=.05:n*=t.deltaMode?1:.002,n=2**n;const o=i.currZoomLevel*n;i.zoomTo(o,{x:t.clientX,y:t.clientY})}}else i.isPannable()&&(t.deltaMode===1&&(e*=18,s*=18),i.panTo(i.pan.x-e,i.pan.y-s))}}function St(r){if(typeof r=="string")return r;if(!r||!r.isCustomSVG)return"";const t=r;let i='';return i=i.split("%d").join(t.size||32),t.outlineID&&(i+=''),i+=t.inner,i+="",i}class xt{constructor(t,i){var e;const s=i.name||i.className;let n=i.html;if(t.options[s]===!1)return;typeof t.options[s+"SVG"]=="string"&&(n=t.options[s+"SVG"]),t.dispatch("uiElementCreate",{data:i});let o="";i.isButton?(o+="pswp__button ",o+=i.className||`pswp__button--${i.name}`):o+=i.className||`pswp__${i.name}`;let a=i.isButton?i.tagName||"button":i.tagName||"div";a=a.toLowerCase();const h=f(o,a);if(i.isButton){a==="button"&&(h.type="button");let{title:d}=i;const{ariaLabel:u}=i;typeof t.options[s+"Title"]=="string"&&(d=t.options[s+"Title"]),d&&(h.title=d);const m=u||d;m&&h.setAttribute("aria-label",m)}h.innerHTML=St(n),i.onInit&&i.onInit(h,t),i.onClick&&(h.onclick=d=>{typeof i.onClick=="string"?t[i.onClick]():typeof i.onClick=="function"&&i.onClick(d,h,t)});const l=i.appendTo||"bar";let c=t.element;l==="bar"?(t.topBar||(t.topBar=f("pswp__top-bar pswp__hide-on-close","div",t.scrollWrap)),c=t.topBar):(h.classList.add("pswp__hide-on-close"),l==="wrapper"&&(c=t.scrollWrap)),(e=c)===null||e===void 0||e.appendChild(t.applyFilters("uiElement",h,i))}}function H(r,t,i){r.classList.add("pswp__button--arrow"),r.setAttribute("aria-controls","pswp__items"),t.on("change",()=>{t.options.loop||(i?r.disabled=!(t.currIndex0))})}const It={name:"arrowPrev",className:"pswp__button--arrow--prev",title:"Previous",order:10,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:'',outlineID:"pswp__icn-arrow"},onClick:"prev",onInit:H},bt={name:"arrowNext",className:"pswp__button--arrow--next",title:"Next",order:11,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:'',outlineID:"pswp__icn-arrow"},onClick:"next",onInit:(r,t)=>{H(r,t,!0)}},At={name:"close",title:"Close",order:20,isButton:!0,html:{isCustomSVG:!0,inner:'',outlineID:"pswp__icn-close"},onClick:"close"},Lt={name:"zoom",title:"Zoom",order:10,isButton:!0,html:{isCustomSVG:!0,inner:'',outlineID:"pswp__icn-zoom"},onClick:"toggleZoom"},Ct={name:"preloader",appendTo:"bar",order:7,html:{isCustomSVG:!0,inner:'',outlineID:"pswp__icn-loading"},onInit:(r,t)=>{let i,e=null;const s=(a,h)=>{r.classList.toggle("pswp__preloader--"+a,h)},n=a=>{i!==a&&(i=a,s("active",a))},o=()=>{var a;if(!((a=t.currSlide)!==null&&a!==void 0&&a.content.isLoading())){n(!1),e&&(clearTimeout(e),e=null);return}e||(e=setTimeout(()=>{var h;n(!!(!((h=t.currSlide)===null||h===void 0)&&h.content.isLoading())),e=null},t.options.preloaderDelay))};t.on("change",o),t.on("loadComplete",a=>{t.currSlide===a.slide&&o()}),t.ui&&(t.ui.updatePreloaderVisibility=o)}},Tt={name:"counter",order:5,onInit:(r,t)=>{t.on("change",()=>{r.innerText=t.currIndex+1+t.options.indexIndicatorSep+t.getNumItems()})}};function D(r,t){r.classList.toggle("pswp--zoomed-in",t)}class zt{constructor(t){this.pswp=t,this.isRegistered=!1,this.uiElementsData=[],this.items=[],this.updatePreloaderVisibility=()=>{},this._lastUpdatedZoomLevel=void 0}init(){const{pswp:t}=this;this.isRegistered=!1,this.uiElementsData=[At,It,bt,Lt,Ct,Tt],t.dispatch("uiRegister"),this.uiElementsData.sort((i,e)=>(i.order||0)-(e.order||0)),this.items=[],this.isRegistered=!0,this.uiElementsData.forEach(i=>{this.registerElement(i)}),t.on("change",()=>{var i;(i=t.element)===null||i===void 0||i.classList.toggle("pswp--one-slide",t.getNumItems()===1)}),t.on("zoomPanUpdate",()=>this._onZoomPanUpdate())}registerElement(t){this.isRegistered?this.items.push(new xt(this.pswp,t)):this.uiElementsData.push(t)}_onZoomPanUpdate(){const{template:t,currSlide:i,options:e}=this.pswp;if(this.pswp.opener.isClosing||!t||!i)return;let{currZoomLevel:s}=i;if(this.pswp.opener.isOpen||(s=i.zoomLevels.initial),s===this._lastUpdatedZoomLevel)return;this._lastUpdatedZoomLevel=s;const n=i.zoomLevels.initial-i.zoomLevels.secondary;if(Math.abs(n)<.01||!i.isZoomable()){D(t,!1),t.classList.remove("pswp--zoom-allowed");return}t.classList.add("pswp--zoom-allowed");const o=s===i.zoomLevels.initial?i.zoomLevels.secondary:i.zoomLevels.initial;D(t,o<=s),(e.imageClickAction==="zoom"||e.imageClickAction==="zoom-or-close")&&t.classList.add("pswp--click-to-zoom")}}function Et(r){const t=r.getBoundingClientRect();return{x:t.left,y:t.top,w:t.width}}function Ot(r,t,i){const e=r.getBoundingClientRect(),s=e.width/t,n=e.height/i,o=s>n?s:n,a=(e.width-t*o)/2,h=(e.height-i*o)/2,l={x:e.left+a,y:e.top+h,w:t*o};return l.innerRect={w:e.width,h:e.height,x:a,y:h},l}function Zt(r,t,i){const e=i.dispatch("thumbBounds",{index:r,itemData:t,instance:i});if(e.thumbBounds)return e.thumbBounds;const{element:s}=t;let n,o;if(s&&i.options.thumbSelector!==!1){const a=i.options.thumbSelector||"img";o=s.matches(a)?s:s.querySelector(a)}return o=i.applyFilters("thumbEl",o,t,r),o&&(t.thumbCropped?n=Ot(o,t.width||t.w||0,t.height||t.h||0):n=Et(o)),i.applyFilters("thumbBounds",n,t,r)}class Dt{constructor(t,i){this.type=t,this.defaultPrevented=!1,i&&Object.assign(this,i)}preventDefault(){this.defaultPrevented=!0}}class Mt{constructor(){this._listeners={},this._filters={},this.pswp=void 0,this.options=void 0}addFilter(t,i,e=100){var s,n,o;this._filters[t]||(this._filters[t]=[]),(s=this._filters[t])===null||s===void 0||s.push({fn:i,priority:e}),(n=this._filters[t])===null||n===void 0||n.sort((a,h)=>a.priority-h.priority),(o=this.pswp)===null||o===void 0||o.addFilter(t,i,e)}removeFilter(t,i){this._filters[t]&&(this._filters[t]=this._filters[t].filter(e=>e.fn!==i)),this.pswp&&this.pswp.removeFilter(t,i)}applyFilters(t,...i){var e;return(e=this._filters[t])===null||e===void 0||e.forEach(s=>{i[0]=s.fn.apply(this,i)}),i[0]}on(t,i){var e,s;this._listeners[t]||(this._listeners[t]=[]),(e=this._listeners[t])===null||e===void 0||e.push(i),(s=this.pswp)===null||s===void 0||s.on(t,i)}off(t,i){var e;this._listeners[t]&&(this._listeners[t]=this._listeners[t].filter(s=>i!==s)),(e=this.pswp)===null||e===void 0||e.off(t,i)}dispatch(t,i){var e;if(this.pswp)return this.pswp.dispatch(t,i);const s=new Dt(t,i);return(e=this._listeners[t])===null||e===void 0||e.forEach(n=>{n.call(this,s)}),s}}class Rt{constructor(t,i){if(this.element=f("pswp__img pswp__img--placeholder",t?"img":"div",i),t){const e=this.element;e.decoding="async",e.alt="",e.src=t,e.setAttribute("role","presentation")}this.element.setAttribute("aria-hidden","true")}setDisplayedSize(t,i){this.element&&(this.element.tagName==="IMG"?(L(this.element,250,"auto"),this.element.style.transformOrigin="0 0",this.element.style.transform=I(0,0,t/250)):L(this.element,t,i))}destroy(){var t;(t=this.element)!==null&&t!==void 0&&t.parentNode&&this.element.remove(),this.element=null}}class Ft{constructor(t,i,e){this.instance=i,this.data=t,this.index=e,this.element=void 0,this.placeholder=void 0,this.slide=void 0,this.displayedImageWidth=0,this.displayedImageHeight=0,this.width=Number(this.data.w)||Number(this.data.width)||0,this.height=Number(this.data.h)||Number(this.data.height)||0,this.isAttached=!1,this.hasSlide=!1,this.isDecoding=!1,this.state=_.IDLE,this.data.type?this.type=this.data.type:this.data.src?this.type="image":this.type="html",this.instance.dispatch("contentInit",{content:this})}removePlaceholder(){this.placeholder&&!this.keepPlaceholder()&&setTimeout(()=>{this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0)},1e3)}load(t,i){if(this.slide&&this.usePlaceholder())if(this.placeholder){const e=this.placeholder.element;e&&!e.parentElement&&this.slide.container.prepend(e)}else{const e=this.instance.applyFilters("placeholderSrc",this.data.msrc&&this.slide.isFirstSlide?this.data.msrc:!1,this);this.placeholder=new Rt(e,this.slide.container)}this.element&&!i||this.instance.dispatch("contentLoad",{content:this,isLazy:t}).defaultPrevented||(this.isImageContent()?(this.element=f("pswp__img","img"),this.displayedImageWidth&&this.loadImage(t)):(this.element=f("pswp__content","div"),this.element.innerHTML=this.data.html||""),i&&this.slide&&this.slide.updateContentSize(!0))}loadImage(t){var i,e;if(!this.isImageContent()||!this.element||this.instance.dispatch("contentLoadImage",{content:this,isLazy:t}).defaultPrevented)return;const s=this.element;this.updateSrcsetSizes(),this.data.srcset&&(s.srcset=this.data.srcset),s.src=(i=this.data.src)!==null&&i!==void 0?i:"",s.alt=(e=this.data.alt)!==null&&e!==void 0?e:"",this.state=_.LOADING,s.complete?this.onLoaded():(s.onload=()=>{this.onLoaded()},s.onerror=()=>{this.onError()})}setSlide(t){this.slide=t,this.hasSlide=!0,this.instance=t.pswp}onLoaded(){this.state=_.LOADED,this.slide&&this.element&&(this.instance.dispatch("loadComplete",{slide:this.slide,content:this}),this.slide.isActive&&this.slide.heavyAppended&&!this.element.parentNode&&(this.append(),this.slide.updateContentSize(!0)),(this.state===_.LOADED||this.state===_.ERROR)&&this.removePlaceholder())}onError(){this.state=_.ERROR,this.slide&&(this.displayError(),this.instance.dispatch("loadComplete",{slide:this.slide,isError:!0,content:this}),this.instance.dispatch("loadError",{slide:this.slide,content:this}))}isLoading(){return this.instance.applyFilters("isContentLoading",this.state===_.LOADING,this)}isError(){return this.state===_.ERROR}isImageContent(){return this.type==="image"}setDisplayedSize(t,i){if(this.element&&(this.placeholder&&this.placeholder.setDisplayedSize(t,i),!this.instance.dispatch("contentResize",{content:this,width:t,height:i}).defaultPrevented&&(L(this.element,t,i),this.isImageContent()&&!this.isError()))){const e=!this.displayedImageWidth&&t;this.displayedImageWidth=t,this.displayedImageHeight=i,e?this.loadImage(!1):this.updateSrcsetSizes(),this.slide&&this.instance.dispatch("imageSizeChange",{slide:this.slide,width:t,height:i,content:this})}}isZoomable(){return this.instance.applyFilters("isContentZoomable",this.isImageContent()&&this.state!==_.ERROR,this)}updateSrcsetSizes(){if(!this.isImageContent()||!this.element||!this.data.srcset)return;const t=this.element,i=this.instance.applyFilters("srcsetSizesWidth",this.displayedImageWidth,this);(!t.dataset.largestUsedSize||i>parseInt(t.dataset.largestUsedSize,10))&&(t.sizes=i+"px",t.dataset.largestUsedSize=String(i))}usePlaceholder(){return this.instance.applyFilters("useContentPlaceholder",this.isImageContent(),this)}lazyLoad(){this.instance.dispatch("contentLazyLoad",{content:this}).defaultPrevented||this.load(!0)}keepPlaceholder(){return this.instance.applyFilters("isKeepingPlaceholder",this.isLoading(),this)}destroy(){this.hasSlide=!1,this.slide=void 0,!this.instance.dispatch("contentDestroy",{content:this}).defaultPrevented&&(this.remove(),this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0),this.isImageContent()&&this.element&&(this.element.onload=null,this.element.onerror=null,this.element=void 0))}displayError(){if(this.slide){var t,i;let e=f("pswp__error-msg","div");e.innerText=(t=(i=this.instance.options)===null||i===void 0?void 0:i.errorMsg)!==null&&t!==void 0?t:"",e=this.instance.applyFilters("contentErrorElement",e,this),this.element=f("pswp__content pswp__error-msg-container","div"),this.element.appendChild(e),this.slide.container.innerText="",this.slide.container.appendChild(this.element),this.slide.updateContentSize(!0),this.removePlaceholder()}}append(){if(this.isAttached||!this.element)return;if(this.isAttached=!0,this.state===_.ERROR){this.displayError();return}if(this.instance.dispatch("contentAppend",{content:this}).defaultPrevented)return;const t="decode"in this.element;this.isImageContent()?t&&this.slide&&(!this.slide.isActive||C())?(this.isDecoding=!0,this.element.decode().catch(()=>{}).finally(()=>{this.isDecoding=!1,this.appendImage()})):this.appendImage():this.slide&&!this.element.parentNode&&this.slide.container.appendChild(this.element)}activate(){this.instance.dispatch("contentActivate",{content:this}).defaultPrevented||!this.slide||(this.isImageContent()&&this.isDecoding&&!C()?this.appendImage():this.isError()&&this.load(!1,!0),this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","false"))}deactivate(){this.instance.dispatch("contentDeactivate",{content:this}),this.slide&&this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","true")}remove(){this.isAttached=!1,!this.instance.dispatch("contentRemove",{content:this}).defaultPrevented&&(this.element&&this.element.parentNode&&this.element.remove(),this.placeholder&&this.placeholder.element&&this.placeholder.element.remove())}appendImage(){this.isAttached&&(this.instance.dispatch("contentAppendImage",{content:this}).defaultPrevented||(this.slide&&this.element&&!this.element.parentNode&&this.slide.container.appendChild(this.element),(this.state===_.LOADED||this.state===_.ERROR)&&this.removePlaceholder()))}}const Bt=5;function W(r,t,i){const e=t.createContentFromData(r,i);let s;const{options:n}=t;if(n){s=new k(n,r,-1);let o;t.pswp?o=t.pswp.viewportSize:o=B(n,t);const a=N(n,o,r,i);s.update(e.width,e.height,a)}return e.lazyLoad(),s&&e.setDisplayedSize(Math.ceil(e.width*s.initial),Math.ceil(e.height*s.initial)),e}function Nt(r,t){const i=t.getItemData(r);if(!t.dispatch("lazyLoadSlide",{index:r,itemData:i}).defaultPrevented)return W(i,t,r)}class kt{constructor(t){this.pswp=t,this.limit=Math.max(t.options.preload[0]+t.options.preload[1]+1,Bt),this._cachedItems=[]}updateLazy(t){const{pswp:i}=this;if(i.dispatch("lazyLoad").defaultPrevented)return;const{preload:e}=i.options,s=t===void 0?!0:t>=0;let n;for(n=0;n<=e[1];n++)this.loadSlideByIndex(i.currIndex+(s?n:-n));for(n=1;n<=e[0];n++)this.loadSlideByIndex(i.currIndex+(s?-n:n))}loadSlideByIndex(t){const i=this.pswp.getLoopedIndex(t);let e=this.getContentByIndex(i);e||(e=Nt(i,this.pswp),e&&this.addToCache(e))}getContentBySlide(t){let i=this.getContentByIndex(t.index);return i||(i=this.pswp.createContentFromData(t.data,t.index),this.addToCache(i)),i.setSlide(t),i}addToCache(t){if(this.removeByIndex(t.index),this._cachedItems.push(t),this._cachedItems.length>this.limit){const i=this._cachedItems.findIndex(e=>!e.isAttached&&!e.hasSlide);i!==-1&&this._cachedItems.splice(i,1)[0].destroy()}}removeByIndex(t){const i=this._cachedItems.findIndex(e=>e.index===t);i!==-1&&this._cachedItems.splice(i,1)}getContentByIndex(t){return this._cachedItems.find(i=>i.index===t)}destroy(){this._cachedItems.forEach(t=>t.destroy()),this._cachedItems=[]}}class Ht extends Mt{getNumItems(){var t;let i=0;const e=(t=this.options)===null||t===void 0?void 0:t.dataSource;e&&"length"in e?i=e.length:e&&"gallery"in e&&(e.items||(e.items=this._getGalleryDOMElements(e.gallery)),e.items&&(i=e.items.length));const s=this.dispatch("numItems",{dataSource:e,numItems:i});return this.applyFilters("numItems",s.numItems,e)}createContentFromData(t,i){return new Ft(t,this,i)}getItemData(t){var i;const e=(i=this.options)===null||i===void 0?void 0:i.dataSource;let s={};Array.isArray(e)?s=e[t]:e&&"gallery"in e&&(e.items||(e.items=this._getGalleryDOMElements(e.gallery)),s=e.items[t]);let n=s;n instanceof Element&&(n=this._domElementToItemData(n));const o=this.dispatch("itemData",{itemData:n||{},index:t});return this.applyFilters("itemData",o.itemData,t)}_getGalleryDOMElements(t){var i,e;return(i=this.options)!==null&&i!==void 0&&i.children||(e=this.options)!==null&&e!==void 0&&e.childSelector?K(this.options.children,this.options.childSelector,t)||[]:[t]}_domElementToItemData(t){const i={element:t},e=t.tagName==="A"?t:t.querySelector("a");if(e){i.src=e.dataset.pswpSrc||e.href,e.dataset.pswpSrcset&&(i.srcset=e.dataset.pswpSrcset),i.width=e.dataset.pswpWidth?parseInt(e.dataset.pswpWidth,10):0,i.height=e.dataset.pswpHeight?parseInt(e.dataset.pswpHeight,10):0,i.w=i.width,i.h=i.height,e.dataset.pswpType&&(i.type=e.dataset.pswpType);const n=t.querySelector("img");if(n){var s;i.msrc=n.currentSrc||n.src,i.alt=(s=n.getAttribute("alt"))!==null&&s!==void 0?s:""}(e.dataset.pswpCropped||e.dataset.cropped)&&(i.thumbCropped=!0)}return this.applyFilters("domItemData",i,t,e)}lazyLoadData(t,i){return W(t,this,i)}}const P=.003;class Wt{constructor(t){this.pswp=t,this.isClosed=!0,this.isOpen=!1,this.isClosing=!1,this.isOpening=!1,this._duration=void 0,this._useAnimation=!1,this._croppedZoom=!1,this._animateRootOpacity=!1,this._animateBgOpacity=!1,this._placeholder=void 0,this._opacityElement=void 0,this._cropContainer1=void 0,this._cropContainer2=void 0,this._thumbBounds=void 0,this._prepareOpen=this._prepareOpen.bind(this),t.on("firstZoomPan",this._prepareOpen)}open(){this._prepareOpen(),this._start()}close(){if(this.isClosed||this.isClosing||this.isOpening)return;const t=this.pswp.currSlide;this.isOpen=!1,this.isOpening=!1,this.isClosing=!0,this._duration=this.pswp.options.hideAnimationDuration,t&&t.currZoomLevel*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps(),setTimeout(()=>{this._start()},this._croppedZoom?30:0)}_prepareOpen(){if(this.pswp.off("firstZoomPan",this._prepareOpen),!this.isOpening){const t=this.pswp.currSlide;this.isOpening=!0,this.isClosing=!1,this._duration=this.pswp.options.showAnimationDuration,t&&t.zoomLevels.initial*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps()}}_applyStartProps(){const{pswp:t}=this,i=this.pswp.currSlide,{options:e}=t;if(e.showHideAnimationType==="fade"?(e.showHideOpacity=!0,this._thumbBounds=void 0):e.showHideAnimationType==="none"?(e.showHideOpacity=!1,this._duration=0,this._thumbBounds=void 0):this.isOpening&&t._initialThumbBounds?this._thumbBounds=t._initialThumbBounds:this._thumbBounds=this.pswp.getThumbBounds(),this._placeholder=i?.getPlaceholderElement(),t.animations.stopAll(),this._useAnimation=!!(this._duration&&this._duration>50),this._animateZoom=!!this._thumbBounds&&i?.content.usePlaceholder()&&(!this.isClosing||!t.mainScroll.isShifted()),!this._animateZoom)this._animateRootOpacity=!0,this.isOpening&&i&&(i.zoomAndPanToInitial(),i.applyCurrentZoomPan());else{var s;this._animateRootOpacity=(s=e.showHideOpacity)!==null&&s!==void 0?s:!1}if(this._animateBgOpacity=!this._animateRootOpacity&&this.pswp.options.bgOpacity>P,this._opacityElement=this._animateRootOpacity?t.element:t.bg,!this._useAnimation){this._duration=0,this._animateZoom=!1,this._animateBgOpacity=!1,this._animateRootOpacity=!0,this.isOpening&&(t.element&&(t.element.style.opacity=String(P)),t.applyBgOpacity(1));return}if(this._animateZoom&&this._thumbBounds&&this._thumbBounds.innerRect){var n;this._croppedZoom=!0,this._cropContainer1=this.pswp.container,this._cropContainer2=(n=this.pswp.currSlide)===null||n===void 0?void 0:n.holderElement,t.container&&(t.container.style.overflow="hidden",t.container.style.width=t.viewportSize.x+"px")}else this._croppedZoom=!1;this.isOpening?(this._animateRootOpacity?(t.element&&(t.element.style.opacity=String(P)),t.applyBgOpacity(1)):(this._animateBgOpacity&&t.bg&&(t.bg.style.opacity=String(P)),t.element&&(t.element.style.opacity="1")),this._animateZoom&&(this._setClosedStateZoomPan(),this._placeholder&&(this._placeholder.style.willChange="transform",this._placeholder.style.opacity=String(P)))):this.isClosing&&(t.mainScroll.itemHolders[0]&&(t.mainScroll.itemHolders[0].el.style.display="none"),t.mainScroll.itemHolders[2]&&(t.mainScroll.itemHolders[2].el.style.display="none"),this._croppedZoom&&t.mainScroll.x!==0&&(t.mainScroll.resetPosition(),t.mainScroll.resize()))}_start(){this.isOpening&&this._useAnimation&&this._placeholder&&this._placeholder.tagName==="IMG"?new Promise(t=>{let i=!1,e=!0;q(this._placeholder).finally(()=>{i=!0,e||t(!0)}),setTimeout(()=>{e=!1,i&&t(!0)},50),setTimeout(t,250)}).finally(()=>this._initiate()):this._initiate()}_initiate(){var t,i;(t=this.pswp.element)===null||t===void 0||t.style.setProperty("--pswp-transition-duration",this._duration+"ms"),this.pswp.dispatch(this.isOpening?"openingAnimationStart":"closingAnimationStart"),this.pswp.dispatch("initialZoom"+(this.isOpening?"In":"Out")),(i=this.pswp.element)===null||i===void 0||i.classList.toggle("pswp--ui-visible",this.isOpening),this.isOpening?(this._placeholder&&(this._placeholder.style.opacity="1"),this._animateToOpenState()):this.isClosing&&this._animateToClosedState(),this._useAnimation||this._onAnimationComplete()}_onAnimationComplete(){const{pswp:t}=this;if(this.isOpen=this.isOpening,this.isClosed=this.isClosing,this.isOpening=!1,this.isClosing=!1,t.dispatch(this.isOpen?"openingAnimationEnd":"closingAnimationEnd"),t.dispatch("initialZoom"+(this.isOpen?"InEnd":"OutEnd")),this.isClosed)t.destroy();else if(this.isOpen){var i;this._animateZoom&&t.container&&(t.container.style.overflow="visible",t.container.style.width="100%"),(i=t.currSlide)===null||i===void 0||i.applyCurrentZoomPan()}}_animateToOpenState(){const{pswp:t}=this;this._animateZoom&&(this._croppedZoom&&this._cropContainer1&&this._cropContainer2&&(this._animateTo(this._cropContainer1,"transform","translate3d(0,0,0)"),this._animateTo(this._cropContainer2,"transform","none")),t.currSlide&&(t.currSlide.zoomAndPanToInitial(),this._animateTo(t.currSlide.container,"transform",t.currSlide.getCurrentTransform()))),this._animateBgOpacity&&t.bg&&this._animateTo(t.bg,"opacity",String(t.options.bgOpacity)),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","1")}_animateToClosedState(){const{pswp:t}=this;this._animateZoom&&this._setClosedStateZoomPan(!0),this._animateBgOpacity&&t.bgOpacity>.01&&t.bg&&this._animateTo(t.bg,"opacity","0"),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","0")}_setClosedStateZoomPan(t){if(!this._thumbBounds)return;const{pswp:i}=this,{innerRect:e}=this._thumbBounds,{currSlide:s,viewportSize:n}=i;if(this._croppedZoom&&e&&this._cropContainer1&&this._cropContainer2){const o=-n.x+(this._thumbBounds.x-e.x)+e.w,a=-n.y+(this._thumbBounds.y-e.y)+e.h,h=n.x-e.w,l=n.y-e.h;t?(this._animateTo(this._cropContainer1,"transform",I(o,a)),this._animateTo(this._cropContainer2,"transform",I(h,l))):(y(this._cropContainer1,o,a),y(this._cropContainer2,h,l))}s&&(p(s.pan,e||this._thumbBounds),s.currZoomLevel=this._thumbBounds.w/s.width,t?this._animateTo(s.container,"transform",s.getCurrentTransform()):s.applyCurrentZoomPan())}_animateTo(t,i,e){if(!this._duration){t.style[i]=e;return}const{animations:s}=this.pswp,n={duration:this._duration,easing:this.pswp.options.easing,onComplete:()=>{s.activeAnimations.length||this._onAnimationComplete()},target:t};n[i]=e,s.startTransition(n)}}const Vt={allowPanToNext:!0,spacing:.1,loop:!0,pinchToClose:!0,closeOnVerticalDrag:!0,hideAnimationDuration:333,showAnimationDuration:333,zoomAnimationDuration:333,escKey:!0,arrowKeys:!0,trapFocus:!0,returnFocus:!0,maxWidthToAnimate:4e3,clickToCloseNonZoomable:!0,imageClickAction:"zoom-or-close",bgClickAction:"close",tapAction:"toggle-controls",doubleTapAction:"zoom",indexIndicatorSep:" / ",preloaderDelay:2e3,bgOpacity:.8,index:0,errorMsg:"The image cannot be loaded",preload:[1,2],easing:"cubic-bezier(.4,0,.22,1)"};class $t extends Ht{constructor(t){super(),this.options=this._prepareOptions(t||{}),this.offset={x:0,y:0},this._prevViewportSize={x:0,y:0},this.viewportSize={x:0,y:0},this.bgOpacity=1,this.currIndex=0,this.potentialIndex=0,this.isOpen=!1,this.isDestroying=!1,this.hasMouse=!1,this._initialItemData={},this._initialThumbBounds=void 0,this.topBar=void 0,this.element=void 0,this.template=void 0,this.container=void 0,this.scrollWrap=void 0,this.currSlide=void 0,this.events=new X,this.animations=new wt,this.mainScroll=new dt(this),this.gestures=new lt(this),this.opener=new Wt(this),this.keyboard=new ut(this),this.contentLoader=new kt(this)}init(){if(this.isOpen||this.isDestroying)return!1;this.isOpen=!0,this.dispatch("init"),this.dispatch("beforeOpen"),this._createMainStructure();let t="pswp--open";return this.gestures.supportsTouch&&(t+=" pswp--touch"),this.options.mainClass&&(t+=" "+this.options.mainClass),this.element&&(this.element.className+=" "+t),this.currIndex=this.options.index||0,this.potentialIndex=this.currIndex,this.dispatch("firstUpdate"),this.scrollWheel=new Pt(this),(Number.isNaN(this.currIndex)||this.currIndex<0||this.currIndex>=this.getNumItems())&&(this.currIndex=0),this.gestures.supportsTouch||this.mouseDetected(),this.updateSize(),this.offset.y=window.pageYOffset,this._initialItemData=this.getItemData(this.currIndex),this.dispatch("gettingData",{index:this.currIndex,data:this._initialItemData,slide:void 0}),this._initialThumbBounds=this.getThumbBounds(),this.dispatch("initialLayout"),this.on("openingAnimationEnd",()=>{const{itemHolders:i}=this.mainScroll;i[0]&&(i[0].el.style.display="block",this.setContent(i[0],this.currIndex-1)),i[2]&&(i[2].el.style.display="block",this.setContent(i[2],this.currIndex+1)),this.appendHeavy(),this.contentLoader.updateLazy(),this.events.add(window,"resize",this._handlePageResize.bind(this)),this.events.add(window,"scroll",this._updatePageScrollOffset.bind(this)),this.dispatch("bindEvents")}),this.mainScroll.itemHolders[1]&&this.setContent(this.mainScroll.itemHolders[1],this.currIndex),this.dispatch("change"),this.opener.open(),this.dispatch("afterInit"),!0}getLoopedIndex(t){const i=this.getNumItems();return this.options.loop&&(t>i-1&&(t-=i),t<0&&(t+=i)),b(t,0,i-1)}appendHeavy(){this.mainScroll.itemHolders.forEach(t=>{var i;(i=t.slide)===null||i===void 0||i.appendHeavy()})}goTo(t){this.mainScroll.moveIndexBy(this.getLoopedIndex(t)-this.potentialIndex)}next(){this.goTo(this.potentialIndex+1)}prev(){this.goTo(this.potentialIndex-1)}zoomTo(...t){var i;(i=this.currSlide)===null||i===void 0||i.zoomTo(...t)}toggleZoom(){var t;(t=this.currSlide)===null||t===void 0||t.toggleZoom()}close(){!this.opener.isOpen||this.isDestroying||(this.isDestroying=!0,this.dispatch("close"),this.events.removeAll(),this.opener.close())}destroy(){var t;if(!this.isDestroying){this.options.showHideAnimationType="none",this.close();return}this.dispatch("destroy"),this._listeners={},this.scrollWrap&&(this.scrollWrap.ontouchmove=null,this.scrollWrap.ontouchend=null),(t=this.element)===null||t===void 0||t.remove(),this.mainScroll.itemHolders.forEach(i=>{var e;(e=i.slide)===null||e===void 0||e.destroy()}),this.contentLoader.destroy(),this.events.removeAll()}refreshSlideContent(t){this.contentLoader.removeByIndex(t),this.mainScroll.itemHolders.forEach((i,e)=>{var s,n;let o=((s=(n=this.currSlide)===null||n===void 0?void 0:n.index)!==null&&s!==void 0?s:0)-1+e;if(this.canLoop()&&(o=this.getLoopedIndex(o)),o===t&&(this.setContent(i,t,!0),e===1)){var a;this.currSlide=i.slide,(a=i.slide)===null||a===void 0||a.setIsActive(!0)}}),this.dispatch("change")}setContent(t,i,e){if(this.canLoop()&&(i=this.getLoopedIndex(i)),t.slide){if(t.slide.index===i&&!e)return;t.slide.destroy(),t.slide=void 0}if(!this.canLoop()&&(i<0||i>=this.getNumItems()))return;const s=this.getItemData(i);t.slide=new j(s,i,this),i===this.currIndex&&(this.currSlide=t.slide),t.slide.append(t.el)}getViewportCenterPoint(){return{x:this.viewportSize.x/2,y:this.viewportSize.y/2}}updateSize(t){if(this.isDestroying)return;const i=B(this.options,this);!t&&x(i,this._prevViewportSize)||(p(this._prevViewportSize,i),this.dispatch("beforeResize"),p(this.viewportSize,this._prevViewportSize),this._updatePageScrollOffset(),this.dispatch("viewportSize"),this.mainScroll.resize(this.opener.isOpen),!this.hasMouse&&window.matchMedia("(any-hover: hover)").matches&&this.mouseDetected(),this.dispatch("resize"))}applyBgOpacity(t){this.bgOpacity=Math.max(t,0),this.bg&&(this.bg.style.opacity=String(this.bgOpacity*this.options.bgOpacity))}mouseDetected(){if(!this.hasMouse){var t;this.hasMouse=!0,(t=this.element)===null||t===void 0||t.classList.add("pswp--has_mouse")}}_handlePageResize(){this.updateSize(),/iPhone|iPad|iPod/i.test(window.navigator.userAgent)&&setTimeout(()=>{this.updateSize()},500)}_updatePageScrollOffset(){this.setScrollOffset(0,window.pageYOffset)}setScrollOffset(t,i){this.offset.x=t,this.offset.y=i,this.dispatch("updateScrollOffset")}_createMainStructure(){this.element=f("pswp","div"),this.element.setAttribute("tabindex","-1"),this.element.setAttribute("role","dialog"),this.template=this.element,this.bg=f("pswp__bg","div",this.element),this.scrollWrap=f("pswp__scroll-wrap","section",this.element),this.container=f("pswp__container","div",this.scrollWrap),this.scrollWrap.setAttribute("aria-roledescription","carousel"),this.container.setAttribute("aria-live","off"),this.container.setAttribute("id","pswp__items"),this.mainScroll.appendHolders(),this.ui=new zt(this),this.ui.init(),(this.options.appendToEl||document.body).appendChild(this.element)}getThumbBounds(){return Zt(this.currIndex,this.currSlide?this.currSlide.data:this._initialItemData,this)}canLoop(){return this.options.loop&&this.getNumItems()>2}_prepareOptions(t){return window.matchMedia("(prefers-reduced-motion), (update: slow)").matches&&(t.showHideAnimationType="none",t.zoomAnimationDuration=0),{...Vt,...t}}}export{$t as default}; diff --git a/website/blog/_astro/preload-helper.DBDNhmf7.js b/website/blog/_astro/preload-helper.DBDNhmf7.js deleted file mode 100644 index 81d1985..0000000 --- a/website/blog/_astro/preload-helper.DBDNhmf7.js +++ /dev/null @@ -1 +0,0 @@ -const p="modulepreload",v=function(l){return"/blog/"+l},d={},y=function(f,c,E){let i=Promise.resolve();if(c&&c.length>0){let r=function(e){return Promise.all(e.map(o=>Promise.resolve(o).then(s=>({status:"fulfilled",value:s}),s=>({status:"rejected",reason:s}))))};document.getElementsByTagName("link");const t=document.querySelector("meta[property=csp-nonce]"),u=t?.nonce||t?.getAttribute("nonce");i=r(c.map(e=>{if(e=v(e),e in d)return;d[e]=!0;const o=e.endsWith(".css"),s=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${s}`))return;const n=document.createElement("link");if(n.rel=o?"stylesheet":p,o||(n.as="script"),n.crossOrigin="",n.href=e,u&&n.setAttribute("nonce",u),document.head.appendChild(n),o)return new Promise((m,h)=>{n.addEventListener("load",m),n.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${e}`)))})}))}function a(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return i.then(r=>{for(const t of r||[])t.status==="rejected"&&a(t.reason);return f().catch(a)})};export{y as _}; diff --git a/website/blog/_astro/props.h8jPqBEd.js b/website/blog/_astro/props.h8jPqBEd.js deleted file mode 100644 index 9f74882..0000000 --- a/website/blog/_astro/props.h8jPqBEd.js +++ /dev/null @@ -1,2 +0,0 @@ -import{aR as X,a1 as D,K as F,aq as Q,v as N,O as fr,aS as sr,aT as tr,aj as ar,aU as ur,aV as nr,aW as lr,Y as cr,aX as or,aY as vr,aZ as U,a_ as dr,g as M,a$ as _r,B as G,b0 as br,b1 as pr,b2 as gr,b3 as Ar,b4 as W,a4 as hr,s as Sr,a8 as B,U as Tr,S as Ir,b5 as Or,u as Nr,aL as Pr,b6 as Lr,b7 as Er,aQ as wr,N as Mr,ag as K,an as V,b8 as Rr,b9 as yr,as as Cr,ba as Ur}from"./template.CyUWgh-J.js";import{c as jr,a as Yr,d as Dr,f as $r,n as Br,g as Gr}from"./utils.DonxBMOE.js";let y=!1;function Kr(r){var e=y;try{return y=!1,[r(),y]}finally{y=e}}function Vr(r,e){var i=void 0,f;X(()=>{i!==(i=e())&&(f&&(D(f),f=null),i&&(f=F(()=>{Q(()=>i(r))})))})}function J(r){var e,i,f="";if(typeof r=="string"||typeof r=="number")f+=r;else if(typeof r=="object")if(Array.isArray(r)){var s=r.length;for(e=0;e=0;){var n=u+t;(u===0||H.includes(f[u-1]))&&(n===f.length||H.includes(f[n]))?f=(u===0?"":f.substring(0,u))+f.substring(n+1):u=n}}return f===""?null:f}function q(r,e=!1){var i=e?" !important;":";",f="";for(var s of Object.keys(r)){var t=r[s];t!=null&&t!==""&&(f+=" "+s+": "+t+i)}return f}function j(r){return r[0]!=="-"||r[1]!=="-"?r.toLowerCase():r}function zr(r,e){if(e){var i="",f,s;if(Array.isArray(e)?(f=e[0],s=e[1]):f=e,r){r=String(r).replaceAll(/\s*\/\*.*?\*\/\s*/g,"").trim();var t=!1,u=0,n=!1,v=[];f&&v.push(...Object.keys(f).map(j)),s&&v.push(...Object.keys(s).map(j));var o=0,d=-1;const I=r.length;for(var p=0;p{$(r,r.__value)});e.observe(r,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),ar(()=>{e.disconnect()})}function Z(r){return"__value"in r?r.__value:r.value}const E=Symbol("class"),w=Symbol("style"),k=Symbol("is custom element"),m=Symbol("is html"),Wr=U?"link":"LINK",Jr=U?"input":"INPUT",kr=U?"option":"OPTION",mr=U?"select":"SELECT";function xr(r){if(N){var e=!1,i=()=>{if(!e){if(e=!0,r.hasAttribute("value")){var f=r.value;C(r,"value",null),r.value=f}if(r.hasAttribute("checked")){var s=r.checked;C(r,"checked",null),r.checked=s}}};r.__on_r=i,cr(i),or()}}function re(r,e){e?r.hasAttribute("selected")||r.setAttribute("selected",""):r.removeAttribute("selected")}function C(r,e,i,f){var s=x(r);N&&(s[e]=r.getAttribute(e),e==="src"||e==="srcset"||e==="href"&&r.nodeName===Wr)||s[e]!==(s[e]=i)&&(e==="loading"&&(r[vr]=i),i==null?r.removeAttribute(e):typeof i!="string"&&rr(r).includes(e)?r[e]=i:r.setAttribute(e,i))}function ee(r,e,i,f,s=!1,t=!1){if(N&&s&&r.nodeName===Jr){var u=r,n=u.type==="checkbox"?"defaultChecked":"defaultValue";n in i||xr(u)}var v=x(r),o=v[k],d=!v[m];let p=N&&o;p&&G(!1);var a=e||{},T=r.nodeName===kr;for(var g in e)g in i||(i[g]=null);i.class?i.class=qr(i.class):i[E]&&(i.class=null),i[w]&&(i.style??=null);var I=rr(r);for(const l in i){let c=i[l];if(T&&l==="value"&&c==null){r.value=r.__value="",a[l]=c;continue}if(l==="class"){var O=r.namespaceURI==="http://www.w3.org/1999/xhtml";Xr(r,O,c,f,e?.[E],i[E]),a[l]=c,a[E]=i[E];continue}if(l==="style"){Fr(r,c,e?.[w],i[w]),a[l]=c,a[w]=i[w];continue}var _=a[l];if(!(c===_&&!(c===void 0&&r.hasAttribute(l)))){a[l]=c;var R=l[0]+l[1];if(R!=="$$")if(R==="on"){const S={},P="$$"+l;let h=l.slice(2);var A=Gr(h);if(jr(h)&&(h=h.slice(0,-7),S.capture=!0),!A&&_){if(c!=null)continue;r.removeEventListener(h,a[P],S),a[P]=null}if(A)Yr(h,r,c),Dr([h]);else if(c!=null){let er=function(ir){a[l].call(this,ir)};a[P]=$r(h,r,er,S)}}else if(l==="style")C(r,l,c);else if(l==="autofocus")br(r,!!c);else if(!o&&(l==="__value"||l==="value"&&c!=null))r.value=r.__value=c;else if(l==="selected"&&T)re(r,c);else{var b=l;d||(b=Br(b));var L=b==="defaultValue"||b==="defaultChecked";if(c==null&&!o&&!L)if(v[l]=null,b==="value"||b==="checked"){let S=r;const P=e===void 0;if(b==="value"){let h=S.defaultValue;S.removeAttribute(b),S.defaultValue=h,S.value=S.__value=P?h:null}else{let h=S.defaultChecked;S.removeAttribute(b),S.defaultChecked=h,S.checked=P?h:!1}}else r.removeAttribute(l);else L||I.includes(b)&&(o||typeof c!="string")?(r[b]=c,b in v&&(v[b]=pr)):typeof c!="function"&&C(r,b,c)}}}return p&&G(!0),a}function ae(r,e,i=[],f=[],s=[],t,u=!1,n=!1){dr(s,i,f,v=>{var o=void 0,d={},p=r.nodeName===mr,a=!1;if(X(()=>{var g=e(...v.map(M)),I=ee(r,o,g,t,u,n);a&&p&&"value"in g&&$(r,g.value);for(let _ of Object.getOwnPropertySymbols(d))g[_]||D(d[_]);for(let _ of Object.getOwnPropertySymbols(g)){var O=g[_];_.description===_r&&(!o||O!==o[_])&&(d[_]&&D(d[_]),d[_]=F(()=>Vr(r,()=>O))),I[_]=O}o=I}),p){var T=r;Q(()=>{$(T,o.value,!0),Qr(T)})}a=!0})}function x(r){return r.__attributes??={[k]:r.nodeName.includes("-"),[m]:r.namespaceURI===ur}}var z=new Map;function rr(r){var e=r.getAttribute("is")||r.nodeName,i=z.get(e);if(i)return i;z.set(e,i=[]);for(var f,s=r,t=Element.prototype;t!==s;){f=lr(s);for(var u in f)f[u].set&&i.push(u);s=nr(s)}return i}const ie={get(r,e){if(!r.exclude.includes(e))return M(r.version),e in r.special?r.special[e]():r.props[e]},set(r,e,i){if(!(e in r.special)){var f=B;try{V(r.parent_effect),r.special[e]=fe({get[e](){return r.props[e]}},e,W)}finally{V(f)}}return r.special[e](i),K(r.version),!0},getOwnPropertyDescriptor(r,e){if(!r.exclude.includes(e)&&e in r.props)return{enumerable:!0,configurable:!0,value:r.props[e]}},deleteProperty(r,e){return r.exclude.includes(e)||(r.exclude.push(e),K(r.version)),!0},has(r,e){return r.exclude.includes(e)?!1:e in r.props},ownKeys(r){return Reflect.ownKeys(r.props).filter(e=>!r.exclude.includes(e))}};function ue(r,e){return new Proxy({props:r,exclude:e,special:{},version:Ir(0),parent_effect:B},ie)}function fe(r,e,i,f){var s=!Pr||(i&Lr)!==0,t=(i&Or)!==0,u=(i&Rr)!==0,n=f,v=!0,o=()=>(v&&(v=!1,n=u?Nr(f):f),n);let d;if(t){var p=Cr in r||Ur in r;d=gr(r,e)?.set??(p&&e in r?A=>r[e]=A:void 0)}var a,T=!1;t?[a,T]=Kr(()=>r[e]):a=r[e],a===void 0&&f!==void 0&&(a=o(),d&&(s&&Ar(),d(a)));var g;if(s?g=()=>{var A=r[e];return A===void 0?o():(v=!0,A)}:g=()=>{var A=r[e];return A!==void 0&&(n=void 0),A===void 0?n:A},s&&(i&W)===0)return g;if(d){var I=r.$$legacy;return(function(A,b){return arguments.length>0?((!s||!b||I||T)&&d(b?g():A),A):g()})}var O=!1,_=((i&Er)!==0?wr:Mr)(()=>(O=!1,g()));t&&M(_);var R=B;return(function(A,b){if(arguments.length>0){const L=b?M(_):s&&t?hr(A):A;return Sr(_,L),O=!0,n!==void 0&&(n=L),A}return yr&&O||(R.f&Tr)!==0?_.v:M(_)})}export{Xr as a,ae as b,ue as l,fe as p,xr as r,C as s}; diff --git a/website/blog/_astro/render.C4NccAY7.js b/website/blog/_astro/render.C4NccAY7.js deleted file mode 100644 index fc2737c..0000000 --- a/website/blog/_astro/render.C4NccAY7.js +++ /dev/null @@ -1,2 +0,0 @@ -import{au as K,g as q,a7 as U,S as z,u as Q,av as k,Y as w,C as u,v as p,a8 as y,aw as H,q as X,y as Z,H as ee,ax as Y,K as c,o as V,W as F,I as B,a0 as te,ay as se,an as M,am as $,az as L,aA as re,aB as ie,ao as ne,ap as j,G as ae,a1 as S,w as R,n as he,A as fe,aC as b,at as oe,aD as de,aE as _e,aF as le,aG as x,x as ce,D as G,aH as ue,a2 as pe,ac as O,B as E,aI as ge,$ as ve,aJ as ye,P as me,b as be,a9 as Ee,F as Te,ab as we,p as Re}from"./template.CyUWgh-J.js";import{b as Ae,r as P,h as W,i as De}from"./utils.DonxBMOE.js";function Ne(i){let e=0,t=z(0),r;return()=>{K()&&(q(t),U(()=>(e===0&&(r=Q(()=>i(()=>k(t)))),e+=1,()=>{w(()=>{e-=1,e===0&&(r?.(),r=void 0,k(t))})})))}}var Fe=oe|de;function Se(i,e,t,r){new xe(i,e,t,r)}class xe{parent;is_pending=!1;transform_error;#t;#u=p?u:null;#i;#o;#e;#n=null;#s=null;#r=null;#a=null;#d=0;#f=0;#_=!1;#p=new Set;#g=new Set;#h=null;#m=Ne(()=>(this.#h=z(this.#d),()=>{this.#h=null}));constructor(e,t,r,f){this.#t=e,this.#i=t,this.#o=s=>{var n=y;n.b=this,n.f|=H,r(s)},this.parent=y.b,this.transform_error=f??this.parent?.transform_error??(s=>s),this.#e=X(()=>{if(p){const s=this.#u;Z();const n=s.data===ee;if(s.data.startsWith(Y)){const a=JSON.parse(s.data.slice(Y.length));this.#E(a)}else n?this.#T():this.#b()}else this.#v()},Fe),p&&(this.#t=u)}#b(){try{this.#n=c(()=>this.#o(this.#t))}catch(e){this.error(e)}}#E(e){const t=this.#i.failed;t&&(this.#r=c(()=>{t(this.#t,()=>e,()=>()=>{})}))}#T(){const e=this.#i.pending;e&&(this.is_pending=!0,this.#s=c(()=>e(this.#t)),w(()=>{var t=this.#a=document.createDocumentFragment(),r=V();t.append(r),this.#n=this.#c(()=>c(()=>this.#o(r))),this.#f===0&&(this.#t.before(t),this.#a=null,F(this.#s,()=>{this.#s=null}),this.#l(B))}))}#v(){try{if(this.is_pending=this.has_pending_snippet(),this.#f=0,this.#d=0,this.#n=c(()=>{this.#o(this.#t)}),this.#f>0){var e=this.#a=document.createDocumentFragment();te(this.#n,e);const t=this.#i.pending;this.#s=c(()=>t(this.#t))}else this.#l(B)}catch(t){this.error(t)}}#l(e){this.is_pending=!1,e.transfer_effects(this.#p,this.#g)}defer_effect(e){se(e,this.#p,this.#g)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#i.pending}#c(e){var t=y,r=ne,f=j;M(this.#e),$(this.#e),L(this.#e.ctx);try{return re.ensure(),e()}catch(s){return ie(s),null}finally{M(t),$(r),L(f)}}#y(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#y(e,t);return}this.#f+=e,this.#f===0&&(this.#l(t),this.#s&&F(this.#s,()=>{this.#s=null}),this.#a&&(this.#t.before(this.#a),this.#a=null))}update_pending_count(e,t){this.#y(e,t),this.#d+=e,!(!this.#h||this.#_)&&(this.#_=!0,w(()=>{this.#_=!1,this.#h&&ae(this.#h,this.#d)}))}get_effect_pending(){return this.#m(),q(this.#h)}error(e){var t=this.#i.onerror;let r=this.#i.failed;if(!t&&!r)throw e;this.#n&&(S(this.#n),this.#n=null),this.#s&&(S(this.#s),this.#s=null),this.#r&&(S(this.#r),this.#r=null),p&&(R(this.#u),he(),R(fe()));var f=!1,s=!1;const n=()=>{if(f){le();return}f=!0,s&&_e(),this.#r!==null&&F(this.#r,()=>{this.#r=null}),this.#c(()=>{this.#v()})},l=a=>{try{s=!0,t?.(a,n),s=!1}catch(h){b(h,this.#e&&this.#e.parent)}r&&(this.#r=this.#c(()=>{try{return c(()=>{var h=y;h.b=this,h.f|=H,r(this.#t,()=>a,()=>n)})}catch(h){return b(h,this.#e.parent),null}}))};w(()=>{var a;try{a=this.transform_error(e)}catch(h){b(h,this.#e&&this.#e.parent);return}a!==null&&typeof a=="object"&&typeof a.then=="function"?a.then(l,h=>b(h,this.#e&&this.#e.parent)):l(a)})}}function ke(i,e){var t=e==null?"":typeof e=="object"?`${e}`:e;t!==(i.__t??=i.nodeValue)&&(i.__t=t,i.nodeValue=`${t}`)}function Oe(i,e){return J(i,e)}function He(i,e){x(),e.intro=e.intro??!1;const t=e.target,r=p,f=u;try{for(var s=ce(t);s&&(s.nodeType!==G||s.data!==ue);)s=pe(s);if(!s)throw O;E(!0),R(s);const n=J(i,{...e,anchor:s});return E(!1),n}catch(n){if(n instanceof Error&&n.message.split(` -`).some(l=>l.startsWith("https://svelte.dev/e/")))throw n;return n!==O&&console.warn("Failed to hydrate: ",n),e.recover===!1&&ge(),x(),ve(t),E(!1),Oe(i,e)}finally{E(r),R(f)}}const T=new Map;function J(i,{target:e,anchor:t,props:r={},events:f,context:s,intro:n=!0,transformError:l}){x();var a=void 0,h=ye(()=>{var m=t??e.appendChild(V());Se(m,{pending:()=>{}},o=>{be({});var d=j;if(s&&(d.c=s),f&&(r.$$events=f),p&&Ee(o,null),a=i(o,r)||{},p&&(y.nodes.end=u,u===null||u.nodeType!==G||u.data!==Te))throw we(),O;Re()},l);var A=new Set,D=o=>{for(var d=0;d{for(var o of A)for(const v of[e,document]){var d=T.get(v),_=d.get(o);--_==0?(v.removeEventListener(o,W),d.delete(o),d.size===0&&T.delete(v)):d.set(o,_)}P.delete(D),m!==t&&m.parentNode?.removeChild(m)}});return C.set(a,h),a}let C=new WeakMap;function Ye(i,e){const t=C.get(i);return t?(C.delete(i),t(e)):Promise.resolve()}export{He as h,Oe as m,ke as s,Ye as u}; diff --git a/website/blog/_astro/roboto-cyrillic-400-normal.Bjg-1-sg.woff b/website/blog/_astro/roboto-cyrillic-400-normal.Bjg-1-sg.woff deleted file mode 100644 index 179ff2d..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-400-normal.Bjg-1-sg.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-cyrillic-400-normal.CBPI_iaY.woff2 b/website/blog/_astro/roboto-cyrillic-400-normal.CBPI_iaY.woff2 deleted file mode 100644 index 2d4b6a4..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-400-normal.CBPI_iaY.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-cyrillic-700-normal.C2o7G-SM.woff2 b/website/blog/_astro/roboto-cyrillic-700-normal.C2o7G-SM.woff2 deleted file mode 100644 index b595d15..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-700-normal.C2o7G-SM.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-cyrillic-700-normal.DhZFXDSN.woff b/website/blog/_astro/roboto-cyrillic-700-normal.DhZFXDSN.woff deleted file mode 100644 index 3a72cc2..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-700-normal.DhZFXDSN.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-cyrillic-ext-400-normal.CaK1767H.woff b/website/blog/_astro/roboto-cyrillic-ext-400-normal.CaK1767H.woff deleted file mode 100644 index bea823d..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-ext-400-normal.CaK1767H.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-cyrillic-ext-400-normal.qHufge6k.woff2 b/website/blog/_astro/roboto-cyrillic-ext-400-normal.qHufge6k.woff2 deleted file mode 100644 index 8abc464..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-ext-400-normal.qHufge6k.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-cyrillic-ext-700-normal.CI7FH63F.woff b/website/blog/_astro/roboto-cyrillic-ext-700-normal.CI7FH63F.woff deleted file mode 100644 index 2939bae..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-ext-700-normal.CI7FH63F.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-cyrillic-ext-700-normal.DmFxo5wj.woff2 b/website/blog/_astro/roboto-cyrillic-ext-700-normal.DmFxo5wj.woff2 deleted file mode 100644 index 0e14dd6..0000000 Binary files a/website/blog/_astro/roboto-cyrillic-ext-700-normal.DmFxo5wj.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-greek-400-normal.Bb5mj_fZ.woff b/website/blog/_astro/roboto-greek-400-normal.Bb5mj_fZ.woff deleted file mode 100644 index c2eadbb..0000000 Binary files a/website/blog/_astro/roboto-greek-400-normal.Bb5mj_fZ.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-greek-400-normal.ai2Z1K3C.woff2 b/website/blog/_astro/roboto-greek-400-normal.ai2Z1K3C.woff2 deleted file mode 100644 index bfdab5f..0000000 Binary files a/website/blog/_astro/roboto-greek-400-normal.ai2Z1K3C.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-greek-700-normal.0aHWxGLu.woff2 b/website/blog/_astro/roboto-greek-700-normal.0aHWxGLu.woff2 deleted file mode 100644 index dabe55f..0000000 Binary files a/website/blog/_astro/roboto-greek-700-normal.0aHWxGLu.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-greek-700-normal.DjRqqLBV.woff b/website/blog/_astro/roboto-greek-700-normal.DjRqqLBV.woff deleted file mode 100644 index 1402c63..0000000 Binary files a/website/blog/_astro/roboto-greek-700-normal.DjRqqLBV.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-400-normal.BqEyEoaF.woff2 b/website/blog/_astro/roboto-latin-400-normal.BqEyEoaF.woff2 deleted file mode 100644 index 77e4259..0000000 Binary files a/website/blog/_astro/roboto-latin-400-normal.BqEyEoaF.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-400-normal.DyYNIH4P.woff b/website/blog/_astro/roboto-latin-400-normal.DyYNIH4P.woff deleted file mode 100644 index b31b963..0000000 Binary files a/website/blog/_astro/roboto-latin-400-normal.DyYNIH4P.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-700-normal.BZpUvMxY.woff2 b/website/blog/_astro/roboto-latin-700-normal.BZpUvMxY.woff2 deleted file mode 100644 index 85b8ace..0000000 Binary files a/website/blog/_astro/roboto-latin-700-normal.BZpUvMxY.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-700-normal.DLgJJpmK.woff b/website/blog/_astro/roboto-latin-700-normal.DLgJJpmK.woff deleted file mode 100644 index 10110ac..0000000 Binary files a/website/blog/_astro/roboto-latin-700-normal.DLgJJpmK.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-ext-400-normal.C3tdtHj3.woff2 b/website/blog/_astro/roboto-latin-ext-400-normal.C3tdtHj3.woff2 deleted file mode 100644 index 100758e..0000000 Binary files a/website/blog/_astro/roboto-latin-ext-400-normal.C3tdtHj3.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-ext-400-normal.scX0fKtV.woff b/website/blog/_astro/roboto-latin-ext-400-normal.scX0fKtV.woff deleted file mode 100644 index 44e20d7..0000000 Binary files a/website/blog/_astro/roboto-latin-ext-400-normal.scX0fKtV.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-ext-700-normal.BUhwtWwy.woff b/website/blog/_astro/roboto-latin-ext-700-normal.BUhwtWwy.woff deleted file mode 100644 index b40671d..0000000 Binary files a/website/blog/_astro/roboto-latin-ext-700-normal.BUhwtWwy.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-latin-ext-700-normal.DSBUz0N1.woff2 b/website/blog/_astro/roboto-latin-ext-700-normal.DSBUz0N1.woff2 deleted file mode 100644 index 2a80739..0000000 Binary files a/website/blog/_astro/roboto-latin-ext-700-normal.DSBUz0N1.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-math-400-normal.BEFej5gc.woff2 b/website/blog/_astro/roboto-math-400-normal.BEFej5gc.woff2 deleted file mode 100644 index f38890d..0000000 Binary files a/website/blog/_astro/roboto-math-400-normal.BEFej5gc.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-math-400-normal.C9RxBKAh.woff b/website/blog/_astro/roboto-math-400-normal.C9RxBKAh.woff deleted file mode 100644 index a50ec81..0000000 Binary files a/website/blog/_astro/roboto-math-400-normal.C9RxBKAh.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-math-700-normal.B8YqGHVc.woff2 b/website/blog/_astro/roboto-math-700-normal.B8YqGHVc.woff2 deleted file mode 100644 index 57b8ce9..0000000 Binary files a/website/blog/_astro/roboto-math-700-normal.B8YqGHVc.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-math-700-normal.DVoD5t2k.woff b/website/blog/_astro/roboto-math-700-normal.DVoD5t2k.woff deleted file mode 100644 index 845d0c3..0000000 Binary files a/website/blog/_astro/roboto-math-700-normal.DVoD5t2k.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-symbols-400-normal.CB1Ce4Gk.woff2 b/website/blog/_astro/roboto-symbols-400-normal.CB1Ce4Gk.woff2 deleted file mode 100644 index cdf432c..0000000 Binary files a/website/blog/_astro/roboto-symbols-400-normal.CB1Ce4Gk.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-symbols-400-normal.DLYbZahX.woff b/website/blog/_astro/roboto-symbols-400-normal.DLYbZahX.woff deleted file mode 100644 index 3e603b1..0000000 Binary files a/website/blog/_astro/roboto-symbols-400-normal.DLYbZahX.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-symbols-700-normal.BiFDindJ.woff2 b/website/blog/_astro/roboto-symbols-700-normal.BiFDindJ.woff2 deleted file mode 100644 index 9cd22b2..0000000 Binary files a/website/blog/_astro/roboto-symbols-700-normal.BiFDindJ.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-symbols-700-normal.BoS6HWkc.woff b/website/blog/_astro/roboto-symbols-700-normal.BoS6HWkc.woff deleted file mode 100644 index 7009e80..0000000 Binary files a/website/blog/_astro/roboto-symbols-700-normal.BoS6HWkc.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-vietnamese-400-normal.D2PTxGxD.woff2 b/website/blog/_astro/roboto-vietnamese-400-normal.D2PTxGxD.woff2 deleted file mode 100644 index 1cd52dd..0000000 Binary files a/website/blog/_astro/roboto-vietnamese-400-normal.D2PTxGxD.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-vietnamese-400-normal.DnpnVwnf.woff b/website/blog/_astro/roboto-vietnamese-400-normal.DnpnVwnf.woff deleted file mode 100644 index bcfb067..0000000 Binary files a/website/blog/_astro/roboto-vietnamese-400-normal.DnpnVwnf.woff and /dev/null differ diff --git a/website/blog/_astro/roboto-vietnamese-700-normal.BEVeWqJt.woff2 b/website/blog/_astro/roboto-vietnamese-700-normal.BEVeWqJt.woff2 deleted file mode 100644 index 6f142f1..0000000 Binary files a/website/blog/_astro/roboto-vietnamese-700-normal.BEVeWqJt.woff2 and /dev/null differ diff --git a/website/blog/_astro/roboto-vietnamese-700-normal.DsFyXAL4.woff b/website/blog/_astro/roboto-vietnamese-700-normal.DsFyXAL4.woff deleted file mode 100644 index ad7a3a5..0000000 Binary files a/website/blog/_astro/roboto-vietnamese-700-normal.DsFyXAL4.woff and /dev/null differ diff --git a/website/blog/_astro/rynh.-a3tfphf_Z11tE8q.webp b/website/blog/_astro/rynh.-a3tfphf_Z11tE8q.webp deleted file mode 100644 index 8781c80..0000000 Binary files a/website/blog/_astro/rynh.-a3tfphf_Z11tE8q.webp and /dev/null differ diff --git a/website/blog/_astro/setting-utils.Bem8IX7u.js b/website/blog/_astro/setting-utils.Bem8IX7u.js deleted file mode 100644 index 27d22eb..0000000 --- a/website/blog/_astro/setting-utils.Bem8IX7u.js +++ /dev/null @@ -1 +0,0 @@ -import{e as a}from"./config.B4FKKqOZ.js";const m="light",u="dark",o="auto",i=o,d=35,l=30,g=d+l;function h(){const t=document.getElementById("config-carrier");return Number.parseInt(t?.dataset.hue||"250")}function T(){const e=localStorage.getItem("hue");return e?Number.parseInt(e):h()}function I(e){localStorage.setItem("hue",String(e));const t=document.querySelector(":root");t&&t.style.setProperty("--hue",String(e))}function E(e){const t=document.documentElement.classList.contains("dark"),r=document.documentElement.getAttribute("data-theme");let n;switch(e){case m:n=!1;break;case u:n=!0;break;case o:n=window.matchMedia("(prefers-color-scheme: dark)").matches;break}const s=t!==n,c=r!==a.theme;!s&&!c||(s&&document.documentElement.classList.add("is-theme-transitioning"),requestAnimationFrame(()=>{s&&(n?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")),document.documentElement.setAttribute("data-theme",a.theme),s&&Promise.resolve().then(()=>{document.documentElement.classList.remove("is-theme-transitioning")})}))}function k(e){localStorage.setItem("theme",e),E(e)}function H(){return localStorage.getItem("theme")||i}export{o as A,l as B,u as D,m as L,E as a,T as b,h as c,I as d,d as e,g as f,H as g,k as s}; diff --git a/website/blog/_astro/template.CyUWgh-J.js b/website/blog/_astro/template.CyUWgh-J.js deleted file mode 100644 index f99efb5..0000000 --- a/website/blog/_astro/template.CyUWgh-J.js +++ /dev/null @@ -1 +0,0 @@ -let Ce=!1,$t=!1;function Wn(){Ce=!0}const Xn=1,Zn=2,Jn=4,Qn=8,er=16,tr=1,nr=2,rr=4,sr=8,ar=16,zt=1,Kt=2,Wt="[",Xt="[!",ir="[?",Zt="]",Be={},E=Symbol(),Jt="http://www.w3.org/1999/xhtml",lr="http://www.w3.org/2000/svg",fr="http://www.w3.org/1998/Math/MathML",ur="@attach",Qt=!1;var en=Array.isArray,tn=Array.prototype.indexOf,ce=Array.prototype.includes,or=Array.from,cr=Object.defineProperty,we=Object.getOwnPropertyDescriptor,nn=Object.getOwnPropertyDescriptors,rn=Object.prototype,sn=Array.prototype,ot=Object.getPrototypeOf,tt=Object.isExtensible;const an=()=>{};function _r(e){return e()}function ln(e){for(var t=0;t{e=r,t=s});return{promise:n,resolve:e,reject:t}}const b=2,_e=4,be=8,Ge=1<<24,j=16,H=32,re=64,fn=128,N=512,m=1024,T=2048,D=4096,I=8192,P=16384,z=32768,nt=1<<25,Ne=65536,Le=1<<17,un=1<<18,Te=1<<19,_t=1<<20,vr=1<<25,se=65536,je=1<<21,ge=1<<22,B=1<<23,Q=Symbol("$state"),dr=Symbol("legacy props"),hr=Symbol(""),q=new class extends Error{name="StaleReactionError";message="The reaction that called `getAbortSignal()` was re-run or destroyed"},wr=!!globalThis.document?.contentType&&globalThis.document.contentType.includes("xml"),Ie=3,vt=8;function on(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function yr(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function cn(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function _n(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function vn(e){throw new Error("https://svelte.dev/e/effect_orphan")}function dn(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function gr(){throw new Error("https://svelte.dev/e/hydration_failed")}function mr(e){throw new Error("https://svelte.dev/e/props_invalid_value")}function hn(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function pn(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function wn(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function Er(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}function $e(e){console.warn("https://svelte.dev/e/hydration_mismatch")}function br(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function Tr(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}let F=!1;function Ar(e){F=e}let g;function ve(e){if(e===null)throw $e(),Be;return g=e}function yn(){return ve(K(g))}function Sr(e){if(F){if(K(g)!==null)throw $e(),Be;g=e}}function Rr(e=1){if(F){for(var t=e,n=g;t--;)n=K(n);g=n}}function xr(e=!0){for(var t=0,n=g;;){if(n.nodeType===vt){var r=n.data;if(r===Zt){if(t===0)return n;t-=1}else(r===Wt||r===Xt||r[0]==="["&&!isNaN(Number(r.slice(1))))&&(t+=1)}var s=K(n);e&&n.remove(),n=s}}function Nr(e){if(!e||e.nodeType!==vt)throw $e(),Be;return e.data}function dt(e){return e===this.v}function gn(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function ht(e){return!gn(e,this.v)}let A=null;function ke(e){A=e}function kr(e,t=!1,n){A={p:A,i:!1,c:null,e:null,s:e,x:null,r:d,l:Ce&&!t?{s:null,u:null,$:[]}:null}}function Or(e){var t=A,n=t.e;if(n!==null){t.e=null;for(var r of n)Ct(r)}return t.i=!0,A=t.p,{}}function Ae(){return!Ce||A!==null&&A.l===null}let X=[];function pt(){var e=X;X=[],ln(e)}function He(e){if(X.length===0&&!ye){var t=X;queueMicrotask(()=>{t===X&&pt()})}X.push(e)}function mn(){for(;X.length>0;)pt()}function En(e){var t=d;if(t===null)return v.f|=B,e;if((t.f&z)===0&&(t.f&_e)===0)throw e;Oe(e,t)}function Oe(e,t){for(;t!==null;){if((t.f&fn)!==0){if((t.f&z)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}const bn=-7169;function y(e,t){e.f=e.f&bn|t}function ze(e){(e.f&N)!==0||e.deps===null?y(e,m):y(e,D)}function wt(e){if(e!==null)for(const t of e)(t.f&b)===0||(t.f&se)===0||(t.f^=se,wt(t.deps))}function Tn(e,t,n){(e.f&T)!==0?t.add(e):(e.f&D)!==0&&n.add(e),wt(e.deps),y(e,m)}const W=new Set;let w=null,M=null,Ye=null,ye=!1,De=!1,oe=null,Re=null;var rt=0;let An=1;class ae{id=An++;current=new Map;previous=new Map;#l=new Set;#f=new Set;#r=new Map;#t=new Map;#d=null;#e=[];#h=[];#a=new Set;#s=new Set;#n=new Map;#u=new Set;is_fork=!1;#o=!1;#i=new Set;#c(){return this.is_fork||this.#t.size>0}#w(){for(const r of this.#i)for(const s of r.#t.keys()){for(var t=!1,n=s;n.parent!==null;){if(this.#n.has(n)){t=!0;break}n=n.parent}if(!t)return!0}return!1}skip_effect(t){this.#n.has(t)||this.#n.set(t,{d:[],m:[]}),this.#u.delete(t)}unskip_effect(t,n=r=>this.schedule(r)){var r=this.#n.get(t);if(r){this.#n.delete(t);for(var s of r.d)y(s,T),n(s);for(s of r.m)y(s,D),n(s)}this.#u.add(t)}#_(){if(rt++>1e3&&(W.delete(this),Rn()),!this.#c()){for(const i of this.#a)this.#s.delete(i),y(i,T),this.schedule(i);for(const i of this.#s)y(i,D),this.schedule(i)}const t=this.#e;this.#e=[],this.apply();var n=oe=[],r=[],s=Re=[];for(const i of t)try{this.#p(i,n,r)}catch(l){throw mt(i),l}if(w=null,s.length>0){var a=ae.ensure();for(const i of s)a.schedule(i)}if(oe=null,Re=null,this.#c()||this.#w()){this.#v(r),this.#v(n);for(const[i,l]of this.#n)gt(i,l)}else{this.#r.size===0&&W.delete(this),this.#a.clear(),this.#s.clear();for(const i of this.#l)i(this);this.#l.clear(),st(r),st(n),this.#d?.resolve()}var f=w;if(this.#e.length>0){const i=f??=this;i.#e.push(...this.#e.filter(l=>!i.#e.includes(l)))}f!==null&&(W.add(f),f.#_())}#p(t,n,r){t.f^=m;for(var s=t.first;s!==null;){var a=s.f,f=(a&(H|re))!==0,i=f&&(a&m)!==0,l=i||(a&I)!==0||this.#n.has(s);if(!l&&s.fn!==null){f?s.f^=m:(a&_e)!==0?n.push(s):de(s)&&((a&j)!==0&&this.#s.add(s),ue(s));var o=s.first;if(o!==null){s=o;continue}}for(;s!==null;){var u=s.next;if(u!==null){s=u;break}s=s.parent}}}#v(t){for(var n=0;n!this.current.has(c));if(s.length===0)t&&u.discard();else if(n.length>0){if(t)for(const c of this.#u)u.unskip_effect(c,_=>{(_.f&(j|ge))!==0?u.schedule(_):u.#v([_])});u.activate();var a=new Set,f=new Map;for(var i of n)yt(i,s,a,f);f=new Map;var l=[...u.current.keys()].filter(c=>this.current.has(c)?this.current.get(c)[0]!==c:!0);for(const c of this.#h)(c.f&(P|I|Le))===0&&Ke(c,l,f)&&((c.f&(ge|j))!==0?(y(c,T),u.schedule(c)):u.#a.add(c));if(u.#e.length>0){u.apply();for(var o of u.#e)u.#p(o,[],[]);u.#e=[]}u.deactivate()}}for(const u of W)u.#i.has(this)&&(u.#i.delete(this),u.#i.size===0&&!u.#c()&&(u.activate(),u.#_()))}increment(t,n){let r=this.#r.get(n)??0;if(this.#r.set(n,r+1),t){let s=this.#t.get(n)??0;this.#t.set(n,s+1)}}decrement(t,n,r){let s=this.#r.get(n)??0;if(s===1?this.#r.delete(n):this.#r.set(n,s-1),t){let a=this.#t.get(n)??0;a===1?this.#t.delete(n):this.#t.set(n,a-1)}this.#o||r||(this.#o=!0,He(()=>{this.#o=!1,this.flush()}))}transfer_effects(t,n){for(const r of t)this.#a.add(r);for(const r of n)this.#s.add(r);t.clear(),n.clear()}oncommit(t){this.#l.add(t)}ondiscard(t){this.#f.add(t)}settled(){return(this.#d??=ct()).promise}static ensure(){if(w===null){const t=w=new ae;De||(W.add(w),ye||He(()=>{w===t&&t.flush()}))}return w}apply(){{M=null;return}}schedule(t){if(Ye=t,t.b?.is_pending&&(t.f&(_e|be|Ge))!==0&&(t.f&z)===0){t.b.defer_effect(t);return}for(var n=t;n.parent!==null;){n=n.parent;var r=n.f;if(oe!==null&&n===d&&(v===null||(v.f&b)===0))return;if((r&(re|H))!==0){if((r&m)===0)return;n.f^=m}}this.#e.push(n)}}function Sn(e){var t=ye;ye=!0;try{for(var n;;){if(mn(),w===null)return n;w.flush()}}finally{ye=t}}function Rn(){try{dn()}catch(e){Oe(e,Ye)}}let Y=null;function st(e){var t=e.length;if(t!==0){for(var n=0;n0)){ee.clear();for(const s of Y){if((s.f&(P|I))!==0)continue;const a=[s];let f=s.parent;for(;f!==null;)Y.has(f)&&(Y.delete(f),a.push(f)),f=f.parent;for(let i=a.length-1;i>=0;i--){const l=a[i];(l.f&(P|I))===0&&ue(l)}}Y.clear()}}Y=null}}function yt(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const s of e.reactions){const a=s.f;(a&b)!==0?yt(s,t,n,r):(a&(ge|j))!==0&&(a&T)===0&&Ke(s,t,r)&&(y(s,T),We(s))}}function Ke(e,t,n){const r=n.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const s of e.deps){if(ce.call(t,s))return!0;if((s.f&b)!==0&&Ke(s,t,n))return n.set(s,!0),!0}return n.set(e,!1),!1}function We(e){w.schedule(e)}function gt(e,t){if(!((e.f&H)!==0&&(e.f&m)!==0)){(e.f&T)!==0?t.d.push(e):(e.f&D)!==0&&t.m.push(e),y(e,m);for(var n=e.first;n!==null;)gt(n,t),n=n.next}}function mt(e){y(e,m);for(var t=e.first;t!==null;)mt(t),t=t.next}function xn(e,t,n,r){const s=Ae()?bt:On;var a=e.filter(_=>!_.settled);if(n.length===0&&a.length===0){r(t.map(s));return}var f=d,i=Nn(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(_=>_.promise)):null;function o(_){i();try{r(_)}catch(p){(f.f&P)===0&&Oe(p,f)}Me()}if(n.length===0){l.then(()=>o(t.map(s)));return}var u=Et();function c(){Promise.all(n.map(_=>kn(_))).then(_=>o([...t.map(s),..._])).catch(_=>Oe(_,f)).finally(()=>u())}l?l.then(()=>{i(),c(),Me()}):c()}function Nn(){var e=d,t=v,n=A,r=w;return function(a=!0){$(e),G(t),ke(n),a&&(e.f&P)===0&&(r?.activate(),r?.apply())}}function Me(e=!0){$(null),G(null),ke(null),e&&w?.deactivate()}function Et(){var e=d,t=e.b,n=w,r=t.is_rendered();return t.update_pending_count(1,n),n.increment(r,e),(s=!1)=>{t.update_pending_count(-1,n),n.decrement(r,e,s)}}function bt(e){var t=b|T,n=v!==null&&(v.f&b)!==0?v:null;return d!==null&&(d.f|=Te),{ctx:A,deps:null,effects:null,equals:dt,f:t,fn:e,reactions:null,rv:0,v:E,wv:0,parent:n??d,ac:null}}function kn(e,t,n){let r=d;r===null&&on();var s=void 0,a=Ze(E),f=!v,i=new Map;return Hn(()=>{var l=d,o=ct();s=o.promise;try{Promise.resolve(e()).then(o.resolve,o.reject).finally(Me)}catch(p){o.reject(p),Me()}var u=w;if(f){if((l.f&z)!==0)var c=Et();if(r.b.is_rendered())i.get(u)?.reject(q),i.delete(u);else{for(const p of i.values())p.reject(q);i.clear()}i.set(u,o)}const _=(p,h=void 0)=>{if(c){var O=h===q;c(O)}if(!(h===q||(l.f&P)!==0)){if(u.activate(),h)a.f|=B,Ue(a,h);else{(a.f&B)!==0&&(a.f^=B),Ue(a,p);for(const[he,Se]of i){if(i.delete(he),he===u)break;Se.reject(q)}}u.deactivate()}};o.promise.then(_,p=>_(null,p||"unknown"))}),jn(()=>{for(const l of i.values())l.reject(q)}),new Promise(l=>{function o(u){function c(){u===s?l(a):o(s)}u.then(c,c)}o(s)})}function On(e){const t=bt(e);return t.equals=ht,t}function Mn(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;nJ(e))),t}function U(e,t,n=!1){v!==null&&(!C||(v.f&Le)!==0)&&Ae()&&(v.f&(b|j|ge|Le))!==0&&(k===null||!ce.call(k,e))&&wn();let r=n?pe(t):t;return Ue(e,r,Re)}function Ue(e,t,n=null){if(!e.equals(t)){ee.set(e,fe?t:e.v);var r=ae.ensure();if(r.capture(e,t),(e.f&b)!==0){const s=e;(e.f&T)!==0&&Xe(s),M===null&&ze(s)}e.wv=Ht(),Rt(e,T,n),Ae()&&d!==null&&(d.f&m)!==0&&(d.f&(H|re))===0&&(x===null?Bn([e]):x.push(e)),!r.is_fork&&qe.size>0&&!St&&Pn()}return t}function Pn(){St=!1;for(const e of qe)(e.f&m)!==0&&y(e,D),de(e)&&ue(e);qe.clear()}function Ir(e,t=1){var n=J(e),r=t===1?n++:n--;return U(e,n),r}function Fe(e){U(e,e.v+1)}function Rt(e,t,n){var r=e.reactions;if(r!==null)for(var s=Ae(),a=r.length,f=0;f{if(te===a)return i();var l=v,o=te;G(null),ut(a);var u=i();return G(l),ut(o),u};return r&&n.set("length",V(e.length)),new Proxy(e,{defineProperty(i,l,o){(!("value"in o)||o.configurable===!1||o.enumerable===!1||o.writable===!1)&&hn();var u=n.get(l);return u===void 0?f(()=>{var c=V(o.value);return n.set(l,c),c}):U(u,o.value,!0),!0},deleteProperty(i,l){var o=n.get(l);if(o===void 0){if(l in i){const u=f(()=>V(E));n.set(l,u),Fe(s)}}else U(o,E),Fe(s);return!0},get(i,l,o){if(l===Q)return e;var u=n.get(l),c=l in i;if(u===void 0&&(!c||we(i,l)?.writable)&&(u=f(()=>{var p=pe(c?i[l]:E),h=V(p);return h}),n.set(l,u)),u!==void 0){var _=J(u);return _===E?void 0:_}return Reflect.get(i,l,o)},getOwnPropertyDescriptor(i,l){var o=Reflect.getOwnPropertyDescriptor(i,l);if(o&&"value"in o){var u=n.get(l);u&&(o.value=J(u))}else if(o===void 0){var c=n.get(l),_=c?.v;if(c!==void 0&&_!==E)return{enumerable:!0,configurable:!0,value:_,writable:!0}}return o},has(i,l){if(l===Q)return!0;var o=n.get(l),u=o!==void 0&&o.v!==E||Reflect.has(i,l);if(o!==void 0||d!==null&&(!u||we(i,l)?.writable)){o===void 0&&(o=f(()=>{var _=u?pe(i[l]):E,p=V(_);return p}),n.set(l,o));var c=J(o);if(c===E)return!1}return u},set(i,l,o,u){var c=n.get(l),_=l in i;if(r&&l==="length")for(var p=o;pV(E)),n.set(p+"",h))}if(c===void 0)(!_||we(i,l)?.writable)&&(c=f(()=>V(void 0)),U(c,pe(o)),n.set(l,c));else{_=c.v!==E;var O=f(()=>pe(o));U(c,O)}var he=Reflect.getOwnPropertyDescriptor(i,l);if(he?.set&&he.set.call(u,o),!_){if(r&&typeof l=="string"){var Se=n.get("length"),Pe=Number(l);Number.isInteger(Pe)&&Pe>=Se.v&&U(Se,Pe+1)}Fe(s)}return!0},ownKeys(i){J(s);var l=Reflect.ownKeys(i).filter(c=>{var _=n.get(c);return _===void 0||_.v!==E});for(var[o,u]of n)u.v!==E&&!(o in i)&&l.push(o);return l},setPrototypeOf(){pn()}})}function at(e){try{if(e!==null&&typeof e=="object"&&Q in e)return e[Q]}catch{}return e}function Pr(e,t){return Object.is(at(e),at(t))}var it,xt,Nt,kt;function Dr(){if(it===void 0){it=window,xt=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;Nt=we(t,"firstChild").get,kt=we(t,"nextSibling").get,tt(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),tt(n)&&(n.__t=void 0)}}function me(e=""){return document.createTextNode(e)}function ie(e){return Nt.call(e)}function K(e){return kt.call(e)}function Fr(e,t){if(!F)return ie(e);var n=ie(g);if(n===null)n=g.appendChild(me());else if(t&&n.nodeType!==Ie){var r=me();return n?.before(r),ve(r),r}return t&&Je(n),ve(n),n}function Lr(e,t=!1){if(!F){var n=ie(e);return n instanceof Comment&&n.data===""?K(n):n}if(t){if(g?.nodeType!==Ie){var r=me();return g?.before(r),ve(r),r}Je(g)}return g}function jr(e,t=1,n=!1){let r=F?g:e;for(var s;t--;)s=r,r=K(r);if(!F)return r;if(n){if(r?.nodeType!==Ie){var a=me();return r===null?s?.after(a):r.before(a),ve(a),a}Je(r)}return ve(r),r}function Hr(e){e.textContent=""}function Yr(){return!1}function Dn(e,t,n){return document.createElementNS(t??Jt,e,void 0)}function Je(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===Ie;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function qr(e,t){if(t){const n=document.body;e.autofocus=!0,He(()=>{document.activeElement===n&&e.focus()})}}let lt=!1;function Fn(){lt||(lt=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(const t of e.target.elements)t.__on_r?.()})},{capture:!0}))}function Qe(e){var t=v,n=d;G(null),$(null);try{return e()}finally{G(t),$(n)}}function Ur(e,t,n,r=n){e.addEventListener(t,()=>Qe(n));const s=e.__on_r;s?e.__on_r=()=>{s(),r(!0)}:e.__on_r=()=>r(!0),Fn()}function Ot(e){d===null&&(v===null&&vn(),_n()),fe&&cn()}function Ln(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function L(e,t){var n=d;n!==null&&(n.f&I)!==0&&(e|=I);var r={ctx:A,deps:null,nodes:null,f:e|T|N,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};w?.register_created_effect(r);var s=r;if((e&_e)!==0)oe!==null?oe.push(r):ae.ensure().schedule(r);else if(t!==null){try{ue(r)}catch(f){throw le(r),f}s.deps===null&&s.teardown===null&&s.nodes===null&&s.first===s.last&&(s.f&Te)===0&&(s=s.first,(e&j)!==0&&(e&Ne)!==0&&s!==null&&(s.f|=Ne))}if(s!==null&&(s.parent=n,n!==null&&Ln(s,n),v!==null&&(v.f&b)!==0&&(e&re)===0)){var a=v;(a.effects??=[]).push(s)}return r}function Mt(){return v!==null&&!C}function jn(e){const t=L(be,null);return y(t,m),t.teardown=e,t}function Vr(e){Ot();var t=d.f,n=!v&&(t&H)!==0&&(t&z)===0;if(n){var r=A;(r.e??=[]).push(e)}else return Ct(e)}function Ct(e){return L(_e|_t,e)}function Br(e){return Ot(),L(be|_t,e)}function Gr(e){ae.ensure();const t=L(re|Te,e);return(n={})=>new Promise(r=>{n.outro?Un(t,()=>{le(t),r(void 0)}):(le(t),r(void 0))})}function $r(e){return L(_e,e)}function zr(e,t){var n=A,r={effect:null,ran:!1,deps:e};n.l.$.push(r),r.effect=It(()=>{if(e(),!r.ran){r.ran=!0;var s=d;try{$(s.parent),Bt(t)}finally{$(s)}}})}function Kr(){var e=A;It(()=>{for(var t of e.l.$){t.deps();var n=t.effect;(n.f&m)!==0&&n.deps!==null&&y(n,D),de(n)&&ue(n),t.ran=!1}})}function Hn(e){return L(ge|Te,e)}function It(e,t=0){return L(be|t,e)}function Wr(e,t=[],n=[],r=[]){xn(r,t,n,s=>{L(be,()=>e(...s.map(J)))})}function Xr(e,t=0){var n=L(j|t,e);return n}function Zr(e,t=0){var n=L(Ge|t,e);return n}function Jr(e){return L(H|Te,e)}function Pt(e){var t=e.teardown;if(t!==null){const n=fe,r=v;ft(!0),G(null);try{t.call(null)}finally{ft(n),G(r)}}}function et(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const s=n.ac;s!==null&&Qe(()=>{s.abort(q)});var r=n.next;(n.f&re)!==0?n.parent=null:le(n,t),n=r}}function Yn(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&H)===0&&le(t),t=n}}function le(e,t=!0){var n=!1;(t||(e.f&un)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(qn(e.nodes.start,e.nodes.end),n=!0),y(e,nt),et(e,t&&!n),Ee(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(const a of r)a.stop();Pt(e),e.f^=nt,e.f|=P;var s=e.parent;s!==null&&s.first!==null&&Dt(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function qn(e,t){for(;e!==null;){var n=e===t?null:K(e);e.remove(),e=n}}function Dt(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function Un(e,t,n=!0){var r=[];Ft(e,r,!0);var s=()=>{n&&le(e),t&&t()},a=r.length;if(a>0){var f=()=>--a||s();for(var i of r)i.out(f)}else s()}function Ft(e,t,n){if((e.f&I)===0){e.f^=I;var r=e.nodes&&e.nodes.t;if(r!==null)for(const i of r)(i.is_global||n)&&t.push(i);for(var s=e.first;s!==null;){var a=s.next,f=(s.f&Ne)!==0||(s.f&H)!==0&&(e.f&j)!==0;Ft(s,t,f?n:!1),s=a}}}function Qr(e){Lt(e,!0)}function Lt(e,t){if((e.f&I)!==0){e.f^=I,(e.f&m)===0&&(y(e,T),ae.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,s=(n.f&Ne)!==0||(n.f&H)!==0;Lt(n,s?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(const f of a)(f.is_global||t)&&f.in()}}function es(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var s=n===r?null:K(n);t.append(n),n=s}}let xe=!1,fe=!1;function ft(e){fe=e}let v=null,C=!1;function G(e){v=e}let d=null;function $(e){d=e}let k=null;function Vn(e){v!==null&&(k===null?k=[e]:k.push(e))}let S=null,R=0,x=null;function Bn(e){x=e}let jt=1,Z=0,te=Z;function ut(e){te=e}function Ht(){return++jt}function de(e){var t=e.f;if((t&T)!==0)return!0;if(t&b&&(e.f&=~se),(t&D)!==0){for(var n=e.deps,r=n.length,s=0;se.wv)return!0}(t&N)!==0&&M===null&&y(e,m)}return!1}function Yt(e,t,n=!0){var r=e.reactions;if(r!==null&&!(k!==null&&ce.call(k,e)))for(var s=0;s{e.ac.abort(q)}),e.ac=null);try{e.f|=je;var u=e.fn,c=u();e.f|=z;var _=e.deps,p=w?.is_fork;if(S!==null){var h;if(p||Ee(e,R),_!==null&&R>0)for(_.length=R+S.length,h=0;he});function zn(e){return $n?.createHTML(e)??e}function Gt(e){var t=Dn("template");return t.innerHTML=zn(e.replaceAll("","")),t.content}function ne(e,t){var n=d;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function rs(e,t){var n=(t&zt)!==0,r=(t&Kt)!==0,s,a=!e.startsWith("");return()=>{if(F)return ne(g,null),g;s===void 0&&(s=Gt(a?e:""+e),n||(s=ie(s)));var f=r||xt?document.importNode(s,!0):s.cloneNode(!0);if(n){var i=ie(f),l=f.lastChild;ne(i,l)}else ne(f,f);return f}}function Kn(e,t,n="svg"){var r=!e.startsWith(""),s=`<${n}>${r?e:""+e}`,a;return()=>{if(F)return ne(g,null),g;if(!a){var f=Gt(s),i=ie(f);a=ie(i)}var l=a.cloneNode(!0);return ne(l,l),l}}function ss(e,t){return Kn(e,t,"svg")}function as(){if(F)return ne(g,null),g;var e=document.createDocumentFragment(),t=document.createComment(""),n=me();return e.append(t,n),ne(t,n),e}function is(e,t){if(F){var n=d;((n.f&z)===0||n.nodes.end===null)&&(n.nodes.end=g),yn();return}e!==null&&e.before(t)}export{Hr as $,xr as A,Ar as B,g as C,vt as D,Jn as E,Zt as F,Ue as G,Xt as H,w as I,vr as J,Jr as K,yr as L,Yr as M,On as N,en as O,or as P,Xn as Q,er as R,Ze as S,Zn as T,P as U,Qr as V,Un as W,I as X,He as Y,H as Z,Qn as _,is as a,ur as a$,es as a0,le as a1,K as a2,V as a3,pe as a4,Ur as a5,ts as a6,It as a7,d as a8,ne as a9,ae as aA,En as aB,Oe as aC,Te as aD,Er as aE,Tr as aF,Dr as aG,Wt as aH,gr as aI,Gr as aJ,Wn as aK,Ce as aL,Vr as aM,Br as aN,ln as aO,_r as aP,bt as aQ,Zr as aR,br as aS,Pr as aT,Jt as aU,ot as aV,nn as aW,Fn as aX,hr as aY,wr as aZ,xn as a_,qn as aa,$e as ab,Be as ac,Dn as ad,lr as ae,fr as af,Ir as ag,ss as ah,Gt as ai,jn as aj,Qe as ak,cr as al,G as am,$ as an,v as ao,A as ap,$r as aq,nt as ar,Q as as,Ne as at,Mt as au,Fe as av,fn as aw,ir as ax,Tn as ay,ke as az,kr as b,qr as b0,E as b1,we as b2,mr as b3,rr as b4,sr as b5,nr as b6,tr as b7,ar as b8,fe as b9,dr as ba,as as c,Mr as d,rs as e,Lr as f,J as g,Fr as h,jr as i,ns as j,Kr as k,zr as l,Cr as m,Rr as n,me as o,Or as p,Xr as q,Sr as r,U as s,Wr as t,Bt as u,F as v,ve as w,ie as x,yn as y,Nr as z}; diff --git a/website/blog/_astro/translation.BRy61wHY.js b/website/blog/_astro/translation.BRy61wHY.js deleted file mode 100644 index 41c630d..0000000 --- a/website/blog/_astro/translation.BRy61wHY.js +++ /dev/null @@ -1 +0,0 @@ -import{s as _}from"./config.B4FKKqOZ.js";import{t as n,i as c,v as s,a as o,k as r,j as e,z as h,b as u,e as a,c as f}from"./zh_TW.CqrCsd4X.js";const g=a,l={es:f,en:a,en_us:a,en_gb:a,en_au:a,zh_cn:u,zh_tw:h,ja:e,ja_jp:e,ko:r,ko_kr:r,th:o,th_th:o,vi:s,vi_vn:s,id:c,tr:n,tr_tr:n};function m(t){return l[t.toLowerCase()]||g}function j(t){const i=_.lang;return m(i)[t]}export{j as i}; diff --git a/website/blog/_astro/tz1.BlHZqIsL_1lE0B.webp b/website/blog/_astro/tz1.BlHZqIsL_1lE0B.webp deleted file mode 100644 index 45e7434..0000000 Binary files a/website/blog/_astro/tz1.BlHZqIsL_1lE0B.webp and /dev/null differ diff --git a/website/blog/_astro/url-utils.CaIMLrxo.js b/website/blog/_astro/url-utils.CaIMLrxo.js deleted file mode 100644 index a36fd08..0000000 --- a/website/blog/_astro/url-utils.CaIMLrxo.js +++ /dev/null @@ -1 +0,0 @@ -import"./config.B4FKKqOZ.js";import"./zh_TW.CqrCsd4X.js";function u(o,t){const n=o.replace(/^\/|\/$/g,"").toLowerCase(),r=t.replace(/^\/|\/$/g,"").toLowerCase();return n===r}function e(...o){return o.join("/").replace(/\/+/g,"/")}function l(o){return a(`/posts/${o}/`)}function a(o){return e("","/blog/",o)}export{l as g,u as p,a as u}; diff --git a/website/blog/_astro/utils.DonxBMOE.js b/website/blog/_astro/utils.DonxBMOE.js deleted file mode 100644 index a059c1a..0000000 --- a/website/blog/_astro/utils.DonxBMOE.js +++ /dev/null @@ -1 +0,0 @@ -import{aj as m,Y as E,ak as k,al as S,am as _,an as b,ao as T,a8 as L}from"./template.CyUWgh-J.js";const i=Symbol("events"),V=new Set,A=new Set;function I(e,t,n,o={}){function r(a){if(o.capture||M.call(t,a),!a.cancelBubble)return k(()=>n?.call(this,a))}return e.startsWith("pointer")||e.startsWith("touch")||e==="wheel"?E(()=>{t.addEventListener(e,r,o)}):t.addEventListener(e,r,o),r}function x(e,t,n,o,r){var a={capture:o,passive:r},u=I(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&m(()=>{t.removeEventListener(e,u,a)})}function B(e,t,n){(t[i]??={})[e]=n}function D(e){for(var t=0;t{throw l});throw c}}finally{e[i]=t,delete e.currentTarget,_(w),b(y)}}}function W(e){return e.endsWith("capture")&&e!=="gotpointercapture"&&e!=="lostpointercapture"}const P=["beforeinput","click","change","dblclick","contextmenu","focusin","focusout","input","keydown","keyup","mousedown","mousemove","mouseout","mouseover","mouseup","pointerdown","pointermove","pointerout","pointerover","pointerup","touchend","touchmove","touchstart"];function q(e){return P.includes(e)}const N={formnovalidate:"formNoValidate",ismap:"isMap",nomodule:"noModule",playsinline:"playsInline",readonly:"readOnly",defaultvalue:"defaultValue",defaultchecked:"defaultChecked",srcobject:"srcObject",novalidate:"noValidate",allowfullscreen:"allowFullscreen",disablepictureinpicture:"disablePictureInPicture",disableremoteplayback:"disableRemotePlayback"};function C(e){return e=e.toLowerCase(),N[e]??e}const O=["touchstart","touchmove"];function R(e){return O.includes(e)}export{B as a,V as b,W as c,D as d,x as e,I as f,q as g,M as h,R as i,C as n,A as r}; diff --git a/website/blog/_astro/widget-manager.B87vf-Ll.js b/website/blog/_astro/widget-manager.B87vf-Ll.js deleted file mode 100644 index 5918a43..0000000 --- a/website/blog/_astro/widget-manager.B87vf-Ll.js +++ /dev/null @@ -1 +0,0 @@ -import{a as s}from"./config.B4FKKqOZ.js";const i={profile:"../components/widget/Profile.astro",announcement:"../components/widget/Announcement.astro",categories:"../components/widget/Categories.astro",tags:"../components/widget/Tags.astro",toc:"../components/widget/TOC.astro","music-player":"../components/widget/MusicPlayer.svelte",custom:null};class a{config;enabledComponents;constructor(e=s){this.config=e,this.enabledComponents=this.getEnabledComponents()}getEnabledComponents(){return this.config.components.filter(e=>e.enable).sort((e,n)=>e.order-n.order)}getComponentsByPosition(e){return this.enabledComponents.filter(n=>n.position===e)}getAnimationDelay(e,n){return e.animationDelay!==void 0?e.animationDelay:this.config.defaultAnimation.enable?this.config.defaultAnimation.baseDelay+n*this.config.defaultAnimation.increment:0}getComponentClass(e,n){const t=[];return e.class&&t.push(e.class),e.responsive?.hidden&&e.responsive.hidden.forEach(o=>{switch(o){case"mobile":t.push("hidden","md:block");break;case"tablet":t.push("md:hidden","lg:block");break;case"desktop":t.push("lg:hidden");break}}),t.join(" ")}getComponentStyle(e,n){const t=[];e.style&&t.push(e.style);const o=this.getAnimationDelay(e,n);return o>0&&t.push(`animation-delay: ${o}ms`),t.join("; ")}isCollapsed(e,n){return e.responsive?.collapseThreshold?n>=e.responsive.collapseThreshold:!1}getComponentPath(e){return i[e]}shouldShowSidebar(e){return this.config.enable?this.config.responsive.layout[e]==="sidebar":!1}getBreakpoints(){return this.config.responsive.breakpoints}updateConfig(e){this.config={...this.config,...e},this.enabledComponents=this.getEnabledComponents()}addComponent(e){this.config.components.push(e),this.enabledComponents=this.getEnabledComponents()}removeComponent(e){this.config.components=this.config.components.filter(n=>n.type!==e),this.enabledComponents=this.getEnabledComponents()}toggleComponent(e,n){const t=this.config.components.find(o=>o.type===e);t&&(t.enable=n,this.enabledComponents=this.getEnabledComponents())}reorderComponent(e,n){const t=this.config.components.find(o=>o.type===e);t&&(t.order=n,this.enabledComponents=this.getEnabledComponents())}}const d=new a;export{d as w}; diff --git a/website/blog/_astro/zh_TW.CqrCsd4X.js b/website/blog/_astro/zh_TW.CqrCsd4X.js deleted file mode 100644 index 66e725e..0000000 --- a/website/blog/_astro/zh_TW.CqrCsd4X.js +++ /dev/null @@ -1 +0,0 @@ -var e=(t=>(t.home="home",t.about="about",t.archive="archive",t.search="search",t.other="other",t.tags="tags",t.categories="categories",t.recentPosts="recentPosts",t.postList="postList",t.tableOfContents="tableOfContents",t.announcement="announcement",t.announcementClose="announcementClose",t.comments="comments",t.untitled="untitled",t.uncategorized="uncategorized",t.noTags="noTags",t.wordCount="wordCount",t.wordsCount="wordsCount",t.minuteCount="minuteCount",t.minutesCount="minutesCount",t.postCount="postCount",t.postsCount="postsCount",t.themeColor="themeColor",t.lightMode="lightMode",t.darkMode="darkMode",t.systemMode="systemMode",t.more="more",t.author="author",t.publishedAt="publishedAt",t.license="license",t.friends="friends",t.anime="anime",t.diary="diary",t.animeTotal="animeTotal",t.animeWatching="animeWatching",t.animeCompleted="animeCompleted",t.animeStatusWatching="animeStatusWatching",t.animeStatusCompleted="animeStatusCompleted",t.diarySubtitle="diarySubtitle",t.diaryCount="diaryCount",t.diaryImage="diaryImage",t.diaryReply="diaryReply",t.diaryTips="diaryTips",t.diaryMinutesAgo="diaryMinutesAgo",t.diaryHoursAgo="diaryHoursAgo",t.diaryDaysAgo="diaryDaysAgo",t.notFound="notFound",t.notFoundTitle="notFoundTitle",t.notFoundDescription="notFoundDescription",t.backToHome="backToHome",t.playlist="playlist",t.gallery="gallery",t.gallerySubtitle="gallerySubtitle",t.galleryGroups="galleryGroups",t.galleryCreateGroup="galleryCreateGroup",t.galleryGroupName="galleryGroupName",t.galleryGroupDescription="galleryGroupDescription",t.galleryGroupCover="galleryGroupCover",t.galleryUploadImages="galleryUploadImages",t.galleryImageCount="galleryImageCount",t.galleryImagesCount="galleryImagesCount",t.galleryViewAll="galleryViewAll",t.galleryEdit="galleryEdit",t.galleryDelete="galleryDelete",t.gallerySort="gallerySort",t.galleryComments="galleryComments",t.galleryAddComment="galleryAddComment",t.galleryNoGroups="galleryNoGroups",t.galleryNoImages="galleryNoImages",t.galleryCreateFirst="galleryCreateFirst",t.projects="projects",t.projectsSubtitle="projectsSubtitle",t.projectsAll="projectsAll",t.projectsWeb="projectsWeb",t.projectsMobile="projectsMobile",t.projectsDesktop="projectsDesktop",t.projectsOther="projectsOther",t.projectTechStack="projectTechStack",t.projectLiveDemo="projectLiveDemo",t.projectSourceCode="projectSourceCode",t.projectDescription="projectDescription",t.projectStatus="projectStatus",t.projectStatusCompleted="projectStatusCompleted",t.projectStatusInProgress="projectStatusInProgress",t.projectStatusPlanned="projectStatusPlanned",t.projectsTotal="projectsTotal",t.projectsCompleted="projectsCompleted",t.projectsInProgress="projectsInProgress",t.projectsTechStack="projectsTechStack",t.projectsFeatured="projectsFeatured",t.projectsPlanned="projectsPlanned",t.projectsDemo="projectsDemo",t.projectsSource="projectsSource",t.skills="skills",t.skillsSubtitle="skillsSubtitle",t.skillsFrontend="skillsFrontend",t.skillsBackend="skillsBackend",t.skillsDatabase="skillsDatabase",t.skillsTools="skillsTools",t.skillsOther="skillsOther",t.skillLevel="skillLevel",t.skillLevelBeginner="skillLevelBeginner",t.skillLevelIntermediate="skillLevelIntermediate",t.skillLevelAdvanced="skillLevelAdvanced",t.skillLevelExpert="skillLevelExpert",t.skillExperience="skillExperience",t.skillYears="skillYears",t.skillMonths="skillMonths",t.skillsTotal="skillsTotal",t.skillsExpert="skillsExpert",t.skillsAdvanced="skillsAdvanced",t.skillsIntermediate="skillsIntermediate",t.skillsBeginner="skillsBeginner",t.skillsAdvancedTitle="skillsAdvancedTitle",t.skillsProjects="skillsProjects",t.skillsDistribution="skillsDistribution",t.skillsByLevel="skillsByLevel",t.skillsByCategory="skillsByCategory",t.timeline="timeline",t.timelineSubtitle="timelineSubtitle",t.timelineEducation="timelineEducation",t.timelineWork="timelineWork",t.timelineProject="timelineProject",t.timelineAchievement="timelineAchievement",t.timelinePresent="timelinePresent",t.timelineLocation="timelineLocation",t.timelineDescription="timelineDescription",t.timelineMonths="timelineMonths",t.timelineYears="timelineYears",t.timelineTotal="timelineTotal",t.timelineProjects="timelineProjects",t.timelineExperience="timelineExperience",t.timelineCurrent="timelineCurrent",t.timelineHistory="timelineHistory",t.timelineAchievements="timelineAchievements",t.timelineStatistics="timelineStatistics",t.timelineByType="timelineByType",t.timelineWorkExperience="timelineWorkExperience",t.timelineTotalExperience="timelineTotalExperience",t.timelineWorkPositions="timelineWorkPositions",t.timelineCurrentRole="timelineCurrentRole",t.timelineEmployed="timelineEmployed",t.timelineAvailable="timelineAvailable",t))(e||{});const i={[e.home]:"Home",[e.about]:"About",[e.archive]:"Archive",[e.search]:"Search",[e.other]:"Other",[e.tags]:"Tags",[e.categories]:"Categories",[e.recentPosts]:"Recent Posts",[e.postList]:"Post List",[e.tableOfContents]:"Table of Contents",[e.announcement]:"Announcement",[e.announcementClose]:"Close",[e.comments]:"Comments",[e.untitled]:"Untitled",[e.uncategorized]:"Uncategorized",[e.noTags]:"No Tags",[e.wordCount]:"word",[e.wordsCount]:"words",[e.minuteCount]:"minute",[e.minutesCount]:"minutes",[e.postCount]:"post",[e.postsCount]:"posts",[e.themeColor]:"Theme Color",[e.lightMode]:"Light",[e.darkMode]:"Dark",[e.systemMode]:"System",[e.more]:"More",[e.author]:"Author",[e.publishedAt]:"Published at",[e.license]:"License",[e.friends]:"Friends",[e.anime]:"Anime",[e.diary]:"Moments",[e.animeTotal]:"Total",[e.animeWatching]:"Watching",[e.animeCompleted]:"Completed",[e.animeStatusWatching]:"Watching",[e.animeStatusCompleted]:"Completed",[e.diarySubtitle]:"Share life anytime, anywhere",[e.diaryCount]:"moments",[e.diaryImage]:"Image",[e.diaryReply]:"Reply",[e.diaryTips]:"Only showing the latest 30 moments",[e.diaryMinutesAgo]:"minutes ago",[e.diaryHoursAgo]:"hours ago",[e.diaryDaysAgo]:"days ago",[e.notFound]:"404",[e.notFoundTitle]:"Page Not Found",[e.notFoundDescription]:"Sorry, the page you are looking for doesn't exist or has been moved.",[e.backToHome]:"Back to Home",[e.playlist]:"Playlist",[e.gallery]:"Gallery",[e.gallerySubtitle]:"Capture and share beautiful moments",[e.galleryGroups]:"Gallery Groups",[e.galleryCreateGroup]:"Create Group",[e.galleryGroupName]:"Group Name",[e.galleryGroupDescription]:"Group Description",[e.galleryGroupCover]:"Cover Image",[e.galleryUploadImages]:"Upload Images",[e.galleryImageCount]:"image",[e.galleryImagesCount]:"images",[e.galleryViewAll]:"View All",[e.galleryEdit]:"Edit",[e.galleryDelete]:"Delete",[e.gallerySort]:"Sort",[e.galleryComments]:"Comments",[e.galleryAddComment]:"Add Comment",[e.galleryNoGroups]:"No gallery groups yet",[e.galleryNoImages]:"No images in this group",[e.galleryCreateFirst]:"Create your first gallery group",[e.projects]:"Projects",[e.projectsSubtitle]:"Showcase of my development projects",[e.projectsAll]:"All",[e.projectsWeb]:"Web",[e.projectsMobile]:"Mobile",[e.projectsDesktop]:"Desktop",[e.projectsOther]:"Other",[e.projectTechStack]:"Tech Stack",[e.projectLiveDemo]:"Live Demo",[e.projectSourceCode]:"Source Code",[e.projectDescription]:"Description",[e.projectStatus]:"Status",[e.projectStatusCompleted]:"Completed",[e.projectStatusInProgress]:"In Progress",[e.projectStatusPlanned]:"Planned",[e.projectsTotal]:"Total Projects",[e.projectsCompleted]:"Completed",[e.projectsInProgress]:"In Progress",[e.projectsTechStack]:"Tech Stack",[e.projectsFeatured]:"Featured Projects",[e.projectsPlanned]:"Planned",[e.projectsDemo]:"Demo",[e.projectsSource]:"Source",[e.skills]:"Skills",[e.skillsSubtitle]:"My technical skills and expertise",[e.skillsFrontend]:"Frontend",[e.skillsBackend]:"Backend",[e.skillsDatabase]:"Database",[e.skillsTools]:"Tools",[e.skillsOther]:"Other",[e.skillLevel]:"Level",[e.skillLevelBeginner]:"Beginner",[e.skillLevelIntermediate]:"Intermediate",[e.skillLevelAdvanced]:"Advanced",[e.skillLevelExpert]:"Expert",[e.skillExperience]:"Experience",[e.skillYears]:"years",[e.skillMonths]:"months",[e.skillsTotal]:"Total Skills",[e.skillsExpert]:"Expert",[e.skillsAdvanced]:"Advanced",[e.skillsIntermediate]:"Intermediate",[e.skillsBeginner]:"Beginner",[e.skillsAdvancedTitle]:"Professional Skills",[e.skillsProjects]:"Related Projects",[e.skillsDistribution]:"Skills Distribution",[e.skillsByLevel]:"By Level",[e.skillsByCategory]:"By Category",[e.timeline]:"Timeline",[e.timelineSubtitle]:"My journey and milestones",[e.timelineEducation]:"Education",[e.timelineWork]:"Work",[e.timelineProject]:"Project",[e.timelineAchievement]:"Achievement",[e.timelinePresent]:"Present",[e.timelineLocation]:"Location",[e.timelineDescription]:"Description",[e.timelineMonths]:"months",[e.timelineYears]:"years",[e.timelineTotal]:"Total",[e.timelineProjects]:"Projects",[e.timelineExperience]:"Experience",[e.timelineCurrent]:"Current Status",[e.timelineHistory]:"History",[e.timelineAchievements]:"Achievements",[e.timelineStatistics]:"Statistics",[e.timelineByType]:"By Type",[e.timelineWorkExperience]:"Work Experience",[e.timelineTotalExperience]:"Total Experience",[e.timelineWorkPositions]:"Positions",[e.timelineCurrentRole]:"Current Status",[e.timelineEmployed]:"Employed",[e.timelineAvailable]:"Available"},l={[e.home]:"Inicio",[e.about]:"Acerca de nosotros",[e.archive]:"Archivo",[e.search]:"Buscar",[e.tags]:"Etiquetas",[e.categories]:"Categorías",[e.recentPosts]:"Publicaciones recientes",[e.comments]:"Comentarios",[e.untitled]:"Sin título",[e.uncategorized]:"Sin categoría",[e.noTags]:"Sin etiquetas",[e.wordCount]:"palabra",[e.wordsCount]:"palabras",[e.minuteCount]:"minuto",[e.minutesCount]:"minutos",[e.postCount]:"publicación",[e.postsCount]:"publicaciones",[e.themeColor]:"Color del tema",[e.lightMode]:"Claro",[e.darkMode]:"Oscuro",[e.systemMode]:"Sistema",[e.more]:"Más",[e.author]:"Autor",[e.publishedAt]:"Publicado el",[e.license]:"Licencia",[e.friends]:"Amigos",[e.anime]:"Anime",[e.diary]:"Momentos",[e.animeTotal]:"Total",[e.animeWatching]:"Viendo",[e.animeCompleted]:"Completado",[e.animeStatusWatching]:"Viendo",[e.animeStatusCompleted]:"Completado",[e.diarySubtitle]:"Comparte la vida en cualquier momento y lugar",[e.diaryCount]:"momentos",[e.diaryImage]:"Imagen",[e.diaryReply]:"Responder",[e.diaryTips]:"Solo se muestran los últimos 30 momentos",[e.diaryMinutesAgo]:"minutos atrás",[e.diaryHoursAgo]:"horas atrás",[e.diaryDaysAgo]:"días atrás",[e.notFound]:"404",[e.notFoundTitle]:"Página no encontrada",[e.notFoundDescription]:"Lo sentimos, la página que buscas no existe o ha sido movida.",[e.backToHome]:"Volver al inicio",[e.playlist]:"Lista de reproducción",[e.projects]:"Proyectos",[e.projectsSubtitle]:"Muestra de mis proyectos de desarrollo",[e.projectsAll]:"Todos",[e.projectsWeb]:"Web",[e.projectsMobile]:"Móvil",[e.projectsDesktop]:"Escritorio",[e.projectsOther]:"Otros",[e.projectTechStack]:"Stack Tecnológico",[e.projectLiveDemo]:"Demo en Vivo",[e.projectSourceCode]:"Código Fuente",[e.projectDescription]:"Descripción",[e.projectStatus]:"Estado",[e.projectStatusCompleted]:"Completado",[e.projectStatusInProgress]:"En Progreso",[e.projectStatusPlanned]:"Planificado",[e.projectsTotal]:"Total de Proyectos",[e.projectsCompleted]:"Completados",[e.projectsInProgress]:"En Progreso",[e.projectsTechStack]:"Stack Tecnológico",[e.projectsFeatured]:"Proyectos Destacados",[e.projectsPlanned]:"Planificados",[e.projectsDemo]:"Demo",[e.projectsSource]:"Código",[e.skills]:"Habilidades",[e.skillsSubtitle]:"Mis habilidades técnicas y experiencia",[e.skillsFrontend]:"Frontend",[e.skillsBackend]:"Backend",[e.skillsDatabase]:"Base de Datos",[e.skillsTools]:"Herramientas",[e.skillsOther]:"Otras Habilidades",[e.skillLevel]:"Nivel de Competencia",[e.skillLevelBeginner]:"Principiante",[e.skillLevelIntermediate]:"Intermedio",[e.skillLevelAdvanced]:"Avanzado",[e.skillLevelExpert]:"Experto",[e.skillExperience]:"Experiencia",[e.skillYears]:"años",[e.skillMonths]:"meses",[e.skillsTotal]:"Total de Habilidades",[e.skillsExpert]:"Experto",[e.skillsAdvanced]:"Avanzado",[e.skillsIntermediate]:"Intermedio",[e.skillsBeginner]:"Principiante",[e.skillsAdvancedTitle]:"Habilidades Avanzadas",[e.skillsProjects]:"Proyectos",[e.skillsDistribution]:"Distribución de Habilidades",[e.skillsByLevel]:"Por Nivel",[e.skillsByCategory]:"Por Categoría",[e.timeline]:"Cronología",[e.timelineSubtitle]:"Mi viaje de desarrollo y experiencias",[e.timelineEducation]:"Educación",[e.timelineWork]:"Trabajo",[e.timelineProject]:"Proyecto",[e.timelineAchievement]:"Logro",[e.timelinePresent]:"Presente",[e.timelineLocation]:"Ubicación",[e.timelineDescription]:"Descripción",[e.timelineMonths]:"meses",[e.timelineYears]:"años",[e.timelineTotal]:"Total",[e.timelineProjects]:"Proyectos",[e.timelineExperience]:"Experiencia",[e.timelineCurrent]:"Actual",[e.timelineHistory]:"Historial",[e.timelineAchievements]:"Logros",[e.timelineStatistics]:"Estadísticas",[e.timelineByType]:"Por Tipo",[e.timelineWorkExperience]:"Experiencia Laboral",[e.timelineTotalExperience]:"Experiencia Total",[e.timelineWorkPositions]:"Posiciones de Trabajo",[e.timelineCurrentRole]:"Rol Actual",[e.timelineEmployed]:"Empleado",[e.timelineAvailable]:"Disponible"},o={[e.home]:"Beranda",[e.about]:"Tentang Kami",[e.archive]:"Arsip",[e.search]:"Cari",[e.tags]:"Tag",[e.categories]:"Kategori",[e.recentPosts]:"Postingan Terbaru",[e.comments]:"Komentar",[e.untitled]:"Tanpa Judul",[e.uncategorized]:"Tanpa Kategori",[e.noTags]:"Tanpa Tag",[e.wordCount]:"kata",[e.wordsCount]:"kata",[e.minuteCount]:"menit",[e.minutesCount]:"menit",[e.postCount]:"postingan",[e.postsCount]:"postingan",[e.themeColor]:"Warna Tema",[e.lightMode]:"Terang",[e.darkMode]:"Gelap",[e.systemMode]:"Sistem",[e.more]:"Lainnya",[e.author]:"Penulis",[e.publishedAt]:"Diterbitkan pada",[e.license]:"Lisensi",[e.friends]:"Teman",[e.anime]:"Anime",[e.diary]:"Momen",[e.animeTotal]:"Total",[e.animeWatching]:"Sedang Ditonton",[e.animeCompleted]:"Selesai",[e.animeStatusWatching]:"Sedang Ditonton",[e.animeStatusCompleted]:"Selesai",[e.diarySubtitle]:"Berbagi kehidupan kapan saja, di mana saja",[e.diaryCount]:"momen",[e.diaryImage]:"Gambar",[e.diaryReply]:"Balas",[e.diaryTips]:"Hanya menampilkan 30 momen terbaru",[e.diaryMinutesAgo]:"menit yang lalu",[e.diaryHoursAgo]:"jam yang lalu",[e.diaryDaysAgo]:"hari yang lalu",[e.notFound]:"404",[e.notFoundTitle]:"Halaman Tidak Ditemukan",[e.notFoundDescription]:"Maaf, halaman yang Anda cari tidak ada atau telah dipindahkan.",[e.backToHome]:"Kembali ke Beranda",[e.playlist]:"Daftar Putar",[e.projects]:"Proyek",[e.projectsSubtitle]:"Showcase proyek pengembangan saya",[e.projectsAll]:"Semua",[e.projectsWeb]:"Web",[e.projectsMobile]:"Mobile",[e.projectsDesktop]:"Desktop",[e.projectsOther]:"Lainnya",[e.projectTechStack]:"Tech Stack",[e.projectLiveDemo]:"Demo Langsung",[e.projectSourceCode]:"Kode Sumber",[e.projectDescription]:"Deskripsi",[e.projectStatus]:"Status",[e.projectStatusCompleted]:"Selesai",[e.projectStatusInProgress]:"Sedang Berlangsung",[e.projectStatusPlanned]:"Direncanakan",[e.projectsTotal]:"Total Proyek",[e.projectsCompleted]:"Selesai",[e.projectsInProgress]:"Sedang Berlangsung",[e.projectsTechStack]:"Tech Stack",[e.projectsFeatured]:"Proyek Unggulan",[e.projectsPlanned]:"Direncanakan",[e.projectsDemo]:"Demo",[e.projectsSource]:"Sumber",[e.skills]:"Keahlian",[e.skillsSubtitle]:"Keahlian teknis dan keahlian saya",[e.skillsFrontend]:"Frontend",[e.skillsBackend]:"Backend",[e.skillsDatabase]:"Database",[e.skillsTools]:"Alat",[e.skillsOther]:"Keahlian Lainnya",[e.skillLevel]:"Tingkat Keahlian",[e.skillLevelBeginner]:"Pemula",[e.skillLevelIntermediate]:"Menengah",[e.skillLevelAdvanced]:"Lanjutan",[e.skillLevelExpert]:"Ahli",[e.skillExperience]:"Pengalaman",[e.skillYears]:"tahun",[e.skillMonths]:"bulan",[e.skillsTotal]:"Total Keahlian",[e.skillsExpert]:"Ahli",[e.skillsAdvanced]:"Lanjutan",[e.skillsIntermediate]:"Menengah",[e.skillsBeginner]:"Pemula",[e.skillsAdvancedTitle]:"Keahlian Lanjutan",[e.skillsProjects]:"Proyek",[e.skillsDistribution]:"Distribusi Keahlian",[e.skillsByLevel]:"Berdasarkan Level",[e.skillsByCategory]:"Berdasarkan Kategori",[e.timeline]:"Timeline",[e.timelineSubtitle]:"Perjalanan pengembangan dan pengalaman saya",[e.timelineEducation]:"Pendidikan",[e.timelineWork]:"Pekerjaan",[e.timelineProject]:"Proyek",[e.timelineAchievement]:"Pencapaian",[e.timelinePresent]:"Sekarang",[e.timelineLocation]:"Lokasi",[e.timelineDescription]:"Deskripsi",[e.timelineMonths]:"bulan",[e.timelineYears]:"tahun",[e.timelineTotal]:"Total",[e.timelineProjects]:"Proyek",[e.timelineExperience]:"Pengalaman",[e.timelineCurrent]:"Saat Ini",[e.timelineHistory]:"Riwayat",[e.timelineAchievements]:"Pencapaian",[e.timelineStatistics]:"Statistik",[e.timelineByType]:"Berdasarkan Tipe",[e.timelineWorkExperience]:"Pengalaman Kerja",[e.timelineTotalExperience]:"Total Pengalaman",[e.timelineWorkPositions]:"Posisi Kerja",[e.timelineCurrentRole]:"Peran Saat Ini",[e.timelineEmployed]:"Bekerja",[e.timelineAvailable]:"Tersedia"},s={[e.home]:"Home",[e.about]:"私たちについて",[e.archive]:"Archive",[e.search]:"検索",[e.tags]:"タグ",[e.categories]:"カテゴリ",[e.recentPosts]:"最近の投稿",[e.postList]:"記事一覧",[e.tableOfContents]:"目次",[e.announcement]:"お知らせ",[e.announcementClose]:"閉じる",[e.comments]:"コメント",[e.untitled]:"タイトルなし",[e.uncategorized]:"カテゴリなし",[e.noTags]:"タグなし",[e.wordCount]:"文字",[e.wordsCount]:"文字",[e.minuteCount]:"分",[e.minutesCount]:"分",[e.postCount]:"件の投稿",[e.postsCount]:"件の投稿",[e.themeColor]:"テーマカラー",[e.lightMode]:"ライト",[e.darkMode]:"ダーク",[e.systemMode]:"システム",[e.more]:"もっと",[e.author]:"作者",[e.publishedAt]:"公開日",[e.license]:"ライセンス",[e.friends]:"友達",[e.anime]:"アニメ",[e.diary]:"つぶやき",[e.animeTotal]:"合計",[e.animeWatching]:"視聴中",[e.animeCompleted]:"視聴済み",[e.animeStatusWatching]:"視聴中",[e.animeStatusCompleted]:"視聴済み",[e.diarySubtitle]:"いつでもどこでも、生活をシェア",[e.diaryCount]:"件のつぶやき",[e.diaryImage]:"画像",[e.diaryReply]:"返信",[e.diaryTips]:"最新30件のつぶやきのみ表示",[e.diaryMinutesAgo]:"分前",[e.diaryHoursAgo]:"時間前",[e.diaryDaysAgo]:"日前",[e.notFound]:"404",[e.notFoundTitle]:"ページが見つかりません",[e.notFoundDescription]:"申し訳ございませんが、お探しのページは存在しないか移動されました。",[e.backToHome]:"ホームに戻る",[e.playlist]:"プレイリスト",[e.projects]:"プロジェクト",[e.projectsSubtitle]:"開発プロジェクトのショーケース",[e.projectsAll]:"すべて",[e.projectsWeb]:"ウェブ",[e.projectsMobile]:"モバイル",[e.projectsDesktop]:"デスクトップ",[e.projectsOther]:"その他",[e.projectTechStack]:"技術スタック",[e.projectLiveDemo]:"ライブデモ",[e.projectSourceCode]:"ソースコード",[e.projectDescription]:"説明",[e.projectStatus]:"ステータス",[e.projectStatusCompleted]:"完了",[e.projectStatusInProgress]:"進行中",[e.projectStatusPlanned]:"計画中",[e.projectsTotal]:"総プロジェクト数",[e.projectsCompleted]:"完了",[e.projectsInProgress]:"進行中",[e.projectsTechStack]:"技術スタック",[e.projectsFeatured]:"注目プロジェクト",[e.projectsPlanned]:"計画中",[e.projectsDemo]:"デモ",[e.projectsSource]:"ソース",[e.skills]:"スキル",[e.skillsSubtitle]:"技術スキルと専門知識",[e.skillsFrontend]:"フロントエンド",[e.skillsBackend]:"バックエンド",[e.skillsDatabase]:"データベース",[e.skillsTools]:"ツール",[e.skillsOther]:"その他のスキル",[e.skillLevel]:"習熟度",[e.skillLevelBeginner]:"初心者",[e.skillLevelIntermediate]:"中級者",[e.skillLevelAdvanced]:"上級者",[e.skillLevelExpert]:"エキスパート",[e.skillExperience]:"経験",[e.skillYears]:"年",[e.skillMonths]:"ヶ月",[e.skillsTotal]:"総スキル数",[e.skillsExpert]:"エキスパート",[e.skillsAdvanced]:"上級者",[e.skillsIntermediate]:"中級者",[e.skillsBeginner]:"初心者",[e.skillsAdvancedTitle]:"上級スキル",[e.skillsProjects]:"プロジェクト",[e.skillsDistribution]:"スキル分布",[e.skillsByLevel]:"レベル別",[e.skillsByCategory]:"カテゴリ別",[e.timeline]:"タイムライン",[e.timelineSubtitle]:"開発の歩みと経験",[e.timelineEducation]:"教育",[e.timelineWork]:"仕事",[e.timelineProject]:"プロジェクト",[e.timelineAchievement]:"成果",[e.timelinePresent]:"現在",[e.timelineLocation]:"場所",[e.timelineDescription]:"説明",[e.timelineMonths]:"ヶ月",[e.timelineYears]:"年",[e.timelineTotal]:"合計",[e.timelineProjects]:"プロジェクト",[e.timelineExperience]:"経験",[e.timelineCurrent]:"現在",[e.timelineHistory]:"履歴",[e.timelineAchievements]:"成果",[e.timelineStatistics]:"統計",[e.timelineByType]:"タイプ別",[e.timelineWorkExperience]:"職歴",[e.timelineTotalExperience]:"総経験",[e.timelineWorkPositions]:"職位",[e.timelineCurrentRole]:"現在の役職",[e.timelineEmployed]:"在職中",[e.timelineAvailable]:"利用可能"},n={[e.home]:"홈",[e.about]:"회사 소개",[e.archive]:"아카이브",[e.search]:"검색",[e.tags]:"태그",[e.categories]:"카테고리",[e.recentPosts]:"최근 게시물",[e.postList]:"게시물 목록",[e.tableOfContents]:"목차",[e.comments]:"댓글",[e.untitled]:"제목 없음",[e.uncategorized]:"분류되지 않음",[e.noTags]:"태그 없음",[e.wordCount]:"단어",[e.wordsCount]:"단어",[e.minuteCount]:"분",[e.minutesCount]:"분",[e.postCount]:"게시물",[e.postsCount]:"게시물",[e.themeColor]:"테마 색상",[e.lightMode]:"밝은 모드",[e.darkMode]:"어두운 모드",[e.systemMode]:"시스템 모드",[e.more]:"더 보기",[e.author]:"저자",[e.publishedAt]:"게시일",[e.license]:"라이선스",[e.friends]:"친구",[e.anime]:"애니메이션",[e.diary]:"일상",[e.animeTotal]:"총계",[e.animeWatching]:"시청 중",[e.animeCompleted]:"시청 완료",[e.animeStatusWatching]:"시청 중",[e.animeStatusCompleted]:"시청 완료",[e.diarySubtitle]:"언제 어디서나, 일상을 공유",[e.diaryCount]:"개의 일상",[e.diaryImage]:"이미지",[e.diaryReply]:"답글",[e.diaryTips]:"최근 30개의 일상만 표시",[e.diaryMinutesAgo]:"분 전",[e.diaryHoursAgo]:"시간 전",[e.diaryDaysAgo]:"일 전",[e.notFound]:"404",[e.notFoundTitle]:"페이지를 찾을 수 없습니다",[e.notFoundDescription]:"죄송합니다. 찾으시는 페이지가 존재하지 않거나 이동되었습니다.",[e.backToHome]:"홈으로 돌아가기",[e.playlist]:"재생목록",[e.projects]:"프로젝트",[e.projectsSubtitle]:"개발 프로젝트 쇼케이스",[e.projectsAll]:"전체",[e.projectsWeb]:"웹",[e.projectsMobile]:"모바일",[e.projectsDesktop]:"데스크톱",[e.projectsOther]:"기타",[e.projectTechStack]:"기술 스택",[e.projectLiveDemo]:"라이브 데모",[e.projectSourceCode]:"소스 코드",[e.projectDescription]:"설명",[e.projectStatus]:"상태",[e.projectStatusCompleted]:"완료",[e.projectStatusInProgress]:"진행 중",[e.projectStatusPlanned]:"계획됨",[e.projectsTotal]:"총 프로젝트",[e.projectsCompleted]:"완료",[e.projectsInProgress]:"진행 중",[e.projectsTechStack]:"기술 스택",[e.projectsFeatured]:"주요 프로젝트",[e.projectsPlanned]:"계획됨",[e.projectsDemo]:"데모",[e.projectsSource]:"소스",[e.skills]:"스킬",[e.skillsSubtitle]:"기술 스킬과 전문 지식",[e.skillsFrontend]:"프론트엔드",[e.skillsBackend]:"백엔드",[e.skillsDatabase]:"데이터베이스",[e.skillsTools]:"도구",[e.skillsOther]:"기타 스킬",[e.skillLevel]:"숙련도",[e.skillLevelBeginner]:"초급",[e.skillLevelIntermediate]:"중급",[e.skillLevelAdvanced]:"고급",[e.skillLevelExpert]:"전문가",[e.skillExperience]:"경험",[e.skillYears]:"년",[e.skillMonths]:"개월",[e.skillsTotal]:"총 스킬",[e.skillsExpert]:"전문가",[e.skillsAdvanced]:"고급",[e.skillsIntermediate]:"중급",[e.skillsBeginner]:"초급",[e.skillsAdvancedTitle]:"고급 스킬",[e.skillsProjects]:"프로젝트",[e.skillsDistribution]:"스킬 분포",[e.skillsByLevel]:"레벨별",[e.skillsByCategory]:"카테고리별",[e.timeline]:"타임라인",[e.timelineSubtitle]:"개발 여정과 경험",[e.timelineEducation]:"교육",[e.timelineWork]:"업무",[e.timelineProject]:"프로젝트",[e.timelineAchievement]:"성과",[e.timelinePresent]:"현재",[e.timelineLocation]:"위치",[e.timelineDescription]:"설명",[e.timelineMonths]:"개월",[e.timelineYears]:"년",[e.timelineTotal]:"총계",[e.timelineProjects]:"프로젝트",[e.timelineExperience]:"경험",[e.timelineCurrent]:"현재",[e.timelineHistory]:"이력",[e.timelineAchievements]:"성과",[e.timelineStatistics]:"통계",[e.timelineByType]:"유형별",[e.timelineWorkExperience]:"업무 경험",[e.timelineTotalExperience]:"총 경험",[e.timelineWorkPositions]:"업무 포지션",[e.timelineCurrentRole]:"현재 역할",[e.timelineEmployed]:"재직 중",[e.timelineAvailable]:"이용 가능"},a={[e.home]:"หน้าแรก",[e.about]:"เกี่ยวกับเรา",[e.archive]:"คลัง",[e.search]:"ค้นหา",[e.tags]:"ป้ายกำกับ",[e.categories]:"หมวดหมู่",[e.recentPosts]:"โพสต์ล่าสุด",[e.comments]:"ความคิดเห็น",[e.untitled]:"ไม่ได้ตั้งชื่อ",[e.uncategorized]:"ไม่ได้จัดหมวดหมู่",[e.noTags]:"ไม่มีป้ายกำกับ",[e.wordCount]:"คำ",[e.wordsCount]:"คำ",[e.minuteCount]:"นาที",[e.minutesCount]:"นาที",[e.postCount]:"โพสต์",[e.postsCount]:"โพสต์",[e.themeColor]:"สีของธีม",[e.lightMode]:"สว่าง",[e.darkMode]:"มืด",[e.systemMode]:"ตามระบบ",[e.more]:"ดูเพิ่ม",[e.author]:"ผู้เขียน",[e.publishedAt]:"เผยแพร่เมื่อ",[e.license]:"สัญญาอนุญาต",[e.friends]:"เพื่อน",[e.anime]:"อนิเมะ",[e.diary]:"ช่วงเวลา",[e.animeTotal]:"ทั้งหมด",[e.animeWatching]:"กำลังดู",[e.animeCompleted]:"ดูจบแล้ว",[e.animeStatusWatching]:"กำลังดู",[e.animeStatusCompleted]:"ดูจบแล้ว",[e.diarySubtitle]:"แบ่งปันชีวิตได้ทุกที่ทุกเวลา",[e.diaryCount]:"ช่วงเวลา",[e.diaryImage]:"รูปภาพ",[e.diaryReply]:"ตอบกลับ",[e.diaryTips]:"แสดงเฉพาะ 30 ช่วงเวลาล่าสุด",[e.diaryMinutesAgo]:"นาทีที่แล้ว",[e.diaryHoursAgo]:"ชั่วโมงที่แล้ว",[e.diaryDaysAgo]:"วันที่แล้ว",[e.notFound]:"404",[e.notFoundTitle]:"ไม่พบหน้า",[e.notFoundDescription]:"ขออภัย หน้าที่คุณกำลังมองหาไม่มีอยู่หรือถูกย้าย",[e.backToHome]:"กลับสู่หน้าแรก",[e.playlist]:"เพลย์ลิสต์",[e.projects]:"โปรเจกต์",[e.projectsSubtitle]:"แสดงผลงานโปรเจกต์การพัฒนาของฉัน",[e.projectsAll]:"ทั้งหมด",[e.projectsWeb]:"เว็บ",[e.projectsMobile]:"มือถือ",[e.projectsDesktop]:"เดสก์ท็อป",[e.projectsOther]:"อื่นๆ",[e.projectTechStack]:"เทคโนโลยีที่ใช้",[e.projectLiveDemo]:"ดูตัวอย่างสด",[e.projectSourceCode]:"ซอร์สโค้ด",[e.projectDescription]:"คำอธิบาย",[e.projectStatus]:"สถานะ",[e.projectStatusCompleted]:"เสร็จสิ้น",[e.projectStatusInProgress]:"กำลังดำเนินการ",[e.projectStatusPlanned]:"วางแผนไว้",[e.projectsTotal]:"โปรเจกต์ทั้งหมด",[e.projectsCompleted]:"เสร็จสิ้น",[e.projectsInProgress]:"กำลังดำเนินการ",[e.projectsTechStack]:"เทคโนโลยีที่ใช้",[e.projectsFeatured]:"โปรเจกต์เด่น",[e.projectsPlanned]:"วางแผนไว้",[e.projectsDemo]:"ตัวอย่าง",[e.projectsSource]:"ซอร์ส",[e.skills]:"ทักษะ",[e.skillsSubtitle]:"ทักษะทางเทคนิคและความเชี่ยวชาญของฉัน",[e.skillsFrontend]:"ฟรอนต์เอนด์",[e.skillsBackend]:"แบ็กเอนด์",[e.skillsDatabase]:"ฐานข้อมูล",[e.skillsTools]:"เครื่องมือ",[e.skillsOther]:"ทักษะอื่นๆ",[e.skillLevel]:"ระดับความชำนาญ",[e.skillLevelBeginner]:"เริ่มต้น",[e.skillLevelIntermediate]:"ปานกลาง",[e.skillLevelAdvanced]:"ขั้นสูง",[e.skillLevelExpert]:"ผู้เชี่ยวชาญ",[e.skillExperience]:"ประสบการณ์",[e.skillYears]:"ปี",[e.skillMonths]:"เดือน",[e.skillsTotal]:"ทักษะทั้งหมด",[e.skillsExpert]:"ผู้เชี่ยวชาญ",[e.skillsAdvanced]:"ขั้นสูง",[e.skillsIntermediate]:"ปานกลาง",[e.skillsBeginner]:"เริ่มต้น",[e.skillsAdvancedTitle]:"ทักษะขั้นสูง",[e.skillsProjects]:"โปรเจกต์",[e.skillsDistribution]:"การกระจายทักษะ",[e.skillsByLevel]:"ตามระดับ",[e.skillsByCategory]:"ตามหมวดหมู่",[e.timeline]:"ไทม์ไลน์",[e.timelineSubtitle]:"เส้นทางการพัฒนาและประสบการณ์ของฉัน",[e.timelineEducation]:"การศึกษา",[e.timelineWork]:"งาน",[e.timelineProject]:"โปรเจกต์",[e.timelineAchievement]:"ความสำเร็จ",[e.timelinePresent]:"ปัจจุบัน",[e.timelineLocation]:"สถานที่",[e.timelineDescription]:"คำอธิบาย",[e.timelineMonths]:"เดือน",[e.timelineYears]:"ปี",[e.timelineTotal]:"ทั้งหมด",[e.timelineProjects]:"โปรเจกต์",[e.timelineExperience]:"ประสบการณ์",[e.timelineCurrent]:"ปัจจุบัน",[e.timelineHistory]:"ประวัติ",[e.timelineAchievements]:"ความสำเร็จ",[e.timelineStatistics]:"สถิติ",[e.timelineByType]:"ตามประเภท",[e.timelineWorkExperience]:"ประสบการณ์การทำงาน",[e.timelineTotalExperience]:"ประสบการณ์ทั้งหมด",[e.timelineWorkPositions]:"ตำแหน่งงาน",[e.timelineCurrentRole]:"บทบาทปัจจุบัน",[e.timelineEmployed]:"ทำงาน",[e.timelineAvailable]:"ว่าง"},r={[e.home]:"Anasayfa",[e.about]:"Hakkımızda",[e.archive]:"Arşiv",[e.search]:"Ara",[e.tags]:"Taglar",[e.categories]:"Katagoriler",[e.recentPosts]:"Son Paylaşımlar",[e.comments]:"Yorumlar",[e.untitled]:"Başlıksız",[e.uncategorized]:"Katagorisiz",[e.noTags]:"Tag Bulunamadı",[e.wordCount]:"kelime",[e.wordsCount]:"kelime",[e.minuteCount]:"dakika",[e.minutesCount]:"dakika",[e.postCount]:"gönderi",[e.postsCount]:"gönderiler",[e.themeColor]:"Tema Rengi",[e.lightMode]:"Aydınlık",[e.darkMode]:"Koyu",[e.systemMode]:"Sistem",[e.more]:"Daha Fazla",[e.author]:"Yazar",[e.publishedAt]:"Yayınlanma:",[e.license]:"Lisans",[e.friends]:"Arkadaşlar",[e.anime]:"Anime",[e.diary]:"Anlar",[e.animeTotal]:"Toplam",[e.animeWatching]:"İzleniyor",[e.animeCompleted]:"Tamamlandı",[e.animeStatusWatching]:"İzleniyor",[e.animeStatusCompleted]:"Tamamlandı",[e.diarySubtitle]:"Her zaman, her yerde hayatı paylaş",[e.diaryCount]:"gönderi",[e.diaryImage]:"Resim",[e.diaryReply]:"Yanıtla",[e.diaryTips]:"Sadece son 30 gönderi gösteriliyor",[e.diaryMinutesAgo]:"dakika önce",[e.diaryHoursAgo]:"saat önce",[e.diaryDaysAgo]:"gün önce",[e.notFound]:"404",[e.notFoundTitle]:"Sayfa Bulunamadı",[e.notFoundDescription]:"Üzgünüz, aradığınız sayfa mevcut değil veya taşınmış.",[e.backToHome]:"Ana Sayfaya Dön",[e.playlist]:"Çalma Listesi",[e.projects]:"Projeler",[e.projectsSubtitle]:"Geliştirme projelerimin vitrini",[e.projectsAll]:"Tümü",[e.projectsWeb]:"Web",[e.projectsMobile]:"Mobil",[e.projectsDesktop]:"Masaüstü",[e.projectsOther]:"Diğer",[e.projectTechStack]:"Teknoloji Yığını",[e.projectLiveDemo]:"Canlı Demo",[e.projectSourceCode]:"Kaynak Kodu",[e.projectDescription]:"Açıklama",[e.projectStatus]:"Durum",[e.projectStatusCompleted]:"Tamamlandı",[e.projectStatusInProgress]:"Devam Ediyor",[e.projectStatusPlanned]:"Planlandı",[e.projectsTotal]:"Toplam Proje",[e.projectsCompleted]:"Tamamlandı",[e.projectsInProgress]:"Devam Ediyor",[e.projectsTechStack]:"Teknoloji Yığını",[e.projectsFeatured]:"Öne Çıkan Projeler",[e.projectsPlanned]:"Planlandı",[e.projectsDemo]:"Demo",[e.projectsSource]:"Kaynak",[e.skills]:"Beceriler",[e.skillsSubtitle]:"Teknik becerilerim ve uzmanlığım",[e.skillsFrontend]:"Frontend",[e.skillsBackend]:"Backend",[e.skillsDatabase]:"Veritabanı",[e.skillsTools]:"Araçlar",[e.skillsOther]:"Diğer Beceriler",[e.skillLevel]:"Yeterlilik Seviyesi",[e.skillLevelBeginner]:"Başlangıç",[e.skillLevelIntermediate]:"Orta",[e.skillLevelAdvanced]:"İleri",[e.skillLevelExpert]:"Uzman",[e.skillExperience]:"Deneyim",[e.skillYears]:"yıl",[e.skillMonths]:"ay",[e.skillsTotal]:"Toplam Beceri",[e.skillsExpert]:"Uzman",[e.skillsAdvanced]:"İleri",[e.skillsIntermediate]:"Orta",[e.skillsBeginner]:"Başlangıç",[e.skillsAdvancedTitle]:"İleri Beceriler",[e.skillsProjects]:"Projeler",[e.skillsDistribution]:"Beceri Dağılımı",[e.skillsByLevel]:"Seviyeye Göre",[e.skillsByCategory]:"Kategoriye Göre",[e.timeline]:"Zaman Çizelgesi",[e.timelineSubtitle]:"Geliştirme yolculuğum ve deneyimlerim",[e.timelineEducation]:"Eğitim",[e.timelineWork]:"İş",[e.timelineProject]:"Proje",[e.timelineAchievement]:"Başarı",[e.timelinePresent]:"Şu An",[e.timelineLocation]:"Konum",[e.timelineDescription]:"Açıklama",[e.timelineMonths]:"ay",[e.timelineYears]:"yıl",[e.timelineTotal]:"Toplam",[e.timelineProjects]:"Projeler",[e.timelineExperience]:"Deneyim",[e.timelineCurrent]:"Şu An",[e.timelineHistory]:"Geçmiş",[e.timelineAchievements]:"Başarılar",[e.timelineStatistics]:"İstatistikler",[e.timelineByType]:"Türe Göre",[e.timelineWorkExperience]:"İş Deneyimi",[e.timelineTotalExperience]:"Toplam Deneyim",[e.timelineWorkPositions]:"İş Pozisyonları",[e.timelineCurrentRole]:"Mevcut Rol",[e.timelineEmployed]:"Çalışıyor",[e.timelineAvailable]:"Müsait"},c={[e.home]:"Trang chủ",[e.about]:"Về chúng tôi",[e.archive]:"Kho bài",[e.search]:"Tìm kiếm",[e.tags]:"Thẻ",[e.categories]:"Danh mục",[e.recentPosts]:"Bài viết mới nhất",[e.comments]:"Bình luận",[e.untitled]:"Không tiêu đề",[e.uncategorized]:"Chưa phân loại",[e.noTags]:"Chưa có thẻ",[e.wordCount]:"từ",[e.wordsCount]:"từ",[e.minuteCount]:"phút đọc",[e.minutesCount]:"phút đọc",[e.postCount]:"bài viết",[e.postsCount]:"bài viết",[e.themeColor]:"Màu giao diện",[e.lightMode]:"Sáng",[e.darkMode]:"Tối",[e.systemMode]:"Hệ thống",[e.more]:"Thêm",[e.author]:"Tác giả",[e.publishedAt]:"Đăng vào lúc",[e.license]:"Giấy phép bản quyền",[e.friends]:"Bạn bè",[e.anime]:"Anime",[e.diary]:"Khoảnh khắc",[e.animeTotal]:"Tổng số",[e.animeWatching]:"Đang xem",[e.animeCompleted]:"Đã hoàn thành",[e.animeStatusWatching]:"Đang xem",[e.animeStatusCompleted]:"Đã hoàn thành",[e.diarySubtitle]:"Chia sẻ cuộc sống mọi lúc, mọi nơi",[e.diaryCount]:"bài viết",[e.diaryImage]:"Hình ảnh",[e.diaryReply]:"Trả lời",[e.diaryTips]:"Chỉ hiển thị 30 khoảnh khắc gần nhất",[e.diaryMinutesAgo]:"phút trước",[e.diaryHoursAgo]:"giờ trước",[e.diaryDaysAgo]:"ngày trước",[e.notFound]:"404",[e.notFoundTitle]:"Không tìm thấy trang",[e.notFoundDescription]:"Xin lỗi, trang bạn đang tìm kiếm không tồn tại hoặc đã được di chuyển.",[e.backToHome]:"Quay về trang chủ",[e.playlist]:"Danh sách phát",[e.projects]:"Dự án",[e.projectsSubtitle]:"Giới thiệu các dự án phát triển của tôi",[e.projectsAll]:"Tất cả",[e.projectsWeb]:"Web",[e.projectsMobile]:"Di động",[e.projectsDesktop]:"Máy tính",[e.projectsOther]:"Khác",[e.projectTechStack]:"Công nghệ",[e.projectLiveDemo]:"Demo trực tiếp",[e.projectSourceCode]:"Mã nguồn",[e.projectDescription]:"Mô tả",[e.projectStatus]:"Trạng thái",[e.projectStatusCompleted]:"Hoàn thành",[e.projectStatusInProgress]:"Đang thực hiện",[e.projectStatusPlanned]:"Đã lên kế hoạch",[e.projectsTotal]:"Tổng số dự án",[e.projectsCompleted]:"Hoàn thành",[e.projectsInProgress]:"Đang thực hiện",[e.projectsTechStack]:"Công nghệ",[e.projectsFeatured]:"Dự án nổi bật",[e.projectsPlanned]:"Đã lên kế hoạch",[e.projectsDemo]:"Demo",[e.projectsSource]:"Nguồn",[e.skills]:"Kỹ năng",[e.skillsSubtitle]:"Kỹ năng kỹ thuật và chuyên môn của tôi",[e.skillsFrontend]:"Frontend",[e.skillsBackend]:"Backend",[e.skillsDatabase]:"Cơ sở dữ liệu",[e.skillsTools]:"Công cụ",[e.skillsOther]:"Kỹ năng khác",[e.skillLevel]:"Trình độ",[e.skillLevelBeginner]:"Mới bắt đầu",[e.skillLevelIntermediate]:"Trung cấp",[e.skillLevelAdvanced]:"Nâng cao",[e.skillLevelExpert]:"Chuyên gia",[e.skillExperience]:"Kinh nghiệm",[e.skillYears]:"năm",[e.skillMonths]:"tháng",[e.skillsTotal]:"Tổng kỹ năng",[e.skillsExpert]:"Chuyên gia",[e.skillsAdvanced]:"Nâng cao",[e.skillsIntermediate]:"Trung cấp",[e.skillsBeginner]:"Mới bắt đầu",[e.skillsAdvancedTitle]:"Kỹ năng nâng cao",[e.skillsProjects]:"Dự án",[e.skillsDistribution]:"Phân bố kỹ năng",[e.skillsByLevel]:"Theo trình độ",[e.skillsByCategory]:"Theo danh mục",[e.timeline]:"Dòng thời gian",[e.timelineSubtitle]:"Hành trình phát triển và kinh nghiệm của tôi",[e.timelineEducation]:"Giáo dục",[e.timelineWork]:"Công việc",[e.timelineProject]:"Dự án",[e.timelineAchievement]:"Thành tựu",[e.timelinePresent]:"Hiện tại",[e.timelineLocation]:"Địa điểm",[e.timelineDescription]:"Mô tả",[e.timelineMonths]:"tháng",[e.timelineYears]:"năm",[e.timelineTotal]:"Tổng cộng",[e.timelineProjects]:"Dự án",[e.timelineExperience]:"Kinh nghiệm",[e.timelineCurrent]:"Hiện tại",[e.timelineHistory]:"Lịch sử",[e.timelineAchievements]:"Thành tựu",[e.timelineStatistics]:"Thống kê",[e.timelineByType]:"Theo loại",[e.timelineWorkExperience]:"Kinh nghiệm làm việc",[e.timelineTotalExperience]:"Tổng kinh nghiệm",[e.timelineWorkPositions]:"Vị trí công việc",[e.timelineCurrentRole]:"Vai trò hiện tại",[e.timelineEmployed]:"Đang làm việc",[e.timelineAvailable]:"Có thể làm việc"},m={[e.home]:"主页",[e.about]:"关于我们",[e.archive]:"归档",[e.search]:"搜索",[e.other]:"其他",[e.tags]:"标签",[e.categories]:"分类",[e.recentPosts]:"最新文章",[e.postList]:"文章列表",[e.tableOfContents]:"目录",[e.announcement]:"公告",[e.announcementClose]:"关闭",[e.comments]:"评论",[e.friends]:"友链",[e.untitled]:"无标题",[e.uncategorized]:"未分类",[e.noTags]:"无标签",[e.wordCount]:"字",[e.wordsCount]:"字",[e.minuteCount]:"分钟",[e.minutesCount]:"分钟",[e.postCount]:"篇文章",[e.postsCount]:"篇文章",[e.themeColor]:"主题色",[e.lightMode]:"亮色",[e.darkMode]:"暗色",[e.systemMode]:"跟随系统",[e.more]:"更多",[e.author]:"作者",[e.publishedAt]:"发布于",[e.license]:"许可协议",[e.anime]:"追番",[e.diary]:"日记",[e.animeTotal]:"总数",[e.animeWatching]:"追番中",[e.animeCompleted]:"已追完",[e.animeStatusWatching]:"追番中",[e.animeStatusCompleted]:"已追完",[e.diarySubtitle]:"随时随地,分享生活",[e.diaryCount]:"条短文",[e.diaryImage]:"图片",[e.diaryReply]:"回复",[e.diaryTips]:"只展示最近30条日记",[e.diaryMinutesAgo]:"分钟前",[e.diaryHoursAgo]:"小时前",[e.diaryDaysAgo]:"天前",[e.notFound]:"404",[e.notFoundTitle]:"页面未找到",[e.notFoundDescription]:"抱歉,您访问的页面不存在或已被移动。",[e.backToHome]:"返回首页",[e.playlist]:"播放列表",[e.gallery]:"相册",[e.gallerySubtitle]:"记录和分享美好瞬间",[e.galleryGroups]:"相册组",[e.galleryCreateGroup]:"创建相册组",[e.galleryGroupName]:"相册组名称",[e.galleryGroupDescription]:"相册组描述",[e.galleryGroupCover]:"封面图片",[e.galleryUploadImages]:"上传图片",[e.galleryImageCount]:"张图片",[e.galleryImagesCount]:"张图片",[e.galleryViewAll]:"查看全部",[e.galleryEdit]:"编辑",[e.galleryDelete]:"删除",[e.gallerySort]:"排序",[e.galleryComments]:"评论",[e.galleryAddComment]:"添加评论",[e.galleryNoGroups]:"暂无相册组",[e.galleryNoImages]:"该相册组暂无图片",[e.galleryCreateFirst]:"创建您的第一个相册组",[e.projects]:"项目展示",[e.projectsSubtitle]:"我的开发项目作品集",[e.projectsAll]:"全部",[e.projectsWeb]:"网页应用",[e.projectsMobile]:"移动应用",[e.projectsDesktop]:"桌面应用",[e.projectsOther]:"其他",[e.projectTechStack]:"技术栈",[e.projectLiveDemo]:"在线演示",[e.projectSourceCode]:"源代码",[e.projectDescription]:"项目描述",[e.projectStatus]:"状态",[e.projectStatusCompleted]:"已完成",[e.projectStatusInProgress]:"进行中",[e.projectStatusPlanned]:"计划中",[e.projectsTotal]:"项目总数",[e.projectsCompleted]:"已完成",[e.projectsInProgress]:"进行中",[e.projectsTechStack]:"技术栈统计",[e.projectsFeatured]:"精选项目",[e.projectsPlanned]:"计划中",[e.projectsDemo]:"在线演示",[e.projectsSource]:"源代码",[e.skills]:"技能展示",[e.skillsSubtitle]:"我的技术技能和专业知识",[e.skillsFrontend]:"前端开发",[e.skillsBackend]:"后端开发",[e.skillsDatabase]:"数据库",[e.skillsTools]:"开发工具",[e.skillsOther]:"其他技能",[e.skillLevel]:"熟练度",[e.skillLevelBeginner]:"初学者",[e.skillLevelIntermediate]:"中级",[e.skillLevelAdvanced]:"高级",[e.skillLevelExpert]:"专家",[e.skillExperience]:"经验",[e.skillYears]:"年",[e.skillMonths]:"个月",[e.skillsTotal]:"总技能数",[e.skillsExpert]:"专家级",[e.skillsAdvanced]:"高级",[e.skillsIntermediate]:"中级",[e.skillsBeginner]:"初级",[e.skillsAdvancedTitle]:"专业技能",[e.skillsProjects]:"相关项目",[e.skillsDistribution]:"技能分布",[e.skillsByLevel]:"按等级分布",[e.skillsByCategory]:"按分类分布",[e.timeline]:"时间线",[e.timelineSubtitle]:"我的成长历程和重要里程碑",[e.timelineEducation]:"教育经历",[e.timelineWork]:"工作经历",[e.timelineProject]:"项目经历",[e.timelineAchievement]:"成就荣誉",[e.timelinePresent]:"至今",[e.timelineLocation]:"地点",[e.timelineDescription]:"详细描述",[e.timelineMonths]:"个月",[e.timelineYears]:"年",[e.timelineTotal]:"总计",[e.timelineProjects]:"项目数",[e.timelineExperience]:"工作经验",[e.timelineCurrent]:"当前状态",[e.timelineHistory]:"历史记录",[e.timelineAchievements]:"成就荣誉",[e.timelineStatistics]:"统计信息",[e.timelineByType]:"按类型分组",[e.timelineWorkExperience]:"工作经验",[e.timelineTotalExperience]:"总工作经验",[e.timelineWorkPositions]:"工作岗位数",[e.timelineCurrentRole]:"当前状态",[e.timelineEmployed]:"在职",[e.timelineAvailable]:"可入职"},p={[e.home]:"首頁",[e.about]:"關於我們",[e.archive]:"彙整",[e.search]:"搜尋",[e.tags]:"標籤",[e.categories]:"分類",[e.recentPosts]:"最新文章",[e.postList]:"文章列表",[e.tableOfContents]:"目錄",[e.comments]:"評論",[e.untitled]:"無標題",[e.uncategorized]:"未分類",[e.noTags]:"無標籤",[e.wordCount]:"字",[e.wordsCount]:"字",[e.minuteCount]:"分鐘",[e.minutesCount]:"分鐘",[e.postCount]:"篇文章",[e.postsCount]:"篇文章",[e.themeColor]:"主題色",[e.lightMode]:"亮色",[e.darkMode]:"暗色",[e.systemMode]:"跟隨系統",[e.more]:"更多",[e.author]:"作者",[e.publishedAt]:"發佈於",[e.license]:"許可協議",[e.friends]:"友鏈",[e.anime]:"追番",[e.diary]:"即刻短文",[e.animeTotal]:"總數",[e.animeWatching]:"追番中",[e.animeCompleted]:"已追完",[e.animeStatusWatching]:"追番中",[e.animeStatusCompleted]:"已追完",[e.diarySubtitle]:"隨時隨地,分享生活",[e.diaryCount]:"條短文",[e.diaryImage]:"圖片",[e.diaryReply]:"回覆",[e.diaryTips]:"只展示最近30條短文",[e.diaryMinutesAgo]:"分鐘前",[e.diaryHoursAgo]:"小時前",[e.diaryDaysAgo]:"天前",[e.notFound]:"404",[e.notFoundTitle]:"頁面未找到",[e.notFoundDescription]:"抱歉,您訪問的頁面不存在或已被移動。",[e.backToHome]:"返回首頁",[e.playlist]:"播放清單",[e.projects]:"專案",[e.projectsSubtitle]:"我的開發專案展示",[e.projectsAll]:"全部",[e.projectsWeb]:"網頁",[e.projectsMobile]:"行動",[e.projectsDesktop]:"桌面",[e.projectsOther]:"其他",[e.projectTechStack]:"技術棧",[e.projectLiveDemo]:"線上展示",[e.projectSourceCode]:"原始碼",[e.projectDescription]:"描述",[e.projectStatus]:"狀態",[e.projectStatusCompleted]:"已完成",[e.projectStatusInProgress]:"進行中",[e.projectStatusPlanned]:"已規劃",[e.projectsTotal]:"專案總數",[e.projectsCompleted]:"已完成",[e.projectsInProgress]:"進行中",[e.projectsTechStack]:"技術棧",[e.projectsFeatured]:"精選專案",[e.projectsPlanned]:"已規劃",[e.projectsDemo]:"展示",[e.projectsSource]:"原始碼",[e.skills]:"技能",[e.skillsSubtitle]:"我的技術技能與專業",[e.skillsFrontend]:"前端",[e.skillsBackend]:"後端",[e.skillsDatabase]:"資料庫",[e.skillsTools]:"工具",[e.skillsOther]:"其他技能",[e.skillLevel]:"熟練度",[e.skillLevelBeginner]:"初學",[e.skillLevelIntermediate]:"中級",[e.skillLevelAdvanced]:"進階",[e.skillLevelExpert]:"專家",[e.skillExperience]:"經驗",[e.skillYears]:"年",[e.skillMonths]:"月",[e.skillsTotal]:"技能總數",[e.skillsExpert]:"專家",[e.skillsAdvanced]:"進階",[e.skillsIntermediate]:"中級",[e.skillsBeginner]:"初學",[e.skillsAdvancedTitle]:"進階技能",[e.skillsProjects]:"專案",[e.skillsDistribution]:"技能分佈",[e.skillsByLevel]:"按等級",[e.skillsByCategory]:"按分類",[e.timeline]:"時間軸",[e.timelineSubtitle]:"我的開發歷程與經歷",[e.timelineEducation]:"教育",[e.timelineWork]:"工作",[e.timelineProject]:"專案",[e.timelineAchievement]:"成就",[e.timelinePresent]:"現在",[e.timelineLocation]:"地點",[e.timelineDescription]:"描述",[e.timelineMonths]:"月",[e.timelineYears]:"年",[e.timelineTotal]:"總計",[e.timelineProjects]:"專案",[e.timelineExperience]:"經驗",[e.timelineCurrent]:"現在",[e.timelineHistory]:"歷史",[e.timelineAchievements]:"成就",[e.timelineStatistics]:"統計",[e.timelineByType]:"按類型",[e.timelineWorkExperience]:"工作經驗",[e.timelineTotalExperience]:"總經驗",[e.timelineWorkPositions]:"工作職位",[e.timelineCurrentRole]:"目前職位",[e.timelineEmployed]:"在職",[e.timelineAvailable]:"可工作"};export{e as I,a,m as b,l as c,i as e,o as i,s as j,n as k,r as t,c as v,p as z}; diff --git a/website/blog/about/index.html b/website/blog/about/index.html deleted file mode 100644 index 8307c26..0000000 --- a/website/blog/about/index.html +++ /dev/null @@ -1,777 +0,0 @@ - FutureOSS Docs - 一切皆为插件的开发者工具运行时框架 - - - - - - -
FutureOSS Docs
主页
归档
-
Gitee
GitHub
-
主页
-
归档
-
Gitee
GitHub
-
Mobile banner image of the blog
Desktop banner image of the blog

FutureOSS

Profile Image of the Author
FutureOSS
一切皆为插件的开发者工具运行时框架
欢迎来到 FutureOSS
一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
快速开始
分类
标签
Blogging Example Markdown Mermaid Video

About This Site#

This website is built with the Astro framework using the Mizuki theme.

matsuzaka-yuki
/
Mizuki
Waiting for api.github.com...
00K
0K
0K
Waiting...

🌟 Theme Features#

🎨 Design & User Experience#

    -
  • Modern & Elegant Design - Clean, minimalist interface with beautiful typography
  • -
  • Fully Responsive - Optimized for all devices from mobile to desktop
  • -
  • Dark/Light Mode - Automatic theme switching with smooth transitions
  • -
  • Beautiful Typography - Enhanced readability with JetBrains Mono font
  • -
  • Smooth Animations - Fluid page transitions and interactive elements
  • -

🔍 Content & Search#

    -
  • Advanced Search - Powered by Pagefind for fast, accurate results
  • -
  • Enhanced Markdown - Extended syntax with code highlighting and math support
  • -
  • Interactive Table of Contents - Auto-scroll navigation for long articles
  • -
  • RSS Feed Generation - Stay updated with automatic feed generation
  • -
  • Reading Time Estimation - Know how long articles take to read
  • -
  • Post Categorization - Organize content with tags and categories
  • -

🌐 Internationalization#

    -
  • Multi-language Support - Real-time translation capabilities
  • -
  • Auto Language Detection - Detects user preferences automatically
  • -
  • Client-side Translation - Powered by Edge Translate technology
  • -
  • 10+ Languages Supported - EN, ZH-CN, ZH-TW, JA, KO, ES, TH, VI, ID, TR
  • -

📱 Special Pages#

    -
  • Anime Tracking Page - Track your anime watching progress with ratings
  • -
  • Friends Links Page - Showcase friend websites with beautiful cards
  • -
  • Diary/Moments Page - Share life moments like social media posts
  • -
  • Archive Page - Organized timeline view of all posts
  • -
  • About Page - Customizable personal introduction (this page!)
  • -

🛠 Technical Features#

    -
  • Enhanced Code Blocks - Powered by Expressive Code
  • -
  • Math Support - LaTeX rendering with KaTeX for mathematical expressions
  • -
  • Image Optimization - PhotoSwipe gallery with lazy loading
  • -
  • SEO Optimized - Built-in sitemap and meta tags for better search visibility
  • -
  • Performance Optimized - Fast loading with caching and optimization
  • -
  • Comment System Ready - Integration support for Twikoo comments
  • -

🎯 Advanced Markdown Features#

    -
  • Callouts & Admonitions - Beautiful info boxes with > [!NOTE], > [!TIP], > [!WARNING]
  • -
  • Mathematical Equations - Write LaTeX math with $inline$ and $$block$$ syntax
  • -
  • GitHub Cards - Embed repository cards with ::github{repo="user/repo"}
  • -
  • Syntax Highlighting - Advanced code highlighting with line numbers
  • -
  • Copy Code Buttons - Easy code copying functionality
  • -

Built with ❤️ using Astro and inspired by modern web design principles.

-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
\ No newline at end of file diff --git a/website/blog/anime/index.html b/website/blog/anime/index.html deleted file mode 100644 index f2b2a75..0000000 --- a/website/blog/anime/index.html +++ /dev/null @@ -1,722 +0,0 @@ - 追番 - FutureOSS Docs - - - - - - - -
FutureOSS Docs
主页
归档
-
Gitee
GitHub
-
主页
-
归档
-
Gitee
GitHub
-
Mobile banner image of the blog
Desktop banner image of the blog

FutureOSS

Profile Image of the Author
FutureOSS
一切皆为插件的开发者工具运行时框架
欢迎来到 FutureOSS
一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
快速开始
分类
标签
Blogging Example Markdown Mermaid Video
追番
4
总数
2
追番中
2
已追完
莉可丽丝

莉可丽丝

少女枪战,瑕不掩瑜

评分:
已追完
若叶女孩

若叶女孩

少女日常,清甜治愈。

评分:
追番中
恋爱小行星

恋爱小行星

星遇少女,纯爱治愈。

评分:
追番中
请问您今天要来点兔子吗??

请问您今天要来点兔子吗??

一群少女的温馨日常

评分:
已追完
-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
\ No newline at end of file diff --git a/website/blog/archive/index.html b/website/blog/archive/index.html deleted file mode 100644 index 37fba48..0000000 --- a/website/blog/archive/index.html +++ /dev/null @@ -1,721 +0,0 @@ - 归档 - FutureOSS Docs - - - - - - -
FutureOSS Docs
主页
归档
-
Gitee
GitHub
-
主页
-
归档
-
Gitee
GitHub
-
Mobile banner image of the blog
Desktop banner image of the blog

FutureOSS

Profile Image of the Author
FutureOSS
一切皆为插件的开发者工具运行时框架
欢迎来到 FutureOSS
一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
快速开始
分类
标签
Blogging Example Markdown Mermaid Video
-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
-© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
-Powered by -Astro & -Mizuki  Version 4.0
\ No newline at end of file diff --git a/website/blog/assets/desktop-banner/1.webp b/website/blog/assets/desktop-banner/1.webp deleted file mode 100644 index 13a0fd9..0000000 Binary files a/website/blog/assets/desktop-banner/1.webp and /dev/null differ diff --git a/website/blog/assets/desktop-banner/2.webp b/website/blog/assets/desktop-banner/2.webp deleted file mode 100644 index e65a141..0000000 Binary files a/website/blog/assets/desktop-banner/2.webp and /dev/null differ diff --git a/website/blog/assets/desktop-banner/3.webp b/website/blog/assets/desktop-banner/3.webp deleted file mode 100644 index 00e3e03..0000000 Binary files a/website/blog/assets/desktop-banner/3.webp and /dev/null differ diff --git a/website/blog/assets/desktop-banner/4.webp b/website/blog/assets/desktop-banner/4.webp deleted file mode 100644 index 6675d0c..0000000 Binary files a/website/blog/assets/desktop-banner/4.webp and /dev/null differ diff --git a/website/blog/assets/desktop-banner/5.webp b/website/blog/assets/desktop-banner/5.webp deleted file mode 100644 index 4397de9..0000000 Binary files a/website/blog/assets/desktop-banner/5.webp and /dev/null differ diff --git a/website/blog/assets/desktop-banner/6.webp b/website/blog/assets/desktop-banner/6.webp deleted file mode 100644 index a2b73d7..0000000 Binary files a/website/blog/assets/desktop-banner/6.webp and /dev/null differ diff --git a/website/blog/assets/js/twikoo.all.min.js b/website/blog/assets/js/twikoo.all.min.js deleted file mode 100644 index 232d3a6..0000000 --- a/website/blog/assets/js/twikoo.all.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see twikoo.all.min.js.LICENSE.txt */ -var e,t;e=this,t=function(){return function(){var e={6885:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(3692);Object.keys(r).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===r[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}}))}));var i=n(2912);Object.keys(i).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===i[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}}))}))},3692:function(e,t){"use strict";var n;Object.defineProperty(t,"__esModule",{value:!0}),t.StorageType=t.AbstractStorage=t.AbstractSDKRequest=void 0,function(e){e.local="local",e.none="none",e.session="session"}(n||(t.StorageType=n={})),t.AbstractSDKRequest=function(){},t.AbstractStorage=function(){}},2912:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.formatUrl=function(e,t,n){void 0===n&&(n={});var r=/\?/.test(t),i="";for(var o in n)""===i?!r&&(t+="?"):i+="&",i+=o+"="+encodeURIComponent(n[o]);return/^http(s)?\:\/\//.test(t+=i)?t:""+e+t}},3052:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.LOGINTYPE=t.DATA_VERSION=void 0,t.getEndPoint=function(){return{BASE_URL:l,PROTOCOL:c}},t.getSdkName=function(){return s},t.getSdkVersion=function(){return a},t.setEndPoint=d,t.setRegionLevelEndpoint=function(e,t,n){d(t?"//"+e+"."+t+".tcb-api.tencentcloudapi.com/web":"//"+e+".ap-shanghai.tcb-api.tencentcloudapi.com/web",n)},t.setSdkName=function(e){s=e,i(e)},t.setSdkVersion=function(e){a=e};var r=n(2566),i=r.constants.setSdkName,o=r.constants.setProtocol,a="",s="@cloudbase/js-sdk";t.DATA_VERSION="2020-01-10";var u,c="undefined"!=typeof location&&"http:"===location.protocol?"http:":"https:",l="//tcb-api.tencentcloudapi.com/web";function d(e,t){l=e,t&&(c=t,o(t))}!function(e){e.ANONYMOUS="ANONYMOUS",e.WECHAT="WECHAT",e.CUSTOM="CUSTOM",e.NULL="NULL"}(u||(t.LOGINTYPE=u={}))},7696:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EVENTS=void 0,t.EVENTS={LOGIN_STATE_CHANGED:"loginStateChanged",LOGIN_STATE_EXPIRED:"loginStateExpire",LOGIN_TYPE_CHANGED:"loginTypeChanged",ANONYMOUS_CONVERTED:"anonymousConverted",ACCESS_TOKEN_REFRESHD:"refreshAccessToken"}},4283:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=t.cloudbase=void 0;var i=r(n(9367)),o=n(2566),a=r(n(2473)),s=n(3219),u=n(4319),c=n(1706),l=n(6153),d=n(3052),f=function(){return f=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=0;u--)(o=e[u])&&(s=(a<3?o(s):a>3?o(t,n,s):o(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},h=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,i["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},m=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},g=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]C:return w(b.INVALID_PARAMS,"timeout is greater than maximum value[10min]"),C;case e<100:return w(b.INVALID_PARAMS,"timeout is less than maximum value[100ms]"),100;default:return e}},p([E({mode:"sync",title:"Cloudbase 初始化失败",messages:["请确认以下各项:"," 1 - 调用 cloudbase.init() 的语法或参数是否正确"," 2 - 如果是非浏览器环境,是否配置了安全应用来源(https://docs.cloudbase.net/api-reference/webv2/adapter.html#jie-ru-liu-cheng)","如果问题依然存在,建议到官方问答社区提问或寻找帮助:"+k]}),h("design:type",Function),h("design:paramtypes",[Object]),h("design:returntype",e)],e.prototype,"init",null),p([E({title:"调用扩展能力失败",messages:["请确认以下各项:"," 1 - 调用 invokeExtension() 的语法或参数是否正确"," 2 - 被调用的扩展能力是否已经安装并通过 registerExtension() 注册","如果问题依然存在,建议到官方问答社区提问或寻找帮助:"+k]}),h("design:type",Function),h("design:paramtypes",[String,Object]),h("design:returntype",Promise)],e.prototype,"invokeExtension",null),e}(),D=t.cloudbase=new I;D.useAdapters(a["default"]),t["default"]=D},4319:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Platform=void 0,t.Platform={}},1706:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getCacheByEnvId=function(e){return f[e]},t.getLocalCache=function(e){return p[e]},t.initCache=function(e){var t=e.env,n=e.persistence,r=e.platformInfo,h={accessTokenKey:o+"_"+t,accessTokenExpireKey:a+"_"+t,refreshTokenKey:s+"_"+t,anonymousUuidKey:u+"_"+t,loginTypeKey:c+"_"+t,userInfoKey:l+"_"+t};f[t]?f[t].updatePersistence(n):f[t]=new d(i(i({},e),{keys:h,platformInfo:r,alwaysLocalKeys:["anonymousUuidKey"]})),p[t]=p[t]||new d(i(i({},e),{keys:h,platformInfo:r,persistence:"local"}))};var r=n(2566),i=function(){return i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=1)return[2,this._refreshAccessToken(--e)];throw new Error(JSON.stringify({code:f.OPERATION_FAIL,message:"重试获取 refresh token 失败"}));case 9:return o.cloudbase.fire(s.EVENTS.LOGIN_STATE_EXPIRED),[4,this._cache.removeStoreAsync(a)];case 10:d.sent(),d.label=11;case 11:throw new Error(JSON.stringify({code:f.NETWORK_ERROR,msg:"refresh access_token failed:"+h.data.code}));case 12:return h.data.access_token?(o.cloudbase.fire(s.EVENTS.ACCESS_TOKEN_REFRESHD),[4,this._cache.setStoreAsync(n,h.data.access_token)]):[3,15];case 13:return d.sent(),[4,this._cache.setStoreAsync(i,h.data.access_token_expire+Date.now())];case 14:return d.sent(),[2,{accessToken:h.data.access_token,accessTokenExpire:h.data.access_token_expire}];case 15:return h.data.refresh_token?[4,this._cache.removeStoreAsync(a)]:[3,19];case 16:return d.sent(),[4,this._cache.setStoreAsync(a,h.data.refresh_token)];case 17:return d.sent(),[4,this._refreshAccessToken()];case 18:d.sent(),d.label=19;case 19:return[2]}}))}))},e.prototype._setRefreshToken=function(e){return l(this,void 0,void 0,(function(){var t,n,r,i;return d(this,(function(o){switch(o.label){case 0:return t=this._cache.keys,n=t.accessTokenKey,r=t.accessTokenExpireKey,i=t.refreshTokenKey,[4,this._cache.removeStoreAsync(n)];case 1:return o.sent(),[4,this._cache.removeStoreAsync(r)];case 2:return o.sent(),[4,this._cache.setStoreAsync(i,e)];case 3:return o.sent(),[2]}}))}))},e}(),w={}},1235:function(e,t){"use strict";var n;Object.defineProperty(t,"__esModule",{value:!0}),t.LOGINTYPE=void 0,function(e){e.ANONYMOUS="ANONYMOUS",e.WECHAT="WECHAT",e.WECHAT_PUBLIC="WECHAT-PUBLIC",e.WECHAT_OPEN="WECHAT-OPEN",e.CUSTOM="CUSTOM",e.EMAIL="EMAIL",e.USERNAME="USERNAME",e.NULL="NULL",e.PHONE="PHONE"}(n||(t.LOGINTYPE=n={}))},3442:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.Auth=void 0,Object.defineProperty(t,"AuthProvider",{enumerable:!0,get:function(){return l.AuthProvider}}),t.eventBus=t.LoginState=t.EVENTS=void 0,t.registerAuth=function(e){try{e.registerComponent(M)}catch(t){console.warn(t)}},t.registerProvider=function(e,t){O.prototype[e]=function(n){var r="_"+e;return this[r]||(this[r]=new t(h(h({},n),this._config))),this[r]}};var i=r(n(9367)),o=n(2566),a=n(9250),s=n(4325),u=n(2007),c=n(1235),l=n(4522),d=n(7036),f=n(9676),p=n(2424),h=function(){return h=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=0;u--)(o=e[u])&&(s=(a<3?o(s):a>3?o(t,n,s):o(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},g=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,i["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},v=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},_=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0;u--)(i=e[u])&&(s=(a<3?i(s):a>3?i(t,n,s):i(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},f=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,o["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},h=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]Date.now()?[4,(s=new r.LoginState({envId:this._config.env,cache:this._cache,request:this._request})).checkLocalStateAsync()]:[3,4]:[3,7];case 3:return o.sent(),[2,s];case 4:return[4,this._cache.removeStoreAsync(t)];case 5:return o.sent(),[4,this._cache.removeStoreAsync(n)];case 6:o.sent(),o.label=7;case 7:return[2]}}))}))},e.prototype.setRefreshToken=function(e){return i(this,void 0,void 0,(function(){var t,n,r,i;return o(this,(function(o){switch(o.label){case 0:return t=this._cache.keys,n=t.accessTokenKey,r=t.accessTokenExpireKey,i=t.refreshTokenKey,[4,this._cache.removeStoreAsync(n)];case 1:return o.sent(),[4,this._cache.removeStoreAsync(r)];case 2:return o.sent(),[4,this._cache.setStoreAsync(i,e)];case 3:return o.sent(),[2]}}))}))},e.prototype.setAccessToken=function(e,t){return i(this,void 0,void 0,(function(){var n,r,i;return o(this,(function(o){switch(o.label){case 0:return n=this._cache.keys,r=n.accessTokenKey,i=n.accessTokenExpireKey,[4,this._cache.setStoreAsync(r,e)];case 1:return o.sent(),[4,this._cache.setStoreAsync(i,t)];case 2:return o.sent(),[2]}}))}))},e.prototype.refreshUserInfo=function(){return i(this,void 0,void 0,(function(){var e;return o(this,(function(t){switch(t.label){case 0:return[4,this._request.send("auth.getUserInfo",{})];case 1:return e=t.sent().data,[4,this.setLocalUserInfo(e)];case 2:return t.sent(),[2,e]}}))}))},e.prototype.setLocalUserInfo=function(e){return i(this,void 0,void 0,(function(){var t;return o(this,(function(n){switch(n.label){case 0:return t=this._cache.keys.userInfoKey,[4,this._cache.setStoreAsync(t,e)];case 1:return n.sent(),[2]}}))}))},e}()},2007:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.CustomAuthProvider=void 0;var i,o=r(n(9367)),a=n(2566),s=n(4522),u=n(1235),c=n(3442),l=(i=function(e,t){return i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},i(e,t)},function(e,t){function n(){this.constructor=e}i(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),d=function(e,t,n,r){var i,a=arguments.length,s=a<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"===("undefined"==typeof Reflect?"undefined":(0,o["default"])(Reflect))&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var u=e.length-1;u>=0;u--)(i=e[u])&&(s=(a<3?i(s):a>3?i(t,n,s):i(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},f=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,o["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},h=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0;u--)(i=e[u])&&(s=(a<3?i(s):a>3?i(t,n,s):i(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},f=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,o["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},h=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0;u--)(i=e[u])&&(s=(a<3?i(s):a>3?i(t,n,s):i(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},f=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,o["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},h=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0;u--)(i=e[u])&&(s=(a<3?i(s):a>3?i(t,n,s):i(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},f=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,o["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},h=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0;u--)(i=e[u])&&(s=(a<3?i(s):a>3?i(t,n,s):i(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},f=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,o["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},h=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0;u--)(o=e[u])&&(s=(a<3?o(s):a>3?o(t,n,s):o(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},s=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,i["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},u=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},c=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0;u--)(o=e[u])&&(s=(a<3?o(s):a>3?o(t,n,s):o(t,n))||s);return a>3&&s&&Object.defineProperty(t,n,s),s},s=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":(0,i["default"])(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},u=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{u(r.next(e))}catch(t){o(t)}}function s(e){try{u(r["throw"](e))}catch(t){o(t)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},c=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),"throw":s(1),"return":s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r["return"]:o[0]?r["throw"]||((i=r["return"])&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]d}));f.unshift(a[d].replace(l,n+"."+r).replace(c,i)),(o=new Error).stack=(s?"@debugger":"Error")+"\n"+f.join("\n")}return o}t.catchErrorsDecorator=function(e){var t=e.mode,n=void 0===t?"async":t,s=e.customInfo,d=void 0===s?{}:s,f=e.title,p=e.messages,h=void 0===p?[]:p;return function(e,t,s){if(a.IS_DEBUG_MODE){var p=d.className||e.constructor.name,m=d.methodName||t,g=s.value,v=function(e){var t="",n=e.stack.split("\n"),r=n.findIndex((function(e){return u.test(e)}));if(-1!==r){var i=c.exec(n[r+1]||"");t=i?i[0]:""}return t}(new Error);s.value="sync"===n?function(){for(var e=[],t=0;t0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=0?JSON.parse(r).content:""}u.printWarn(c.ERRORS.INVALID_OPERATION,"current platform's storage is asynchronous, please use getStoreAsync insteed")},e.prototype.getStoreAsync=function(e,t){var n;return o(this,void 0,void 0,(function(){var r;return a(this,(function(i){switch(i.label){case 0:try{if("undefined"!=typeof process&&(null===(n=process.env)||void 0===n?void 0:n.tcb_token))return[2,process.env.tcb_token];if(!this._storage)return[2,""]}catch(o){return[2,""]}return t=t||"localCachev1",[4,this._storage.getItem(e)];case 1:return(r=i.sent())&&r.indexOf(t)>=0?[2,JSON.parse(r).content]:[2,""]}}))}))},e.prototype.removeStore=function(e){"async"!==this.mode?this._storage.removeItem(e):u.printWarn(c.ERRORS.INVALID_OPERATION,"current platform's storage is asynchronous, please use removeStoreAsync insteed")},e.prototype.removeStoreAsync=function(e){return o(this,void 0,void 0,(function(){return a(this,(function(t){switch(t.label){case 0:return[4,this._storage.removeItem(e)];case 1:return t.sent(),[2]}}))}))},e}();t.CloudbaseCache=f},9978:function(e,t,n){"use strict";var r,i=(r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},r(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=function(){for(var e=0,t=0,n=arguments.length;t0},e}();t.CloudbaseEventEmitter=c;var l=new c;t.addEventListener=function(e,t){l.on(e,t)},t.activateEvent=function(e,t){void 0===t&&(t={}),l.fire(e,t)},t.removeEventListener=function(e,t){l.off(e,t)}},5939:function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e:{"default":e}};Object.defineProperty(t,"__esModule",{value:!0}),t.transformPhone=t.sleep=t.printGroupLog=t.throwError=t.printInfo=t.printError=t.printWarn=t.execCallback=t.createPromiseCallback=t.removeParam=t.getHash=t.getQuery=t.toQueryString=t.createSign=t.formatUrl=t.genSeqId=t.isFormData=t.isInstanceOf=t.isNull=t.isPalinObject=t.isUndefined=t.isString=t.isArray=void 0;var i=r(n(4180)),o=r(n(6253)),a=r(n(1717)),s=n(3440);function u(e){var t=o["default"].stringify(e);return t=(t=(t=t.replace(/=+$/,"")).replace(/\+/g,"-")).replace(/\//g,"_")}t.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},t.isString=function(e){return"string"==typeof e},t.isUndefined=function(e){return void 0===e},t.isPalinObject=function(e){return"[object Object]"===Object.prototype.toString.call(e)},t.isNull=function(e){return"[object Null]"===Object.prototype.toString.call(e)},t.isInstanceOf=function(e,t){return e instanceof t},t.isFormData=function(e){return"[object FormData]"===Object.prototype.toString.call(e)},t.genSeqId=function(){return Math.random().toString(16).slice(2)},t.formatUrl=function(e,t,n){void 0===n&&(n={});var r=/\?/.test(t),i="";for(var o in n)""===i?!r&&(t+="?"):i+="&",i+=o+"="+encodeURIComponent(n[o]);return/^http(s)?\:\/\//.test(t+=i)?t:""+e+t},t.createSign=function(e,t){var n=u(a["default"].parse(JSON.stringify({alg:"HS256",typ:"JWT"})))+"."+u(a["default"].parse(JSON.stringify(e)));return n+"."+u(i["default"](n,t))},t.toQueryString=function(e){void 0===e&&(e={});var t=[];for(var n in e)t.push(n+"="+encodeURIComponent(e[n]));return t.join("&")},t.getQuery=function(e,t){if("undefined"==typeof window)return!1;var n=t||window.location.search,r=new RegExp("(^|&)"+e+"=([^&]*)(&|$)"),i=n.substr(n.indexOf("?")+1).match(r);return null!=i?i[2]:""},t.getHash=function(e){if("undefined"==typeof window)return"";var t=window.location.hash.match(new RegExp("[#?&/]"+e+"=([^&#]*)"));return t?t[1]:""},t.removeParam=function(e,t){var n=t.split("?")[0],r=[],i=-1!==t.indexOf("?")?t.split("?")[1]:"";if(""!==i){for(var o=(r=i.split("&")).length-1;o>=0;o-=1)r[o].split("=")[0]===e&&r.splice(o,1);n=n+"?"+r.join("&")}return n},t.createPromiseCallback=function(){var e;if(!Promise){(e=function(){}).promise={};var t=function(){throw new Error('Your Node runtime does support ES6 Promises. Set "global.Promise" to your preferred implementation of promises.')};return Object.defineProperty(e.promise,"then",{get:t}),Object.defineProperty(e.promise,"catch",{get:t}),e}var n=new Promise((function(t,n){e=function(e,r){return e?n(e):t(r)}}));return e.promise=n,e},t.execCallback=function(e,t,n){if(void 0===n&&(n=null),e&&"function"==typeof e)return e(t,n);if(t)throw t;return n},t.printWarn=function(e,t){console.warn("["+s.getSdkName()+"]["+e+"]:"+t)},t.printError=function(e,t){console.error({code:e,msg:"["+s.getSdkName()+"]["+e+"]:"+t})},t.printInfo=function(e,t){console.log("["+s.getSdkName()+"]["+e+"]:"+t)},t.throwError=function(e,t){throw new Error(JSON.stringify({code:e,msg:"["+s.getSdkName()+"]["+e+"]:"+t}))},t.printGroupLog=function(e){var t=e.title,n=e.subtitle,r=void 0===n?"":n,i=e.content,o=void 0===i?[]:i,a=e.printTrace,s=void 0!==a&&a,u=e.collapsed;void 0!==u&&u?console.groupCollapsed(t,r):console.group(t,r);for(var c=0,l=o;c>16)+(t>>16)+(n>>16)<<16|65535&n}function a(e,t,n,r,i,a){return o((s=o(o(t,e),o(r,a)))<<(u=i)|s>>>32-u,n);var s,u}function s(e,t,n,r,i,o,s){return a(t&n|~t&r,e,t,i,o,s)}function u(e,t,n,r,i,o,s){return a(t&r|n&~r,e,t,i,o,s)}function c(e,t,n,r,i,o,s){return a(t^n^r,e,t,i,o,s)}function l(e,t,n,r,i,o,s){return a(n^(t|~r),e,t,i,o,s)}function d(e,t){var n,r,i,a,d;e[t>>5]|=128<>>9<<4)]=t;var f=1732584193,p=-271733879,h=-1732584194,m=271733878;for(n=0;n>5]>>>t%32&255);return n}function p(e){var t,n=[];for(n[(e.length>>2)-1]=undefined,t=0;t>5]|=(255&e.charCodeAt(t/8))<>>4&15)+r.charAt(15&t);return i}function m(e){return unescape(encodeURIComponent(e))}function g(e){return function(e){return f(d(p(e),8*e.length))}(m(e))}function v(e,t){return function(e,t){var n,r,i=p(e),o=[],a=[];for(o[15]=a[15]=undefined,i.length>16&&(i=d(i,8*e.length)),n=0;n<16;n+=1)o[n]=909522486^i[n],a[n]=1549556828^i[n];return r=d(o.concat(p(t)),512+8*t.length),f(d(a.concat(r),640))}(m(e),m(t))}function _(e,t,n){return t?n?v(t,e):h(v(t,e)):n?g(e):h(g(e))}(r=function(){return _}.call(t,n,t,e))===undefined||(e.exports=r)}()},2473:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.wxMpStorage=t["default"]=t.WxRequest=t.WxMpWebSocket=void 0;var r,i=n(6885),o=(r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},r(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),a=function(){return a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]>>2]>>>24-o%4*8&255;t[r+o>>>2]|=a<<24-(r+o)%4*8}else for(o=0;o>>2]=n[o>>>2];return this.sigBytes+=i,this},clamp:function(){var t=this.words,n=this.sigBytes;t[n>>>2]&=4294967295<<32-n%4*8,t.length=e.ceil(n/4)},clone:function(){var e=o.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var n,r=[],i=function(t){var n=987654321,r=4294967295;return function(){var i=((n=36969*(65535&n)+(n>>16)&r)<<16)+(t=18e3*(65535&t)+(t>>16)&r)&r;return i/=4294967296,(i+=.5)*(e.random()>.5?1:-1)}},o=0;o>>2]>>>24-i%4*8&255;r.push((o>>>4).toString(16)),r.push((15&o).toString(16))}return r.join("")},parse:function(e){for(var t=e.length,n=[],r=0;r>>3]|=parseInt(e.substr(r,2),16)<<24-r%8*4;return new a.init(n,t/2)}},c=s.Latin1={stringify:function(e){for(var t=e.words,n=e.sigBytes,r=[],i=0;i>>2]>>>24-i%4*8&255;r.push(String.fromCharCode(o))}return r.join("")},parse:function(e){for(var t=e.length,n=[],r=0;r>>2]|=(255&e.charCodeAt(r))<<24-r%4*8;return new a.init(n,t)}},l=s.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},d=i.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new a.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=l.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var n=this._data,r=n.words,i=n.sigBytes,o=this.blockSize,s=i/(4*o),u=(s=t?e.ceil(s):e.max((0|s)-this._minBufferSize,0))*o,c=e.min(4*u,i);if(u){for(var l=0;l>>2]>>>24-o%4*8&255)<<16|(t[o+1>>>2]>>>24-(o+1)%4*8&255)<<8|t[o+2>>>2]>>>24-(o+2)%4*8&255,s=0;s<4&&o+.75*s>>6*(3-s)&63));var u=r.charAt(64);if(u)for(;i.length%4;)i.push(u);return i.join("")},parse:function(e){var t=e.length,r=this._map,i=this._reverseMap;if(!i){i=this._reverseMap=[];for(var o=0;o>>6-a%4*2;i[o>>>2]|=(s|u)<<24-o%4*8,o++}return n.create(i,o)}(e,t,i)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},e.enc.Base64},"object"===(0,s["default"])(t)?e.exports=t=a(n(4794)):(i=[n(4794)],(o="function"==typeof(r=a)?r.apply(t,i):r)===undefined||(e.exports=o))},1717:function(e,t,n){"use strict";var r,i,o,a,s=n(477)(n(9367));a=function(e){return e.enc.Utf8},"object"===(0,s["default"])(t)?e.exports=t=a(n(4794)):(i=[n(4794)],(o="function"==typeof(r=a)?r.apply(t,i):r)===undefined||(e.exports=o))},4180:function(e,t,n){"use strict";var r,i,o,a,s=n(477)(n(9367));a=function(e){return e.HmacSHA256},"object"===(0,s["default"])(t)?e.exports=t=a(n(4794),n(5794),n(2910)):(i=[n(4794),n(5794),n(2910)],(o="function"==typeof(r=a)?r.apply(t,i):r)===undefined||(e.exports=o))},2910:function(e,t,n){"use strict";var r,i,o,a,s=n(477)(n(9367));a=function(e){var t,n,r;n=(t=e).lib.Base,r=t.enc.Utf8,t.algo.HMAC=n.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=r.parse(t));var n=e.blockSize,i=4*n;t.sigBytes>i&&(t=e.finalize(t)),t.clamp();for(var o=this._oKey=t.clone(),a=this._iKey=t.clone(),s=o.words,u=a.words,c=0;c>>7)^(h<<14|h>>>18)^h>>>3,g=c[p-2],v=(g<<15|g>>>17)^(g<<13|g>>>19)^g>>>10;c[p]=m+c[p-7]+v+c[p-16]}var _=r&i^r&o^i&o,y=(r<<30|r>>>2)^(r<<19|r>>>13)^(r<<10|r>>>22),b=f+((s<<26|s>>>6)^(s<<21|s>>>11)^(s<<7|s>>>25))+(s&l^~s&d)+u[p]+c[p];f=d,d=l,l=s,s=a+b|0,a=o,o=i,i=r,r=b+(y+_)|0}n[0]=n[0]+r|0,n[1]=n[1]+i|0,n[2]=n[2]+o|0,n[3]=n[3]+a|0,n[4]=n[4]+s|0,n[5]=n[5]+l|0,n[6]=n[6]+d|0,n[7]=n[7]+f|0},_doFinalize:function(){var e=this._data,n=e.words,r=8*this._nDataBytes,i=8*e.sigBytes;return n[i>>>5]|=128<<24-i%32,n[14+(i+64>>>9<<4)]=t.floor(r/4294967296),n[15+(i+64>>>9<<4)]=r,e.sigBytes=4*n.length,this._process(),this._hash},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}});n.SHA256=o._createHelper(l),n.HmacSHA256=o._createHmacHelper(l)}(Math),e.SHA256},"object"===(0,s["default"])(t)?e.exports=t=a(n(4794)):(i=[n(4794)],(o="function"==typeof(r=a)?r.apply(t,i):r)===undefined||(e.exports=o))},9067:function(e){"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n="",r="undefined"!=typeof t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),r&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),r&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n})).join("")},t.i=function(e,n,r,i,o){"string"==typeof e&&(e=[[null,e,undefined]]);var a={};if(r)for(var s=0;s0?" ".concat(l[5]):""," {").concat(l[1],"}")),l[5]=o),n&&(l[2]?(l[1]="@media ".concat(l[2]," {").concat(l[1],"}"),l[2]=n):l[2]=n),i&&(l[4]?(l[1]="@supports (".concat(l[4],") {").concat(l[1],"}"),l[4]=i):l[4]="".concat(i)),t.push(l))}},t}},5346:function(e){"use strict";e.exports=function(e){return e[1]}},1463:function(e,t,n){"use strict";var r=n(477)(n(9367));e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===(0,r["default"])(e)&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=96)}({0:function(e,t,n){function r(e,t,n,r,i,o,a,s){var u,c="function"==typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),r&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(u=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),i&&i.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=u):i&&(u=s?function(){i.call(this,this.$root.$options.shadowRoot)}:i),u)if(c.functional){c._injectStyles=u;var l=c.render;c.render=function(e,t){return u.call(t),l(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,u):[u]}return{exports:e,options:c}}n.d(t,"a",(function(){return r}))},96:function(e,t,n){n.r(t);var r=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("button",{staticClass:"el-button","class":[e.type?"el-button--"+e.type:"",e.buttonSize?"el-button--"+e.buttonSize:"",{"is-disabled":e.buttonDisabled,"is-loading":e.loading,"is-plain":e.plain,"is-round":e.round,"is-circle":e.circle}],attrs:{disabled:e.buttonDisabled||e.loading,autofocus:e.autofocus,type:e.nativeType},on:{click:e.handleClick}},[e.loading?n("i",{staticClass:"el-icon-loading"}):e._e(),e.icon&&!e.loading?n("i",{"class":e.icon}):e._e(),e.$slots["default"]?n("span",[e._t("default")],2):e._e()])};r._withStripped=!0;var i={name:"ElButton",inject:{elForm:{"default":""},elFormItem:{"default":""}},props:{type:{type:String,"default":"default"},size:String,icon:{type:String,"default":""},nativeType:{type:String,"default":"button"},loading:Boolean,disabled:Boolean,plain:Boolean,autofocus:Boolean,round:Boolean,circle:Boolean},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},buttonSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},buttonDisabled:function(){return this.$options.propsData.hasOwnProperty("disabled")?this.disabled:(this.elForm||{}).disabled}},methods:{handleClick:function(e){this.$emit("click",e)}}},o=n(0),a=Object(o.a)(i,r,[],!1,null,null,null);a.options.__file="packages/button/src/button.vue";var s=a.exports;s.install=function(e){e.component(s.name,s)},t["default"]=s}})},5735:function(e,t,n){"use strict";var r=n(477)(n(9367));e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===(0,r["default"])(e)&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=75)}({0:function(e,t,n){function r(e,t,n,r,i,o,a,s){var u,c="function"==typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),r&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(u=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),i&&i.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=u):i&&(u=s?function(){i.call(this,this.$root.$options.shadowRoot)}:i),u)if(c.functional){c._injectStyles=u;var l=c.render;c.render=function(e,t){return u.call(t),l(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,u):[u]}return{exports:e,options:c}}n.d(t,"a",(function(){return r}))},11:function(e,t){e.exports=n(2036)},21:function(e,t){e.exports=n(4524)},4:function(e,t){e.exports=n(5956)},75:function(e,t,n){n.r(t);var r=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{"class":["textarea"===e.type?"el-textarea":"el-input",e.inputSize?"el-input--"+e.inputSize:"",{"is-disabled":e.inputDisabled,"is-exceed":e.inputExceed,"el-input-group":e.$slots.prepend||e.$slots.append,"el-input-group--append":e.$slots.append,"el-input-group--prepend":e.$slots.prepend,"el-input--prefix":e.$slots.prefix||e.prefixIcon,"el-input--suffix":e.$slots.suffix||e.suffixIcon||e.clearable||e.showPassword}],on:{mouseenter:function(t){e.hovering=!0},mouseleave:function(t){e.hovering=!1}}},["textarea"!==e.type?[e.$slots.prepend?n("div",{staticClass:"el-input-group__prepend"},[e._t("prepend")],2):e._e(),"textarea"!==e.type?n("input",e._b({ref:"input",staticClass:"el-input__inner",attrs:{tabindex:e.tabindex,type:e.showPassword?e.passwordVisible?"text":"password":e.type,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"input",e.$attrs,!1)):e._e(),e.$slots.prefix||e.prefixIcon?n("span",{staticClass:"el-input__prefix"},[e._t("prefix"),e.prefixIcon?n("i",{staticClass:"el-input__icon","class":e.prefixIcon}):e._e()],2):e._e(),e.getSuffixVisible()?n("span",{staticClass:"el-input__suffix"},[n("span",{staticClass:"el-input__suffix-inner"},[e.showClear&&e.showPwdVisible&&e.isWordLimitVisible?e._e():[e._t("suffix"),e.suffixIcon?n("i",{staticClass:"el-input__icon","class":e.suffixIcon}):e._e()],e.showClear?n("i",{staticClass:"el-input__icon el-icon-circle-close el-input__clear",on:{mousedown:function(e){e.preventDefault()},click:e.clear}}):e._e(),e.showPwdVisible?n("i",{staticClass:"el-input__icon el-icon-view el-input__clear",on:{click:e.handlePasswordVisible}}):e._e(),e.isWordLimitVisible?n("span",{staticClass:"el-input__count"},[n("span",{staticClass:"el-input__count-inner"},[e._v("\n "+e._s(e.textLength)+"/"+e._s(e.upperLimit)+"\n ")])]):e._e()],2),e.validateState?n("i",{staticClass:"el-input__icon","class":["el-input__validateIcon",e.validateIcon]}):e._e()]):e._e(),e.$slots.append?n("div",{staticClass:"el-input-group__append"},[e._t("append")],2):e._e()]:n("textarea",e._b({ref:"textarea",staticClass:"el-textarea__inner",style:e.textareaStyle,attrs:{tabindex:e.tabindex,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"textarea",e.$attrs,!1)),e.isWordLimitVisible&&"textarea"===e.type?n("span",{staticClass:"el-input__count"},[e._v(e._s(e.textLength)+"/"+e._s(e.upperLimit))]):e._e()],2)};r._withStripped=!0;var i=n(4),o=n.n(i),a=n(11),s=n.n(a),u=void 0,c=["letter-spacing","line-height","padding-top","padding-bottom","font-family","font-weight","font-size","text-rendering","text-transform","width","text-indent","padding-left","padding-right","border-width","box-sizing"];function l(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:1,n=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;u||(u=document.createElement("textarea"),document.body.appendChild(u));var r=function(e){var t=window.getComputedStyle(e),n=t.getPropertyValue("box-sizing"),r=parseFloat(t.getPropertyValue("padding-bottom"))+parseFloat(t.getPropertyValue("padding-top")),i=parseFloat(t.getPropertyValue("border-bottom-width"))+parseFloat(t.getPropertyValue("border-top-width"));return{contextStyle:c.map((function(e){return e+":"+t.getPropertyValue(e)})).join(";"),paddingSize:r,borderSize:i,boxSizing:n}}(e),i=r.paddingSize,o=r.borderSize,a=r.boxSizing,s=r.contextStyle;u.setAttribute("style",s+";\n height:0 !important;\n visibility:hidden !important;\n overflow:hidden !important;\n position:absolute !important;\n z-index:-1000 !important;\n top:0 !important;\n right:0 !important\n"),u.value=e.value||e.placeholder||"";var l=u.scrollHeight,d={};"border-box"===a?l+=o:"content-box"===a&&(l-=i),u.value="";var f=u.scrollHeight-i;if(null!==t){var p=f*t;"border-box"===a&&(p=p+i+o),l=Math.max(p,l),d.minHeight=p+"px"}if(null!==n){var h=f*n;"border-box"===a&&(h=h+i+o),l=Math.min(h,l)}return d.height=l+"px",u.parentNode&&u.parentNode.removeChild(u),u=null,d}var d=n(9),f=n.n(d),p=n(21),h={name:"ElInput",componentName:"ElInput",mixins:[o.a,s.a],inheritAttrs:!1,inject:{elForm:{"default":""},elFormItem:{"default":""}},data:function(){return{textareaCalcStyle:{},hovering:!1,focused:!1,isComposing:!1,passwordVisible:!1}},props:{value:[String,Number],size:String,resize:String,form:String,disabled:Boolean,readonly:Boolean,type:{type:String,"default":"text"},autosize:{type:[Boolean,Object],"default":!1},autocomplete:{type:String,"default":"off"},autoComplete:{type:String,validator:function(e){return!0}},validateEvent:{type:Boolean,"default":!0},suffixIcon:String,prefixIcon:String,label:String,clearable:{type:Boolean,"default":!1},showPassword:{type:Boolean,"default":!1},showWordLimit:{type:Boolean,"default":!1},tabindex:String},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},validateState:function(){return this.elFormItem?this.elFormItem.validateState:""},needStatusIcon:function(){return!!this.elForm&&this.elForm.statusIcon},validateIcon:function(){return{validating:"el-icon-loading",success:"el-icon-circle-check",error:"el-icon-circle-close"}[this.validateState]},textareaStyle:function(){return f()({},this.textareaCalcStyle,{resize:this.resize})},inputSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputDisabled:function(){return this.disabled||(this.elForm||{}).disabled},nativeInputValue:function(){return null===this.value||this.value===undefined?"":String(this.value)},showClear:function(){return this.clearable&&!this.inputDisabled&&!this.readonly&&this.nativeInputValue&&(this.focused||this.hovering)},showPwdVisible:function(){return this.showPassword&&!this.inputDisabled&&!this.readonly&&(!!this.nativeInputValue||this.focused)},isWordLimitVisible:function(){return this.showWordLimit&&this.$attrs.maxlength&&("text"===this.type||"textarea"===this.type)&&!this.inputDisabled&&!this.readonly&&!this.showPassword},upperLimit:function(){return this.$attrs.maxlength},textLength:function(){return"number"==typeof this.value?String(this.value).length:(this.value||"").length},inputExceed:function(){return this.isWordLimitVisible&&this.textLength>this.upperLimit}},watch:{value:function(e){this.$nextTick(this.resizeTextarea),this.validateEvent&&this.dispatch("ElFormItem","el.form.change",[e])},nativeInputValue:function(){this.setNativeInputValue()},type:function(){var e=this;this.$nextTick((function(){e.setNativeInputValue(),e.resizeTextarea(),e.updateIconOffset()}))}},methods:{focus:function(){this.getInput().focus()},blur:function(){this.getInput().blur()},getMigratingConfig:function(){return{props:{icon:"icon is removed, use suffix-icon / prefix-icon instead.","on-icon-click":"on-icon-click is removed."},events:{click:"click is removed."}}},handleBlur:function(e){this.focused=!1,this.$emit("blur",e),this.validateEvent&&this.dispatch("ElFormItem","el.form.blur",[this.value])},select:function(){this.getInput().select()},resizeTextarea:function(){if(!this.$isServer){var e=this.autosize;if("textarea"===this.type)if(e){var t=e.minRows,n=e.maxRows;this.textareaCalcStyle=l(this.$refs.textarea,t,n)}else this.textareaCalcStyle={minHeight:l(this.$refs.textarea).minHeight}}},setNativeInputValue:function(){var e=this.getInput();e&&e.value!==this.nativeInputValue&&(e.value=this.nativeInputValue)},handleFocus:function(e){this.focused=!0,this.$emit("focus",e)},handleCompositionStart:function(e){this.$emit("compositionstart",e),this.isComposing=!0},handleCompositionUpdate:function(e){this.$emit("compositionupdate",e);var t=e.target.value,n=t[t.length-1]||"";this.isComposing=!Object(p.isKorean)(n)},handleCompositionEnd:function(e){this.$emit("compositionend",e),this.isComposing&&(this.isComposing=!1,this.handleInput(e))},handleInput:function(e){this.isComposing||e.target.value!==this.nativeInputValue&&(this.$emit("input",e.target.value),this.$nextTick(this.setNativeInputValue))},handleChange:function(e){this.$emit("change",e.target.value)},calcIconOffset:function(e){var t=[].slice.call(this.$el.querySelectorAll(".el-input__"+e)||[]);if(t.length){for(var n=null,r=0;r0&&arguments[0]!==undefined?arguments[0]:{};if(!i.a.prototype.$isServer){if("string"==typeof(e=_()({},b,e)).target&&(e.target=document.querySelector(e.target)),e.target=e.target||document.body,e.target!==document.body?e.fullscreen=!1:e.body=!0,e.fullscreen&&k)return k;var t=e.body?document.body:e.target,n=new y({el:document.createElement("div"),data:e});return function(e,t,n){var r={};e.fullscreen?(n.originalPosition=Object(l.getStyle)(document.body,"position"),n.originalOverflow=Object(l.getStyle)(document.body,"overflow"),r.zIndex=d.PopupManager.nextZIndex()):e.body?(n.originalPosition=Object(l.getStyle)(document.body,"position"),["top","left"].forEach((function(t){var n="top"===t?"scrollTop":"scrollLeft";r[t]=e.target.getBoundingClientRect()[t]+document.body[n]+document.documentElement[n]+"px"})),["height","width"].forEach((function(t){r[t]=e.target.getBoundingClientRect()[t]+"px"}))):n.originalPosition=Object(l.getStyle)(t,"position"),Object.keys(r).forEach((function(e){n.$el.style[e]=r[e]}))}(e,t,n),"absolute"!==n.originalPosition&&"fixed"!==n.originalPosition&&"sticky"!==n.originalPosition&&Object(l.addClass)(t,"el-loading-parent--relative"),e.fullscreen&&e.lock&&Object(l.addClass)(t,"el-loading-parent--hidden"),t.appendChild(n.$el),i.a.nextTick((function(){n.visible=!0})),e.fullscreen&&(k=n),n}};t["default"]={install:function(e){e.use(g),e.prototype.$loading=w},directive:g,service:w}},9:function(e,t){e.exports=n(8589)}})},5956:function(e,t){"use strict";function n(e,t,r){this.$children.forEach((function(i){i.$options.componentName===e?i.$emit.apply(i,[t].concat(r)):n.apply(i,[e,t].concat([r]))}))}t.__esModule=!0,t["default"]={methods:{dispatch:function(e,t,n){for(var r=this.$parent||this.$root,i=r.$options.componentName;r&&(!i||i!==e);)(r=r.$parent)&&(i=r.$options.componentName);r&&r.$emit.apply(r,[t].concat(n))},broadcast:function(e,t,r){n.call(this,e,t,r)}}}},2036:function(e,t,n){"use strict";t.__esModule=!0,n(2417),t["default"]={mounted:function(){},methods:{getMigratingConfig:function(){return{props:{},events:{}}}}}},3725:function(e,t){"use strict";t.__esModule=!0,t["default"]=function(e,t){var n=arguments.length>2&&arguments[2]!==undefined?arguments[2]:300,r=arguments.length>3&&arguments[3]!==undefined&&arguments[3];if(!e||!t)throw new Error("instance & callback is required");var i=!1,o=function(){i||(i=!0,t&&t.apply(null,arguments))};r?e.$once("after-leave",o):e.$on("after-leave",o),setTimeout((function(){o()}),n+100)}},2865:function(e,t,n){"use strict";var r=n(477)(n(9367));t.__esModule=!0,t.isInContainer=t.getScrollContainer=t.isScroll=t.getStyle=t.once=t.off=t.on=undefined;var i="function"==typeof Symbol&&"symbol"===(0,r["default"])(Symbol.iterator)?function(e){return(0,r["default"])(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":(0,r["default"])(e)};t.hasClass=m,t.addClass=function(e,t){if(e){for(var n=e.className,r=(t||"").split(" "),i=0,o=r.length;i-1}t.once=function(e,t,n){p(e,t,(function r(){n&&n.apply(this,arguments),h(e,t,r)}))};var g=t.getStyle=l<9?function(e,t){if(!s){if(!e||!t)return null;"float"===(t=f(t))&&(t="styleFloat");try{if("opacity"===t)try{return e.filters.item("alpha").opacity/100}catch(n){return 1}return e.style[t]||e.currentStyle?e.currentStyle[t]:null}catch(n){return e.style[t]}}}:function(e,t){if(!s){if(!e||!t)return null;"float"===(t=f(t))&&(t="cssFloat");try{var n=document.defaultView.getComputedStyle(e,"");return e.style[t]||n?n[t]:null}catch(r){return e.style[t]}}},v=t.isScroll=function(e,t){if(!s){var n=null!==t&&t!==undefined;return g(e,n?t?"overflow-y":"overflow-x":"overflow").match(/(scroll|auto|overlay)/)}};t.getScrollContainer=function(e,t){if(!s){for(var n=e;n;){if([window,document,document.documentElement].includes(n))return window;if(v(n,t))return n;n=n.parentNode}return n}},t.isInContainer=function(e,t){if(s||!e||!t)return!1;var n=e.getBoundingClientRect(),r=void 0;return r=[window,document,document.documentElement,null,undefined].includes(t)?{top:0,right:window.innerWidth,bottom:window.innerHeight,left:0}:t.getBoundingClientRect(),n.topr.top&&n.right>r.left&&n.left0?this._openTimer=setTimeout((function(){t._openTimer=null,t.doOpen(n)}),r):this.doOpen(n)},doOpen:function(e){if(!this.$isServer&&(!this.willOpen||this.willOpen())&&!this.opened){this._opening=!0;var t=this.$el,n=e.modal,r=e.zIndex;if(r&&(o["default"].zIndex=r),n&&(this._closing&&(o["default"].closeModal(this._popupId),this._closing=!1),o["default"].openModal(this._popupId,o["default"].nextZIndex(),this.modalAppendToBody?undefined:t,e.modalClass,e.modalFade),e.lockScroll)){this.withoutHiddenClass=!(0,s.hasClass)(document.body,"el-popup-parent--hidden"),this.withoutHiddenClass&&(this.bodyPaddingRight=document.body.style.paddingRight,this.computedBodyPaddingRight=parseInt((0,s.getStyle)(document.body,"paddingRight"),10)),l=(0,a["default"])();var i=document.documentElement.clientHeight0&&(i||"scroll"===u)&&this.withoutHiddenClass&&(document.body.style.paddingRight=this.computedBodyPaddingRight+l+"px"),(0,s.addClass)(document.body,"el-popup-parent--hidden")}"static"===getComputedStyle(t).position&&(t.style.position="absolute"),t.style.zIndex=o["default"].nextZIndex(),this.opened=!0,this.onOpen&&this.onOpen(),this.doAfterOpen()}},doAfterOpen:function(){this._opening=!1},close:function(){var e=this;if(!this.willClose||this.willClose()){null!==this._openTimer&&(clearTimeout(this._openTimer),this._openTimer=null),clearTimeout(this._closeTimer);var t=Number(this.closeDelay);t>0?this._closeTimer=setTimeout((function(){e._closeTimer=null,e.doClose()}),t):this.doClose()}},doClose:function(){this._closing=!0,this.onClose&&this.onClose(),this.lockScroll&&setTimeout(this.restoreBodyStyle,200),this.opened=!1,this.doAfterClose()},doAfterClose:function(){o["default"].closeModal(this._popupId),this._closing=!1},restoreBodyStyle:function(){this.modal&&this.withoutHiddenClass&&(document.body.style.paddingRight=this.bodyPaddingRight,(0,s.removeClass)(document.body,"el-popup-parent--hidden")),this.withoutHiddenClass=!0}}},t.PopupManager=o["default"]},8432:function(e,t,n){"use strict";t.__esModule=!0;var r,i=n(4478),o=(r=i)&&r.__esModule?r:{"default":r},a=n(2865),s=!1,u=!1,c=void 0,l=function(){if(!o["default"].prototype.$isServer){var e=f.modalDom;return e?s=!0:(s=!1,e=document.createElement("div"),f.modalDom=e,e.addEventListener("touchmove",(function(e){e.preventDefault(),e.stopPropagation()})),e.addEventListener("click",(function(){f.doOnModalClick&&f.doOnModalClick()}))),e}},d={},f={modalFade:!0,getInstance:function(e){return d[e]},register:function(e,t){e&&t&&(d[e]=t)},deregister:function(e){e&&(d[e]=null,delete d[e])},nextZIndex:function(){return f.zIndex++},modalStack:[],doOnModalClick:function(){var e=f.modalStack[f.modalStack.length-1];if(e){var t=f.getInstance(e.id);t&&t.closeOnClickModal&&t.close()}},openModal:function(e,t,n,r,i){if(!o["default"].prototype.$isServer&&e&&t!==undefined){this.modalFade=i;for(var u=this.modalStack,c=0,d=u.length;c0){var r=t[t.length-1];if(r.id===e)r.modalClass&&r.modalClass.trim().split(/\s+/).forEach((function(e){return(0,a.removeClass)(n,e)})),t.pop(),t.length>0&&(n.style.zIndex=t[t.length-1].zIndex);else for(var i=t.length-1;i>=0;i--)if(t[i].id===e){t.splice(i,1);break}}0===t.length&&(this.modalFade&&(0,a.addClass)(n,"v-modal-leave"),setTimeout((function(){0===t.length&&(n.parentNode&&n.parentNode.removeChild(n),n.style.display="none",f.modalDom=undefined),(0,a.removeClass)(n,"v-modal-leave")}),200))}};Object.defineProperty(f,"zIndex",{configurable:!0,get:function(){return u||(c=c||(o["default"].prototype.$ELEMENT||{}).zIndex||2e3,u=!0),c},set:function(e){c=e}}),o["default"].prototype.$isServer||window.addEventListener("keydown",(function(e){if(27===e.keyCode){var t=function(){if(!o["default"].prototype.$isServer&&f.modalStack.length>0){var e=f.modalStack[f.modalStack.length-1];if(!e)return;return f.getInstance(e.id)}}();t&&t.closeOnPressEscape&&(t.handleClose?t.handleClose():t.handleAction?t.handleAction("cancel"):t.close())}})),t["default"]=f},9686:function(e,t,n){"use strict";t.__esModule=!0,t["default"]=function(){if(o["default"].prototype.$isServer)return 0;if(a!==undefined)return a;var e=document.createElement("div");e.className="el-scrollbar__wrap",e.style.visibility="hidden",e.style.width="100px",e.style.position="absolute",e.style.top="-9999px",document.body.appendChild(e);var t=e.offsetWidth;e.style.overflow="scroll";var n=document.createElement("div");n.style.width="100%",e.appendChild(n);var r=n.offsetWidth;return e.parentNode.removeChild(e),a=t-r};var r,i=n(4478),o=(r=i)&&r.__esModule?r:{"default":r},a=void 0},4524:function(e,t){"use strict";t.__esModule=!0,t.isDef=function(e){return e!==undefined&&null!==e},t.isKorean=function(e){return/([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi.test(e)}},6200:function(e,t,n){"use strict";var r=n(477)(n(9367));t.__esModule=!0,t.isDefined=t.isUndefined=t.isFunction=undefined;var i="function"==typeof Symbol&&"symbol"===(0,r["default"])(Symbol.iterator)?function(e){return(0,r["default"])(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":(0,r["default"])(e)};t.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},t.isObject=function(e){return"[object Object]"===Object.prototype.toString.call(e)},t.isHtmlElement=function(e){return e&&e.nodeType===Node.ELEMENT_NODE};var o,a=n(4478),s=(o=a)&&o.__esModule?o:{"default":o},u=function(e){return e&&"[object Function]"==={}.toString.call(e)};"object"===("undefined"==typeof Int8Array?"undefined":i(Int8Array))||!s["default"].prototype.$isServer&&"function"==typeof document.childNodes||(t.isFunction=u=function(e){return"function"==typeof e||!1}),t.isFunction=u,t.isUndefined=function(e){return void 0===e},t.isDefined=function(e){return e!==undefined&&null!==e}},2417:function(e,t,n){"use strict";var r=n(477)(n(9367));t.__esModule=!0,t.isMac=t.isEmpty=t.isEqual=t.arrayEquals=t.looseEqual=t.capitalize=t.kebabCase=t.autoprefixer=t.isFirefox=t.isEdge=t.isIE=t.coerceTruthyValueToArray=t.arrayFind=t.arrayFindIndex=t.escapeRegexpString=t.valueEquals=t.generateId=t.getValueByPath=undefined;var i="function"==typeof Symbol&&"symbol"===(0,r["default"])(Symbol.iterator)?function(e){return(0,r["default"])(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":(0,r["default"])(e)};t.noop=function(){},t.hasOwn=function(e,t){return c.call(e,t)},t.toObject=function(e){for(var t={},n=0;n0&&arguments[0]!==undefined?arguments[0]:"";return String(e).replace(/[|\\{}()[\]^$+*?.]/g,"\\$&")};var d=t.arrayFindIndex=function(e,t){for(var n=0;n!==e.length;++n)if(t(e[n]))return n;return-1},f=(t.arrayFind=function(e,t){var n=d(e,t);return-1!==n?e[n]:undefined},t.coerceTruthyValueToArray=function(e){return Array.isArray(e)?e:e?[e]:[]},t.isIE=function(){return!s["default"].prototype.$isServer&&!isNaN(Number(document.documentMode))},t.isEdge=function(){return!s["default"].prototype.$isServer&&navigator.userAgent.indexOf("Edge")>-1},t.isFirefox=function(){return!s["default"].prototype.$isServer&&!!window.navigator.userAgent.match(/firefox/i)},t.autoprefixer=function(e){if("object"!==(void 0===e?"undefined":i(e)))return e;var t=["ms-","webkit-"];return["transform","transition","animation"].forEach((function(n){var r=e[n];n&&r&&t.forEach((function(t){e[t+n]=r}))})),e},t.kebabCase=function(e){var t=/([^-])([A-Z])/g;return e.replace(t,"$1-$2").replace(t,"$1-$2").toLowerCase()},t.capitalize=function(e){return(0,u.isString)(e)?e.charAt(0).toUpperCase()+e.slice(1):e},t.looseEqual=function(e,t){var n=(0,u.isObject)(e),r=(0,u.isObject)(t);return n&&r?JSON.stringify(e)===JSON.stringify(t):!n&&!r&&String(e)===String(t)}),p=t.arrayEquals=function(e,t){if(t=t||[],(e=e||[]).length!==t.length)return!1;for(var n=0;n0&&arguments[0]!==undefined?arguments[0]:{},i=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};!(n&&n.context&&r.target&&i.target)||e.contains(r.target)||e.contains(i.target)||e===r.target||n.context.popperElm&&(n.context.popperElm.contains(r.target)||n.context.popperElm.contains(i.target))||(t.expression&&e[u].methodName&&n.context[e[u].methodName]?n.context[e[u].methodName]():e[u].bindingFn&&e[u].bindingFn())}}!o["default"].prototype.$isServer&&(0,a.on)(document,"mousedown",(function(e){return i=e})),!o["default"].prototype.$isServer&&(0,a.on)(document,"mouseup",(function(e){s.forEach((function(t){return t[u].documentHandler(e,i)}))})),t["default"]={bind:function(e,t,n){s.push(e);var r=c++;e[u]={id:r,documentHandler:l(e,t,n),methodName:t.expression,bindingFn:t.value}},update:function(e,t,n){e[u].documentHandler=l(e,t,n),e[u].methodName=t.expression,e[u].bindingFn=t.value},unbind:function(e){for(var t=s.length,n=0;n-1}t.once=function(e,t,n){d(e,t,(function r(){n&&n.apply(this,arguments),f(e,t,r)}))};var h=t.getStyle=u<9?function(e,t){if(!o){if(!e||!t)return null;"float"===(t=l(t))&&(t="styleFloat");try{if("opacity"===t)try{return e.filters.item("alpha").opacity/100}catch(n){return 1}return e.style[t]||e.currentStyle?e.currentStyle[t]:null}catch(n){return e.style[t]}}}:function(e,t){if(!o){if(!e||!t)return null;"float"===(t=l(t))&&(t="cssFloat");try{var n=document.defaultView.getComputedStyle(e,"");return e.style[t]||n?n[t]:null}catch(r){return e.style[t]}}},m=t.isScroll=function(e,t){if(!o){var n=null!==t&&t!==undefined;return h(e,n?t?"overflow-y":"overflow-x":"overflow").match(/(scroll|auto|overlay)/)}};t.getScrollContainer=function(e,t){if(!o){for(var n=e;n;){if([window,document,document.documentElement].includes(n))return window;if(m(n,t))return n;n=n.parentNode}return n}},t.isInContainer=function(e,t){if(o||!e||!t)return!1;var n,r=e.getBoundingClientRect();return n=[window,document,document.documentElement,null,undefined].includes(t)?{top:0,right:window.innerWidth,bottom:window.innerHeight,left:0}:t.getBoundingClientRect(),r.topn.top&&r.right>n.left&&r.left>>6,u[l++]=128|63&s):s<55296||s>=57344?(u[l++]=224|s>>>12,u[l++]=128|s>>>6&63,u[l++]=128|63&s):(s=65536+((1023&s)<<10|1023&e.charCodeAt(++o)),u[l++]=240|s>>>18,u[l++]=128|s>>>12&63,u[l++]=128|s>>>6&63,u[l++]=128|63&s);e=u}else{if("object"!==a)throw new Error(t);if(null===e)throw new Error(t);if(d&&e.constructor===ArrayBuffer)e=new Uint8Array(e);else if(!(Array.isArray(e)||d&&ArrayBuffer.isView(e)))throw new Error(t)}e.length>64&&(e=new E(n,!0).update(e).array());var f=[],p=[];for(o=0;o<64;++o){var h=e[o]||0;f[o]=92^h,p[o]=54^h}E.call(this,n,r),this.update(p),this.oKeyPad=f,this.inner=!0,this.sharedMemory=r}E.prototype.update=function(e){if(!this.finalized){var n,r=(0,i["default"])(e);if("string"!==r){if("object"!==r)throw new Error(t);if(null===e)throw new Error(t);if(d&&e.constructor===ArrayBuffer)e=new Uint8Array(e);else if(!(Array.isArray(e)||d&&ArrayBuffer.isView(e)))throw new Error(t);n=!0}for(var o,a,s=0,u=e.length,c=this.blocks;s>>2]|=e[s]<>>2]|=o<>>2]|=(192|o>>>6)<>>2]|=(128|63&o)<=57344?(c[a>>>2]|=(224|o>>>12)<>>2]|=(128|o>>>6&63)<>>2]|=(128|63&o)<>>2]|=(240|o>>>18)<>>2]|=(128|o>>>12&63)<>>2]|=(128|o>>>6&63)<>>2]|=(128|63&o)<=64?(this.block=c[16],this.start=a-64,this.hash(),this.hashed=!0):this.start=a}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296|0,this.bytes=this.bytes%4294967296),this}},E.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var e=this.blocks,t=this.lastByteIndex;e[16]=this.block,e[t>>>2]|=p[3&t],this.block=e[16],t>=56&&(this.hashed||this.hash(),e[0]=this.block,e[16]=e[1]=e[2]=e[3]=e[4]=e[5]=e[6]=e[7]=e[8]=e[9]=e[10]=e[11]=e[12]=e[13]=e[14]=e[15]=0),e[14]=this.hBytes<<3|this.bytes>>>29,e[15]=this.bytes<<3,this.hash()}},E.prototype.hash=function(){var e,t,n,r,i,o,a,s,u,c=this.h0,l=this.h1,d=this.h2,f=this.h3,p=this.h4,h=this.h5,g=this.h6,v=this.h7,_=this.blocks;for(e=16;e<64;++e)t=((i=_[e-15])>>>7|i<<25)^(i>>>18|i<<14)^i>>>3,n=((i=_[e-2])>>>17|i<<15)^(i>>>19|i<<13)^i>>>10,_[e]=_[e-16]+t+_[e-7]+n|0;for(u=l&d,e=0;e<64;e+=4)this.first?(this.is224?(o=300032,v=(i=_[0]-1413257819)-150054599|0,f=i+24177077|0):(o=704751109,v=(i=_[0]-210244248)-1521486534|0,f=i+143694565|0),this.first=!1):(t=(c>>>2|c<<30)^(c>>>13|c<<19)^(c>>>22|c<<10),r=(o=c&l)^c&d^u,v=f+(i=v+(n=(p>>>6|p<<26)^(p>>>11|p<<21)^(p>>>25|p<<7))+(p&h^~p&g)+m[e]+_[e])|0,f=i+(t+r)|0),t=(f>>>2|f<<30)^(f>>>13|f<<19)^(f>>>22|f<<10),r=(a=f&c)^f&l^o,g=d+(i=g+(n=(v>>>6|v<<26)^(v>>>11|v<<21)^(v>>>25|v<<7))+(v&p^~v&h)+m[e+1]+_[e+1])|0,t=((d=i+(t+r)|0)>>>2|d<<30)^(d>>>13|d<<19)^(d>>>22|d<<10),r=(s=d&f)^d&c^a,h=l+(i=h+(n=(g>>>6|g<<26)^(g>>>11|g<<21)^(g>>>25|g<<7))+(g&v^~g&p)+m[e+2]+_[e+2])|0,t=((l=i+(t+r)|0)>>>2|l<<30)^(l>>>13|l<<19)^(l>>>22|l<<10),r=(u=l&d)^l&f^s,p=c+(i=p+(n=(h>>>6|h<<26)^(h>>>11|h<<21)^(h>>>25|h<<7))+(h&g^~h&v)+m[e+3]+_[e+3])|0,c=i+(t+r)|0,this.chromeBugWorkAround=!0;this.h0=this.h0+c|0,this.h1=this.h1+l|0,this.h2=this.h2+d|0,this.h3=this.h3+f|0,this.h4=this.h4+p|0,this.h5=this.h5+h|0,this.h6=this.h6+g|0,this.h7=this.h7+v|0},E.prototype.hex=function(){this.finalize();var e=this.h0,t=this.h1,n=this.h2,r=this.h3,i=this.h4,o=this.h5,a=this.h6,s=this.h7,u=f[e>>>28&15]+f[e>>>24&15]+f[e>>>20&15]+f[e>>>16&15]+f[e>>>12&15]+f[e>>>8&15]+f[e>>>4&15]+f[15&e]+f[t>>>28&15]+f[t>>>24&15]+f[t>>>20&15]+f[t>>>16&15]+f[t>>>12&15]+f[t>>>8&15]+f[t>>>4&15]+f[15&t]+f[n>>>28&15]+f[n>>>24&15]+f[n>>>20&15]+f[n>>>16&15]+f[n>>>12&15]+f[n>>>8&15]+f[n>>>4&15]+f[15&n]+f[r>>>28&15]+f[r>>>24&15]+f[r>>>20&15]+f[r>>>16&15]+f[r>>>12&15]+f[r>>>8&15]+f[r>>>4&15]+f[15&r]+f[i>>>28&15]+f[i>>>24&15]+f[i>>>20&15]+f[i>>>16&15]+f[i>>>12&15]+f[i>>>8&15]+f[i>>>4&15]+f[15&i]+f[o>>>28&15]+f[o>>>24&15]+f[o>>>20&15]+f[o>>>16&15]+f[o>>>12&15]+f[o>>>8&15]+f[o>>>4&15]+f[15&o]+f[a>>>28&15]+f[a>>>24&15]+f[a>>>20&15]+f[a>>>16&15]+f[a>>>12&15]+f[a>>>8&15]+f[a>>>4&15]+f[15&a];return this.is224||(u+=f[s>>>28&15]+f[s>>>24&15]+f[s>>>20&15]+f[s>>>16&15]+f[s>>>12&15]+f[s>>>8&15]+f[s>>>4&15]+f[15&s]),u},E.prototype.toString=E.prototype.hex,E.prototype.digest=function(){this.finalize();var e=this.h0,t=this.h1,n=this.h2,r=this.h3,i=this.h4,o=this.h5,a=this.h6,s=this.h7,u=[e>>>24&255,e>>>16&255,e>>>8&255,255&e,t>>>24&255,t>>>16&255,t>>>8&255,255&t,n>>>24&255,n>>>16&255,n>>>8&255,255&n,r>>>24&255,r>>>16&255,r>>>8&255,255&r,i>>>24&255,i>>>16&255,i>>>8&255,255&i,o>>>24&255,o>>>16&255,o>>>8&255,255&o,a>>>24&255,a>>>16&255,a>>>8&255,255&a];return this.is224||u.push(s>>>24&255,s>>>16&255,s>>>8&255,255&s),u},E.prototype.array=E.prototype.digest,E.prototype.arrayBuffer=function(){this.finalize();var e=new ArrayBuffer(this.is224?28:32),t=new DataView(e);return t.setUint32(0,this.h0),t.setUint32(4,this.h1),t.setUint32(8,this.h2),t.setUint32(12,this.h3),t.setUint32(16,this.h4),t.setUint32(20,this.h5),t.setUint32(24,this.h6),this.is224||t.setUint32(28,this.h7),e},A.prototype=new E,A.prototype.finalize=function(){if(E.prototype.finalize.call(this),this.inner){this.inner=!1;var e=this.array();E.call(this,this.is224,this.sharedMemory),this.update(this.oKeyPad),this.update(e),E.prototype.finalize.call(this)}};var C=y();C.sha256=C,C.sha224=y(!0),C.sha256.hmac=w(),C.sha224.hmac=w(!0),c?e.exports=C:(a.sha256=C.sha256,a.sha224=C.sha224,l&&((r=function(){return C}.call(C,n,C,e))===undefined||(e.exports=r)))}()},210:function(){"use strict";!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){var e={javascript:"clike",actionscript:"javascript",apex:["clike","sql"],arduino:"cpp",aspnet:["markup","csharp"],birb:"clike",bison:"c",c:"clike",csharp:"clike",cpp:"c",cfscript:"clike",chaiscript:["clike","cpp"],cilkc:"c",cilkcpp:"cpp",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],etlua:["lua","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",ftl:"markup-templating",gml:"clike",glsl:"c",go:"clike",gradle:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",hlsl:"c",idris:"haskell",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike","typescript"],"js-extras":"javascript",json5:"json",jsonp:"json","js-templates":"javascript",kotlin:"clike",latte:["clike","markup-templating","php"],less:"css",lilypond:"scheme",liquid:"markup-templating",markdown:"markup","markup-templating":"markup",mongodb:"javascript",n4js:"javascript",objectivec:"c",opencl:"c",parser:"markup",php:"markup-templating",phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],purebasic:"clike",purescript:"haskell",qsharp:"clike",qml:"javascript",qore:"clike",racket:"scheme",cshtml:["markup","csharp"],jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",solidity:"clike",soy:"markup-templating",sparql:"turtle",sqf:"clike",squirrel:"clike",stata:["mata","java","python"],"t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","vbnet"],tap:"yaml",tt2:["clike","markup-templating"],textile:"markup",twig:"markup-templating",typescript:"javascript",v:"clike",vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup","xml-doc":"markup",xquery:"markup"},t={html:"markup",xml:"markup",svg:"markup",mathml:"markup",ssml:"markup",atom:"markup",rss:"markup",js:"javascript",g4:"antlr4",ino:"arduino","arm-asm":"armasm",art:"arturo",adoc:"asciidoc",avs:"avisynth",avdl:"avro-idl",gawk:"awk",sh:"bash",shell:"bash",shortcode:"bbcode",rbnf:"bnf",oscript:"bsl",cs:"csharp",dotnet:"csharp",cfc:"cfscript","cilk-c":"cilkc","cilk-cpp":"cilkcpp",cilk:"cilkcpp",coffee:"coffeescript",conc:"concurnas",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gv:"dot",eta:"ejs",xlsx:"excel-formula",xls:"excel-formula",gamemakerlanguage:"gml",po:"gettext",gni:"gn",ld:"linker-script","go-mod":"go-module",hbs:"handlebars",mustache:"handlebars",hs:"haskell",idr:"idris",gitignore:"ignore",hgignore:"ignore",npmignore:"ignore",webmanifest:"json",kt:"kotlin",kts:"kotlin",kum:"kumir",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",moon:"moonscript",n4jsd:"n4js",nani:"naniscript",objc:"objectivec",qasm:"openqasm",objectpascal:"pascal",px:"pcaxis",pcode:"peoplecode",plantuml:"plant-uml",pq:"powerquery",mscript:"powerquery",pbfasm:"purebasic",purs:"purescript",py:"python",qs:"qsharp",rkt:"racket",razor:"cshtml",rpy:"renpy",res:"rescript",robot:"robotframework",rb:"ruby","sh-session":"shell-session",shellsession:"shell-session",smlnj:"sml",sol:"solidity",sln:"solution-file",rq:"sparql",sclang:"supercollider",t4:"t4-cs",trickle:"tremor",troy:"tremor",trig:"turtle",ts:"typescript",tsconfig:"typoscript",uscript:"unrealscript",uc:"unrealscript",url:"uri",vb:"visual-basic",vba:"visual-basic",webidl:"web-idl",mathematica:"wolfram",nb:"wolfram",wl:"wolfram",xeoracube:"xeora",yml:"yaml"},n={},r="components/",i=Prism.util.currentScript();if(i){var o=/\bplugins\/autoloader\/prism-autoloader\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i,a=/(^|\/)[\w-]+\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i,s=i.getAttribute("data-autoloader-path");if(null!=s)r=s.trim().replace(/\/?$/,"/");else{var u=i.src;o.test(u)?r=u.replace(o,"components/"):a.test(u)&&(r=u.replace(a,"$1components/"))}}var c=Prism.plugins.autoloader={languages_path:r,use_minified:!0,loadLanguages:d};Prism.hooks.add("complete",(function(e){var t=e.element,n=e.language;if(t&&n&&"none"!==n){var r=function(e){var t=(e.getAttribute("data-dependencies")||"").trim();if(!t){var n=e.parentElement;n&&"pre"===n.tagName.toLowerCase()&&(t=(n.getAttribute("data-dependencies")||"").trim())}return t?t.split(/\s*,\s*/g):[]}(t);/^diff-./i.test(n)?(r.push("diff"),r.push(n.substr(5))):r.push(n),r.every(l)||d(r,(function(){Prism.highlightElement(t)}))}}))}function l(e){if(e.indexOf("!")>=0)return!1;if((e=t[e]||e)in Prism.languages)return!0;var r=n[e];return r&&!r.error&&!1===r.loading}function d(r,i,o){"string"==typeof r&&(r=[r]);var a=r.length,s=0,u=!1;function p(){u||++s===a&&i&&i(r)}0!==a?r.forEach((function(r){!function(r,i,o){var a=r.indexOf("!")>=0;function s(){var e=n[r];e||(e=n[r]={callbacks:[]}),e.callbacks.push({success:i,error:o}),!a&&l(r)?f(r,"success"):!a&&e.error?f(r,"error"):!a&&e.loading||(e.loading=!0,e.error=!1,function(e,t,n){var r=document.createElement("script");r.src=e,r.async=!0,r.onload=function(){document.body.removeChild(r),t&&t()},r.onerror=function(){document.body.removeChild(r),n&&n()},document.body.appendChild(r)}(function(e){return c.languages_path+"prism-"+e+(c.use_minified?".min":"")+".js"}(r),(function(){e.loading=!1,f(r,"success")}),(function(){e.loading=!1,e.error=!0,f(r,"error")})))}r=r.replace("!",""),r=t[r]||r;var u=e[r];u&&u.length?d(u,s,o):s()}(r,p,(function(){u||(u=!0,o&&o(r))}))})):i&&setTimeout(i,0)}function f(e,t){if(n[e]){for(var r=n[e].callbacks,i=0,o=r.length;i=d.reach);E+=w.value.length,w=w.next){var A=w.value;if(t.length>e.length)return;if(!(A instanceof o)){var C,x=1;if(_){if(!(C=a(k,E,e,v))||C.index>=e.length)break;var I=C.index,D=C.index+C[0].length,S=E;for(S+=w.value.length;I>=S;)S+=(w=w.next).value.length;if(E=S-=w.value.length,w.value instanceof o)continue;for(var O=w;O!==t.tail&&(Sd.reach&&(d.reach=P);var F=w.prev;if(M&&(F=c(t,F,M),E+=M.length),l(t,F,x),w=c(t,F,new o(f,g?i.tokenize(T,g):T,y,T)),N&&c(t,w,N),x>1){var L={cause:f+","+h,reach:P};s(e,t,n,w.prev,E,L),d&&L.reach>d.reach&&(d.reach=L.reach)}}}}}}function u(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var r=t.next,i={value:n,prev:t,next:r};return t.next=i,r.prev=i,e.length++,i}function l(e,t,n){for(var r=t.next,i=0;i"+r.content+""},!e.document)return e.addEventListener?(i.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),r=n.language,o=n.code,a=n.immediateClose;e.postMessage(i.highlight(o,i.languages[r],r)),a&&e.close()}),!1),i):i;var d=i.util.currentScript();function f(){i.manual||i.highlightAll()}if(d&&(i.filename=d.src,d.hasAttribute("data-manual")&&(i.manual=!0)),!i.manual){var p=document.readyState;"loading"===p||"interactive"===p&&d&&d.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return i}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=r),"undefined"!=typeof n.g&&(n.g.Prism=r),r.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},r.languages.markup.tag.inside["attr-value"].inside.entity=r.languages.markup.entity,r.languages.markup.doctype.inside["internal-subset"].inside=r.languages.markup,r.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(r.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:r.languages[t]},n.cdata=/^$/i;var i={"included-cdata":{pattern://i,inside:n}};i["language-"+t]={pattern:/[\s\S]+/,inside:r.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:i},r.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(r.languages.markup.tag,"addAttribute",{value:function(e,t){r.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:r.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),r.languages.html=r.languages.markup,r.languages.mathml=r.languages.markup,r.languages.svg=r.languages.markup,r.languages.xml=r.languages.extend("markup",{}),r.languages.ssml=r.languages.xml,r.languages.atom=r.languages.xml,r.languages.rss=r.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{"function":/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,"function":{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(r),r.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,"function":/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},r.languages.javascript=r.languages.extend("clike",{"class-name":[r.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],"function":/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),r.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,r.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:r.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:r.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:r.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:r.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:r.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),r.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:r.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),r.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),r.languages.markup&&(r.languages.markup.tag.addInlined("script","javascript"),r.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),r.languages.js=r.languages.javascript,function(){if(void 0!==r&&"undefined"!=typeof document){Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var e={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},t="data-src-status",n="loading",i="loaded",o="pre[data-src]:not(["+t+'="'+i+'"]):not(['+t+'="'+n+'"])';r.hooks.add("before-highlightall",(function(e){e.selector+=", "+o})),r.hooks.add("before-sanity-check",(function(a){var s=a.element;if(s.matches(o)){a.code="",s.setAttribute(t,n);var u=s.appendChild(document.createElement("CODE"));u.textContent="Loading…";var c=s.getAttribute("data-src"),l=a.language;if("none"===l){var d=(/\.(\w+)$/.exec(c)||[,"none"])[1];l=e[d]||d}r.util.setLanguage(u,l),r.util.setLanguage(s,l);var f=r.plugins.autoloader;f&&f.loadLanguages(l),function(e,t,n){var r=new XMLHttpRequest;r.open("GET",e,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?t(r.responseText):r.status>=400?n("✖ Error "+r.status+" while fetching file: "+r.statusText):n("✖ Error: File does not exist or is empty"))},r.send(null)}(c,(function(e){s.setAttribute(t,i);var n=function(e){var t=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(e||"");if(t){var n=Number(t[1]),r=t[2],i=t[3];return r?i?[n,Number(i)]:[n,undefined]:[n,n]}return undefined}(s.getAttribute("data-range"));if(n){var o=e.split(/\r\n?|\n/g),a=n[0],c=null==n[1]?o.length:n[1];a<0&&(a+=o.length),a=Math.max(0,Math.min(a-1,o.length)),c<0&&(c+=o.length),c=Math.max(0,Math.min(c,o.length)),e=o.slice(a,c).join("\n"),s.hasAttribute("data-start")||s.setAttribute("data-start",String(a+1))}u.textContent=e,r.highlightElement(u)}),(function(e){s.setAttribute(t,"failed"),u.textContent=e}))}})),r.plugins.fileHighlight={highlight:function(e){for(var t,n=(e||document).querySelectorAll(o),i=0;t=n[i++];)r.highlightElement(t)}};var a=!1;r.fileHighlight=function(){a||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),a=!0),r.plugins.fileHighlight.highlight.apply(this,arguments)}}}()},8926:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(8323)),o=r(n(1452)),a=r(n(2053));t.A={components:{TkComments:i["default"],TkFooter:o["default"],TkAdmin:a["default"]},data:function(){return{showAdmin:!1,showAdminEntry:!1}},methods:{onShowAdminEntry:function(e){this.showAdminEntry=e}}}},3397:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(3491)),o=r(n(6370)),a=r(n(6359)),s=r(n(5910));t.A={data:function(){return{iconComment:i["default"],iconCommentSolid:o["default"],iconLike:a["default"],iconLikeSolid:s["default"]}},props:{liked:Boolean,likeCount:Number,repliesCount:Number},computed:{likeCountStr:function(){return this.likeCount>0?"".concat(this.likeCount):""},repliesCountStr:function(){return this.repliesCount>0?"".concat(this.repliesCount):""}},methods:{onLike:function(e){e.preventDefault(),this.$emit("like")},onReply:function(e){e.preventDefault(),this.$emit("reply")}}}},4238:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(479)),o=r(n(4964)),a=r(n(2889)),s=r(n(8559)),u=r(n(1140)),c=r(n(9985)),l=r(n(9097)),d=n(8129),f=r(n(9671));t.A={components:{TkAdminComment:s["default"],TkAdminConfig:u["default"],TkAdminImport:c["default"],TkAdminExport:l["default"]},props:{show:Boolean},data:function(){return{iconClose:f["default"],loading:!0,version:"",needUpdate:!1,isLogin:!1,isSetPassword:!0,isSetCredentials:!1,credentials:"",password:"",passwordConfirm:"",loginErrorMessage:"",activeTabName:"comment"}},computed:{canRegist:function(){return!this.isSetPassword&&!!this.password&&this.password===this.passwordConfirm&&(this.isSetCredentials||this.credentials)}},methods:{t:d.t,onLogin:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n,r;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(e.password){t.next=3;break}return e.loginErrorMessage=(0,d.t)("ADMIN_PASSWORD_REQUIRED"),t.abrupt("return");case 3:return e.loading=!0,e.loginErrorMessage="",n=(0,a["default"])(e.password),t.next=8,(0,d.call)(e.$tcb,"LOGIN",{password:n});case 8:if(!(r=t.sent).result.message){t.next=13;break}e.loginErrorMessage=r.result.message,t.next=28;break;case 13:if(!r.result.ticket){t.next=27;break}return t.prev=14,t.next=17,e.$tcb.auth.customAuthProvider().signIn(r.result.ticket);case 17:d.logger.log("登录成功"),e.password="",e.checkAuth(),t.next=25;break;case 22:t.prev=22,t.t0=t["catch"](14),d.logger.error("登录失败",t.t0);case 25:t.next=28;break;case 27:0===r.result.code&&(d.logger.log("登录成功"),localStorage.setItem("twikoo-access-token",n),e.password="",e.checkAuth());case 28:e.loading=!1;case 29:case"end":return t.stop()}}),t,null,[[14,22]])})))()},onLogout:function(e){var t=this;return(0,o["default"])(i["default"].mark((function n(){return i["default"].wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(e.preventDefault(),t.loading=!0,!t.$tcb){n.next=9;break}return n.next=5,t.$tcb.auth.signOut();case 5:return n.next=7,t.$tcb.auth.anonymousAuthProvider().signIn();case 7:n.next=10;break;case 9:localStorage.removeItem("twikoo-access-token");case 10:t.isLogin=!1,t.loading=!1;case 12:case"end":return n.stop()}}),n)})))()},onRegist:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n,r;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading=!0,n=(0,a["default"])(e.password),t.next=4,(0,d.call)(e.$tcb,"SET_PASSWORD",{password:n,credentials:e.credentials});case 4:(r=t.sent).result.code?(e.loginErrorMessage=(0,d.t)("ADMIN_REGIST_FAILED"),r.result.message&&(e.loginErrorMessage+=","+r.result.message),d.logger.warn("Twikoo 注册失败",r)):(e.passwordMd5="",e.isSetPassword=!0,e.onLogin()),e.loading=!1;case 7:case"end":return t.stop()}}),t)})))()},onShow:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading=!0,t.next=3,e.checkAuth();case 3:if(e.isLogin){t.next=7;break}return t.next=6,e.checkIfPasswordSet();case 6:e.focusPassword();case 7:e.loading=!1;case 8:case"end":return t.stop()}}),t)})))()},focusPassword:function(){var e=this;setTimeout((function(){e.$refs.focusme&&e.$refs.focusme.focus()}),500)},checkAuth:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n,r;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!e.$tcb){t.next=7;break}return t.next=3,e.$tcb.auth.getCurrenUser();case 3:n=t.sent,e.isLogin="CUSTOM"===n.loginType,t.next=11;break;case 7:return t.next=9,(0,d.call)(e.$tcb,"GET_CONFIG");case 9:(r=t.sent)&&r.result&&r.result.config&&(e.isLogin=r.result.config.IS_ADMIN);case 11:case"end":return t.stop()}}),t)})))()},checkIfPasswordSet:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.prev=0,t.next=3,(0,d.call)(e.$tcb,"GET_PASSWORD_STATUS");case 3:n=t.sent,e.version=n.result.version,e.isSetPassword=n.result.status,e.isSetCredentials=!e.$tcb,t.next=14;break;case 9:throw t.prev=9,t.t0=t["catch"](0),e.needUpdate=!0,e.loading=!1,t.t0;case 14:case"end":return t.stop()}}),t,null,[[0,9]])})))()},onClose:function(e){e.preventDefault(),this.$emit("close")}},watch:{show:function(e){e&&this.onShow()}}}},4555:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(479)),o=r(n(4964)),a=n(1085),s=n(8129),u=n(2199),c=r(n(4785)),l=r(n(6431));t.A={components:{TkAvatar:c["default"],TkPagination:l["default"]},data:function(){return{loading:!0,comments:[],serverConfig:{},serverVersion:this.$twikoo.serverConfig.VERSION,clientVersion:u.version,count:0,pageSize:5,currentPage:1,filter:{keyword:"",type:""}}},methods:{t:s.t,displayCreated:function(e){return(0,s.timeago)(e.created)},convertLink:function(e){return(0,s.convertLink)(e)},getComments:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading=!0,t.next=3,(0,s.call)(e.$tcb,"COMMENT_GET_FOR_ADMIN",{per:e.pageSize,page:e.currentPage,keyword:e.filter.keyword,type:e.filter.type});case 3:(n=t.sent).result&&!n.result.code&&(e.count=n.result.count,e.comments=n.result.data),e.$nextTick((function(){(0,s.renderLinks)(e.$refs.comments),(0,s.renderMath)(e.$refs["comment-list"],e.$twikoo.katex),e.highlightCode()})),e.loading=!1;case 7:case"end":return t.stop()}}),t)})))()},getConfig:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,(0,s.call)(e.$tcb,"GET_CONFIG_FOR_ADMIN");case 2:(n=t.sent).result&&!n.result.code&&(e.serverConfig=n.result.config,e.checkConfig());case 4:case"end":return t.stop()}}),t)})))()},checkConfig:function(){var e=this;this.serverConfig.HIGHLIGHT||(this.serverConfig.HIGHLIGHT="true");var t={},n=localStorage.getItem("twikoo");n&&(t=JSON.parse(n)),["nick","mail","avatar"].forEach((function(n){t[n]?e.serverConfig[n]=t[n]:e.serverConfig[n]=""})),!t.nick&&this.serverConfig.BLOGGER_NICK&&(t.nick=this.serverConfig.BLOGGER_NICK),!t.mail&&this.serverConfig.BLOGGER_EMAIL&&(t.mail=this.serverConfig.BLOGGER_EMAIL),!t.link&&this.serverConfig.SITE_URL&&(t.link=this.serverConfig.SITE_URL),localStorage.setItem("twikoo",JSON.stringify(t)),a.app.$emit("initMeta")},onPageSizeChange:function(e){this.pageSize=e,this.getComments()},switchPage:function(e){this.currentPage=e,this.getComments()},handleView:function(e){window.open("".concat(e.url,"#").concat(e._id))},handleDelete:function(e){var t=this;return(0,o["default"])(i["default"].mark((function n(){return i["default"].wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(confirm((0,s.t)("ADMIN_COMMENT_DELETE_CONFIRM"))){n.next=2;break}return n.abrupt("return");case 2:return t.loading=!0,n.next=5,(0,s.call)(t.$tcb,"COMMENT_DELETE_FOR_ADMIN",{id:e._id});case 5:return n.next=7,t.getComments();case 7:t.loading=!1;case 8:case"end":return n.stop()}}),n)})))()},handleSpam:function(e,t){this.setComment(e,{isSpam:t})},handleTop:function(e,t){this.setComment(e,{top:t})},setComment:function(e,t){var n=this;return(0,o["default"])(i["default"].mark((function r(){return i["default"].wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return n.loading=!0,r.next=3,(0,s.call)(n.$tcb,"COMMENT_SET_FOR_ADMIN",{id:e._id,set:t});case 3:return r.next=5,n.getComments();case 5:n.loading=!1;case 6:case"end":return r.stop()}}),r)})))()},highlightCode:function(){"true"===this.serverConfig.HIGHLIGHT&&(0,s.renderCode)(this.$refs["comment-list"],this.serverConfig.HIGHLIGHT_THEME,this.serverConfig.HIGHLIGHT_PLUGIN)}},mounted:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,Promise.all([e.getConfig(),e.getComments()]);case 2:e.highlightCode();case 3:case"end":return t.stop()}}),t)})))()}}},4868:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(479)),o=r(n(4964)),a=n(8129),s=n(2199);function u(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return c(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,o=e},f:function(){try{a||null==n["return"]||n["return"]()}finally{if(s)throw o}}}}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&this.$refs["tk-replies"]&&(this.hasExpand=this.$refs["tk-replies"].scrollHeight>236)},showContentExpandIfNeed:function(){this.hasContentExpand=this.hasContentExpand||this.$refs["tk-content"].scrollHeight>500},showContentExpandIfNeedAfterImagesLoaded:function(){var e=this;this.$refs["tk-content"].querySelectorAll("img").forEach((function(t){t.onload=e.showContentExpandIfNeed}))},scrollToComment:function(){-1!==window.location.hash.indexOf(this.comment.id)&&(this.$refs["tk-comment"].scrollIntoView({behavior:"smooth"}),this.$emit("expand"))},onLike:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!e.likeLoading){t.next=2;break}return t.abrupt("return");case 2:return e.likeLoading=!0,t.next=5,(0,a.call)(e.$tcb,"COMMENT_LIKE",{id:e.comment.id});case 5:e.liked?e.like--:e.like++,e.liked=!e.liked,e.likeLoading=!1;case 8:case"end":return t.stop()}}),t)})))()},onReply:function(e){this.pid=e,this.$emit("reply",this.comment.id)},onReplyReply:function(e){this.pid=e,e?this.$emit("reply",this.comment.id):this.$emit("reply","")},onCancel:function(){this.pid="",this.$emit("reply","")},onLoad:function(){this.comment.replies.length>0&&this.$refs["tk-replies"].lastElementChild.scrollIntoView({behavior:"smooth",block:"center"}),this.pid="",this.$emit("reply",""),this.$emit("load"),this.onExpand()},onExpand:function(){this.isExpanded=!0},onCollapse:function(){this.isExpanded=!1},onContentExpand:function(){this.isContentExpanded=!0},onContentCollapse:function(){this.isContentExpanded=!1},checkAuth:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!e.$tcb){t.next=7;break}return t.next=3,e.$tcb.auth.getCurrenUser();case 3:n=t.sent,e.isLogin="CUSTOM"===n.loginType,t.next=8;break;case 7:e.isLogin=e.$twikoo.serverConfig&&e.$twikoo.serverConfig.IS_ADMIN;case 8:case"end":return t.stop()}}),t)})))()},handleSpam:function(e,t){t.preventDefault(),this.setComment({isSpam:e})},handleTop:function(e,t){t.preventDefault(),this.setComment({top:e})},popupLightbox:function(e){if("true"===this.$twikoo.serverConfig.LIGHTBOX){var t=e.target;if("IMG"===t.tagName&&!t.classList.contains("tk-owo-emotion")){var n=document.createElement("div");n.className="tk-lightbox";var r=document.createElement("img");r.className="tk-lightbox-image",r.src=t.src,n.appendChild(r),n.addEventListener("click",(function(){document.body.removeChild(n)})),document.body.appendChild(n)}}},setComment:function(e){var t=this;return(0,o["default"])(i["default"].mark((function n(){return i["default"].wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return t.loading=!0,n.next=3,(0,a.call)(t.$tcb,"COMMENT_SET_FOR_ADMIN",{id:t.comment.id,set:e});case 3:t.loading=!1,t.$emit("load");case 5:case"end":return n.stop()}}),n)})))()}},mounted:function(){var e=this;this.$nextTick(this.showContentExpandIfNeed),this.$nextTick(this.showContentExpandIfNeedAfterImagesLoaded),this.$nextTick(this.showExpandIfNeed),this.$nextTick(this.scrollToComment),this.$nextTick((function(){(0,a.renderLinks)(e.$refs.comment),(0,a.renderMath)(e.$refs.comment,e.$twikoo.katex)})),this.checkAuth()},watch:{"comment.like":{handler:function(e){this.like=this.comment.like,this.liked=this.comment.liked},immediate:!0},"config.HIGHLIGHT":{handler:function(e){var t=this;"true"===e&&this.$nextTick((function(){(0,a.renderCode)(t.$refs.comment,t.config.HIGHLIGHT_THEME,t.config.HIGHLIGHT_PLUGIN)}))},immediate:!0}}}},4333:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(479)),o=r(n(4964)),a=n(8129),s=r(n(5438)),u=r(n(9078)),c=r(n(504)),l=r(n(9966)),d=r(n(4478));t.A={components:{TkSubmit:s["default"],TkComment:u["default"]},props:{showAdminEntry:Boolean},data:function(){return{loading:!0,loadingMore:!1,errorMessage:"",config:{},comments:[],showExpand:!0,count:0,replyId:"",iconSetting:c["default"],iconRefresh:l["default"]}},methods:{t:a.t,initConfig:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,(0,a.call)(e.$tcb,"GET_CONFIG");case 2:(n=t.sent)&&n.result&&n.result.config&&(e.config=n.result.config,d["default"].prototype.$twikoo.serverConfig=n.result.config);case 4:case"end":return t.stop()}}),t)})))()},initComments:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading=!0,n=(0,a.getUrl)(e.$twikoo.path),t.next=4,e.getComments({url:n});case 4:e.loading=!1;case 5:case"end":return t.stop()}}),t)})))()},refresh:function(){this.comments=[],this.initComments()},onExpand:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n,r;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(!e.loadingMore){t.next=2;break}return t.abrupt("return");case 2:return e.loadingMore=!0,n=(0,a.getUrl)(e.$twikoo.path),r=e.comments.filter((function(e){return!e.top})).map((function(e){return e.created})).sort((function(e,t){return e-t}))[0],t.next=7,e.getComments({url:n,before:r});case 7:e.loadingMore=!1;case 8:case"end":return t.stop()}}),t)})))()},onCommentLoaded:function(){"function"==typeof this.$twikoo.onCommentLoaded&&this.$twikoo.onCommentLoaded()},getComments:function(e){var t=this;return(0,o["default"])(i["default"].mark((function n(){var r;return i["default"].wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.prev=0,n.next=3,(0,a.call)(t.$tcb,"COMMENT_GET",e);case 3:(r=n.sent)&&r.result&&r.result.data&&(t.comments=e.before?t.comments.concat(r.result.data):r.result.data,t.showExpand=r.result.more,t.count=r.result.count||t.comments.length||0,t.$nextTick(t.onCommentLoaded)),n.next=10;break;case 7:n.prev=7,n.t0=n["catch"](0),t.errorMessage=n.t0.message;case 10:case"end":return n.stop()}}),n,null,[[0,7]])})))()},onReply:function(e){this.replyId=e},openAdmin:function(){this.$emit("admin")}},mounted:function(){this.initConfig(),this.initComments()}}},418:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(479)),o=r(n(4964)),a=n(2199),s=n(8129);t.A={data:function(){return{version:a.version,counter:{}}},methods:{getCounter:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n,r,o,a;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(n=document.getElementById("twikoo_visitors")){t.next=3;break}return t.abrupt("return");case 3:if(-1===["localhost","127.0.0.1","0.0.0.0"].indexOf(window.location.hostname)){t.next=5;break}return t.abrupt("return");case 5:return r=(0,s.getUrl)(e.$twikoo.path),o=(0,s.getHref)(e.$twikoo.href),t.next=9,(0,s.call)(e.$tcb,"COUNTER_GET",{url:r,href:o,title:document.title});case 9:a=t.sent,e.counter=a.result,(e.counter.time||0===e.counter.time)&&(n.innerHTML=e.counter.time);case 12:case"end":return t.stop()}}),t)})))()}},mounted:function(){this.getCounter()}}},2362:function(e,t,n){"use strict";Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var r=n(1085),i=n(8129),o=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;t.A={props:{nick:String,mail:String,link:String,config:Object},data:function(){return{metaInputs:[{key:"nick",locale:(0,i.t)("META_INPUT_NICK"),name:"nick",type:"text"},{key:"mail",locale:(0,i.t)("META_INPUT_MAIL"),name:"mail",type:"email"},{key:"link",locale:(0,i.t)("META_INPUT_LINK"),name:"link",type:"text"}],metaData:{nick:"",mail:"",link:""}}},computed:{displayedFields:function(){var e=this.config.DISPLAYED_FIELDS;return{nick:!e||-1!==e.indexOf("nick"),mail:!e||-1!==e.indexOf("mail"),link:!e||-1!==e.indexOf("link")}},displayedInputs:function(){var e=this;return this.metaInputs.filter((function(t){return!!e.displayedFields[t.key]}))},requiredFields:function(){var e=this.config.REQUIRED_FIELDS;return{nick:!e||-1!==e.indexOf("nick"),mail:!e||-1!==e.indexOf("mail"),link:!!e&&-1!==e.indexOf("link")}}},methods:{t:i.t,initMeta:function(){var e=localStorage.getItem("twikoo");if(e){var t=JSON.parse(e);this.metaData.nick=t.nick,this.metaData.mail=t.mail,this.metaData.link=t.link}this.updateMeta()},updateMeta:function(){localStorage.setItem("twikoo",JSON.stringify(this.metaData)),this.$emit("update",{meta:this.metaData,valid:this.checkValid()})},checkValid:function(){var e=o.test(this.metaData.mail);return(this.metaData.nick||!this.requiredFields.nick)&&(e||!this.requiredFields.mail)&&(this.metaData.link||!this.requiredFields.link)},checkQQ:function(){if((0,i.isQQ)(this.metaData.nick)){var e=this.metaData.nick.replace(/@qq.com/gi,""),t="".concat(e,"@qq.com");this.metaData.mail=t,this.getQQNick(e)}},getQQNick:function(e){var t=this,n="https://api.qjqq.cn/api/qqinfo?qq=".concat(e),r=new XMLHttpRequest;r.onreadystatechange=function(){if(4===r.readyState&&200===r.status){var e=JSON.parse(r.responseText);t.metaData.nick=e.name,t.updateMeta()}},r.open("GET",n),r.send()},checkAdminCrypt:function(){var e=this.$root.$children[0],t=!this.config.HIDE_ADMIN_CRYPT||this.config.HIDE_ADMIN_CRYPT===this.metaData.nick;e.onShowAdminEntry(t)},onMetaChange:function(){this.checkQQ(),this.updateMeta(),this.checkAdminCrypt()}},watch:{nick:function(e){this.metaData.nick=e},mail:function(e){this.metaData.mail=e},link:function(e){this.metaData.link=e},requiredFields:{handler:function(e,t){this.$emit("update",{meta:this.metaData,valid:this.checkValid()})},deep:!0},"config.VERSION":function(){this.checkAdminCrypt()}},mounted:function(){r.app.$on("initMeta",this.initMeta),this.initMeta()}}},9171:function(e,t,n){"use strict";Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var r=n(8129);t.A={props:{pageSize:{type:Number,"default":10},total:{type:Number,"default":0}},data:function(){return{currentPage:1,userInput:0,userPageSize:0,pagers:[]}},computed:{pageCount:function(){return Math.ceil(this.total/this.pageSize)}},methods:{t:r.t,generatePager:function(){for(var e=[],t=1;t<=this.pageCount;t++)Math.abs(this.currentPage-t)<3||1===t||t===this.pageCount?e.push({title:"".concat(t),page:t}):Math.abs(this.currentPage-t)<4&&e.push({title:"...",page:t});this.pagers=e},currentChange:function(e){this.currentPage=parseInt(e),this.currentPage>this.pageCount&&(this.currentPage=this.pageCount),this.userInput=0,this.$emit("current-change",this.currentPage),this.generatePager()},pageSizeChamge:function(e){this.userPageSize=0,this.$emit("page-size-change",parseInt(e))},handleInput:function(e){this.userInput=parseInt(e)},handleInputPageSize:function(e){this.userPageSize=parseInt(e)}},watch:{total:{handler:function(){this.generatePager()},immediate:!0},pageSize:{handler:function(){this.generatePager()}}}}},147:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"B",{value:!0}),t.A=void 0;var i=r(n(479)),o=r(n(4964)),a=r(n(1423)),s=r(n(6639)),u=r(n(5171)),c=r(n(2573)),l=r(n(4785)),d=r(n(3415)),f=n(8129),p=r(n(1628)),h=["apng","bmp","gif","jpeg","jpg","png","svg","tif","tiff","webp"];t.A={components:{TkAvatar:l["default"],TkMetaInput:d["default"]},directives:{Clickoutside:c["default"]},props:{replyId:String,pid:String,config:Object},data:function(){return{isSending:!1,isPreviewing:!1,isMetaValid:!1,errorMessage:"",owo:null,comment:"",commentHtml:"",nick:"",mail:"",link:"",turnstileLoad:null,iconMarkdown:a["default"],iconEmotion:s["default"],iconImage:u["default"]}},computed:{canSend:function(){return!this.isSending&&!!this.isMetaValid&&!!this.comment.trim()},textarea:function(){return this.$refs.textarea?this.$refs.textarea.$refs.textarea:null},commentPlaceholder:function(){var e=this.$twikoo.placeholder||this.config.COMMENT_PLACEHOLDER||"";return e=e.replace(/
/g,"\n")},maxLength:function(){var e=parseInt(this.config.LIMIT_LENGTH);return Number.isNaN(e)&&(e=500),e>0?e:null}},methods:{t:f.t,initDraft:function(){var e=localStorage.getItem("twikoo-draft");!this.comment&&e&&(this.comment=e)},saveDraft:function(){localStorage.setItem("twikoo-draft",this.comment)},initOwo:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if("true"!==e.config.SHOW_EMOTION){t.next=6;break}return t.next=3,(0,f.initOwoEmotions)(e.config.EMOTION_CDN||"https://owo.imaegoo.com/owo.json");case 3:n=t.sent,e.owo=new p["default"]({logo:s["default"],container:e.$refs.owo,target:e.textarea,odata:n,position:"down",maxHeight:"250px"}),f.marked.setOptions({odata:(0,f.initMarkedOwo)(n)});case 6:case"end":return t.stop()}}),t)})))()},initTurnstile:function(){var e=this;this.config.TURNSTILE_SITE_KEY&&(window.turnstile?this.turnstileLoad=Promise.resolve():this.turnstileLoad=new Promise((function(t,n){var r=document.createElement("script");r.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",r.onload=t,r.onerror=n,e.$refs["turnstile-container"].appendChild(r)})))},getTurnstileToken:function(){var e=this;return new Promise((function(t,n){e.turnstileLoad.then((function(){var r=window.turnstile.render(e.$refs.turnstile,{sitekey:e.config.TURNSTILE_SITE_KEY,callback:function(e){t(e),setTimeout((function(){window.turnstile.remove(r)}),5e3)},"error-callback":n})}))}))},onMetaUpdate:function(e){this.nick=e.meta.nick,this.mail=e.meta.mail,this.link=e.meta.link,this.isMetaValid=e.valid},cancel:function(){this.$emit("cancel")},onCommentInput:function(){this.saveDraft(),this.updatePreview()},preview:function(){this.isPreviewing=!this.isPreviewing,this.updatePreview()},updatePreview:function(){var e=this;this.isPreviewing&&(this.commentHtml=(0,f.marked)(this.comment),this.$nextTick((function(){(0,f.renderLinks)(e.$refs["comment-preview"]),(0,f.renderMath)(e.$refs["comment-preview"],e.$twikoo.katex),"true"===e.config.HIGHLIGHT&&(0,f.renderCode)(e.$refs["comment-preview"],e.config.HIGHLIGHT_THEME,e.config.HIGHLIGHT_PLUGIN)})))},send:function(){var e=this;return(0,o["default"])(i["default"].mark((function t(){var n,r;return i["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(e.isSending=!0,t.prev=1,!e.comment.match(new RegExp("!\\[".concat((0,f.t)("IMAGE_UPLOAD_PLACEHOLDER"),".+\\]\\(\\)")))){t.next=4;break}throw new Error((0,f.t)("IMAGE_UPLOAD_PLEASE_WAIT"));case 4:return t.t0=e.nick,t.t1=e.mail,t.t2=e.link,t.next=9,(0,f.getUserAgent)();case 9:if(t.t3=t.sent,t.t4=(0,f.getUrl)(e.$twikoo.path),t.t5=(0,f.getHref)(e.$twikoo.href),t.t6=(0,f.marked)(e.comment),t.t7=e.pid?e.pid:e.replyId,t.t8=e.replyId,n={nick:t.t0,mail:t.t1,link:t.t2,ua:t.t3,url:t.t4,href:t.t5,comment:t.t6,pid:t.t7,rid:t.t8},!e.config.TURNSTILE_SITE_KEY){t.next=20;break}return t.next=19,e.getTurnstileToken();case 19:n.turnstileToken=t.sent;case 20:return t.next=22,(0,f.call)(e.$tcb,"COMMENT_SUBMIT",n);case 22:if(!((r=t.sent)&&r.result&&r.result.id)){t.next=30;break}e.comment="",e.errorMessage="",e.$emit("load"),e.saveDraft(),t.next=31;break;case 30:throw new Error(r.result.message);case 31:t.next=37;break;case 33:t.prev=33,t.t9=t["catch"](1),f.logger.error("评论失败",t.t9),e.errorMessage="".concat((0,f.t)("COMMENT_FAILED"),": ").concat(t.t9&&t.t9.message);case 37:return t.prev=37,e.isSending=!1,t.finish(37);case 40:case"end":return t.stop()}}),t,null,[[1,33,37,40]])})))()},addEventListener:function(){this.textarea&&this.textarea.addEventListener("paste",this.onPaste)},onBgImgChange:function(){this.config.COMMENT_BG_IMG&&this.textarea&&(this.textarea.style["background-image"]='url("'.concat(this.config.COMMENT_BG_IMG,'")'))},onEnterKeyUp:function(e){(e.ctrlKey||e.metaKey)&&this.canSend&&(this.send(),e.preventDefault())},closeOwo:function(){this.owo&&this.owo.container.classList.contains("OwO-open")&&this.owo.toggle()},openSelectImage:function(){this.$refs.inputFile.click()},onSelectImage:function(){var e=this.$refs.inputFile.files[0];this.parseAndUploadPhoto(e)},onPaste:function(e){var t;e.clipboardData&&(e.clipboardData.files[0]?t=e.clipboardData.files[0]:e.clipboardData.items[0]&&e.clipboardData.items[0].getAsFile()&&(t=e.clipboardData.items[0].getAsFile()),this.parseAndUploadPhoto(t))},parseAndUploadPhoto:function(e){if(e&&"true"===this.config.SHOW_IMAGE){var t=e.name.split("."),n=t.length>1?t.pop():"";if(-1!==h.indexOf(n.toLowerCase())){var r=this.getUserId(),i="".concat(Date.now(),"-").concat(r),o=t.join(".");this.paste(this.getImagePlaceholder(i,n));var a=this.config.IMAGE_CDN;!this.$tcb||a&&"qcloud"!==a?a?this.uploadPhotoToThirdParty(i,o,n,e):this.uploadFailed(i,n,(0,f.t)("IMAGE_UPLOAD_FAILED_NO_CONF")):this.uploadPhotoToQcloud(i,o,n,e)}}},getUserId:function(){return this.$tcb?this.$tcb.auth.currentUser.uid:localStorage.getItem("twikoo-access-token")},uploadPhotoToQcloud:function(e,t,n,r){var a=this;return(0,o["default"])(i["default"].mark((function s(){var o,u,c;return i["default"].wrap((function(i){for(;;)switch(i.prev=i.next){case 0:return i.prev=0,i.next=3,a.$tcb.app.uploadFile({cloudPath:"tk-img/".concat(e,".").concat(n),filePath:r});case 3:if(!(o=i.sent).fileID){i.next=10;break}return i.next=7,a.$tcb.app.getTempFileURL({fileList:[o.fileID]});case 7:u=i.sent,c=u.fileList[0].tempFileURL,a.uploadCompleted(e,t,n,c);case 10:i.next=16;break;case 12:i.prev=12,i.t0=i["catch"](0),console.error(i.t0),a.uploadFailed(e,n,i.t0.message);case 16:case"end":return i.stop()}}),s,null,[[0,12]])})))()},uploadPhotoToThirdParty:function(e,t,n,r){var a=this;return(0,o["default"])(i["default"].mark((function s(){var o,u,c;return i["default"].wrap((function(i){for(;;)switch(i.prev=i.next){case 0:return i.prev=0,i.t0=f.call,i.t1=a.$tcb,i.t2="".concat(e,".").concat(n),i.next=6,(0,f.blobToDataURL)(r);case 6:return i.t3=i.sent,i.t4={fileName:i.t2,photo:i.t3},i.next=10,(0,i.t0)(i.t1,"UPLOAD_IMAGE",i.t4);case 10:u=i.sent,(c=u.result).data?a.uploadCompleted(e,t,n,c.data.url):1040===c.code&&c.err&&(o=c.err.match(/this image exists at: (http[^ ]+)/))?(console.warn(c),a.uploadCompleted(e,t,n,o[1])):(console.error(c),a.uploadFailed(e,n,c.err)),i.next=19;break;case 15:i.prev=15,i.t5=i["catch"](0),console.error(i.t5),a.uploadFailed(e,n,i.t5.message);case 19:case"end":return i.stop()}}),s,null,[[0,15]])})))()},uploadCompleted:function(e,t,n,r){t=t.replace(/[[\]]/g,"_"),this.comment=this.comment.replace(this.getImagePlaceholder(e,n),"![".concat(t,"](").concat(r,")")),this.$refs.inputFile.value=""},uploadFailed:function(e,t,n){this.comment=this.comment.replace(this.getImagePlaceholder(e,t),"_".concat((0,f.t)("IMAGE_UPLOAD_FAILED"),": ").concat(n,"_")),this.$refs.inputFile.value=""},paste:function(e){if(document.selection)document.selection.createRange().text=e;else if(this.textarea.selectionStart||0===this.textarea.selectionStart){var t=this.textarea.selectionStart,n=this.textarea.selectionEnd;this.comment=this.comment.substring(0,t)+e+this.comment.substring(n,this.comment.length),this.textarea.selectionStart=t+e.length,this.textarea.selectionEnd=t+e.length}else this.comment+=e},getImagePlaceholder:function(e,t){return"![".concat((0,f.t)("IMAGE_UPLOAD_PLACEHOLDER")," ").concat(e,".").concat(t,"]()")}},mounted:function(){this.pid&&this.$refs["tk-submit"].scrollIntoView({behavior:"instant",block:"center"}),this.initDraft(),this.initOwo(),this.addEventListener(),this.onBgImgChange(),this.initTurnstile()},watch:{"config.SHOW_EMOTION":function(){this.initOwo()},"config.COMMENT_BG_IMG":function(){this.onBgImgChange()},"config.TURNSTILE_SITE_KEY":function(){this.initTurnstile()}}}},1573:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"twikoo",attrs:{id:"twikoo"}},[t("tk-comments",{attrs:{"show-admin-entry":e.showAdminEntry},on:{admin:function(t){e.showAdmin=!0}}}),e._v(" "),t("tk-footer"),e._v(" "),t("tk-admin",{attrs:{show:e.showAdmin},on:{close:function(t){e.showAdmin=!1}}})],1)},t.Yp=[]},8114:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-action"},[t("a",{staticClass:"tk-action-link","class":{"tk-liked":e.liked},attrs:{href:"#"},on:{click:e.onLike}},[t("span",{staticClass:"tk-action-icon",domProps:{innerHTML:e._s(e.iconLike)}}),e._v(" "),t("span",{staticClass:"tk-action-icon tk-action-icon-solid",domProps:{innerHTML:e._s(e.iconLikeSolid)}}),e._v(" "),t("span",{staticClass:"tk-action-count"},[e._v(e._s(e.likeCountStr))])]),e._v(" "),t("a",{staticClass:"tk-action-link",attrs:{href:"#"},on:{click:e.onReply}},[t("span",{staticClass:"tk-action-icon",domProps:{innerHTML:e._s(e.iconComment)}}),e._v(" "),t("span",{staticClass:"tk-action-icon tk-action-icon-solid",domProps:{innerHTML:e._s(e.iconCommentSolid)}}),e._v(" "),t("span",{staticClass:"tk-action-count"},[e._v(e._s(e.repliesCountStr))])])])},t.Yp=[]},4576:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-admin-container"},[t("div",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticClass:"tk-admin","class":{__show:e.show}},[t("a",{staticClass:"tk-admin-close",attrs:{href:"#"},domProps:{innerHTML:e._s(e.iconClose)},on:{click:e.onClose}}),e._v(" "),e.needUpdate?t("div",{staticClass:"tk-login-title"},[t("div",[e._v(e._s(e.t("ADMIN_NEED_UPDATE")))]),e._v(" "),t("a",{attrs:{href:"https://twikoo.js.org/update.html",target:"_blank"}},[e._v("https://twikoo.js.org/update.html")])]):e._e(),e._v(" "),e.needUpdate?e._e():t("div",[!e.isLogin&&e.isSetPassword?t("div",{staticClass:"tk-login"},[t("div",{staticClass:"tk-login-title"},[e._v(e._s(e.t("ADMIN_LOGIN_TITLE")))]),e._v(" "),t("form",[t("input",{attrs:{type:"hidden"}}),e._v(" "),t("el-input",{ref:"focusme",staticClass:"tk-password",attrs:{placeholder:e.t("ADMIN_PASSWORD_PLACEHOLDER"),"show-password":""},nativeOn:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.onLogin.apply(null,arguments)}},model:{value:e.password,callback:function(t){e.password=t},expression:"password"}},[t("template",{slot:"prepend"},[e._v(e._s(e.t("ADMIN_PASSWORD")))]),e._v(" "),t("el-button",{attrs:{slot:"append"},on:{click:e.onLogin},slot:"append"},[e._v(e._s(e.t("ADMIN_LOGIN")))])],2)],1),e._v(" "),e.loginErrorMessage?t("div",{staticClass:"tk-login-msg"},[e._v("\n "+e._s(e.loginErrorMessage)+"\n "),t("a",{attrs:{href:"https://twikoo.js.org/faq.html",rel:"noopener noreferrer",target:"_blank"}},[e._v(e._s(e.t("ADMIN_FORGOT")))])]):e._e()]):e._e(),e._v(" "),e.isLogin||e.isSetPassword?e._e():t("div",{staticClass:"tk-regist"},[t("div",{staticClass:"tk-login-title"},[e._v(e._s(e.t("ADMIN_LOGIN_TITLE")))]),e._v(" "),t("form",[e.isSetCredentials?e._e():t("el-input",{ref:"focusme",staticClass:"tk-password",attrs:{placeholder:e.t("ADMIN_CREDENTIALS_PLACEHOLDER")},model:{value:e.credentials,callback:function(t){e.credentials=t},expression:"credentials"}},[t("template",{slot:"prepend"},[e._v(e._s(e.t("ADMIN_CREDENTIALS")))])],2),e._v(" "),t("el-input",{staticClass:"tk-password",attrs:{placeholder:e.t("ADMIN_SET_PASSWORD_PLACEHOLDER"),"show-password":""},model:{value:e.password,callback:function(t){e.password=t},expression:"password"}},[t("template",{slot:"prepend"},[e._v(e._s(e.t("ADMIN_SET_PASSWORD")))])],2),e._v(" "),t("el-input",{staticClass:"tk-password",attrs:{placeholder:e.t("ADMIN_SET_PASSWORD_CONFIRM_PLACEHOLDER"),"show-password":""},model:{value:e.passwordConfirm,callback:function(t){e.passwordConfirm=t},expression:"passwordConfirm"}},[t("template",{slot:"prepend"},[e._v(e._s(e.t("ADMIN_SET_PASSWORD_CONFIRM")))])],2)],1),e._v(" "),t("el-button",{staticClass:"tk-regist-button",attrs:{disabled:!e.canRegist},on:{click:e.onRegist}},[e._v(e._s(e.t("ADMIN_REGIST")))]),e._v(" "),e.loginErrorMessage?t("div",{staticClass:"tk-login-msg"},[e._v(e._s(e.loginErrorMessage))]):e._e(),e._v(" "),e.isSetCredentials?e._e():t("div",{staticClass:"tk-login-msg"},[t("a",{attrs:{href:"https://twikoo.js.org/faq.html",rel:"noopener noreferrer",target:"_blank"}},[e._v(e._s(e.t("ADMIN_CREDENTIALS_FAQ")))])])],1),e._v(" "),e.isLogin?t("div",{staticClass:"tk-panel"},[t("div",{staticClass:"tk-panel-title"},[t("div",[e._v(e._s(e.t("ADMIN_TITLE")))]),e._v(" "),t("a",{staticClass:"tk-panel-logout",attrs:{href:"#"},on:{click:e.onLogout}},[e._v(e._s(e.t("ADMIN_LOGOUT")))])]),e._v(" "),t("div",{staticClass:"tk-tabs"},[t("div",{staticClass:"tk-tab","class":{__active:"comment"===e.activeTabName},on:{click:function(t){e.activeTabName="comment"}}},[e._v(e._s(e.t("ADMIN_COMMENT")))]),e._v(" "),t("div",{staticClass:"tk-tab","class":{__active:"config"===e.activeTabName},on:{click:function(t){e.activeTabName="config"}}},[e._v(e._s(e.t("ADMIN_CONFIG")))]),e._v(" "),t("div",{staticClass:"tk-tab","class":{__active:"import"===e.activeTabName},on:{click:function(t){e.activeTabName="import"}}},[e._v(e._s(e.t("ADMIN_IMPORT")))]),e._v(" "),t("div",{staticClass:"tk-tab","class":{__active:"export"===e.activeTabName},on:{click:function(t){e.activeTabName="export"}}},[e._v(e._s(e.t("ADMIN_EXPORT")))])]),e._v(" "),t("tk-admin-comment",{directives:[{name:"show",rawName:"v-show",value:"comment"===e.activeTabName,expression:"activeTabName === 'comment'"}]}),e._v(" "),t("tk-admin-config",{directives:[{name:"show",rawName:"v-show",value:"config"===e.activeTabName,expression:"activeTabName === 'config'"}]}),e._v(" "),t("tk-admin-import",{directives:[{name:"show",rawName:"v-show",value:"import"===e.activeTabName,expression:"activeTabName === 'import'"}]}),e._v(" "),t("tk-admin-export",{directives:[{name:"show",rawName:"v-show",value:"export"===e.activeTabName,expression:"activeTabName === 'export'"}]})],1):e._e()])])])},t.Yp=[]},3227:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticClass:"tk-admin-comment"},[e.clientVersion!==e.serverVersion?t("div",{staticClass:"tk-admin-warn"},[t("span",[e._v(e._s(e.t("ADMIN_CLIENT_VERSION"))+e._s(e.clientVersion)+",")]),e._v(" "),t("span",[e._v(e._s(e.t("ADMIN_SERVER_VERSION"))+e._s(e.serverVersion)+",")]),e._v(" "),e._m(0)]):e._e(),e._v(" "),t("div",{staticClass:"tk-admin-comment-filter"},[t("el-input",{staticClass:"tk-admin-comment-filter-keyword",attrs:{size:"small",placeholder:e.t("ADMIN_COMMENT_SEARCH_PLACEHOLDER")},nativeOn:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.getComments.apply(null,arguments)}},model:{value:e.filter.keyword,callback:function(t){e.$set(e.filter,"keyword",t)},expression:"filter.keyword"}}),e._v(" "),t("select",{directives:[{name:"model",rawName:"v-model",value:e.filter.type,expression:"filter.type"}],staticClass:"tk-admin-comment-filter-type",on:{change:function(t){var n=Array.prototype.filter.call(t.target.options,(function(e){return e.selected})).map((function(e){return"_value"in e?e._value:e.value}));e.$set(e.filter,"type",t.target.multiple?n:n[0])}}},[t("option",{attrs:{value:""}},[e._v(e._s(e.t("ADMIN_COMMENT_FILTER_ALL")))]),e._v(" "),t("option",{attrs:{value:"VISIBLE"}},[e._v(e._s(e.t("ADMIN_COMMENT_FILTER_VISIBLE")))]),e._v(" "),t("option",{attrs:{value:"HIDDEN"}},[e._v(e._s(e.t("ADMIN_COMMENT_FILTER_HIDDEN")))])]),e._v(" "),t("el-button",{attrs:{size:"small",type:"primary"},on:{click:e.getComments}},[e._v(e._s(e.t("ADMIN_COMMENT_SEARCH")))])],1),e._v(" "),t("div",{ref:"comment-list",staticClass:"tk-admin-comment-list"},e._l(e.comments,(function(n){return t("div",{key:n._id,staticClass:"tk-admin-comment-item"},[t("div",{staticClass:"tk-admin-comment-meta"},[t("tk-avatar",{attrs:{config:e.serverConfig,avatar:n.avatar,nick:n.nick,mail:n.mail,link:n.link}}),e._v(" "),n.link?e._e():t("span",[e._v(e._s(n.nick)+" ")]),e._v(" "),n.link?t("a",{attrs:{href:e.convertLink(n.link),target:"_blank"}},[e._v(e._s(n.nick)+" ")]):e._e(),e._v(" "),n.mail?t("span",[e._v("("),t("a",{attrs:{href:"mailto:".concat(n.mail)}},[e._v(e._s(n.mail))]),e._v(") ")]):e._e(),e._v(" "),n.isSpam?t("span",[e._v(e._s(e.t("ADMIN_COMMENT_IS_SPAM_SUFFIX"))+" ")]):e._e(),e._v(" "),t("span",{staticClass:"tk-time"},[e._v(e._s(e.displayCreated(n))+" ")]),e._v(" "),t("span",{attrs:{title:n.ua}},[e._v(e._s(n.ipRegion))])],1),e._v(" "),t("div",{ref:"comments",refInFor:!0,staticClass:"tk-content",domProps:{innerHTML:e._s(n.comment)}}),e._v(" "),t("div",{staticClass:"tk-admin-actions"},[t("el-button",{attrs:{size:"mini",type:"text"},on:{click:function(t){return e.handleView(n)}}},[e._v(e._s(e.t("ADMIN_COMMENT_VIEW")))]),e._v(" "),n.isSpam?t("el-button",{attrs:{size:"mini",type:"text"},on:{click:function(t){return e.handleSpam(n,!1)}}},[e._v(e._s(e.t("ADMIN_COMMENT_SHOW")))]):e._e(),e._v(" "),n.isSpam?e._e():t("el-button",{attrs:{size:"mini",type:"text"},on:{click:function(t){return e.handleSpam(n,!0)}}},[e._v(e._s(e.t("ADMIN_COMMENT_HIDE")))]),e._v(" "),!n.rid&&n.top?t("el-button",{attrs:{size:"mini",type:"text"},on:{click:function(t){return e.handleTop(n,!1)}}},[e._v(e._s(e.t("ADMIN_COMMENT_UNTOP")))]):e._e(),e._v(" "),n.rid||n.top?e._e():t("el-button",{attrs:{size:"mini",type:"text"},on:{click:function(t){return e.handleTop(n,!0)}}},[e._v(e._s(e.t("ADMIN_COMMENT_TOP")))]),e._v(" "),t("el-button",{attrs:{size:"mini",type:"text"},on:{click:function(t){return e.handleDelete(n)}}},[e._v(e._s(e.t("ADMIN_COMMENT_DELETE")))])],1)])})),0),e._v(" "),t("tk-pagination",{attrs:{"page-size":e.pageSize,total:e.count},on:{"page-size-change":e.onPageSizeChange,"current-change":e.switchPage}})],1)},t.Yp=[function(){var e=this,t=e._self._c;return t("span",[e._v("请参考 "),t("a",{attrs:{href:"https://twikoo.js.org/update.html",target:"_blank"}},[e._v("版本更新")]),e._v(" 进行升级")])}]},74:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticClass:"tk-admin-config"},[e.clientVersion!==e.serverVersion?t("div",{staticClass:"tk-admin-warn"},[t("span",[e._v(e._s(e.t("ADMIN_CLIENT_VERSION"))+e._s(e.clientVersion)+",")]),e._v(" "),t("span",[e._v(e._s(e.t("ADMIN_SERVER_VERSION"))+e._s(e.serverVersion)+",")]),e._v(" "),e._m(0)]):e._e(),e._v(" "),t("div",{staticClass:"tk-admin-config-groups"},[e._l(e.settings,(function(n){return t("details",{key:n.name,staticClass:"tk-admin-config-group"},[t("summary",{staticClass:"tk-admin-config-group-title"},[e._v(e._s(n.name))]),e._v(" "),e._l(n.items,(function(n){return t("div",{key:n.key,staticClass:"tk-admin-config-item"},[t("div",{staticClass:"tk-admin-config-title",attrs:{title:n.key}},[e._v(e._s(n.key))]),e._v(" "),t("div",{staticClass:"tk-admin-config-input"},[t("el-input",{attrs:{placeholder:n.ph,size:"small","show-password":n.secret},model:{value:n.value,callback:function(t){e.$set(n,"value",t)},expression:"setting.value"}})],1),e._v(" "),t("div"),e._v(" "),t("div",{staticClass:"tk-admin-config-desc"},[e._v(e._s(n.desc))])])}))],2)})),e._v(" "),t("details",{staticClass:"tk-admin-config-group"},[t("summary",{staticClass:"tk-admin-config-group-title"},[e._v(e._s(e.t("ADMIN_CONFIG_EMAIL_TEST")))]),e._v(" "),t("div",{staticClass:"tk-admin-config-email-test"},[t("div",{staticClass:"tk-admin-config-email-test-desc"},[e._v(e._s(e.t("ADMIN_CONFIG_EMAIL_TEST_HELP")))]),e._v(" "),t("div",{staticClass:"tk-admin-config-input"},[t("el-input",{attrs:{size:"small"},model:{value:e.emailTestAddress,callback:function(t){e.emailTestAddress=t},expression:"emailTestAddress"}},[t("el-button",{attrs:{slot:"append",type:"info"},on:{click:e.testEmail},slot:"append"},[e._v(e._s(e.t("ADMIN_CONFIG_EMAIL_TEST_BTN")))])],1)],1),e._v(" "),t("div",{staticClass:"tk-admin-config-email-test-desc"},[e._v(e._s(e.t("ADMIN_CONFIG_EMAIL_TEST_RESULT"))+e._s(e.emailTestResult))])])])],2),e._v(" "),t("div",{staticClass:"tk-admin-config-actions"},[t("el-button",{attrs:{size:"small",type:"primary"},on:{click:e.saveConfig}},[e._v(e._s(e.t("ADMIN_CONFIG_SAVE")))]),e._v(" "),t("el-button",{attrs:{size:"small",type:"info"},on:{click:e.resetConfig}},[e._v(e._s(e.t("ADMIN_CONFIG_RESET")))])],1),e._v(" "),t("div",{staticClass:"tk-admin-config-message"},[e._v(e._s(e.message))])])},t.Yp=[function(){var e=this,t=e._self._c;return t("span",[e._v("请参考 "),t("a",{attrs:{href:"https://twikoo.js.org/update.html",target:"_blank"}},[e._v("版本更新")]),e._v(" 进行升级")])}]},9976:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-admin-export"},[t("div",{staticClass:"tk-admin-warn tk-admin-import-warn"},[t("p",[e._v(e._s(e.t("ADMIN_EXPORT_WARN")))])]),e._v(" "),t("el-button",{attrs:{size:"small",disabled:e.loading},on:{click:function(t){return e.doExport("comment")}}},[e._v(e._s(e.t("ADMIN_EXPORT_COMMENT")))]),e._v(" "),t("el-button",{attrs:{size:"small",disabled:e.loading},on:{click:function(t){return e.doExport("counter")}}},[e._v(e._s(e.t("ADMIN_EXPORT_COUNTER")))])],1)},t.Yp=[]},872:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-admin-import"},[t("div",{staticClass:"tk-admin-warn tk-admin-import-warn"},[t("p",[e._v(e._s(e.t("ADMIN_IMPORT_WARN")))]),e._v(" "),t("p",[e._v(e._s(e.warnText[e.source]))])]),e._v(" "),t("div",{staticClass:"tk-admin-import-label"},[e._v(e._s(e.t("ADMIN_IMPORT_SELECT_SOURCE")))]),e._v(" "),t("select",{directives:[{name:"model",rawName:"v-model",value:e.source,expression:"source"}],on:{change:function(t){var n=Array.prototype.filter.call(t.target.options,(function(e){return e.selected})).map((function(e){return"_value"in e?e._value:e.value}));e.source=t.target.multiple?n:n[0]}}},[t("option",{attrs:{disabled:"",value:""}},[e._v(e._s(e.t("ADMIN_IMPORT_SELECT")))]),e._v(" "),t("option",{attrs:{value:"valine"}},[e._v("Valine (JSON)")]),e._v(" "),t("option",{attrs:{value:"disqus"}},[e._v("Disqus (XML)")]),e._v(" "),t("option",{attrs:{value:"artalk"}},[e._v("Artalk v1 (JSON)")]),e._v(" "),t("option",{attrs:{value:"artalk2"}},[e._v("Artalk v2 (Artrans)")]),e._v(" "),t("option",{attrs:{value:"twikoo"}},[e._v("Twikoo (JSON)")])]),e._v(" "),t("div",{staticClass:"tk-admin-import-label"},[e._v(e._s(e.t("ADMIN_IMPORT_SELECT_FILE")))]),e._v(" "),t("input",{ref:"inputFile",attrs:{type:"file",value:""}}),e._v(" "),t("el-button",{attrs:{size:"small",disabled:e.loading},on:{click:e.uploadFile}},[e._v(e._s(e.t("ADMIN_IMPORT_START")))]),e._v(" "),t("el-input",{ref:"logTextArea",attrs:{type:"textarea",rows:10,placeholder:e.t("ADMIN_IMPORT_LOG"),readonly:""},model:{value:e.logText,callback:function(t){e.logText=t},expression:"logText"}})],1)},t.Yp=[]},5897:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-avatar","class":{"tk-clickable":!!e.link,"tk-has-avatar":!!e.avatarInner},on:{click:e.onClick}},[e.avatarInner?e._e():t("div",{staticClass:"tk-avatar-img",domProps:{innerHTML:e._s(e.iconUser)}}),e._v(" "),e.avatarInner?t("img",{staticClass:"tk-avatar-img",attrs:{src:e.avatarInner,alt:""}}):e._e()])},t.Yp=[]},3072:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{ref:"tk-comment",staticClass:"tk-comment","class":{"tk-master":e.comment.master},attrs:{id:e.comment.id}},[t("tk-avatar",{attrs:{config:e.config,nick:e.comment.nick,avatar:e.comment.avatar,"mail-md5":e.comment.mailMd5,link:e.convertedLink}}),e._v(" "),t("div",{staticClass:"tk-main"},[t("div",{staticClass:"tk-row"},[t("div",{staticClass:"tk-meta"},[e.convertedLink?e._e():t("strong",{staticClass:"tk-nick"},[e._v(e._s(e.comment.nick))]),e._v(" "),e.convertedLink?t("a",{staticClass:"tk-nick tk-nick-link",attrs:{href:e.convertedLink,target:"_blank",rel:"noopener noreferrer"}},[t("strong",[e._v(e._s(e.comment.nick))])]):e._e(),e._v(" "),e.comment.master?t("span",{staticClass:"tk-tag tk-tag-green"},[e._v(e._s(e.config.MASTER_TAG||e.t("COMMENT_MASTER_TAG")))]):e._e(),e._v(" "),e.comment.top?t("span",{staticClass:"tk-tag tk-tag-red"},[e._v(e._s(e.t("COMMENT_TOP_TAG")))]):e._e(),e._v(" "),e.comment.isSpam?t("span",{staticClass:"tk-tag tk-tag-yellow"},[e._v(e._s(e.t("COMMENT_REVIEWING_TAG")))]):e._e(),e._v(" "),t("small",{staticClass:"tk-time"},[t("time",{attrs:{datetime:e.jsonTimestamp,title:e.localeTime}},[e._v(e._s(e.displayCreated))])]),e._v(" "),e.isLogin?t("small",{staticClass:"tk-actions"},[e.comment.isSpam?t("a",{attrs:{href:"#"},on:{click:function(t){return e.handleSpam(!1,t)}}},[e._v(e._s(e.t("ADMIN_COMMENT_SHOW")))]):e._e(),e._v(" "),e.comment.isSpam?e._e():t("a",{attrs:{href:"#"},on:{click:function(t){return e.handleSpam(!0,t)}}},[e._v(e._s(e.t("ADMIN_COMMENT_HIDE")))]),e._v(" "),!e.comment.rid&&e.comment.top?t("a",{attrs:{href:"#"},on:{click:function(t){return e.handleTop(!1,t)}}},[e._v(e._s(e.t("ADMIN_COMMENT_UNTOP")))]):e._e(),e._v(" "),e.comment.rid||e.comment.top?e._e():t("a",{attrs:{href:"#"},on:{click:function(t){return e.handleTop(!0,t)}}},[e._v(e._s(e.t("ADMIN_COMMENT_TOP")))])]):e._e()]),e._v(" "),t("tk-action",{attrs:{liked:e.liked,"like-count":e.like,"replies-count":e.comment.replies.length},on:{like:e.onLike,reply:e.onReply}})],1),e._v(" "),t("div",{ref:"tk-content",staticClass:"tk-content","class":{"tk-content-expand":e.isContentExpanded||!e.showContentExpand}},[e.comment.pid?t("span",[e._v(e._s(e.t("COMMENT_REPLIED"))+" "),t("a",{staticClass:"tk-ruser",attrs:{href:"#".concat(e.comment.pid)}},[e._v("@"+e._s(e.comment.ruser))]),e._v(" :")]):e._e(),e._v(" "),t("span",{ref:"comment",domProps:{innerHTML:e._s(e.comment.comment)},on:{click:e.popupLightbox}})]),e._v(" "),e.showContentExpand?t("div",{staticClass:"tk-expand-wrap"},[t("div",{staticClass:"tk-expand",on:{click:e.onContentExpand}},[e._v(e._s(e.t("COMMENT_EXPAND")))])]):e._e(),e._v(" "),e.showContentCollapse?t("div",{staticClass:"tk-collapse-wrap"},[t("div",{staticClass:"tk-expand _collapse",on:{click:e.onContentCollapse}},[e._v(e._s(e.t("COMMENT_COLLAPSE")))])]):e._e(),e._v(" "),e.comment.ipRegion||e.comment.os||e.comment.browser?t("div",{staticClass:"tk-extras"},[e.comment.ipRegion?t("div",{staticClass:"tk-extra"},[t("span",{staticClass:"tk-icon __comment",domProps:{innerHTML:e._s(e.iconLocation)}}),e._v(" "),t("span",{staticClass:"tk-extra-text"},[e._v(" "+e._s(e.comment.ipRegion))])]):e._e(),e._v(" "),e.comment.os?t("div",{staticClass:"tk-extra"},[t("span",{staticClass:"tk-icon __comment",domProps:{innerHTML:e._s(e.iconOs)}}),e._v(" "),t("span",{staticClass:"tk-extra-text"},[e._v(" "+e._s(e.comment.os))])]):e._e(),e._v(" "),e.comment.browser?t("div",{staticClass:"tk-extra"},[t("span",{staticClass:"tk-icon __comment",domProps:{innerHTML:e._s(e.iconBrowser)}}),e._v(" "),t("span",{staticClass:"tk-extra-text"},[e._v(" "+e._s(e.comment.browser))])]):e._e()]):e._e(),e._v(" "),e.replying&&!e.pid?t("tk-submit",{attrs:{"reply-id":e.replyId?e.replyId:e.comment.id,pid:e.comment.id,config:e.config},on:{load:e.onLoad,cancel:e.onCancel}}):e._e(),e._v(" "),t("div",{ref:"tk-replies",staticClass:"tk-replies","class":{"tk-replies-expand":e.isExpanded||!e.showExpand||e.replying}},e._l(e.comment.replies,(function(n){return t("tk-comment",{key:n.id,attrs:{comment:n,replyId:e.comment.id,replying:e.replying&&e.pid===n.id,config:e.config},on:{expand:e.onExpand,load:e.onLoad,reply:e.onReplyReply}})})),1),e._v(" "),e.showExpand&&!e.replying?t("div",{staticClass:"tk-expand-wrap"},[t("div",{staticClass:"tk-expand",on:{click:e.onExpand}},[e._v(e._s(e.t("COMMENT_EXPAND")))])]):e._e(),e._v(" "),e.showCollapse&&!e.replying?t("div",{staticClass:"tk-collapse-wrap"},[t("div",{staticClass:"tk-expand _collapse",on:{click:e.onCollapse}},[e._v(e._s(e.t("COMMENT_COLLAPSE")))])]):e._e()],1)],1)},t.Yp=[]},2048:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-comments"},[t("tk-submit",{attrs:{config:e.config},on:{load:e.initComments}}),e._v(" "),t("div",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticClass:"tk-comments-container"},[t("div",{staticClass:"tk-comments-title"},[t("span",{staticClass:"tk-comments-count","class":{__hidden:!e.comments.length}},[t("span",[e._v(e._s(e.count))]),e._v(" "),t("span",[e._v(e._s(e.t("COMMENTS_COUNT_SUFFIX")))])]),e._v(" "),t("span",[e.loading||e.loadingMore?e._e():t("span",{staticClass:"tk-icon __comments",domProps:{innerHTML:e._s(e.iconRefresh)},on:{click:e.refresh}}),e.showAdminEntry?t("span",{staticClass:"tk-icon __comments",domProps:{innerHTML:e._s(e.iconSetting)},on:{click:e.openAdmin}}):e._e()])]),e._v(" "),e.loading||e.comments.length?e._e():t("div",{staticClass:"tk-comments-no"},[e.errorMessage?e._e():t("span",[e._v(e._s(e.t("COMMENTS_NO_COMMENTS")))]),e._v(" "),e.errorMessage?t("span",{staticClass:"tk-comments-error"},[e._v(e._s(e.errorMessage))]):e._e()]),e._v(" "),e._l(e.comments,(function(n){return t("tk-comment",{key:n.id,attrs:{comment:n,replying:e.replyId===n.id,config:e.config},on:{reply:e.onReply,load:e.initComments}})})),e._v(" "),e.showExpand&&!e.loading?t("div",{staticClass:"tk-expand-wrap"},[t("div",{directives:[{name:"loading",rawName:"v-loading",value:e.loadingMore,expression:"loadingMore"}],staticClass:"tk-expand",on:{click:e.onExpand}},[e._v(e._s(e.t("COMMENTS_EXPAND")))])]):e._e()],2)],1)},t.Yp=[]},2080:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-footer"},[e._v("\n Powered by "),t("a",{attrs:{href:"https://twikoo.js.org",target:"_blank"}},[e._v("Twikoo")]),e._v("\n v"+e._s(e.version)+"\n")])},t.Yp=[]},1412:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-meta-input"},e._l(e.displayedInputs,(function(n){return t("el-input",{key:n.key,attrs:{name:n.name,type:n.type,placeholder:e.requiredFields[n.key]?e.t("META_INPUT_REQUIRED"):e.t("META_INPUT_NOT_REQUIRED"),size:"small"},on:{change:e.onMetaChange},model:{value:e.metaData[n.key],callback:function(t){e.$set(e.metaData,n.key,t)},expression:"metaData[metaInput.key]"}},[t("template",{slot:"prepend"},[e._v(e._s(n.locale))])],2)})),1)},t.Yp=[]},8675:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{staticClass:"tk-pagination"},[e.pageCount?t("div",{staticClass:"tk-pagination-options"},[t("div",[t("span",[e._v(e._s(e.t("PAGINATION_COUNT_PREFIX")))]),e._v(" "),t("span",[e._v(e._s(e.total))]),e._v(" "),t("span",[e._v(e._s(e.t("PAGINATION_COUNT_SUFFIX")))])]),e._v(" "),t("el-input",{attrs:{type:"number",min:"1",max:"100",value:e.userPageSize?e.userPageSize:e.pageSize},on:{input:e.handleInputPageSize,change:e.pageSizeChamge}}),e._v(" "),t("span",[e._v(e._s(e.t("PAGINATION_PAGESIZE")))])],1):e._e(),e._v(" "),t("div",{staticClass:"tk-pagination-pagers"},e._l(e.pagers,(function(n){return t("div",{key:n.page,staticClass:"tk-pagination-pager","class":{__current:n.page===e.currentPage},on:{click:function(t){return e.currentChange(n.page)}}},[e._v(e._s(n.title))])})),0),e._v(" "),e.pageCount?t("div",{staticClass:"tk-pagination-options"},[t("span",[e._v(e._s(e.t("PAGINATION_GOTO_PREFIX")))]),e._v(" "),t("el-input",{attrs:{type:"number",min:"1",max:e.pageCount,value:e.userInput?e.userInput:e.currentPage},on:{input:e.handleInput,change:e.currentChange}}),e._v(" "),t("span",[e._v(e._s(e.t("PAGINATION_GOTO_SUFFIX")))])],1):e._e()])},t.Yp=[]},9564:function(e,t){"use strict";t.Yp=t.XX=void 0,t.XX=function(){var e=this,t=e._self._c;return t("div",{ref:"tk-submit",staticClass:"tk-submit tk-fade-in"},[t("div",{staticClass:"tk-row"},[t("tk-avatar",{attrs:{config:e.config,mail:e.mail,nick:e.nick}}),e._v(" "),t("div",{staticClass:"tk-col"},[t("tk-meta-input",{attrs:{nick:e.nick,mail:e.mail,link:e.link,config:e.config},on:{update:e.onMetaUpdate}}),e._v(" "),t("el-input",{ref:"textarea",staticClass:"tk-input",attrs:{type:"textarea","show-word-limit":"",placeholder:e.commentPlaceholder,autosize:{minRows:3},maxlength:e.maxLength},on:{input:e.onCommentInput},nativeOn:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.onEnterKeyUp(t)}},model:{value:e.comment,callback:function(t){e.comment=t},expression:"comment"}})],1)],1),e._v(" "),t("div",{staticClass:"tk-row actions"},[t("div",{staticClass:"tk-row-actions-start"},[t("div",{directives:[{name:"show",rawName:"v-show",value:"true"===e.config.SHOW_EMOTION,expression:"config.SHOW_EMOTION === 'true'"},{name:"clickoutside",rawName:"v-clickoutside",value:e.closeOwo,expression:"closeOwo"}],ref:"owo",staticClass:"tk-submit-action-icon OwO",domProps:{innerHTML:e._s(e.iconEmotion)}}),e._v(" "),t("div",{directives:[{name:"show",rawName:"v-show",value:"true"===e.config.SHOW_IMAGE,expression:"config.SHOW_IMAGE === 'true'"}],staticClass:"tk-submit-action-icon",domProps:{innerHTML:e._s(e.iconImage)},on:{click:e.openSelectImage}}),e._v(" "),t("input",{ref:"inputFile",staticClass:"tk-input-image",attrs:{type:"file",accept:"image/*",value:""},on:{change:e.onSelectImage}}),e._v(" "),t("div",{staticClass:"tk-error-message"},[e._v(e._s(e.errorMessage))])]),e._v(" "),t("a",{staticClass:"tk-submit-action-icon __markdown",attrs:{alt:"Markdown is supported",href:"https://guides.github.com/features/mastering-markdown/",target:"_blank",rel:"noopener noreferrer"},domProps:{innerHTML:e._s(e.iconMarkdown)}}),e._v(" "),e.replyId?t("el-button",{staticClass:"tk-cancel",attrs:{size:"small"},on:{click:e.cancel}},[e._v(e._s(e.t("SUBMIT_CANCEL")))]):e._e(),e._v(" "),t("el-button",{staticClass:"tk-preview",attrs:{size:"small"},on:{click:e.preview}},[e._v(e._s(e.t("SUBMIT_PREVIEW")))]),e._v(" "),t("el-button",{staticClass:"tk-send",attrs:{type:"primary",size:"small",disabled:!e.canSend},on:{click:e.send}},[e._v(e._s(e.isSending?e.t("SUBMIT_SENDING"):e.t("SUBMIT_SEND")))]),e._v(" "),t("div",{ref:"turnstile-container",staticClass:"tk-turnstile-container"},[t("div",{ref:"turnstile",staticClass:"tk-turnstile"})])],1),e._v(" "),e.isPreviewing?t("div",{ref:"comment-preview",staticClass:"tk-preview-container",domProps:{innerHTML:e._s(e.commentHtml)}}):e._e()])},t.Yp=[]},5547:function(e,t){"use strict";t.A=function(e,t){for(var n=[],r={},i=0;i=0&&Math.floor(t)===t&&isFinite(e)}function _(e){return l(e)&&"function"==typeof e.then&&"function"==typeof e["catch"]}function y(e){return null==e?"":Array.isArray(e)||g(e)&&e.toString===m?JSON.stringify(e,b,2):String(e)}function b(e,t){return t&&t.__v_isRef?t.value:t}function k(e){var t=parseFloat(e);return isNaN(t)?e:t}function w(e,t){for(var n=Object.create(null),r=e.split(","),i=0;i-1)return e.splice(r,1)}}var C=Object.prototype.hasOwnProperty;function x(e,t){return C.call(e,t)}function I(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}var D=/-(\w)/g,S=I((function(e){return e.replace(D,(function(e,t){return t?t.toUpperCase():""}))})),O=I((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),T=/\B([A-Z])/g,M=I((function(e){return e.replace(T,"-$1").toLowerCase()})),N=Function.prototype.bind?function(e,t){return e.bind(t)}:function(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n};function P(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function F(e,t){for(var n in t)e[n]=t[n];return e}function L(e){for(var t={},n=0;n0,ne=Z&&Z.indexOf("edge/")>0;Z&&Z.indexOf("android");var re=Z&&/iphone|ipad|ipod|ios/.test(Z);Z&&/chrome\/\d+/.test(Z),Z&&/phantomjs/.test(Z);var ie,oe=Z&&Z.match(/firefox\/(\d+)/),ae={}.watch,se=!1;if(Q)try{var ue={};Object.defineProperty(ue,"passive",{get:function(){se=!0}}),window.addEventListener("test-passive",null,ue)}catch(s){}var ce=function(){return void 0===ie&&(ie=!Q&&"undefined"!=typeof n.g&&n.g.process&&"server"===n.g.process.env.VUE_ENV),ie},le=Q&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function de(e){return"function"==typeof e&&/native code/.test(e.toString())}var fe,pe="undefined"!=typeof Symbol&&de(Symbol)&&"undefined"!=typeof Reflect&&de(Reflect.ownKeys);fe="undefined"!=typeof Set&&de(Set)?Set:function(){function e(){(0,i["default"])(this,e),this.set=Object.create(null)}return(0,o["default"])(e,[{key:"has",value:function(e){return!0===this.set[e]}},{key:"add",value:function(e){this.set[e]=!0}},{key:"clear",value:function(){this.set=Object.create(null)}}]),e}();var he=null;function me(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:null;e||he&&he._scope.off(),he=e,e&&e._scope.on()}var ge=function(){function e(t,n,r,o,a,s,u,c){(0,i["default"])(this,e),this.tag=t,this.data=n,this.children=r,this.text=o,this.elm=a,this.ns=void 0,this.context=s,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=n&&n.key,this.componentOptions=u,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=c,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return(0,o["default"])(e,[{key:"child",get:function(){return this.componentInstance}}]),e}(),ve=function(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"",t=new ge;return t.text=e,t.isComment=!0,t};function _e(e){return new ge(void 0,void 0,void 0,String(e))}function ye(e){var t=new ge(e.tag,e.data,e.children&&e.children.slice(),e.text,e.elm,e.context,e.componentOptions,e.asyncFactory);return t.ns=e.ns,t.isStatic=e.isStatic,t.key=e.key,t.isComment=e.isComment,t.fnContext=e.fnContext,t.fnOptions=e.fnOptions,t.fnScopeId=e.fnScopeId,t.asyncMeta=e.asyncMeta,t.isCloned=!0,t}var be=0,ke=[],we=function(){for(var e=0;e1&&arguments[1]!==undefined&&arguments[1],r=arguments.length>2&&arguments[2]!==undefined&&arguments[2];if((0,i["default"])(this,e),this.value=t,this.shallow=n,this.mock=r,this.dep=r?Ne:new Ee,this.vmCount=0,K(t,"__ob__",this),u(t)){if(!r)if(J)t.__proto__=De;else for(var o=0,a=Se.length;o6&&undefined;var a=new Ee,s=Object.getOwnPropertyDescriptor(e,t);if(!s||!1!==s.configurable){var c=s&&s.get,l=s&&s.set;c&&!l||n!==Oe&&2!==arguments.length||(n=e[t]);var d=i?n&&n.__ob__:Fe(n,!1,o);return Object.defineProperty(e,t,{enumerable:!0,configurable:!0,get:function(){var t=c?c.call(e):n;return Ee.target&&(a.depend(),d&&(d.dep.depend(),u(t)&&$e(t))),Ve(t)&&!i?t.value:t},set:function(t){var r=c?c.call(e):n;if(z(r,t)){if(l)l.call(e,t);else{if(c)return;if(!i&&Ve(r)&&!Ve(t))return void(r.value=t);n=t}d=i?t&&t.__ob__:Fe(t,!1,o),a.notify()}}}),a}}function Re(e,t,n){if(!He(e)){var r=e.__ob__;return u(e)&&v(t)?(e.length=Math.max(e.length,t),e.splice(t,1,n),r&&!r.shallow&&r.mock&&Fe(n,!1,!0),n):t in e&&!(t in Object.prototype)?(e[t]=n,n):e._isVue||r&&r.vmCount?n:r?(Le(r.value,t,n,void 0,r.shallow,r.mock),r.dep.notify(),n):(e[t]=n,n)}}function je(e,t){if(u(e)&&v(t))e.splice(t,1);else{var n=e.__ob__;e._isVue||n&&n.vmCount||He(e)||x(e,t)&&(delete e[t],n&&n.dep.notify())}}function $e(e){for(var t,n=0,r=e.length;n2&&arguments[2]!==undefined?arguments[2]:s,o=i.immediate,a=i.deep,c=i.flush,l=void 0===c?"pre":c,d=(i.onTrack,i.onTrigger,he),f=function(e,t){var n=en(e,null,arguments.length>2&&arguments[2]!==undefined?arguments[2]:null,d,t);return a&&n&&n.__ob__&&n.__ob__.dep.depend(),n},h=!1,m=!1;if(Ve(e)?(n=function(){return e.value},h=ze(e)):Ge(e)?(n=function(){return e.__ob__.dep.depend(),e},a=!0):u(e)?(m=!0,h=e.some((function(e){return Ge(e)||ze(e)})),n=function(){return e.map((function(e){return Ve(e)?e.value:Ge(e)?(e.__ob__.dep.depend(),On(e)):p(e)?f(e,rt):void 0}))}):n=p(e)?t?function(){return f(e,rt)}:function(){if(!d||!d._isDestroyed)return r&&r(),f(e,tt,[v])}:R,t&&a){var g=n;n=function(){return On(g())}}var v=function(e){r=_.onStop=function(){f(e,it)}};if(ce())return v=R,t?o&&f(t,nt,[n(),m?[]:void 0,v]):n(),R;var _=new Pn(he,n,R,{lazy:!0});_.noRecurse=!t;var y=m?[]:st;return _.run=function(){if(_.active)if(t){var e=_.get();(a||h||(m?e.some((function(e,t){return z(e,y[t])})):z(e,y)))&&(r&&r(),f(t,nt,[e,y===st?void 0:y,v]),y=e)}else _.get()},"sync"===l?_.update=_.run:"post"===l?(_.post=!0,_.update=function(){return nr(_)}):_.update=function(){if(d&&d===he&&!d._isMounted){var e=d._preWatchers||(d._preWatchers=[]);e.indexOf(_)<0&&e.push(_)}else nr(_)},t?o?_.run():y=_.get():"post"===l&&d?d.$once("hook:mounted",(function(){return _.get()})):_.get(),function(){_.teardown()}}var ct=function(){function e(){var t=arguments.length>0&&arguments[0]!==undefined&&arguments[0];(0,i["default"])(this,e),this.detached=t,this.active=!0,this.effects=[],this.cleanups=[],this.parent=at,!t&&at&&(this.index=(at.scopes||(at.scopes=[])).push(this)-1)}return(0,o["default"])(e,[{key:"run",value:function(e){if(this.active){var t=at;try{return at=this,e()}finally{at=t}}}},{key:"on",value:function(){at=this}},{key:"off",value:function(){at=this.parent}},{key:"stop",value:function(e){if(this.active){var t,n;for(t=0,n=this.effects.length;t0&&(_t((r=yt(r,"".concat(t||"","_").concat(n)))[0])&&_t(o)&&(a[i]=_e(o.text+r[0].text),r.shift()),a.push.apply(a,r)):f(r)?_t(o)?a[i]=_e(o.text+r):""!==r&&a.push(_e(r)):_t(r)&&_t(o)?a[i]=_e(o.text+r.text):(d(e._isVList)&&l(r.tag)&&c(r.key)&&l(t)&&(r.key="__vlist".concat(t,"_").concat(n,"__")),a.push(r)));return a}function bt(e,t){var n,r,i,o,a=null;if(u(e)||"string"==typeof e)for(a=new Array(e.length),n=0,r=e.length;n0,a=t?!!t.$stable:!o,u=t&&t.$key;if(t){if(t._normalized)return t._normalized;if(a&&r&&r!==s&&u===r.$key&&!o&&!r.$hasNormal)return r;for(var c in i={},t)t[c]&&"$"!==c[0]&&(i[c]=$t(e,n,c,t[c]))}else i={};for(var l in n)l in i||(i[l]=Ut(n,l));return t&&Object.isExtensible(t)&&(t._normalized=i),K(i,"$stable",a),K(i,"$key",u),K(i,"$hasNormal",o),i}function $t(e,t,n,r){var i=function(){var t=he;me(e);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==(0,a["default"])(n)&&!u(n)?[n]:vt(n))&&n[0];return me(t),n&&(!i||1===n.length&&i.isComment&&!Rt(i))?void 0:n};return r.proxy&&Object.defineProperty(t,n,{get:i,enumerable:!0,configurable:!0}),i}function Ut(e,t){return function(){return e[t]}}function Bt(e){return{get attrs(){if(!e._attrsProxy){var t=e._attrsProxy={};K(t,"_v_attr_proxy",!0),Gt(t,e.$attrs,s,e,"$attrs")}return e._attrsProxy},get listeners(){return e._listenersProxy||Gt(e._listenersProxy={},e.$listeners,s,e,"$listeners"),e._listenersProxy},get slots(){return function(e){return e._slotsProxy||Ht(e._slotsProxy={},e.$scopedSlots),e._slotsProxy}(e)},emit:N(e.$emit,e),expose:function(t){t&&Object.keys(t).forEach((function(n){return Xe(e,t,n)}))}}}function Gt(e,t,n,r,i){var o=!1;for(var a in t)a in e?t[a]!==n[a]&&(o=!0):(o=!0,zt(e,a,r,i));for(var s in e)s in t||(o=!0,delete e[s]);return o}function zt(e,t,n,r){Object.defineProperty(e,t,{enumerable:!0,configurable:!0,get:function(){return n[r][t]}})}function Ht(e,t){for(var n in t)e[n]=t[n];for(var r in e)r in t||delete e[r]}function qt(){var e=he;return e._setupContext||(e._setupContext=Bt(e))}var Vt=null;function Wt(e,t){return(e.__esModule||pe&&"Module"===e[Symbol.toStringTag])&&(e=e["default"]),h(e)?t.extend(e):e}function Xt(e){if(u(e))for(var t=0;t1&&arguments[1]!==undefined?arguments[1]:he;if(n)return function(e,t,n){var r=e.$options;r[t]=gr(r[t],n)}(n,e,t)}}var mn=hn("beforeMount"),gn=hn("mounted"),vn=hn("beforeUpdate"),_n=hn("updated"),yn=hn("beforeDestroy"),bn=hn("destroyed"),kn=hn("activated"),wn=hn("deactivated"),En=hn("serverPrefetch"),An=hn("renderTracked"),Cn=hn("renderTriggered"),xn=hn("errorCaptured"),In="2.7.16",Dn=Object.freeze({__proto__:null,version:In,defineComponent:function(e){return e},ref:function(e){return We(e,!1)},shallowRef:function(e){return We(e,!0)},isRef:Ve,toRef:Ke,toRefs:function(e){var t=u(e)?new Array(e.length):{};for(var n in e)t[n]=Ke(e,n);return t},unref:function(e){return Ve(e)?e.value:e},proxyRefs:function(e){if(Ge(e))return e;for(var t={},n=Object.keys(e),r=0;r2&&arguments[2]!==undefined&&arguments[2],r=he;if(r){var i=r.$parent&&r.$parent._provided;if(i&&e in i)return i[e];if(arguments.length>1)return n&&p(t)?t.call(r):t}},h:function(e,t,n){return Jt(he,e,t,n,2,!0)},getCurrentInstance:function(){return he&&{proxy:he}},useSlots:function(){return qt().slots},useAttrs:function(){return qt().attrs},useListeners:function(){return qt().listeners},mergeDefaults:function(e,t){var n=u(e)?e.reduce((function(e,t){return e[t]={},e}),{}):e;for(var r in t){var i=n[r];i?u(i)||p(i)?n[r]={type:i,"default":t[r]}:i["default"]=t[r]:null===i&&(n[r]={"default":t[r]})}return n},nextTick:pn,set:Re,del:je,useCssModule:function(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"$style";return he&&he[e]||s},useCssVars:function(e){if(Q){var t=he;t&&ot((function(){var n=t.$el,r=e(t,t._setupProxy);if(n&&1===n.nodeType){var i=n.style;for(var o in r)i.setProperty("--".concat(o),r[o])}}))}},defineAsyncComponent:function(e){p(e)&&(e={loader:e});var t=e,n=t.loader,r=t.loadingComponent,i=t.errorComponent,o=t.delay,a=void 0===o?200:o,s=t.timeout,u=(t.suspensible,t.onError),c=null,l=0,d=function f(){var e;return c||(e=c=n()["catch"]((function(e){if(e=e instanceof Error?e:new Error(String(e)),u)return new Promise((function(t,n){u(e,(function(){return t((l++,c=null,f()))}),(function(){return n(e)}),l+1)}));throw e})).then((function(t){return e!==c&&c?c:(t&&(t.__esModule||"Module"===t[Symbol.toStringTag])&&(t=t["default"]),t)})))};return function(){return{component:d(),delay:a,timeout:s,error:i,loading:r}}},onBeforeMount:mn,onMounted:gn,onBeforeUpdate:vn,onUpdated:_n,onBeforeUnmount:yn,onUnmounted:bn,onActivated:kn,onDeactivated:wn,onServerPrefetch:En,onRenderTracked:An,onRenderTriggered:Cn,onErrorCaptured:function(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:he;xn(e,t)}}),Sn=new fe;function On(e){return Tn(e,Sn),Sn.clear(),e}function Tn(e,t){var n,r,i=u(e);if(!(!i&&!h(e)||e.__v_skip||Object.isFrozen(e)||e instanceof ge)){if(e.__ob__){var o=e.__ob__.dep.id;if(t.has(o))return;t.add(o)}if(i)for(n=e.length;n--;)Tn(e[n],t);else if(Ve(e))Tn(e.value,t);else for(n=(r=Object.keys(e)).length;n--;)Tn(e[r[n]],t)}}var Mn,Nn=0,Pn=function(){function e(t,n,r,o,a){(0,i["default"])(this,e),function(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:at;t&&t.active&&t.effects.push(e)}(this,at&&!at._vm?at:t?t._scope:void 0),(this.vm=t)&&a&&(t._watcher=this),o?(this.deep=!!o.deep,this.user=!!o.user,this.lazy=!!o.lazy,this.sync=!!o.sync,this.before=o.before):this.deep=this.user=this.lazy=this.sync=!1,this.cb=r,this.id=++Nn,this.active=!0,this.post=!1,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new fe,this.newDepIds=new fe,this.expression="",p(n)?this.getter=n:(this.getter=function(e){if(!Y.test(e)){var t=e.split(".");return function(e){for(var n=0;n3&&arguments[3]!==undefined)||arguments[3];Ce();var i=he,o=lt();r&&me(e);var a=e.$options[t],s="".concat(t," hook");if(a)for(var u=0,c=a.length;udocument.createEvent("Event").timeStamp&&(Qn=function(){return Zn.now()})}var er=function(e,t){if(e.post){if(!t.post)return 1}else if(t.post)return-1;return e.id-t.id};function tr(){var e,t;for(Jn=Qn(),Kn=!0,qn.sort(er),Yn=0;YnYn&&qn[n].id>e.id;)n--;qn.splice(n+1,0,e)}else qn.push(e);Xn||(Xn=!0,pn(tr))}}function rr(e,t){if(e){for(var n=Object.create(null),r=pe?Reflect.ownKeys(e):Object.keys(e),i=0;i2&&arguments[2]!==undefined)||arguments[2];if(!t)return e;for(var a=pe?Reflect.ownKeys(t):Object.keys(t),s=0;s-1)if(o&&!x(i,"default"))a=!1;else if(""===a||a===M(e)){var u=Cr(String,i.type);(u<0||s-1:"string"==typeof e?e.split(",").indexOf(t)>-1:(n=e,"[object RegExp]"===m.call(n)&&e.test(t));var n}function $r(e,t){var n=e.cache,r=e.keys,i=e._vnode,o=e.$vnode;for(var a in n){var s=n[a];if(s){var u=s.name;u&&!t(u)&&Ur(n,a,r,i)}}o.componentOptions.children=void 0}function Ur(e,t,n,r){var i=e[t];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),e[t]=null,A(n,t)}!function(e){e.prototype._init=function(e){var t=this;t._uid=Pr++,t._isVue=!0,t.__v_skip=!0,t._scope=new ct(!0),t._scope.parent=void 0,t._scope._vm=!0,e&&e._isComponent?function(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r;var i=r.componentOptions;n.propsData=i.propsData,n._parentListeners=i.listeners,n._renderChildren=i.children,n._componentTag=i.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}(t,e):t.$options=yr(Fr(t.constructor),e||{},t),t._renderProxy=t,t._self=t,function(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._provided=n?n._provided:Object.create(null),e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}(t),function(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&jn(e,t)}(t),function(e){e._vnode=null,e._staticTrees=null;var t=e.$options,n=e.$vnode=t._parentVnode,r=n&&n.context;e.$slots=Ft(t._renderChildren,r),e.$scopedSlots=n?jt(e.$parent,n.data.scopedSlots,e.$slots):s,e._c=function(t,n,r,i){return Jt(e,t,n,r,i,!1)},e.$createElement=function(t,n,r,i){return Jt(e,t,n,r,i,!0)};var i=n&&n.data;Le(e,"$attrs",i&&i.attrs||s,null,!0),Le(e,"$listeners",t._parentListeners||s,null,!0)}(t),Hn(t,"beforeCreate",void 0,!1),function(e){var t=rr(e.$options.inject,e);t&&(Me(!1),Object.keys(t).forEach((function(n){Le(e,n,t[n])})),Me(!0))}(t),Dr(t),function(e){var t=e.$options.provide;if(t){var n=p(t)?t.call(e):t;if(!h(n))return;for(var r=dt(e),i=pe?Reflect.ownKeys(n):Object.keys(n),o=0;o1?P(n):n;for(var r=P(arguments,1),i='event handler for "'.concat(e,'"'),o=0,a=n.length;oparseInt(this.max)&&Ur(e,t[0],t,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Ur(this.cache,e,this.keys)},mounted:function(){var e=this;this.cacheVNode(),this.$watch("include",(function(t){$r(e,(function(e){return jr(t,e)}))})),this.$watch("exclude",(function(t){$r(e,(function(e){return!jr(t,e)}))}))},updated:function(){this.cacheVNode()},render:function(){var e=this.$slots["default"],t=Xt(e),n=t&&t.componentOptions;if(n){var r=Rr(n),i=this.include,o=this.exclude;if(i&&(!r||!jr(i,r))||o&&r&&jr(o,r))return t;var a=this.cache,s=this.keys,u=null==t.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):t.key;a[u]?(t.componentInstance=a[u].componentInstance,A(s,u),s.push(u)):(this.vnodeToCache=t,this.keyToCache=u),t.data.keepAlive=!0}return t||e&&e[0]}}};!function(e){var t={get:function(){return W}};Object.defineProperty(e,"config",t),e.util={warn:fr,extend:F,mergeOptions:yr,defineReactive:Le},e.set=Re,e["delete"]=je,e.nextTick=pn,e.observable=function(e){return Fe(e),e},e.options=Object.create(null),q.forEach((function(t){e.options[t+"s"]=Object.create(null)})),e.options._base=e,F(e.options.components,Gr),function(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var n=P(arguments,1);return n.unshift(this),p(e.install)?e.install.apply(e,n):p(e)&&e.apply(null,n),t.push(e),this}}(e),function(e){e.mixin=function(e){return this.options=yr(this.options,e),this}}(e),function(e){e.cid=0;var t=1;e.extend=function(e){e=e||{};var n=this,r=n.cid,i=e._Ctor||(e._Ctor={});if(i[r])return i[r];var o=sr(e)||sr(n.options),a=function(e){this._init(e)};return(a.prototype=Object.create(n.prototype)).constructor=a,a.cid=t++,a.options=yr(n.options,e),a["super"]=n,a.options.props&&function(e){var t=e.options.props;for(var n in t)Ir(e.prototype,"_props",n)}(a),a.options.computed&&function(e){var t=e.options.computed;for(var n in t)Or(e.prototype,n,t[n])}(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,q.forEach((function(e){a[e]=n[e]})),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=e,a.sealedOptions=F({},a.options),i[r]=a,a}}(e),function(e){q.forEach((function(t){e[t]=function(e,n){return n?("component"===t&&g(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&p(n)&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}}))}(e)}(Lr),Object.defineProperty(Lr.prototype,"$isServer",{get:ce}),Object.defineProperty(Lr.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Lr,"FunctionalRenderContext",{value:ir}),Lr.version=In;var zr=w("style,class"),Hr=w("input,textarea,option,select,progress"),qr=w("contenteditable,draggable,spellcheck"),Vr=w("events,caret,typing,plaintext-only"),Wr=function(e,t){return Qr(t)||"false"===t?"false":"contenteditable"===e&&Vr(t)?t:"true"},Xr=w("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),Kr="http://www.w3.org/1999/xlink",Yr=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},Jr=function(e){return Yr(e)?e.slice(6,e.length):""},Qr=function(e){return null==e||!1===e};function Zr(e,t){return{staticClass:ei(e.staticClass,t.staticClass),"class":l(e["class"])?[e["class"],t["class"]]:t["class"]}}function ei(e,t){return e?t?e+" "+t:e:t||""}function ti(e){return Array.isArray(e)?function(e){for(var t,n="",r=0,i=e.length;r-1?Ci(e,t,n):Xr(t)?Qr(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):qr(t)?e.setAttribute(t,Wr(t,n)):Yr(t)?Qr(n)?e.removeAttributeNS(Kr,Jr(t)):e.setAttributeNS(Kr,t,n):Ci(e,t,n)}function Ci(e,t,n){Qr(n)?e.removeAttribute(t):(!ee||te||"TEXTAREA"!==e.tagName||"placeholder"!==t||""===n||e.__ieph||(e.addEventListener("input",(function r(t){t.stopImmediatePropagation(),e.removeEventListener("input",r)})),e.__ieph=!0),e.setAttribute(t,n))}var xi={create:Ei,update:Ei};function Ii(e,t){var n=t.elm,r=t.data,i=e.data;if(!(c(r.staticClass)&&c(r["class"])&&(c(i)||c(i.staticClass)&&c(i["class"])))){var o=function(e){for(var t=e.data,n=e,r=e;l(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(t=Zr(r.data,t));for(;l(n=n.parent);)n&&n.data&&(t=Zr(t,n.data));return function(e,t){return l(e)||l(t)?ei(e,ti(t)):""}(t.staticClass,t["class"])}(t),a=n._transitionClasses;l(a)&&(o=ei(o,ti(a))),o!==n._prevClass&&(n.setAttribute("class",o),n._prevClass=o)}}var Di,Si={create:Ii,update:Ii},Oi="__r",Ti="__c";function Mi(e,t,n){var r=Di;return function i(){null!==t.apply(null,arguments)&&Fi(e,i,n,r)}}var Ni=on&&!(oe&&Number(oe[1])<=53);function Pi(e,t,n,r){if(Ni){var i=Jn,o=t;t=o._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=i||e.timeStamp<=0||e.target.ownerDocument!==document)return o.apply(this,arguments)}}Di.addEventListener(e,t,se?{capture:n,passive:r}:n)}function Fi(e,t,n,r){(r||Di).removeEventListener(e,t._wrapper||t,n)}function Li(e,t){if(!c(e.data.on)||!c(t.data.on)){var n=t.data.on||{},r=e.data.on||{};Di=t.elm||e.elm,function(e){if(l(e[Oi])){var t=ee?"change":"input";e[t]=[].concat(e[Oi],e[t]||[]),delete e[Oi]}l(e[Ti])&&(e.change=[].concat(e[Ti],e.change||[]),delete e[Ti])}(n),ht(n,r,Pi,Fi,Mi,t.context),Di=void 0}}var Ri,ji={create:Li,update:Li,destroy:function(e){return Li(e,fi)}};function $i(e,t){if(!c(e.data.domProps)||!c(t.data.domProps)){var n,r,i=t.elm,o=e.data.domProps||{},a=t.data.domProps||{};for(n in(l(a.__ob__)||d(a._v_attr_proxy))&&(a=t.data.domProps=F({},a)),o)n in a||(i[n]="");for(n in a){if(r=a[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),r===o[n])continue;1===i.childNodes.length&&i.removeChild(i.childNodes[0])}if("value"===n&&"PROGRESS"!==i.tagName){i._value=r;var s=c(r)?"":String(r);Ui(i,s)&&(i.value=s)}else if("innerHTML"===n&&ii(i.tagName)&&c(i.innerHTML)){(Ri=Ri||document.createElement("div")).innerHTML="".concat(r,"");for(var u=Ri.firstChild;i.firstChild;)i.removeChild(i.firstChild);for(;u.firstChild;)i.appendChild(u.firstChild)}else if(r!==o[n])try{i[n]=r}catch(e){}}}}function Ui(e,t){return!e.composing&&("OPTION"===e.tagName||function(e,t){var n=!0;try{n=document.activeElement!==e}catch(e){}return n&&e.value!==t}(e,t)||function(e,t){var n=e.value,r=e._vModifiers;if(l(r)){if(r.number)return k(n)!==k(t);if(r.trim)return n.trim()!==t.trim()}return n!==t}(e,t))}var Bi={create:$i,update:$i},Gi=I((function(e){var t={},n=/:(.+)/;return e.split(/;(?![^(]*\))/g).forEach((function(e){if(e){var r=e.split(n);r.length>1&&(t[r[0].trim()]=r[1].trim())}})),t}));function zi(e){var t=Hi(e.style);return e.staticStyle?F(e.staticStyle,t):t}function Hi(e){return Array.isArray(e)?L(e):"string"==typeof e?Gi(e):e}var qi,Vi=/^--/,Wi=/\s*!important$/,Xi=function(e,t,n){if(Vi.test(t))e.style.setProperty(t,n);else if(Wi.test(n))e.style.setProperty(M(t),n.replace(Wi,""),"important");else{var r=Yi(t);if(Array.isArray(n))for(var i=0,o=n.length;i-1?t.split(Zi).forEach((function(t){return e.classList.add(t)})):e.classList.add(t);else{var n=" ".concat(e.getAttribute("class")||""," ");n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function to(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(Zi).forEach((function(t){return e.classList.remove(t)})):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var n=" ".concat(e.getAttribute("class")||""," "),r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?e.setAttribute("class",n):e.removeAttribute("class")}}function no(e){if(e){if("object"==(0,a["default"])(e)){var t={};return!1!==e.css&&F(t,ro(e.name||"v")),F(t,e),t}return"string"==typeof e?ro(e):void 0}}var ro=I((function(e){return{enterClass:"".concat(e,"-enter"),enterToClass:"".concat(e,"-enter-to"),enterActiveClass:"".concat(e,"-enter-active"),leaveClass:"".concat(e,"-leave"),leaveToClass:"".concat(e,"-leave-to"),leaveActiveClass:"".concat(e,"-leave-active")}})),io=Q&&!te,oo="transition",ao="animation",so="transition",uo="transitionend",co="animation",lo="animationend";io&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(so="WebkitTransition",uo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(co="WebkitAnimation",lo="webkitAnimationEnd"));var fo=Q?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function po(e){fo((function(){fo(e)}))}function ho(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),eo(e,t))}function mo(e,t){e._transitionClasses&&A(e._transitionClasses,t),to(e,t)}function go(e,t,n){var r=_o(e,t),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===oo?uo:lo,u=0,c=function(){e.removeEventListener(s,l),n()},l=function(t){t.target===e&&++u>=a&&c()};setTimeout((function(){u0&&(n=oo,l=a,d=o.length):t===ao?c>0&&(n=ao,l=c,d=u.length):d=(n=(l=Math.max(a,c))>0?a>c?oo:ao:null)?n===oo?o.length:u.length:0,{type:n,timeout:l,propCount:d,hasTransform:n===oo&&vo.test(r[so+"Property"])}}function yo(e,t){for(;e.length1}function Co(e,t){!0!==t.data.show&&ko(t)}var xo=function(e){var t,n,r={},i=e.modules,o=e.nodeOps;for(t=0;th?y(e,c(n[v+1])?null:n[v+1].elm,n,p,v,r):p>v&&k(t,f,h)}(f,m,v,n,u):l(v)?(l(e.text)&&o.setTextContent(f,""),y(f,null,v,0,v.length-1,n)):l(m)?k(m,0,m.length-1):l(e.text)&&o.setTextContent(f,""):e.text!==t.text&&o.setTextContent(f,t.text),l(h)&&l(p=h.hook)&&l(p=p.postpatch)&&p(e,t)}}}function x(e,t,n){if(d(n)&&l(e.parent))e.parent.data.pendingInsert=t;else for(var r=0;r-1,a.selected!==o&&(a.selected=o);else if(U(To(a),r))return void(e.selectedIndex!==s&&(e.selectedIndex=s));i||(e.selectedIndex=-1)}}function Oo(e,t){return t.every((function(t){return!U(t,e)}))}function To(e){return"_value"in e?e._value:e.value}function Mo(e){e.target.composing=!0}function No(e){e.target.composing&&(e.target.composing=!1,Po(e.target,"input"))}function Po(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function Fo(e){return!e.componentInstance||e.data&&e.data.transition?e:Fo(e.componentInstance._vnode)}var Lo={bind:function(e,t,n){var r=t.value,i=(n=Fo(n)).data&&n.data.transition,o=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;r&&i?(n.data.show=!0,ko(n,(function(){e.style.display=o}))):e.style.display=r?o:"none"},update:function(e,t,n){var r=t.value;!r!=!t.oldValue&&((n=Fo(n)).data&&n.data.transition?(n.data.show=!0,r?ko(n,(function(){e.style.display=e.__vOriginalDisplay})):wo(n,(function(){e.style.display="none"}))):e.style.display=r?e.__vOriginalDisplay:"none")},unbind:function(e,t,n,r,i){i||(e.style.display=e.__vOriginalDisplay)}},Ro={model:Io,show:Lo},jo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function $o(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?$o(Xt(t.children)):e}function Uo(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var i=n._parentListeners;for(var o in i)t[S(o)]=i[o];return t}function Bo(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var Go=function(e){return e.tag||Rt(e)},zo=function(e){return"show"===e.name},Ho={name:"transition",props:jo,abstract:!0,render:function(e){var t=this,n=this.$slots["default"];if(n&&(n=n.filter(Go)).length){var r=this.mode,i=n[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return i;var o=$o(i);if(!o)return i;if(this._leaving)return Bo(e,i);var a="__transition-".concat(this._uid,"-");o.key=null==o.key?o.isComment?a+"comment":a+o.tag:f(o.key)?0===String(o.key).indexOf(a)?o.key:a+o.key:o.key;var s=(o.data||(o.data={})).transition=Uo(this),u=this._vnode,c=$o(u);if(o.data.directives&&o.data.directives.some(zo)&&(o.data.show=!0),c&&c.data&&!function(e,t){return t.key===e.key&&t.tag===e.tag}(o,c)&&!Rt(c)&&(!c.componentInstance||!c.componentInstance._vnode.isComment)){var l=c.data.transition=F({},s);if("out-in"===r)return this._leaving=!0,mt(l,"afterLeave",(function(){t._leaving=!1,t.$forceUpdate()})),Bo(e,i);if("in-out"===r){if(Rt(o))return u;var d,p=function(){d()};mt(s,"afterEnter",p),mt(s,"enterCancelled",p),mt(l,"delayLeave",(function(e){d=e}))}}return i}}},qo=F({tag:String,moveClass:String},jo);delete qo.mode;var Vo={props:qo,beforeMount:function(){var e=this,t=this._update;this._update=function(n,r){var i=Un(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,i(),t.call(e,n,r)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,i=this.$slots["default"]||[],o=this.children=[],a=Uo(this),s=0;s-1?ai[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:ai[e]=/HTMLUnknownElement/.test(t.toString())},F(Lr.options.directives,Ro),F(Lr.options.components,Yo),Lr.prototype.__patch__=Q?xo:R,Lr.prototype.$mount=function(e,t){return function(e,t,n){var r;e.$el=t,e.$options.render||(e.$options.render=ve),Hn(e,"beforeMount"),r=function(){e._update(e._render(),n)},new Pn(e,r,R,{before:function(){e._isMounted&&!e._isDestroyed&&Hn(e,"beforeUpdate")}},!0),n=!1;var i=e._preWatchers;if(i)for(var o=0;o.5&&(n="x"+n.toString(16)),r+="&#"+n+";";return r}t.Lexer=function(){function e(t){(0,i["default"])(this,e),this.tokens=[],this.tokens.links=Object.create(null),this.options=t||s.defaults,this.options.tokenizer=this.options.tokenizer||new a.Tokenizer,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};var n={block:u.block.normal,inline:u.inline.normal};this.options.pedantic?(n.block=u.block.pedantic,n.inline=u.inline.pedantic):this.options.gfm&&(n.block=u.block.gfm,this.options.breaks?n.inline=u.inline.breaks:n.inline=u.inline.gfm),this.tokenizer.rules=n}return(0,o["default"])(e,[{key:"lex",value:function(e){var t;for(e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," "),this.blockTokens(e,this.tokens);t=this.inlineQueue.shift();)this.inlineTokens(t.src,t.tokens);return this.tokens}},{key:"blockTokens",value:function(e){var t,n,r,i,o=this,a=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];this.options.pedantic&&(e=e.replace(/^ +$/gm,""));for(var s,u=function(){if(o.options.extensions&&o.options.extensions.block&&o.options.extensions.block.some((function(n){return!!(t=n.call({lexer:o},e,a))&&(e=e.substring(t.raw.length),a.push(t),!0)})))return 0;if(t=o.tokenizer.space(e))return e=e.substring(t.raw.length),1===t.raw.length&&a.length>0?a[a.length-1].raw+="\n":a.push(t),0;if(t=o.tokenizer.code(e))return e=e.substring(t.raw.length),!(n=a[a.length-1])||"paragraph"!==n.type&&"text"!==n.type?a.push(t):(n.raw+="\n"+t.raw,n.text+="\n"+t.text,o.inlineQueue[o.inlineQueue.length-1].src=n.text),0;if(t=o.tokenizer.fences(e))return e=e.substring(t.raw.length),a.push(t),0;if(t=o.tokenizer.heading(e))return e=e.substring(t.raw.length),a.push(t),0;if(t=o.tokenizer.hr(e))return e=e.substring(t.raw.length),a.push(t),0;if(t=o.tokenizer.blockquote(e))return e=e.substring(t.raw.length),a.push(t),0;if(t=o.tokenizer.list(e))return e=e.substring(t.raw.length),a.push(t),0;if(t=o.tokenizer.html(e))return e=e.substring(t.raw.length),a.push(t),0;if(t=o.tokenizer.def(e))return e=e.substring(t.raw.length),!(n=a[a.length-1])||"paragraph"!==n.type&&"text"!==n.type?o.tokens.links[t.tag]||(o.tokens.links[t.tag]={href:t.href,title:t.title}):(n.raw+="\n"+t.raw,n.text+="\n"+t.raw,o.inlineQueue[o.inlineQueue.length-1].src=n.text),0;if(t=o.tokenizer.table(e))return e=e.substring(t.raw.length),a.push(t),0;if(t=o.tokenizer.lheading(e))return e=e.substring(t.raw.length),a.push(t),0;if(r=e,o.options.extensions&&o.options.extensions.startBlock){var s,u=Infinity,c=e.slice(1);o.options.extensions.startBlock.forEach((function(e){"number"==typeof(s=e.call({lexer:this},c))&&s>=0&&(u=Math.min(u,s))})),u=0&&(r=e.substring(0,u+1))}if(o.state.top&&(t=o.tokenizer.paragraph(r)))return n=a[a.length-1],i&&"paragraph"===n.type?(n.raw+="\n"+t.raw,n.text+="\n"+t.text,o.inlineQueue.pop(),o.inlineQueue[o.inlineQueue.length-1].src=n.text):a.push(t),i=r.length!==e.length,e=e.substring(t.raw.length),0;if(t=o.tokenizer.text(e))return e=e.substring(t.raw.length),(n=a[a.length-1])&&"text"===n.type?(n.raw+="\n"+t.raw,n.text+="\n"+t.text,o.inlineQueue.pop(),o.inlineQueue[o.inlineQueue.length-1].src=n.text):a.push(t),0;if(e){var l="Infinite loop on byte: "+e.charCodeAt(0);if(o.options.silent)return console.error(l),1;throw new Error(l)}};e&&(0===(s=u())||1!==s););return this.state.top=!0,a}},{key:"inline",value:function(e,t){this.inlineQueue.push({src:e,tokens:t})}},{key:"inlineTokens",value:function(e){var t,n,r,i,o,a,s=this,u=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[],f=e;if(this.tokens.links){var p=Object.keys(this.tokens.links);if(p.length>0)for(;null!=(i=this.tokenizer.rules.inline.reflinkSearch.exec(f));)p.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(f=f.slice(0,i.index)+"["+(0,c.repeatString)("a",i[0].length-2)+"]"+f.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(i=this.tokenizer.rules.inline.blockSkip.exec(f));)f=f.slice(0,i.index)+"["+(0,c.repeatString)("a",i[0].length-2)+"]"+f.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(i=this.tokenizer.rules.inline.escapedEmSt.exec(f));)f=f.slice(0,i.index)+"++"+f.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);for(var h,m=function(){if(o||(a=""),o=!1,t=s.tokenizer.owo(e))return e=e.substring(t.raw.length),t.type&&u.push(t),0;if(s.options.extensions&&s.options.extensions.inline&&s.options.extensions.inline.some((function(n){return!!(t=n.call({lexer:s},e,u))&&(e=e.substring(t.raw.length),u.push(t),!0)})))return 0;if(t=s.tokenizer.escape(e))return e=e.substring(t.raw.length),u.push(t),0;if(t=s.tokenizer.tag(e))return e=e.substring(t.raw.length),(n=u[u.length-1])&&"text"===t.type&&"text"===n.type?(n.raw+=t.raw,n.text+=t.text):u.push(t),0;if(t=s.tokenizer.link(e))return e=e.substring(t.raw.length),u.push(t),0;if(t=s.tokenizer.reflink(e,s.tokens.links))return e=e.substring(t.raw.length),(n=u[u.length-1])&&"text"===t.type&&"text"===n.type?(n.raw+=t.raw,n.text+=t.text):u.push(t),0;if(t=s.tokenizer.emStrong(e,f,a))return e=e.substring(t.raw.length),u.push(t),0;if(t=s.tokenizer.codespan(e))return e=e.substring(t.raw.length),u.push(t),0;if(t=s.tokenizer.br(e))return e=e.substring(t.raw.length),u.push(t),0;if(t=s.tokenizer.del(e))return e=e.substring(t.raw.length),u.push(t),0;if(t=s.tokenizer.autolink(e,d))return e=e.substring(t.raw.length),u.push(t),0;if(!s.state.inLink&&(t=s.tokenizer.url(e,d)))return e=e.substring(t.raw.length),u.push(t),0;if(r=e,s.options.extensions&&s.options.extensions.startInline){var i,c=Infinity,p=e.slice(1);s.options.extensions.startInline.forEach((function(e){"number"==typeof(i=e.call({lexer:this},p))&&i>=0&&(c=Math.min(c,i))})),c=0&&(r=e.substring(0,c+1))}if(t=s.tokenizer.inlineText(r,l))return e=e.substring(t.raw.length),"_"!==t.raw.slice(-1)&&(a=t.raw.slice(-1)),o=!0,(n=u[u.length-1])&&"text"===n.type?(n.raw+=t.raw,n.text+=t.text):u.push(t),0;if(e){var h="Infinite loop on byte: "+e.charCodeAt(0);if(s.options.silent)return console.error(h),1;throw new Error(h)}};e&&(0===(h=m())||1!==h););return u}}],[{key:"rules",get:function(){return{block:u.block,inline:u.inline}}},{key:"lex",value:function(t,n){return new e(n).lex(t)}},{key:"lexInline",value:function(t,n){return new e(n).inlineTokens(t)}}]),e}()},2817:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.Parser=void 0;var i=r(n(8850)),o=r(n(1332)),a=n(7565),s=n(1674),u=n(2123),c=n(4008),l=n(9105);t.Parser=function(){function e(t){(0,i["default"])(this,e),this.options=t||c.defaults,this.options.renderer=this.options.renderer||new a.Renderer,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new s.TextRenderer,this.slugger=new u.Slugger}return(0,o["default"])(e,[{key:"parse",value:function(e){var t,n,r,i,o,a,s,u,c,d,f,p,h,m,g,v,_,y,b,k=!(arguments.length>1&&arguments[1]!==undefined)||arguments[1],w="",E=e.length;for(t=0;t0&&"paragraph"===g.tokens[0].type?(g.tokens[0].text=y+" "+g.tokens[0].text,g.tokens[0].tokens&&g.tokens[0].tokens.length>0&&"text"===g.tokens[0].tokens[0].type&&(g.tokens[0].tokens[0].text=y+" "+g.tokens[0].tokens[0].text)):g.tokens.unshift({type:"text",text:y}):m+=y),m+=this.parse(g.tokens,h),c+=this.renderer.listitem(m,_,v);w+=this.renderer.list(c,f,p);continue;case"html":w+=this.renderer.html(d.text);continue;case"paragraph":w+=this.renderer.paragraph(this.parseInline(d.tokens));continue;case"text":for(c=d.tokens?this.parseInline(d.tokens):d.text;t+1':":"+e+":"}},{key:"code",value:function(e,t,n){var r=(t||"").match(/\S*/)[0];if(this.options.highlight){var i=this.options.highlight(e,r);null!=i&&i!==e&&(n=!0,e=i)}return e=e.replace(/\n$/,"")+"\n",r?'
'+(n?e:(0,s.escape)(e,!0))+"
\n":"
"+(n?e:(0,s.escape)(e,!0))+"
\n"}},{key:"blockquote",value:function(e){return"
\n"+e+"
\n"}},{key:"html",value:function(e){return e}},{key:"heading",value:function(e,t,n,r){return this.options.headerIds?"'+e+"\n":""+e+"\n"}},{key:"hr",value:function(){return this.options.xhtml?"
\n":"
\n"}},{key:"list",value:function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"\n"}},{key:"listitem",value:function(e){return"
  • "+e+"
  • \n"}},{key:"checkbox",value:function(e){return" "}},{key:"paragraph",value:function(e){return"

    "+e+"

    \n"}},{key:"table",value:function(e,t){return t&&(t=""+t+""),"\n\n"+e+"\n"+t+"
    \n"}},{key:"tablerow",value:function(e){return"\n"+e+"\n"}},{key:"tablecell",value:function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+"\n"}},{key:"strong",value:function(e){return""+e+""}},{key:"em",value:function(e){return""+e+""}},{key:"codespan",value:function(e){return""+e+""}},{key:"br",value:function(){return this.options.xhtml?"
    ":"
    "}},{key:"del",value:function(e){return""+e+""}},{key:"link",value:function(e,t,n){if(null===(e=(0,s.cleanUrl)(this.options.sanitize,this.options.baseUrl,e)))return n;var r='"}},{key:"image",value:function(e,t,n){if(null===(e=(0,s.cleanUrl)(this.options.sanitize,this.options.baseUrl,e)))return n;var r=''+n+'":">"}},{key:"text",value:function(e){return e}}]),e}()},2123:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.Slugger=void 0;var i=r(n(8850)),o=r(n(1332));t.Slugger=function(){function e(){(0,i["default"])(this,e),this.seen={}}return(0,o["default"])(e,[{key:"serialize",value:function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")}},{key:"getNextSafeSlug",value:function(e,t){var n=e,r=0;if(this.seen.hasOwnProperty(n)){r=this.seen[e];do{n=e+"-"+ ++r}while(this.seen.hasOwnProperty(n))}return t||(this.seen[e]=r,this.seen[n]=0),n}},{key:"slug",value:function(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{},n=this.serialize(e);return this.getNextSafeSlug(n,t.dryrun)}}]),e}()},1674:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.TextRenderer=void 0;var i=r(n(8850)),o=r(n(1332));t.TextRenderer=function(){function e(){(0,i["default"])(this,e)}return(0,o["default"])(e,[{key:"strong",value:function(e){return e}},{key:"em",value:function(e){return e}},{key:"codespan",value:function(e){return e}},{key:"del",value:function(e){return e}},{key:"html",value:function(e){return e}},{key:"text",value:function(e){return e}},{key:"link",value:function(e,t,n){return""+n}},{key:"image",value:function(e,t,n){return""+n}},{key:"br",value:function(){return""}}]),e}()},4001:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.Tokenizer=void 0;var i=r(n(8850)),o=r(n(1332)),a=r(n(9272)),s=n(4008),u=n(9105);function c(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return l(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,o=e},f:function(){try{a||null==n["return"]||n["return"]()}finally{if(s)throw o}}}}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0)return{type:"space",raw:t[0]}}},{key:"code",value:function(e){var t=this.rules.block.code.exec(e);if(t){var n=t[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?n:(0,u.rtrim)(n,"\n")}}}},{key:"fences",value:function(e){var t=this.rules.block.fences.exec(e);if(t){var n=t[0],r=function(e,t){var n=e.match(/^(\s+)(?:```)/);if(null===n)return t;var r=n[1];return t.split("\n").map((function(e){var t=e.match(/^\s+/);return null===t?e:(0,a["default"])(t,1)[0].length>=r.length?e.slice(r.length):e})).join("\n")}(n,t[3]||"");return{type:"code",raw:n,lang:t[2]?t[2].trim():t[2],text:r}}}},{key:"heading",value:function(e){var t=this.rules.block.heading.exec(e);if(t){var n=t[2].trim();if(/#$/.test(n)){var r=(0,u.rtrim)(n,"#");this.options.pedantic?n=r.trim():r&&!/ $/.test(r)||(n=r.trim())}var i={type:"heading",raw:t[0],depth:t[1].length,text:n,tokens:[]};return this.lexer.inline(i.text,i.tokens),i}}},{key:"hr",value:function(e){var t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[0]}}},{key:"blockquote",value:function(e){var t=this.rules.block.blockquote.exec(e);if(t){var n=t[0].replace(/^ *> ?/gm,"");return{type:"blockquote",raw:t[0],tokens:this.lexer.blockTokens(n,[]),text:n}}}},{key:"list",value:function(e){var t=this.rules.block.list.exec(e);if(t){var n,r,i,o,a,s,u,l,d,f,p,h,m=t[1].trim(),g=m.length>1,v={type:"list",raw:"",ordered:g,start:g?+m.slice(0,-1):"",loose:!1,items:[]};m=g?"\\d{1,9}\\".concat(m.slice(-1)):"\\".concat(m),this.options.pedantic&&(m=g?m:"[*+-]");for(var _=new RegExp("^( {0,3}".concat(m,")((?: [^\\n]*)?(?:\\n|$))"));e&&(h=!1,t=_.exec(e))&&!this.rules.block.hr.test(e);){if(n=t[0],e=e.substring(n.length),l=t[2].split("\n",1)[0],d=e.split("\n",1)[0],this.options.pedantic?(o=2,p=l.trimLeft()):(o=(o=t[2].search(/[^ ]/))>4?1:o,p=l.slice(o),o+=t[1].length),s=!1,!l&&/^ *$/.test(d)&&(n+=d+"\n",e=e.substring(d.length+1),h=!0),!h)for(var y=new RegExp("^ {0,".concat(Math.min(3,o-1),"}(?:[*+-]|\\d{1,9}[.)])"));e&&(l=f=e.split("\n",1)[0],this.options.pedantic&&(l=l.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),!y.test(l));){if(l.search(/[^ ]/)>=o||!l.trim())p+="\n"+l.slice(o);else{if(s)break;p+="\n"+l}s||l.trim()||(s=!0),n+=f+"\n",e=e.substring(f.length+1)}v.loose||(u?v.loose=!0:/\n *\n *$/.test(n)&&(u=!0)),this.options.gfm&&(r=/^\[[ xX]\] /.exec(p))&&(i="[ ] "!==r[0],p=p.replace(/^\[[ xX]\] +/,"")),v.items.push({type:"list_item",raw:n,task:!!r,checked:i,loose:!1,text:p}),v.raw+=n}v.items[v.items.length-1].raw=n.trimRight(),v.items[v.items.length-1].text=p.trimRight(),v.raw=v.raw.trimRight();var b=v.items.length;for(a=0;a1)return!0}catch(i){r.e(i)}finally{r.f()}return!1}));!v.loose&&k.length&&w&&(v.loose=!0,v.items[a].loose=!0)}return v}}},{key:"html",value:function(e){var t=this.rules.block.html.exec(e);if(t){var n={type:"html",raw:t[0],pre:!this.options.sanitizer&&("pre"===t[1]||"script"===t[1]||"style"===t[1]),text:t[0]};return this.options.sanitize&&(n.type="paragraph",n.text=this.options.sanitizer?this.options.sanitizer(t[0]):(0,u.escape)(t[0]),n.tokens=[],this.lexer.inline(n.text,n.tokens)),n}}},{key:"def",value:function(e){var t=this.rules.block.def.exec(e);if(t)return t[3]&&(t[3]=t[3].substring(1,t[3].length-1)),{type:"def",tag:t[1].toLowerCase().replace(/\s+/g," "),raw:t[0],href:t[2],title:t[3]}}},{key:"table",value:function(e){var t=this.rules.block.table.exec(e);if(t){var n={type:"table",header:(0,u.splitCells)(t[1]).map((function(e){return{text:e}})),align:t[2].replace(/^ *|\| *$/g,"").split(/ *\| */),rows:t[3]&&t[3].trim()?t[3].replace(/\n[ \t]*$/,"").split("\n"):[]};if(n.header.length===n.align.length){n.raw=t[0];var r,i,o,a,s=n.align.length;for(r=0;r/i.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(t[0]):(0,u.escape)(t[0]):t[0]}}},{key:"link",value:function(e){var t=this.rules.inline.link.exec(e);if(t){var n=t[2].trim();if(!this.options.pedantic&&/^$/.test(n))return;var r=(0,u.rtrim)(n.slice(0,-1),"\\");if((n.length-r.length)%2==0)return}else{var i=(0,u.findClosingBracket)(t[2],"()");if(i>-1){var o=(0===t[0].indexOf("!")?5:4)+t[1].length+i;t[2]=t[2].substring(0,i),t[0]=t[0].substring(0,o).trim(),t[3]=""}}var a=t[2],s="";if(this.options.pedantic){var c=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(a);c&&(a=c[1],s=c[3])}else s=t[3]?t[3].slice(1,-1):"";return a=a.trim(),/^$/.test(n)?a.slice(1):a.slice(1,-1)),d(t,{href:a?a.replace(this.rules.inline._escapes,"$1"):a,title:s?s.replace(this.rules.inline._escapes,"$1"):s},t[0],this.lexer)}}},{key:"reflink",value:function(e,t){var n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){var r=(n[2]||n[1]).replace(/\s+/g," ");if(!(r=t[r.toLowerCase()])||!r.href){var i=n[0].charAt(0);return{type:"text",raw:i,text:i}}return d(n,r,n[0],this.lexer)}}},{key:"emStrong",value:function(e,t){var n=arguments.length>2&&arguments[2]!==undefined?arguments[2]:"",r=this.rules.inline.emStrong.lDelim.exec(e);if(r&&(!r[3]||!n.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDF50-\uDF59\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD887][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEC0-\uDED3\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDCD0-\uDCEB\uDCF0-\uDCF9\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF39\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD888[\uDC00-\uDFAF])/))){var i=r[1]||r[2]||"";if(!i||i&&(""===n||this.rules.inline.punctuation.exec(n))){var o,a,s=r[0].length-1,u=s,c=0,l="*"===r[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(l.lastIndex=0,t=t.slice(-1*e.length+s);null!=(r=l.exec(t));)if(o=r[1]||r[2]||r[3]||r[4]||r[5]||r[6])if(a=o.length,r[3]||r[4])u+=a;else if(!((r[5]||r[6])&&s%3)||(s+a)%3){if(!((u-=a)>0)){if(a=Math.min(a,a+u+c),Math.min(s,a)%2){var d=e.slice(1,s+r.index+a);return{type:"em",raw:e.slice(0,s+r.index+a+1),text:d,tokens:this.lexer.inlineTokens(d,[])}}var f=e.slice(2,s+r.index+a-1);return{type:"strong",raw:e.slice(0,s+r.index+a+1),text:f,tokens:this.lexer.inlineTokens(f,[])}}}else c+=a}}}},{key:"codespan",value:function(e){var t=this.rules.inline.code.exec(e);if(t){var n=t[2].replace(/\n/g," "),r=/[^ ]/.test(n),i=/^ /.test(n)&&/ $/.test(n);return r&&i&&(n=n.substring(1,n.length-1)),n=(0,u.escape)(n,!0),{type:"codespan",raw:t[0],text:n}}}},{key:"br",value:function(e){var t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}},{key:"del",value:function(e){var t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2],[])}}},{key:"owo",value:function(e){var t=this.rules.inline.owo.exec(e);if(t&&t[0].length>1)return{type:"owo",raw:t[0],text:t[1]}}},{key:"autolink",value:function(e,t){var n,r,i=this.rules.inline.autolink.exec(e);if(i)return r="@"===i[2]?"mailto:"+(n=(0,u.escape)(this.options.mangle?t(i[1]):i[1])):n=(0,u.escape)(i[1]),{type:"link",raw:i[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}}},{key:"url",value:function(e,t){var n;if(n=this.rules.inline.url.exec(e)){var r,i;if("@"===n[2])i="mailto:"+(r=(0,u.escape)(this.options.mangle?t(n[0]):n[0]));else{var o;do{o=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])[0]}while(o!==n[0]);r=(0,u.escape)(n[0]),i="www."===n[1]?"http://"+r:r}return{type:"link",raw:n[0],text:r,href:i,tokens:[{type:"text",raw:r,text:r}]}}}},{key:"inlineText",value:function(e,t){var n,r=this.rules.inline.text.exec(e);if(r)return n=this.lexer.state.inRawBlock?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(r[0]):(0,u.escape)(r[0]):r[0]:(0,u.escape)(this.options.smartypants?t(r[0]):r[0]),{type:"text",raw:r[0],text:n}}}]),e}()},4008:function(e,t){"use strict";function n(){return{baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}Object.defineProperty(t,"__esModule",{value:!0}),t.changeDefaults=function(e){t.defaults=e},t.defaults=void 0,t.getDefaults=n,t.defaults={baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}},9105:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.checkSanitizeDeprecation=function(e){e&&e.sanitize&&!e.silent&&console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options")},t.cleanUrl=function(e,t,n){if(e){var r;try{r=decodeURIComponent(c(n)).replace(d,"").toLowerCase()}catch(i){return null}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:")||0===r.indexOf("data:"))return null}t&&!f.test(n)&&(n=v(t,n));try{n=encodeURI(n).replace(/%25/g,"%")}catch(i){return null}return n},t.edit=function(e,t){e=e.source||e,t=t||"";var n={replace:function(t,r){return r=(r=r.source||r).replace(l,"$1"),e=e.replace(t,r),n},getRegex:function(){return new RegExp(e,t)}};return n},t.escape=function(e,t){if(t){if(n.test(e))return e.replace(r,s)}else if(i.test(e))return e.replace(o,s);return e},t.findClosingBracket=function(e,t){if(-1===e.indexOf(t[1]))return-1;for(var n=e.length,r=0,i=0;i1;)1&t&&(n+=e),t>>=1,e+=e;return n+e},t.resolveUrl=v,t.rtrim=_,t.splitCells=function(e,t){var n=e.replace(/\|/g,(function(e,t,n){for(var r=!1,i=t;--i>=0&&"\\"===n[i];)r=!r;return r?"|":" |"})).split(/ \|/),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n[n.length-1].trim()&&n.pop(),n.length>t)n.splice(t);else for(;n.length"']/,r=/[&<>"']/g,i=/[<>"']|&(?!#?\w+;)/,o=/[<>"']|&(?!#?\w+;)/g,a={"&":"&","<":"<",">":">",'"':""","'":"'"},s=function(e){return a[e]},u=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function c(e){return e.replace(u,(function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""}))}var l=/(^|[^\[])\^/g,d=/[^\w:]/g,f=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i,p={},h=/^[^:]+:\/*[^/]*$/,m=/^([^:]+:)[\s\S]*$/,g=/^([^:]+:\/*[^/]*)[\s\S]*$/;function v(e,t){p[" "+e]||(h.test(e)?p[" "+e]=e+"/":p[" "+e]=_(e,"/",!0));var n=-1===(e=p[" "+e]).indexOf(":");return"//"===t.substring(0,2)?n?t:e.replace(m,"$1")+t:"/"===t.charAt(0)?n?t:e.replace(g,"$1")+t:e+t}function _(e,t,n){var r=e.length;if(0===r)return"";for(var i=0;i=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,o=e},f:function(){try{a||null==n["return"]||n["return"]()}finally{if(s)throw o}}}}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nAn error occurred:

    "+(0,c.escape)(d.message+"",!0)+"
    ";throw d}}p.options=p.setOptions=function(e){return(0,c.merge)(p.defaults,e),(0,l.changeDefaults)(p.defaults),p},p.getDefaults=l.getDefaults,p.defaults=l.defaults,p.use=function(){for(var e=arguments.length,t=new Array(e),n=0;nAn error occurred:

    "+(0,c.escape)(o.message+"",!0)+"
    ";throw o}},p.Parser=i.Parser,p.parser=i.Parser.parse,p.Renderer=a.Renderer,p.TextRenderer=s.TextRenderer,p.Lexer=r.Lexer,p.lexer=r.Lexer.lex,p.Tokenizer=o.Tokenizer,p.Slugger=u.Slugger,p.parse=p,t.options=p.options,t.setOptions=p.setOptions,t.use=p.use,t.walkTokens=p.walkTokens,t.parseInline=p.parseInline,t.parse=p,t.parser=i.Parser.parse,t.lexer=r.Lexer.lex},5779:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.inline=t.block=void 0;var r=n(9105),i=t.block={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,table:r.noopTest,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,text:/^[^\n]+/};i._label=/(?!\s*\])(?:\\.|[^\[\]\\])+/,i._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/,i.def=(0,r.edit)(i.def).replace("label",i._label).replace("title",i._title).getRegex(),i.bullet=/(?:[*+-]|\d{1,9}[.)])/,i.listItemStart=(0,r.edit)(/^( *)(bull) */).replace("bull",i.bullet).getRegex(),i.list=(0,r.edit)(i.list).replace(/bull/g,i.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+i.def.source+")").getRegex(),i._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",i._comment=/|$)/,i.html=(0,r.edit)(i.html,"i").replace("comment",i._comment).replace("tag",i._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),i.paragraph=(0,r.edit)(i._paragraph).replace("hr",i.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",i._tag).getRegex(),i.blockquote=(0,r.edit)(i.blockquote).replace("paragraph",i.paragraph).getRegex(),i.normal=(0,r.merge)({},i),i.gfm=(0,r.merge)({},i.normal,{table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),i.gfm.table=(0,r.edit)(i.gfm.table).replace("hr",i.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",i._tag).getRegex(),i.gfm.paragraph=(0,r.edit)(i._paragraph).replace("hr",i.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("table",i.gfm.table).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",i._tag).getRegex(),i.pedantic=(0,r.merge)({},i.normal,{html:(0,r.edit)("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",i._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:r.noopTest,paragraph:(0,r.edit)(i.normal._paragraph).replace("hr",i.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",i.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});var o=t.inline={owo:/^:(\S*):/,escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:r.noopTest,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(ref)\]/,nolink:/^!?\[(ref)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,rDelimUnd:/^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:r.noopTest,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~",o.punctuation=(0,r.edit)(o.punctuation).replace(/punctuation/g,o._punctuation).getRegex(),o.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,o.escapedEmSt=/\\\*|\\_/g,o._comment=(0,r.edit)(i._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),o.emStrong.lDelim=(0,r.edit)(o.emStrong.lDelim).replace(/punct/g,o._punctuation).getRegex(),o.emStrong.rDelimAst=(0,r.edit)(o.emStrong.rDelimAst,"g").replace(/punct/g,o._punctuation).getRegex(),o.emStrong.rDelimUnd=(0,r.edit)(o.emStrong.rDelimUnd,"g").replace(/punct/g,o._punctuation).getRegex(),o._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,o._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,o._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,o.autolink=(0,r.edit)(o.autolink).replace("scheme",o._scheme).replace("email",o._email).getRegex(),o._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,o.tag=(0,r.edit)(o.tag).replace("comment",o._comment).replace("attribute",o._attribute).getRegex(),o._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,o._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,o._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,o.link=(0,r.edit)(o.link).replace("label",o._label).replace("href",o._href).replace("title",o._title).getRegex(),o.reflink=(0,r.edit)(o.reflink).replace("label",o._label).replace("ref",i._label).getRegex(),o.nolink=(0,r.edit)(o.nolink).replace("ref",i._label).getRegex(),o.reflinkSearch=(0,r.edit)(o.reflinkSearch,"g").replace("reflink",o.reflink).replace("nolink",o.nolink).getRegex(),o.normal=(0,r.merge)({},o),o.pedantic=(0,r.merge)({},o.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:(0,r.edit)(/^!?\[(label)\]\((.*?)\)/).replace("label",o._label).getRegex(),reflink:(0,r.edit)(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",o._label).getRegex()}),o.gfm=(0,r.merge)({},o.normal,{escape:(0,r.edit)(o.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\'.concat(e.logo,"")+'
    ',r=0;r');for(var i=this.odata[this.packages[r]].container,o=0;o').concat(a,"")}n+=""}n+='
      ';for(var s=0;s".concat(this.packages[s],"");n+="
    ",this.container.innerHTML=n,this.logo=this.container.getElementsByClassName("OwO-logo")[0],this.logo.addEventListener("click",(function(){t.toggle()})),this.container.getElementsByClassName("OwO-body")[0].addEventListener("click",(function(e){var n=null;if(e.target.classList.contains("OwO-item")?n=e.target:e.target.parentNode.classList.contains("OwO-item")&&(n=e.target.parentNode),n){var r=t.area.selectionEnd,i=t.area.value,o=n.innerHTML;if(-1!==o.indexOf("2&&f[2]!==undefined?f[2]:{},o=e||(s.app?s.app.$tcb:null),a=r.envId||s.app.$twikoo.envId,u=r.funcName||(null===s.app||void 0===s.app?void 0:s.app.$twikoo.funcName)||"twikoo",!o){t.next=33;break}return t.prev=5,t.next=8,o.app.callFunction({name:u,data:c({event:n},r)});case 8:case 27:case 36:return t.abrupt("return",t.sent);case 11:t.prev=11,t.t0=t["catch"](5),t.t1=n,t.next="COMMENT_LIKE"===t.t1?16:"COMMENT_GET"===t.t1?18:"COMMENT_SUBMIT"===t.t1?20:"COUNTER_GET"===t.t1?22:24;break;case 16:return d="comment-like",t.abrupt("break",24);case 18:return d="comment-get",t.abrupt("break",24);case 20:return d="comment-submit",t.abrupt("break",24);case 22:return d="counter-get",t.abrupt("break",24);case 24:if(!d){t.next=30;break}return t.next=27,o.app.callFunction({name:d,data:r});case 30:throw new Error("请升级 Twikoo 云函数版本再试,如果仍无法解决,请删除并重新创建 Twikoo 云函数 - https://twikoo.js.org");case 31:t.next=40;break;case 33:if(!l(a)){t.next=39;break}return t.next=36,new Promise((function(e,t){try{var i=localStorage.getItem("twikoo-access-token"),o=new XMLHttpRequest;o.onreadystatechange=function(){if(4===o.readyState)if(200===o.status){var n=JSON.parse(o.responseText);n.accessToken&&localStorage.setItem("twikoo-access-token",n.accessToken),e({result:n})}else t(o.status)},o.open("POST",a),o.setRequestHeader("Content-Type","application/json"),o.send(JSON.stringify(c({event:n,accessToken:i},r)))}catch(s){t(s)}}));case 39:throw new Error("缺少 envId 配置 - https://twikoo.js.org");case 40:case"end":return t.stop()}}),t,null,[[5,11]])})));return function(t,n){return e.apply(this,arguments)}}()},7080:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getQQAvatar=function(e){var t=e.replace(/@qq.com/gi,"");return"https://thirdqq.qlogo.cn/g?b=sdk&nk=".concat(t,"&s=140")},t.isQQ=function(e){return/^[1-9][0-9]{4,10}$/.test(e)||/^[1-9][0-9]{4,10}@qq.com$/i.test(e)},t.normalizeMail=function(e){return String(e).trim().toLowerCase()}},9212:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.initMarkedOwo=function(e){if(e&&Object.values(e)){var t={};return Object.values(e).forEach((function(e){e.container.forEach((function(e){var n=p(e.icon);n&&(t[e.text]=n)}))})),t}},t.initOwoEmotions=function(e){return d.apply(this,arguments)};var i=r(n(479)),o=r(n(1819)),a=r(n(4964)),s=n(8129);function u(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return c(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,o=e},f:function(){try{a||null==n["return"]||n["return"]()}finally{if(s)throw o}}}}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=200&&n.status<300||304===n.status){var e=function(e){try{return Object.values(e).forEach((function(e){if("image"===e.type){var t,n=u(e.container);try{for(n.s();!(t=n.n()).done;){var r=t.value;r.text||(r.text=h(p(r.icon)))}}catch(i){n.e(i)}finally{n.f()}}})),e}catch(t){s.logger.warn("OwO data is bad: ",t)}}(JSON.parse(n.responseText));t(e)}else s.logger.warn("OwO data request was unsuccessful: "+n.status)},n.open("get",e,!0),n.send(null)}))}function d(){return(d=(0,a["default"])(i["default"].mark((function e(t){var n,r;return i["default"].wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n={},e.next=3,Promise.all(t.split(",").map((function(e){return l(e.trim())})));case 3:return r=e.sent,Object.assign.apply(Object,[n].concat((0,o["default"])(r))),e.abrupt("return",n);case 6:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var f=document.createElement("template");function p(e){try{return f.innerHTML=e,f.content.childNodes[0].src}catch(t){return""}}function h(e){return e.split("#").shift().split("?").shift().split("/").pop()}},4161:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=void 0;var r,i,o=n(1085),a=function(e,t){var n=document.getElementById("twikoo");i&&n.contains(i)||!e||"none"===e||((i=document.createElement("link")).href="default"===e?"".concat(t,"/themes/prism.min.css"):"".concat(t,"/themes/prism-").concat(e,".min.css"),i.rel="stylesheet",i.type="text/css",n.appendChild(i))};t["default"]=function(e,t,i){var s=o.app&&o.app.$twikoo.prismCdn?o.app.$twikoo.prismCdn:"https://cdn.jsdelivr.net/npm/prismjs@1.28.0";window.Prism=window.Prism||{},window.Prism.manual=!0,r||(r=n(1965),n(210),r.plugins.autoloader.languages_path="".concat(s,"/components/"),i&&(n(8072),i.split(",").map((function(e){return e.trim()})).forEach((function(e){"showLanguage"===e?n(4296):"copyButton"===e&&n(5472)})))),a(t,s),r.highlightAllUnder(e)}},7564:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=void 0;var i,o=r(n(3852)),a="ADMIN_COMMENT",s="ADMIN_CONFIG_CATEGORY",u="ADMIN_CONFIG_ITEM",c="ADMIN_IMPORT",l=["qmsg","serverchan","pushplus","pushplushxtrip","dingtalk","wecom","bark","gocqhttp","atri","pushdeer","igot","telegram","feishu"].map((function(e){return'"'.concat(e,'"')})),d=["126","163","1und1","AOL","DebugMail","DynectEmail","FastMail","GandiMail","Gmail","Godaddy","GodaddyAsia","GodaddyEurope","Hotmail","Mail.ru","Maildev","Mailgun","Mailjet","Mailosaur","Mandrill","Naver","OpenMailBox","Outlook365","Postmark","QQ","QQex","SES","SES-EU-WEST-1","SES-US-EAST-1","SES-US-WEST-2","SendCloud","SendGrid","SendPulse","SendinBlue","Sparkpost","Yahoo","Yandex","Zoho","hot.ee","iCloud","mail.ee","qiye.aliyun"].map((function(e){return'"'.concat(e,'"')})),f=["default","coy","dark","funky","okaidia","solarizedlight","tomorrow","twilight"].map((function(e){return'"'.concat(e,'"')})),p=["showLanguage","copyButton"].map((function(e){return'"'.concat(e,'"')})),h=["qcloud","7bu (https://7bu.top)","smms (https://sm.ms)","lskypro","piclist","easyimage"].map((function(e){return'"'.concat(e,'"')})),m=["lskypro","piclist","easyimage"].map((function(e){return'"'.concat(e,'"')})),g=["404","mp","identicon","monsterid","wavatar","retro","robohash","blank"].map((function(e){return'"'.concat(e,'"')}));t["default"]=(i={ADMIN_CLIENT_VERSION:["前端版本:","前端版本:","前端版本:","Client version: ","Клиент версияси: ","クライアントバージョン:","클라이언트 버전: "],ADMIN_SERVER_VERSION:["云函数版本:","云函數版本:","雲端函式版本:","Server version: ","Сервернинг версияси: ","サーバーサイドバージョン: ","서버 버전: "]},(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,a,["评论管理","評論管理","留言管理","Comment","Изоҳ","コメント管理","댓글 관리"]),a+"_DELETE",["删除","刪除","移除","Delete","Ўчирмоқ","削除","삭제"]),a+"_DELETE_CONFIRM",["确认删除?","確認刪除?","確認移除?","Confirm deletion?","Ўчириш тасдиқлансинми?","本当に削除しますか?","정말 삭제하시겠습니까?"]),a+"_FILTER_ALL",["全部","全部","全部","All","Ҳаммаси","全部","전체"]),a+"_FILTER_VISIBLE",["只看可见","只看可見","只看可見","Visible","Кўринадиган","表示中のみ","표시 댓글"]),a+"_FILTER_HIDDEN",["只看隐藏","只看隱藏","只看隱藏","Hidden","Яширилган","非表示中のみ","숨김 댓글"]),a+"_HIDE",["隐藏","隱藏","隱藏","Hide","Яширмоқ","非表示","숨기기"]),a+"_IS_SPAM_SUFFIX",[" (已隐藏)"," (已隱藏)"," (已隱藏)"," (Hidden)"," (Яширилган)"," (非表示)"," (숨김 처리됨)"]),a+"_SEARCH",["搜索","搜索","搜尋","Search","Излаш","検索","검색"]),a+"_SEARCH_PLACEHOLDER",["搜索昵称、邮箱、网址、IP、评论正文、文章地址","搜索暱稱、郵箱、網址、IP、評論正文、文章地址","搜索暱稱、郵件、網址、IP、留言正文、文章路徑","Search by nick, mail, website, IP, comment, or article path","Тахаллус, почта, веб-сайт, ИП, шарҳ ёки мақола йўли бўйича излаш","名前、メールアドレス、ウェブサイトURL、IPアドレス、コメント内容、記事のURLを検索","닉네임, 이메일, 웹사이트, IP, 댓글 내용, 게시글 주소로 검색"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,a+"_SHOW",["显示","顯示","顯示","Show","Кўрсатиш","表示","표시"]),a+"_TOP",["置顶","置頂","置頂","Pin","Қадамоқ","固定する","고정"]),a+"_UNTOP",["取消置顶","取消置頂","取消置頂","Unpin","Қадоқни ечмоқ","固定を解除","고정 해제"]),a+"_VIEW",["查看","查看","檢視","View","Кўриниш","閲覧","보기"]),"ADMIN_CONFIG",["配置管理","配置管理","設定值管理","Configuration","Конфигурация","設定管理","환경설정"]),s+"_COMMON",["通用","通用","一般","General","Умумий","一般","일반"]),s+"_IM",["即时通知","即時通知","即時通知","Instant notification","Тезкор хабарнома","即時通知","실시간 알림"]),s+"_MAIL",["邮件通知","郵件通知","郵件通知","Email notification","Электрон почта хабарномаси","メール通知","이메일 알림"]),s+"_PLUGIN",["插件","插件","擴充功能","Plugin","Плагин","プラグイン","플러그인"]),s+"_PRIVACY",["隐私","隱私","隱私權","Privacy","Шахсий қоидалар","プライバシー","개인정보"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,s+"_SPAM",["反垃圾","反垃圾","防垃圾","Spam","Спам","スパム対策","스팸 관리"]),"ADMIN_CONFIG_EMAIL_TEST",["邮件通知测试","郵件通知測試","郵件通知測試","Email notification test","Электрон почта хабарномаси тести","メール通知テスト","이메일 알림 테스트"]),"ADMIN_CONFIG_EMAIL_TEST_BTN",["发送测试邮件","發送測試郵件","發送測試郵件","Send test mail","Синов хатини юбориш","テストメールを送信","테스트 메일 발송"]),"ADMIN_CONFIG_EMAIL_TEST_HELP",["输入一个邮箱地址,发送测试邮件","輸入一個郵箱位址,發送測試郵件","輸入一個郵箱帳號,發送測試郵件","Input an email address & send test mail","Э-почта манзилини киритинг ва синов хатини юборинг","メールアドレスを入力してテストメールを送信","이메일 주소를 입력하고 테스트 메일을 발송하세요"]),"ADMIN_CONFIG_EMAIL_TEST_RESULT",["测试结果:","測試結果:","測試結果:","Test result: ","Тест натижаси: ","テスト結果:","테스트 결과: "]),"ADMIN_CONFIG_EXAMPLE",["示例:","示例:","範例:","Example: ","Намуна: ","例:","예시: "]),u+"_AKISMET_KEY",['Akismet 反垃圾评论,用于垃圾评论检测,设为 "MANUAL_REVIEW" 开启人工审核,留空不使用反垃圾。注册:https://akismet.com','Akismet 反垃圾評論,用於垃圾評論檢測,設為 "MANUAL_REVIEW" 開啟人工審核,留空不使用反垃圾。註冊:https://akismet.com','Akismet 防垃圾留言,用於垃圾留言檢測,設為 "MANUAL_REVIEW" 以開啟人工審核,留空則不使用防垃圾。註冊:https://akismet.com','Akismet spam protection. Set to "MANUAL_REVIEW" to enable manual review. Leave it blank to not use anti-spam. Register Akismet: https://akismet.com','Акисмет спам ҳимояси. Қўлда кўриб чиқишни ёқиш учун "MANUAL_REVIEW" га созланг. Анти-спамдан фойдаланмаслик учун уни бўш қолдиринг. Акисметни рўйхатдан ўтказиш: https://akismet.com','Akismetは、スパムコメントの検出に使用されるアンチスパムサービスです。"MANUAL_REVIEW"に設定することで、手動レビューを有効化します。コメントのスパム対策にAkismetを使用することで、不要なコメントをブロックし、サイトのセキュリティを向上させることができます。 Akismetの詳細情報と登録は、https://akismet.com で提供されています。','Akismet 스팸 방지. 스팸 댓글 감지에 사용합니다. "MANUAL_REVIEW"를 설정하면 수동 검토를 활성화합니다. 비워두면 스팸 수동 검토를 사용하지 않습니다. Akismet 등록: https://akismet.com']),u+"_BLOGGER_NICK",["博主的昵称。","博主的昵稱。","站長的暱稱。","Admin nick name.","Админ исми.","管理者の名前。","관리자 닉네임."]),u+"_BLOGGER_EMAIL",["博主的邮箱地址,用于邮件通知、博主标识。","博主的郵箱地址,用於郵件通知、博主標識。","站長的郵箱帳號,用於郵件通知、站長認證。","Admin Email address. Used for Email notification and admin identification.","Админ электрон почта манзили. Электрон почта хабарномаси ва администратор идентификацияси учун фойдаланилади.","管理者のメールアドレス。メール通知と管理者の識別に使用されます。","관리자 이메일 주소. 이메일 알림 및 관리자 식별에 사용됩니다."]),u+"_COMMENT_BG_IMG",["评论框自定义背景图片 URL 地址。","評論框自定義背景圖片 URL 地址。","留言區塊自訂背景圖片 URL 網址。","URL for custom background image.","Махсус фон расми учун УРЛ.","コメントボックスのカスタム背景画像のURL。","댓글창 배경 이미지 URL 주소."]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,u+"_COMMENT_PAGE_SIZE",["评论列表分页大小,默认为 8。","評論列表分頁大小,預設為 8。","留言列表分頁大小,預設為 8。","Comment page size. Default: 8.","Изоҳ саҳифаси ўлчами. Стандарт: 8.","コメントリストのページサイズ。デフォルトは8。","한 페이지당 표시 댓글 수. 기본값: 8."]),u+"_COMMENT_PLACEHOLDER",["评论框提示信息,可用
    换行,默认为空","評論框提示信息,可用
    換行,預設為空","留言區塊提示資訊,可用
    換行,預設空白","Comment placeholder. Use
    to start a newline. Default: empty.","Изоҳ тўлдирувчиси. Янги қаторни бошлаш учун <бр> дан фойдаланинг. Стандарт: бўш.","コメントボックスのヒントメッセージ。
    で改行。デフォルトは空。","댓글 입력창에 표시될 기본 문구.
    태그로 줄바꿈 가능. 기본값: 비어 있음."]),u+"_CORS_ALLOW_ORIGIN",["CORS 安全域名,注意:如果您不了解什么是 CORS,此项请留空,错误设置会导致无法加载,默认为空,格式为 https://blog.example.com;如需添加多域名请使用,分隔","CORS 安全域名,注意:错误设置会导致无法加載,默認為空,格式为 https://blog.example.com;如需添加多域名請使用,分隔","CORS 安全網域,注意:設定錯誤將會導致載入失敗,預設空白,格式應為 https://blog.example.com;如需添加多域名請使用,分隔","CORS allow origin, note: incorrect settings can cause loading failure. Default: blank, format: https://blog.example.com; If you need to add multiple domain names, please use, separate","Версел СОРС келиб чиқишига рухсат беради, эътибор беринг: нотўғри созламалар юклашда хатоликка олиб келиши мумкин. Стандарт: бўш, формат: https://blog.example.com; Агар сиз бир нечта домен номларини қўшмоқчи бўлсангиз, илтимос, ажратишдан фойдаланинг.","CORS セキュアドメイン。注意:誤った設定は読み込みエラーを引き起こす可能性があります。デフォルトは空、形式は https://blog.example.com です。複数のドメインを追加する場合は、コンマで区切ってください。","댓글 서버 접근 허용 웹사이트 주소. 참고: 등록된 웹사이트만 댓글 시스템과 안전하게 통신합니다. 주소 오류 시 댓글창이 사라질 수 있습니다. 기본값: 비어 있음(보안 취약), 형식: https://blog.example.com; 여러 주소는 쉼표(,)로 구분."]),u+"_DEFAULT_GRAVATAR",['默认的头像显示。默认值(留空)为 "initials",可选:'.concat(g.join("、")),'預設的頭像顯示。預設值(留空)為 "initials",可選:'.concat(g.join("、")),'預設的大頭貼照圖示。預設值(留空)為 "initials",選項:'.concat(g.join("、")),'Avatar placeholder. Default (when empty): "initials". Choose from: '.concat(g.join(", ")),"Аватар тўлдирувчиси. Стандарт (агар бўш қолдирилса): «идентификатор». Қуйидагилардан танланг: ".concat(g.join(", ")),'デフォルトのプロフィール画像表示。デフォルト(空欄時)は "initials" で、選択肢は:'.concat(g.join("、")," です"),'프로필 기본 이미지. 기본값(비워둘 경우): "initials". 사용 가능 스타일: '.concat(g.join(", "))]),u+"_EMOTION_CDN",["表情 CDN,英文逗号分隔。默认为:https://owo.imaegoo.com/owo.json","表情 CDN,英文逗號分隔。預設為:https://owo.imaegoo.com/owo.json","表情 CDN 來源,使用英文逗號分隔。預設為:https://owo.imaegoo.com/owo.json","Emoji CDN. Separate by comma. Default: https://owo.imaegoo.com/owo.json","Emoji CDN. Вергул билан ажратинг. Default: https://owo.imaegoo.com/owo.json","顔文字CDN。コンマで区切ってください。デフォルト:https://owo.imaegoo.com/owo.json","이모티콘 데이터 웹 주소. 쉼표(,)로 구분. 기본값: https://owo.imaegoo.com/owo.json"]),u+"_FORBIDDEN_WORDS",["违禁词配置,包含违禁词的内容会直接标记为垃圾评论。英文逗号分隔。","違禁詞配置,包含違禁詞的內容會直接標記為垃圾評論。英文逗號分隔。","禁用詞語設定,包含禁用詞語的內容會直接標記為垃圾留言。使用英文逗號分隔。","Configure prohibited words. Comments containing prohibited words will be auto spammed. Separate by comma.","Тақиқланган сўзларни созланг. Тақиқланган сўзларни ўз ичига олган шарҳлар автоматик равишда спамга юборилади. Вергул билан ажратинг.","禁止ワード設定。禁止ワードを含むコンテンツは直ちにスパムコメントとしてマークされます。コンマで区切ってください。","금지어 설정. 금지어 포함 댓글은 스팸으로 숨김 처리 됩니다. 쉼표로 구분."]),u+"_BLOCKED_WORDS",["屏蔽词配置,包含屏蔽词的内容会直接评论失败。英文逗号分隔。","屏蔽词配置,包含屏蔽词的内容会直接评论失败。英文逗号分隔。","屏蔽词配置,包含屏蔽词的内容会直接评论失败。英文逗号分隔。","Configure blocked words. Comments containing blocked words will fail to send. Separate by comma.","Configure blocked words. Comments containing blocked words will fail to send. Separate by comma.","ブロックワード設定。ブロックワードを含むコンテンツは送信に失敗します。コンマで区切ってください。","차단어 설정. 차단어 포함 댓글은 등록에 실패합니다. 쉼표로 구분."]),u+"_GRAVATAR_CDN",["自定义头像 CDN 地址。如:cn.gravatar.com, weavatar.com, cravatar.cn, sdn.geekzu.org, gravatar.loli.net,默认:weavatar.com","自定義頭像 CDN 地址。如:cn.gravatar.com, weavatar.com, cravatar.cn, sdn.geekzu.org, gravatar.loli.net,預設:weavatar.com","自訂大頭貼照 CDN 來源。如:cn.gravatar.com, weavatar.com, cravatar.cn, sdn.geekzu.org, gravatar.loli.net,預設:weavatar.com","Custom avator CDN. (Examples: gravatar.com) Default: weavatar.com.","Custom avator CDN. (Мисоллар: gravatar.com) Default: weavatar.com.","カスタムプロフィール画像CDNアドレス。例:cn.gravatar.com、weavatar.com、cravatar.cn、sdn.geekzu.org、gravatar.loli.net、デフォルト:weavatar.com","프로필 이미지(아바타) Gravatar 서버 주소. 더 빠르거나 안정적인 서버를 선택할 수 있습니다. (예: gravatar.com) 기본값: weavatar.com."]),u+"_HIDE_ADMIN_CRYPT",["隐藏管理面板入口。可设置一个“暗号”,只有在“昵称”一栏输入相同的“暗号”时,管理面板入口才会显示,留空则不隐藏管理入口","隱藏管理面板入口。可設定一個“暗號”,只有在“暱稱”一欄輸入相同的“暗號”時,管理面板入口才會顯示,留空則不隱藏管理入口","隱藏管理控制台入口。可設定一個“暗號”,只有在「暱稱」一欄輸入相同的「暗號」時,管理控制台入口才會顯示,留白則不隱藏管理入口","Set a cipher to hide the management panel entrance, only when the same cipher is entered in the nickname field the management panel entry will be displayed. Leave it blank to not hide the management entrance.","Бошқарув панелига киришни яшириш учун шифрни ўрнатинг, фақат тахаллус майдонига худди шу шифр киритилганда бошқарув панелидаги ёзув кўрсатилади. Бошқарув киришини яширмаслик учун уни бўш қолдиринг.",'管理パネルのログイン画面を非表示にする。 "パスワード" を設定でき、 "名前" フィールドに同じ "パスワード" を入力した場合のみ、管理パネルのログイン画面が表示されます。空白の場合、管理パネルのログイン画面は非表示にされません。',"환경설정 버튼을 숨깁니다. 암호를 설정하여, 닉네임 입력란에 동일한 암호를 입력해야만 환경설정 버튼이 표시됩니다. 비워두면 버튼을 숨기지 않습니다."]),u+"_HIGHLIGHT",["启用代码高亮功能。如果您的主题和代码高亮有冲突,请设为 false。默认:true","啟用代碼高亮功能。如果您的主題和代碼高亮有衝突,請設為 false。預設:true","啟用程式碼醒目顯示功能。如果您的主題和此功能發生衝突,請設定為 false。預設:true","Enable code highlighting. If your theme conflicts with code highlighting, please set it to false. Default: true.","Кодни ажратиб кўрсатишни ёқинг. Агар мавзуингиз кодни ажратиб кўрсатишга зид бўлса, уни «фалсе» га ўрнатинг. Стандарт: рост.","コードハイライト機能を有効にします。テーマとコードハイライトに競合がある場合、falseに設定してください。デフォルト:true","코드 하이라이팅 기능을 활성화합니다. 테마와 코드 하이라이팅이 충돌하면 false로 설정하세요. 기본값: true."]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,u+"_HIGHLIGHT_THEME",["代码高亮主题,可选:".concat(f.join("、"),",访问 https://prismjs.com 可预览主题效果。如果您的主题和代码高亮有冲突,请设为 none。默认:none"),"代碼高亮主題,可選:".concat(f.join("、"),",訪問 https://prismjs.com 可預覽主題效果。如果您的主題和代碼高亮有衝突,請設為 none。預設:none"),"程式碼醒目顯示主題,選項:".concat(f.join("、"),",瀏覽 https://prismjs.com 可預覽主題效果。如果您的主題和此功能發生衝突,請設定為 none。預設:none"),"Code highlighting theme. Select from: ".concat(f.join(", "),". Visit https://prismjs.com for preview. If your theme conflicts with code highlighting, please set it to none. Default: none."),"Кодни таъкидлаш мавзуси. Қуйидагилардан танланг: ".concat(f.join(", "),". Олдиндан кўриш учун https://prismjs.com сайтига ташриф буюринг. Агар мавзуингиз кодни ажратиб кўрсатишга зид бўлса, уни «Ҳеч» га ўрнатинг. Стандарт: йўқ."),"コードハイライトのテーマ。選択肢:".concat(f.join("、"),"、テーマの効果をプレビューするには https://prismjs.com を訪問してください。テーマとコードハイライトに競合がある場合、noneに設定してください。デフォルト:none"),"코드 하이라이팅 테마. 사용 가능 테마: ".concat(f.join(", "),". https://prismjs.com 에서 미리보기를 확인하세요. 테마와 코드 하이라이팅이 충돌하면 none으로 설정하세요. 기본값: none.")]),u+"_HIGHLIGHT_PLUGIN",["代码高亮插件,可选:".concat(p.join("、"),",分别表示:展示代码语言、展示代码拷贝按钮。可以同时设置多个选项,如果想要不添加任何代码高亮插件,请设为 none。默认:none。"),"代碼高亮插件,可選:".concat(p.join("、"),",分別表示:展示代碼語言、展示代碼拷貝按鈕。可以同時設置多個選項,如果想要不添加任何代碼高亮插件,請設為 none。預設:none。"),"代碼高亮外掛程式,可選:".concat(p.join("、"),",分別表示:展示代碼語言、展示代碼拷貝按鈕。 可以同時設置多個選項,如果想要不添加任何代碼高亮外掛程式,請設定為 none。預設:none。"),"Code highlight plug-in, optional: ".concat(p.join(", "),", respectively: show code language, show code copy button. Multiple options can be set at the same time, if you want to add no code highlighting plug-ins, please set it to none. Default: none. "),"Плагин подсветки кода, опционально: ".concat(p.join(","),", соответственно: показывать язык кода, показывать кнопку копирования кода. Вы можете установить несколько опций одновременно, если вы хотите не добавлять плагин подсветки кода, установите значение none. по умолчанию: none."),"コード・ハイライト・プラグイン。オプション: ".concat(p.join(","),", それぞれ: コード言語の表示、コード・コピー・ボタンの表示。複数のオプションを同時に設定できますが、コード・ハイライト・プラグインを追加したくない場合は、noneに設定してください。"),"코드 하이라이트 추가 기능. 선택 가능: ".concat(p.join(", "),". (코드 언어 표시, 복사 버튼) 여러 기능을 동시에 설정할 수 있으며, 추가하지 않으려면 none으로 설정하세요. 기본값: none.")]),u+"_IMAGE_CDN",["插入图片所使用的图床,目前支持:".concat(h.join("、")),"插入圖片所使用的圖床,目前支持:".concat(h.join("、")),"插入圖片所使用的圖床,目前支援:".concat(h.join("、")),"The image bed for image uploading. Select from: ".concat(h.join(", ")),"Расм юклаш учун расм тўшаги. Қуйидагилардан танланг: ".concat(h.join(", ")),"画像のアップロードに使用する画像ホスティングサービス。次のうちから選択してください:".concat(h.join("、")),"댓글 이미지 업로드 기능에 사용될 호스팅 서비스. 사용 가능 목록: ".concat(h.join(", "))]),u+"_IMAGE_CDN_URL",["图床的 URL,仅当 IMAGE_CDN 为 ".concat(m.join(" / ")," 时需要填写"),"圖床的 URL,僅當 IMAGE_CDN 為 ".concat(m.join(" / ")," 時需要填寫"),"圖床的 URL,僅當 IMAGE_CDN 為 ".concat(m.join(" / ")," 時需要填寫"),"The URL for the image bed. Required if your IMAGE_CDN is one of these: ".concat(m.join(", ")),"IMAGE_CDN томонидан белгиланган расм тўшаги URL. Агар сизнинг IMAGE_CDN шулардан бири бўлса: ".concat(m.join(", ")),"IMAGE_CDNで設定した画像ホスティングサービスのURL。IMAGE_CDNが以下のいずれかの場合は入力が必要です:".concat(m.join("、")),"이미지 저장소 URL. IMAGE_CDN 설정이 다음 중 하나인 경우 필요합니다: ${customImageBedServices.join(",")}"]),u+"_IMAGE_CDN_TOKEN",["图床 token。qcloud 图床无需设置","图床 token。qcloud 图床无需设置","圖床 token。qcloud 圖床不需設定","The image bed token. Unnessessary for qcloud","Тасвир токен белгиси. Қслоуд учун кераксиз","画像ホスティングトークン。qcloud画像ホスティングを利用する場合は設定の必要はありません","이미지 호스팅 토큰. qcloud은 설정 불필요."]),u+"_LIGHTBOX",["使用简易图片点击放大效果。默认:false","使用簡易圖片點擊放大效果。預設:false","使用簡易圖片點擊放大效果。預設:false","Use simple Lightbox effect. Default: false","Используйте простые эффекты лайтбокса. По умолчанию: false","シンプルな画像拡大機能を使用します。デフォルト:false","라이트박스 효과, 댓글 이미지 클릭 시 확대 효과 사용. 기본값: false"]),u+"_LIMIT_PER_MINUTE",["单个 IP 发言频率限制(条/10分钟),0 为无限制,默认:10","單個 IP 發言頻率限制(條/10分鐘),0 為無限制,預設:10","單個 IP 留言頻率限制(則/10分鐘),0 為無限,預設:10","How many comments can be posted by each IP every 10 minutes, 0 is unlimited, default: 10.","Ҳар бир ИП ҳар 10 дақиқада қанча шарҳ қолдириши мумкин, 0 чексиз, стандарт: 10.","同一IPにおける10分ごとの投稿回数制限。0は無制限、デフォルト:10","IP별 댓글 작성 빈도 제한 (10분당 건수), 0은 무제한. 기본값: 10."]),u+"_LIMIT_PER_MINUTE_ALL",["全站发言频率限制(条/10分钟),0 为无限制,默认:10","全站發言頻率限制(條/10分鐘),0 為無限制,預設:10","全站留言頻率限制(則/10分鐘),0 為無限,預設:10","How many comments can be posted by all IPs every 10 minutes, 0 is unlimited, default: 10.","Барча ИП-лар ҳар 10 дақиқада қанча шарҳ қўйиши мумкин, 0 чексиз, стандарт: 10.","全IPにおける10分ごとの投稿回数制限。0は無制限、デフォルト:10","10분당 사이트 전체에 작성 가능한 총 댓글 수 제한. 0은 무제한. 기본값: 10."]),u+"_LIMIT_LENGTH",["评论长度限制,0 为无限制,默认:500","評論長度限制,0 為無限制,預設:500","留言長度限制,0 為無限,預設:500","Comment length limitation, 0 is unlimited, default: 500.","Шарҳ узунлиги чеклови, 0 чексиз, стандарт: 500.","コメント長さの制限。0は無制限、デフォルト:500","댓글 길이 제한. 0은 무제한. 기본값: 500."]),u+"_MAIL_SUBJECT",["自定义通知邮件主题,留空则使用默认主题。","自定義通知郵件主題,留空則使用預設主題。","自訂通知郵件主題,留白則使用預設主題。","Custom Email notification subject. Leave it blank to use the default subject.","Махсус электрон почта хабарномаси мавзуси. Стандарт мавзуни ишлатиш учун уни бўш қолдиринг.","カスタム通知メールの件名。空白の場合はデフォルトの件名を使用します。","댓글 알림 이메일 제목 설정. 비워두면 기본 제목을 사용합니다."]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,u+"_MAIL_SUBJECT_ADMIN",["自定义博主通知邮件主题,留空则使用默认主题。","自定義博主通知郵件主題,留空則使用預設主題。","自訂站長通知郵件主題,留白則使用預設主題。","Custom admin Email notification subject. Leave it blank to use the default subject.","Махсус администратор электрон почта хабарномаси мавзуси. Стандарт мавзуни ишлатиш учун уни бўш қолдиринг.","管理者へのカスタム通知メールの件名。空白の場合はデフォルトの件名を使用します。","관리자에게 발송되는 댓글 알림 이메일 제목 설정. 비워두면 기본 제목을 사용합니다."]),u+"_MAIL_TEMPLATE",["自定义通知邮件模板,留空则使用默认模板。可包含的字段:${SITE_URL}, ${SITE_NAME}, ${PARENT_NICK}, ${PARENT_COMMENT}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IMG}, ${PARENT_IMG}","自定義通知郵件模板,留空則使用預設模板。可包含的字段:${SITE_URL}, ${SITE_NAME}, ${PARENT_NICK}, ${PARENT_COMMENT}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IMG}, ${PARENT_IMG}","自訂通知郵件模板,留白則使用預設模板。可包含的欄位:${SITE_URL}, ${SITE_NAME}, ${PARENT_NICK}, ${PARENT_COMMENT}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IMG}, ${PARENT_IMG}","Custom Email notification template. Leave it blank to use the default template. Fields that can be included: ${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IMG}, ${PARENT_IMG}","Махсус электрон почта хабарномаси шаблони. Стандарт шаблонни ишлатиш учун уни бўш қолдиринг. Қўшилиши мумкин бўлган майдонлар: ${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IMG}, ${PARENT_IMG}","カスタム通知メールテンプレート。空白の場合はデフォルトテンプレートを使用します。使用可能なフィールド:${SITE_URL}、${SITE_NAME}、${PARENT_NICK}、${PARENT_COMMENT}、${NICK}、${COMMENT}、${POST_URL}、${IMG}、${PARENT_IMG}","댓글 알림 이메일 템플릿 설정. 비워두면 기본 템플릿 사용. 다음 변수를 사용하면 해당 값으로 자동 치환됩니다: ${SITE_URL}, ${SITE_NAME}, ${PARENT_NICK}, ${PARENT_COMMENT}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IMG}, ${PARENT_IMG}"]),u+"_MAIL_TEMPLATE_ADMIN",["自定义博主通知邮件模板,留空则使用默认模板。可包含的字段:${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IP}, ${MAIL}, ${IMG}","自定義博主通知郵件模板,留空則使用預設模板。可包含的字段:${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IP}, ${MAIL}, ${IMG}","自訂站長通知郵件模板,留白則使用預設模板。可包含的欄位:${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IP}, ${MAIL}, ${IMG}","Custom admin Email notification template. Leave it blank to use the default template. Fields that can be included: ${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IP}, ${MAIL}, ${IMG}","Махсус администратор электрон почта хабарномаси шаблони. Стандарт шаблонни ишлатиш учун уни бўш қолдиринг. Қўшилиши мумкин бўлган майдонлар: ${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IMG}, ${PARENT_IMG}","管理者へのカスタム通知メールテンプレート。空白の場合はデフォルトテンプレートを使用します。使用可能なフィールド:${SITE_URL}、${SITE_NAME}、${NICK}、${COMMENT}、${POST_URL}、${IP}、${MAIL}、${IMG}","관리자 알림 이메일 템플릿 설정. 비워두면 기본 템플릿 사용. 다음 변수를 사용하면 해당 값으로 자동 치환됩니다: ${SITE_URL}, ${SITE_NAME}, ${NICK}, ${COMMENT}, ${POST_URL}, ${IP}, ${MAIL}, ${IMG}"]),u+"_MASTER_TAG",["博主标识自定义文字,默认为 “博主”。","博主標識自定義文字,預設為 “博主”。","站長認證自訂文字,預設為「博主」。","Custom admin identifier.","Махсус администратор идентификатори.",'管理者を表すカスタムテキスト。デフォルト:"ブロガー"',"관리자 태그 설정. (닉네임 옆에 표시됨. 예: 관리자)"]),u+"_NOTIFY_SPAM",["垃圾评论是否发送通知,默认:true","垃圾評論是否發送通知,默認:true","垃圾留言是否發送通知,預設:true","Notifications for spam comments. Default: true.","Спам шарҳлар учун билдиришномалар. Стандарт: рост.","スパムコメントの通知を送信するかどうか。デフォルト:true","스팸 댓글 알림 발송 여부. 기본값: true."]),u+"_TURNSTILE_SITE_KEY",["Turnstile 验证码的站点密钥。申请地址: https://dash.cloudflare.com/?to=/:account/turnstile","Turnstile 验证码的站点密钥。申请地址: https://dash.cloudflare.com/?to=/:account/turnstile","Turnstile 验证码的站点密钥。申请地址: https://dash.cloudflare.com/?to=/:account/turnstile","Turnstile CAPTCHA Site Key. Get from: https://dash.cloudflare.com/?to=/:account/turnstile","Turnstile CAPTCHA Site Key. Get from: https://dash.cloudflare.com/?to=/:account/turnstile","Turnstile CAPTCHAのサイトキー。参照: https://dash.cloudflare.com/?to=/:account/turnstile","Turnstile CAPTCHA(스팸봇 방지) 사이트 키. 발급처: https://dash.cloudflare.com/?to=/:account/turnstile"]),u+"_TURNSTILE_SECRET_KEY",["Turnstile 验证码的密钥","Turnstile 验证码的密钥","Turnstile 验证码的密钥","Turnstile CAPTCHA Secret Key","Turnstile CAPTCHA Secret Key","Turnstile CAPTCHAのシークレットキー","Turnstile CAPTCHA Secret Key"]),u+"_QCLOUD_SECRET_ID",["腾讯云 secret id,用于垃圾评论检测。同时设置腾讯云和 Akismet 时,只有腾讯云会生效。注册:https://twikoo.js.org/cms.html","騰訊雲 secret id,用於垃圾評論檢測。同時設定騰訊雲和 Akismet 時,只有騰訊雲會生效。註冊:https://twikoo.js.org/cms.html","騰訊雲 Secret ID,用於垃圾留言檢測。同時設定騰訊雲和 Akismet 時,只有騰訊雲會被啟用。註冊:https://twikoo.js.org/cms.html","Tencent Cloud secret id for spam detection. When Tencent Cloud and Akismet are set at the same time, only Tencent Cloud will take effect. Register: https://twikoo.js.org/cms.html","Спамни аниқлаш учун Тенсент Слоуд махфий идентификатори. Тенсент Слоуд ва Акисмет бир вақтнинг ўзида ўрнатилганда, фақат Тенсент Слоуд кучга киради. Рўйхатдан ўтиш: https://twikoo.js.org/cms.html","Tencent CloudのシークレットID。スパムコメントの検出に使用されます。同時にTencent CloudとAkismetを設定した場合、Tencent Cloudのみが有効になります。登録:https://twikoo.js.org/cms.html","Tencent Cloud secret id (스팸 감지용). Tencent Cloud와 Akismet 동시 설정 시 Tencent Cloud만 적용. 등록: https://twikoo.js.org/cms.html"]),u+"_QCLOUD_CMS_BIZTYPE",["腾讯云内容安全 Biztype 名称,用于垃圾评论策略。可以自定义垃圾拦截规则","騰訊雲內容安全 Biztype 名稱,用於垃圾評論策略。可以自定義垃圾攔截規則","騰訊雲內容安全 Biztype 名稱,用於垃圾評論策略。可以自定義垃圾攔截規則","Tencent Cloud Content Security Biztype name for spam comment policy. Spam blocking rules can be customized","Tencent Cloud Content Security Biztype име, използвано за спам политика. Може да персонализира правилата за блокиране на спам","Tencent Cloud Content Security Biztype name スパムコメントポリシー。スパムブロックルールはカスタマイズ可能","Tencent Cloud Content Security Biztype 이름 (스팸 댓글 정책용). 스팸 차단 규칙 설정 가능."]),u+"_QCLOUD_SECRET_KEY",["腾讯云 secret key","騰訊雲 secret key","騰訊雲 Secret Key","Tencent Cloud secret key.","Тенсент Клауд махфий калити.","Tencent Cloudのシークレットキー","Tencent Cloud Secret Key."]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,u+"_PUSHOO_CHANNEL",["即时消息推送平台名称,支持:".concat(l.join("、")," 等"),"即時消息推送平台名称,支持:".concat(l.join("、")," 等"),"即時訊息推送平台名稱,支援:".concat(l.join("、")," 等"),"IM notification push channel. Support: ".concat(l.join(", ")),"ИМ билдиришномаси суриш канали. Қўллаб-қувватлаш: ".concat(l.join(", ")),"即時メッセージプッシュプラットフォームの名前。".concat(l.join("、")," などに対応しています。"),"실시간 알림을 받을 서비스 설정. 지원: ".concat(l.join(", "))]),u+"_PUSHOO_TOKEN",["即时消息推送 token。请参考 https://pushoo.js.org 里的详细说明配置","即時消息推送 token。请参考 https://pushoo.js.org 里的详细说明配置","即時訊息推送 Token。請参考 https://pushoo.js.org 裡的詳細說明進行設定","IM notification push token. See https://pushoo.js.org for details","ИМ билдиришномаси пуш токени. Тафсилотлар учун https://pushoo.js.org га қаранг","即時メッセージプッシュトークン。詳細な設定については、https://pushoo.js.org の説明をご覧ください","선택한 실시간 알림 서비스 인증 토큰. 설정 방법은 https://pushoo.js.org 를 참조."]),u+"_DISPLAYED_FIELDS",["界面上展示的输入框,默认:nick,mail,link","界面上顯示的輸入框,預設:nick,mail,link","界面上顯示的輸入框,預設:nick,mail,link","Input boxes displayed on the interface. Default: nick,mail,link","Поля ввода, отображаемые на интерфейсе, Стандарт: nick,mail,link","画面に表示される入力欄。デフォルト:nick,mail,link","화면에 표시할 정보 입력란. 기본값: nick,mail,link"]),u+"_REQUIRED_FIELDS",["评论必填信息,设为 nick,mail,link 代表全必填,设为 none 代表全选填,默认:nick,mail","評論必填信息,設為 nick,mail,link 代表全必填,設為 none 代表全選填,預設:nick,mail","留言必填資訊,設為 nick,mail,link 代表全必填,設為 none 代表全選填,預設:nick,mail",'Required fields for comments. Set to "nick,mail,link" means all fields are required. Set to "none" means all fields are optional. Default: nick,mail.',"Шарҳлар учун зарур майдонлар. «Ниск,маил,линк» га ўрнатилган бўлса, барча майдонлар талаб қилинади. «Йўқ» га ўрнатилиши барча майдонлар ихтиёрий эканлигини англатади. Стандарт: ник, почта.","コメント必須項目。すべてを必須にする場合は nick,mail,link に設定、すべてを任意にする場合はnoneに設定してください。デフォルト:nick,mail",'댓글 작성 시 필수 입력 정보. "nick,mail,link"는 모두 필수, "none"은 모두 선택 압력. 기본값: nick,mail.']),u+"_SC_MAIL_NOTIFY",["是否同时通过 IM 和邮件 2 种方式通知博主,默认只通过 IM 通知博主,默认:false","是否同時通過 IM 和郵件 2 種方式通知博主,預設只通過 IM 通知博主,預設:false","是否同時透過 IM 和郵件 2 種方式通知博主,預設只透過 IM 通知博主,預設:false","Whether to notify admin via IM and email at the same time, the default is to notify admin only via IM. Default: false.","Администраторни бир вақтнинг ўзида ИМ ва электрон почта орқали хабардор қилиш керакми, сукут бўйича администраторни фақат ИМ орқали хабардор қилиш керак. Стандарт: нотўғри.","管理者にIMとメールで同時に通知するかどうか。デフォルトはIMのみで通知、デフォルト:false","실시간 알림과 이메일로 동시에 관리자에게 알릴지 여부. 기본값은 실시간 알림만 사용. 기본값: false."]),u+"_SENDER_EMAIL",["邮件通知邮箱地址。对于大多数邮箱服务商,SENDER_EMAIL 必须和 SMTP_USER 保持一致,否则无法发送邮件。","郵件通知郵箱地址。對於大多數郵箱服務商,SENDER_EMAIL 必須和 SMTP_USER 保持一致,否則無法發送郵件。","郵件通知郵箱帳號。對於大多數電郵服務提供商,SENDER_EMAIL 必須和 SMTP_USER 保持一致,否則無法傳送郵件。","Email address for Email notification. For most email service providers, SENDER_EMAIL must be consistent with SMTP_USER, otherwise emails cannot be sent.","Электрон почта хабарномаси учун электрон почта манзили. Аксарият электрон почта хизмати провайдерлари учун SENDER_EMAIL билан мос келиши керак, акс ҳолда электрон почта хабарларини юбориб бўлмайди.","メール通知のメールアドレス。 ほとんどのメールボックス・プロバイダでは、SENDER_EMAILはSMTP_USERと同じでなければなりません。","알림 이메일 발신 주소. 대부분의 이메일 서비스 제공자의 경우 SENDER_EMAIL과 SMTP_USER가 일치해야 메일 발송이 가능합니다."]),u+"_SENDER_NAME",["邮件通知标题。","郵件通知標題。","郵件通知標題。","The title for Email notification.","Электрон почта хабарномаси сарлавҳаси.","メール通知のタイトル","알림 이메일 발신자 이름."]),u+"_SHOW_EMOTION",["启用插入表情功能,默认为:true","啟用插入表情功能,預設為:true","啟用插入表情功能,預設為:true","Enable emojis. Default: true.","Кулгичларни ёқинг. Стандарт: рост.","顔文字の挿入を有効にするかどうか。デフォルト:true","이모티콘 삽입 기능 활성화. 기본값: true."]),u+"_SHOW_IMAGE",["启用插入图片功能,默认为:true","啟用插入圖片功能,預設為:true","啟用插入圖片功能,預設為:true","Enable picture uploading. Default: true.","Расм юклашни ёқинг. Стандарт: рост.","画像のアップロードを有効にするかどうか。デフォルト:true","이미지 업로드 기능 활성화. 기본값: true."]),u+"_SHOW_UA",["是否显示用户系统和浏览器,默认为:true","是否顯示使用者系統和瀏覽器,預設為:true","是否顯示使用者作業系統和瀏覽器,預設為:true","Show users' OS and browser. Default: true.","Фойдаланувчиларнинг ОС ва браузерини кўрсатиш. Стандарт: рост.","ユーザーのOSとブラウザーの情報を表示するかどうか。デフォルト:true","댓글 작성자의 운영체제 및 브라우저 표시 여부. 기본값: true."]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,u+"_SHOW_REGION",["是否显示用户 IP 属地到省,可能不准确,不支持 IPv6,默认为:false","是否顯示使用者 IP 屬地到省,預設為:false","是否顯示使用者 IP 所屬地(精確到省),預設為:false","Show users' IP region (province). Default: false.","Фойдаланувчиларнинг ИП ҳудудини (вилоят) кўрсатиш. Стандарт: нотўғри.","ユーザーIPの所在地(省)を表示するかどうか。正確でない場合があります。IPv6はサポートされていません。デフォルト:false","사용자 IP 지역(도/시 단위) 표시 여부 (부정확할 수 있음, IPv6 미지원). 기본값: false."]),u+"_SITE_NAME",["网站名称","網站名稱","網站名稱","Website name.","Вебсайт номи.","ウェブサイト名","웹사이트 이름."]),u+"_SITE_URL",["网站地址","網站地址","網站網址","Website URL.","Вебсайт URL.","ウェブサイトのアドレス","웹사이트 주소."]),u+"_SMTP_HOST",["自定义 SMTP 服务器地址。如您已配置 SMTP_SERVICE,此项请留空。","自定義 SMTP 伺服器地址。如您已配置 SMTP_SERVICE,此項請留空。","自訂 SMTP 伺服器位址。如您已設定 SMTP_SERVICE,此項請留白。","Custom SMTP server address. If you have configured SMTP_SERVICE, please leave it empty.","Махсус СМТП сервер манзили. Агар сиз СМТП_СEРВИСE созлаган бўлсангиз, уни бўш қолдиринг.","自定义 SMTP 服务器地址。如您已配置 SMTP_SERVICE,此项请留空。","カスタムSMTPサーバのアドレス。SMTP_SERVICEを設定している場合は空白のままにします。","SMTP 서버 주소. SMTP_SERVICE를 설정한 경우 비워두세요."]),u+"_SMTP_PASS",["邮件通知邮箱密码,QQ、163邮箱请填写授权码。","郵件通知郵箱密碼,QQ、163郵箱請填寫授權碼。","郵件通知郵箱密碼,QQ、163 郵箱請填寫授權碼。","Email notification mailbox password. Enter authorization code for QQ/163 mail.","Электрон почта хабарномаси почта қутиси пароли. ҚҚ/163 почтаси учун авторизация кодини киритинг.","メール通知のメールボックスパスワード。QQ、163メールは認証コードを入力してください","알림 이메일 계정 SMTP용 비밀번호. (QQ, 163 등 대부분 별도의 앱 비밀번호/인증 코드 사용)"]),u+"_SMTP_PORT",["自定义 SMTP 端口。如您已配置 SMTP_SERVICE,此项请留空。","自定義 SMTP 端口。如您已配置 SMTP_SERVICE,此項請留空。","自訂 SMTP 連接埠。如您已設定 SMTP_SERVICE,此項請留白。","Custom SMTP port. If you have configured SMTP_SERVICE, please leave it empty.","Махсус СМТП порти. Агар сиз СМТП_СEРВИС созлаган бўлсангиз, уни бўш қолдиринг.","カスタムSMTPポート。SMTP_SERVICEを設定している場合は、空白のままにします。","SMTP 포트. SMTP_SERVICE를 설정한 경우 비워두세요."]),u+"_SMTP_SECURE",["自定义 SMTP 是否使用TLS,请填写 true 或 false。如您已配置 SMTP_SERVICE,此项请留空。","自定義 SMTP 是否使用TLS,請填寫 true 或 false。如您已配置 SMTP_SERVICE,此項請留空。","自訂 SMTP 是否使用 TLS,請填寫 true 或 false。如您已設定 SMTP_SERVICE,此項請留白。",'Custom TLS for SMTP. Enter "true" or "false". If you have configured SMTP_SERVICE, please leave it empty.',"СМТП учун махсус ТЛС. «Тўғри» ёки «нотўғри» ни киритинг. Агар сиз СМТП_СEРВИС созлаган бўлсангиз, уни бўш қолдиринг.","SMTPがTLSを使用するかどうかをカスタマイズします。trueまたはfalseを記入してください。SMTP_SERVICEを設定している場合は、この項目を空白にしてください。","SMTP TLS 사용 여부 (true 또는 false 입력). SMTP_SERVICE를 설정한 경우 비워두세요."]),u+"_SMTP_SERVICE",["邮件通知邮箱服务商。支持:".concat(d.join("、")),"郵件通知郵箱服務商。支持:".concat(d.join("、")),"郵件通知郵箱服務提供商。支援:".concat(d.join("、")),"Email service provider for Email notification. Support: ".concat(d.join(", ")),"Электрон почта хабарномаси учун электрон почта хизмати провайдери. Қўллаб-қувватлаш: ".concat(d.join(", ")),"メール通知メールボックスサービスプロバイダ。サポート: ".concat(d.join(","),"."),"알림 발송 이메일 서비스 선택. 지원 목록: ".concat(d.join(", "))]),u+"_SMTP_USER",["邮件通知邮箱用户名。","郵件通知郵箱用户名。","郵件通知郵箱使用者名稱。","Email notification mailbox username.","Электрон почта хабарномаси почта қутиси фойдаланувчи номи.","メール通知のメールボックスユーザー名。","선택한 이메일 알림 서비스 아이디"]),"ADMIN_CONFIG_RESET",["重置","重置","還原","Reset","Ресет","リセット","초기화"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,"ADMIN_CONFIG_SAVE",["保存","保存","儲存","Save","Сақлаш","保存","저장"]),"ADMIN_CREDENTIALS",["私钥文件","私鑰文件","私鑰檔案","Private key file","Shaxsiy kalit fayli","秘密鍵ファイル","개인 키 파일"]),"ADMIN_CREDENTIALS_FAQ",["如何获得私钥","如何獲得私鑰","如何獲取私鑰","How to get the private key","Shaxsiy kalitni qanday olish mumkin","秘密鍵を取得する方法","개인 키 발급 방법"]),"ADMIN_CREDENTIALS_PLACEHOLDER",["请粘贴私钥文件内容","請貼上私鑰文件內容","請貼上私鑰檔案內容","Please paste the contents of the private key file","Iltimos, shaxsiy kalit faylining mazmunini joylashtiring","秘密鍵ファイルの内容を貼り付けてください","개인 키 파일 내용을 붙여넣으세요"]),"ADMIN_FORGOT",["忘记密码","忘記密碼","忘記密碼","Forget your password","Парол унутилган","パスワードを忘れた","비밀번호 찾기"]),"ADMIN_EXPORT",["导出","匯出","匯出","Export","Экспорт","エクスポート","내보내기"]),"ADMIN_EXPORT_WARN",["将全部数据导出为 JSON 文件。如果遇到评论较多、导出失败或缺失数据,请连接数据库手动导出","將全部數據匯出為 JSON 檔。如果遇到評論較多、匯出失敗或缺失數據,請連接資料庫手動匯出","將全部數據匯出為 JSON 檔。如果遇到評論較多、匯出失敗或缺失數據,請連接資料庫手動匯出","Export all data as a JSON file. If you encounter export failures or missing data, connect to the database to export manually","Барча маълумотларни ЖСОН файли сифатида экспорт қилинг. Экспорт хатоси ёки этишмаётган маълумотларга дуч келсангиз, қўлда экспорт қилиш учун маълумотлар базасига уланинг","すべてのデータをJSONファイルとしてエクスポートします。コメントが多く、エクスポートに失敗したりデータが欠落している場合は、データベースに手動で接続してエクスポートしてください","모든 데이터를 JSON 파일로 내보냅니다. 댓글이 많아 내보내기 실패 또는 데이터 누락 발생 시, 데이터베이스에 직접 연결하여 수동으로 내보내세요."]),"ADMIN_EXPORT_COMMENT",["导出评论","匯出評論","匯出評論","Export comment","Изохни экспорт килиш","コメントをエクスポート","댓글 내보내기"]),"ADMIN_EXPORT_COUNTER",["导出访问量","匯出訪問量","匯出訪問量","Export counter","Экспорт сони","ページビューをエクスポート","통계 내보내기"]),c,["导入","匯入","匯入","Import","Импорт","インポート","가져오기"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,c+"_FILE_REQUIRED",["未选择文件","未選擇文件","未選擇檔案","No file selected","Файлни танланмади","ファイルが選択されていません","파일이 선택되지 않았습니다"]),c+"_IMPORTED",["完成导入 ","完成匯入 ","完成匯入 ","Imported ","Импорт қилинди ","インポート完了 ","가져오기 완료 "]),c+"_IMPORTING",["开始导入 ","開始匯入 ","開始匯入 ","Importing ","Импорт қилинмоқда ","インポートを開始 ","가져오는 중 "]),c+"_LOG",["日志","日誌","日誌","Log","Лог","システムログ","로그"]),c+"_SELECT",["请选择","請選擇","請選擇","Select","Танланг","選択してください","선택하세요"]),c+"_SELECT_FILE",["选择文件","選擇文件","選擇檔案","Select file","Файлни танланг","ファイルを選択","파일 선택"]),c+"_SELECT_SOURCE",["选择源系统","選擇源系統","選擇來源系統","Select source","Манба танланг","ソースを選択","가져올 댓글 데이터 선택"]),c+"_SOURCE_REQUIRED",["未选择源系统","未選擇源系統","未選擇來源系統","No source selected.","Ҳеч қандай манба танланмаган.","ソースが選択されていません","가져올 댓글 데이터가 선택되지 않았습니다."]),c+"_START",["开始导入","開始匯入","開始匯入","Start import","Импортни бошлаш","インポートを開始","가져오기 시작"]),c+"_STARTING",["开始导入","開始匯入","開始匯入","Importing","Импорт қилинмоқда","インポート中です","가져오는 중"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,c+"_TIP_ARTALK",["请上传 JSON 格式的 Artalk 导出文件,文件名通常为 comments.data.json","請上傳 JSON 格式的 Artalk 導出文件,文件名通常為 comments.data.json","請上傳 JSON 格式的 Artalk 匯出檔案,檔名通常為 comments.data.json","Please upload the Artalk export file in JSON format.The file name is usually comments.data.json","Арталк экспорт файлини ЖСОН форматида юкланг. Файл номи одатда comments.data.json бўлади.","JSON形式のArtalkエクスポートファイルをアップロードしてください。ファイル名は通常、comments.data.jsonです。","JSON 형식의 Artalk 내보내기 파일을 업로드하세요. 파일 이름은 보통 comments.data.json 입니다."]),c+"_TIP_DISQUS",["请上传 XML 格式的 Disqus 导出文件,文件名通常为 [网站名称]-[导出时间]-all.xml","請上傳 XML 格式的 Disqus 導出文件,文件名通常為 [網站名稱]-[導出時間]-all.xml","請上傳 XML 格式的 Disqus 匯出檔案,檔名通常為 [網站名稱]-[匯出時間]-all.xml","Please upload the Disqus export file in XML format. The file name is usually [website name]-[export time]-all.xml","Disqus экспорт файлини ХМЛ форматида юкланг. Файл номи одатда [веб-сайт номи]-[экспорт vaqti]-all.xml","DisqusエクスポートファイルをXML形式でアップロードしてください。ファイル名は通常、[サイト名]-[エクスポート時間]-all.xmlです。","XML 형식의 Disqus 내보내기 파일을 업로드하세요. 파일 이름은 보통 [웹사이트이름]-[내보내기시간]-all.xml 입니다."]),c+"_TIP_VALINE",["请上传 JSON 格式的 Valine 导出文件,文件名通常为 Comment.json","請上傳 JSON 格式的 Valine 導出文件,文件名通常為 Comment.json","請上傳 JSON 格式的 Valine 匯出檔案,檔名通常為 Comment.json","Please upload the Valine export file in JSON format. The file name is usually Comment.json","Илтимос, Валине экспорт файлини ЖСОН форматида юкланг. Файл номи одатда Comment.json","JSON形式のValineエクスポートファイルをアップロードしてください。ファイル名は通常、Comment.jsonです。","JSON 형식의 Valine 내보내기 파일을 업로드하세요. 파일 이름은 보통 Comment.json 입니다."]),c+"_UPLOADED",["上传完成 ","上傳完成 ","上傳完成 ","Uploaded ","Юкланди ","アップロード完了","업로드 완료 "]),c+"_UPLOADING",["已上传 ","已上傳 ","已上傳 ","Uploading ","Юкланмоқда ","アップロード中です","업로드 중 "]),c+"_WARN",["支持从其他评论系统的备份文件导入评论。\n数据是安全的,导入功能完全在您的云环境进行。\n建议在导入前备份 comment 数据库。","支持從其他評論系統的備份文件匯入評論。\n數據是安全的,匯入功能完全在您的雲環境進行。\n建議在匯入前備份 comment 數據庫。","支援從其他留言系統的備份檔案匯入留言。\n資料是安全的,匯入功能完全在您的雲端環境進行。\n建議在匯入前備份 comment 資料庫。","Import comments from other comment systems.\nThe data is safe, and the import function is performed entirely in your cloud environment.\nPlease backup your comment database before importing.","Бошқа шарҳ тизимларидан шарҳларни импорт қилинг.\nМаълумотлар хавфсиз ва импорт функцияси тўлиқ булутли муҳитда амалга оширилади.\nИмпорт қилишдан олдин шарҳлар маълумотлар базасини захираланг.","他のコメントシステムのバックアップファイルからのインポートに対応。\nデータは安全で、インポート機能はすべてクラウド環境で実行されます。\nインポート前にコメントデータベースをバックアップすることを推奨します。","다른 댓글 시스템의 백업 파일에서 댓글을 가져올 수 있습니다.\n데이터 가져오기는 설정하신 클라우드에서만 안전하게 진행됩니다.\n가져오기 전에 댓글 데이터베이스를 백업하는 것이 좋습니다."]),"ADMIN_LOGIN",["登录","登入","登入","Sign in","Тизимга кириш","ログイン","로그인"]),"ADMIN_LOGIN_TITLE",["Twikoo 评论管理","Twikoo 評論管理","Twikoo 留言管理","Twikoo Management Panel","Twikoo Бошқарув Панели","Twikoo コメント管理","Twikoo 관리자 패널"]),"ADMIN_LOGOUT",["退出登录","退出登入","登出","Sign out","Тизимдан чиқиш","ログアウト","로그아웃"]),"ADMIN_NEED_UPDATE",["若要使用评论管理,请更新 Twikoo 云函数","若要使用評論管理,請更新 Twikoo 雲函數","若要使用留言管理功能,請更新 Twikoo 雲端函數","A new version of Twikoo is required for comment management.","Фикрларни бошқариш учун Твикоо нинг янги версияси талаб қилинади.","コメント管理を使用するには、Twikoo クラウド関数を更新してください","새 버전의 댓글 관리를 사용하려면 Twikoo Cloud Function을 업데이트하세요."]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,"ADMIN_PASSWORD",["密码","密碼","密碼","Password","Пароль","パスワード","비밀번호"]),"ADMIN_PASSWORD_PLACEHOLDER",["请输入","請輸入","請輸入","Enter your password...","Паролингизни киритинг...","入力してください","비밀번호를 입력하세요..."]),"ADMIN_PASSWORD_REQUIRED",["请输入密码","請輸入密碼","請輸入密碼","Please enter your password","Илтимос, паролингизни киритинг","パスワードを入力してください","비밀번호를 입력하세요"]),"ADMIN_REGIST",["注册","註冊","註冊","Register","Рўйхатдан ўтиш","登録","관리자 등록"]),"ADMIN_REGIST_FAILED",["注册失败","註冊失敗","註冊失敗","Register failed","Рўйхатдан ўтиш амалга ошмади","登録に失敗しました","관리자 등록 실패"]),"ADMIN_SET_PASSWORD",["设置密码","設置密碼","設定密碼","Set password","Пароль қўйиш","パスワードの設定","비밀번호 설정"]),"ADMIN_SET_PASSWORD_CONFIRM",["确认密码","確認密碼","確認密碼","Confirm password","Паролни тасдиқланг","パスワードの確認","비밀번호 확인"]),"ADMIN_SET_PASSWORD_CONFIRM_PLACEHOLDER",["确认密码","確認密碼","確認密碼","Confirm password...","Паролни тасдиқлаш...","パスワードの確認","비밀번호 확인..."]),"ADMIN_SET_PASSWORD_PLACEHOLDER",["密码","密碼","密碼","Password","Пароль","パスワード","비밀번호"]),"ADMIN_TITLE",["Twikoo 管理面板","Twikoo 管理面板","Twikoo 管理控制台","Twikoo Management Panel","Twikoo Бошқарув Панели","Twikoo管理パネル","Twikoo 관리 패널"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,"COMMENTS_COUNT_SUFFIX",[" 条评论"," 條評論"," 則留言"," comments"," изоҳлар"," 件のコメント","개의 댓글"]),"COMMENTS_EXPAND",["查看更多","查看更多","檢視更多","Load more","Давомини юклаш","もっと見る","더 보기"]),"COMMENTS_NO_COMMENTS",["没有评论","沒有評論","沒有留言","No comment","Изоҳларсиз","コメントはありません","아직 댓글이 없습니다."]),"COMMENT_EXPAND",["展开","展開","展開","Read more","Давомини ўқиш","全文を表示","더 보기"]),"COMMENT_COLLAPSE",["收起","收起","閉合","Collapse","Очиш","折りたたむ","접기"]),"COMMENT_MASTER_TAG",["博主","博主","站長","Admin","Модератор","管理者","관리자"]),"COMMENT_REPLIED",["回复","回覆","回覆","Reply","Жавоб бериш","返信","답글"]),"COMMENT_REVIEWING_TAG",["审核中","審核中","審核中","Pending","Кутилмоқда","検討中","검토 중"]),"COMMENT_TOP_TAG",["置顶","置頂","置頂","Pinned","Қадоқланган","固定","고정됨"]),"COMMENT_FAILED",["评论失败","評論失敗","評論失敗","Comment failed","Фикр билдирилмади","コメント失敗","댓글 등록 실패"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,"META_INPUT_LINK",["网址","網址","網址","Website","Веб-сайт","ウェブサイト","웹사이트"]),"META_INPUT_MAIL",["邮箱","郵箱","郵箱","Email","Email","メールアドレス","이메일"]),"META_INPUT_NICK",["昵称","暱稱","暱稱","Nickname","Исм","名前","닉네임"]),"META_INPUT_NOT_REQUIRED",["选填","選填","選填","Optional","Ихтиёрий","任意","선택"]),"META_INPUT_REQUIRED",["必填","必填","必填","Required","Мажбурий","必須","필수"]),"PAGINATION_COUNT_PREFIX",["共 ","共 ","共 ","","","合計 ","총 "]),"PAGINATION_COUNT_SUFFIX",[" 条"," 條"," 條"," entries"," ёзувлар"," 件","개"]),"PAGINATION_GOTO_PREFIX",["前往","前往","前往","Goto page","Саҳифага ўтиш","ページに移動","이동할 페이지: "]),"PAGINATION_GOTO_SUFFIX",["页","頁","頁","","ページ",""]),"PAGINATION_PAGESIZE",["条/页","條/頁","則/頁","entries/page","ёзувлар/саҳифа","件/ページ","개/페이지"]),(0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])((0,o["default"])(i,"SUBMIT_CANCEL",["取消","取消","取消","Cancel","Бекор қилиш","キャンセル","취소"]),"SUBMIT_PREVIEW",["预览","預覽","預覽","Preview","Кўриб чиқиш","プレビュー","미리보기"]),"SUBMIT_SEND",["发送","發送","傳送","Send","Юбормоқ","送信","등록"]),"IMAGE_UPLOAD_PLACEHOLDER",["图片上传中","圖片上傳中","圖片上傳中","Uploading image","Расм юклаш","画像のアップロード中","이미지 업로드 중"]),"IMAGE_UPLOAD_FAILED",["图片上传失败","圖片上傳失敗","圖片上傳失敗","IMAGE UPLOAD FAILED","РАСМ ЮКЛАНМАДИ","画像のアップロード失敗","이미지 업로드 실패"]),"IMAGE_UPLOAD_FAILED_NO_CONF",["博主未配置图床服务","博主未配置圖床服務","博主未配置圖床服務","The blogger didn't configured any image bed service","Муаллиф ҳеч қандай тасвир хизматини созламаган","管理者が画像配信サービスを設定していません","블로거가 이미지 호스팅 서비스를 설정하지 않았습니다."]),"IMAGE_UPLOAD_PLEASE_WAIT",["图片上传中,请稍候再发送","圖片上傳中,請稍候再發送","圖片上傳中,請稍候再傳送","Uploading image, please try again later","Расм юкланмоқда, кейинроқ қайта уриниб кўринг","画像のアップロードが完了するまでお待ちください","이미지 업로드 중입니다. 잠시 후 다시 시도해주세요."]),"SUBMIT_SENDING",["发送中","發送中","正在傳送","Sending","Юбориш","送信中","등록 중"]),"TIMEAGO_DAYS",["天前","天前","天前","days ago","кунлар олдин","日前","일 전"]),"TIMEAGO_HOURS",["小时前","小時前","小時前","hours ago","соатлар олдин","時間前","시간 전"]),(0,o["default"])((0,o["default"])((0,o["default"])(i,"TIMEAGO_MINUTES",["分钟前","分鐘前","分鐘前","minutes ago","дақиқалар олдин","分前","분 전"]),"TIMEAGO_NOW",["刚刚","剛剛","剛剛","Just now","Ҳозиргина","たった今","방금 전"]),"TIMEAGO_SECONDS",["秒前","秒前","秒前","seconds ago","сониялар олдин","秒前","초 전"]))},5878:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.setLanguage=t["default"]=void 0;var i=r(n(7564)),o={zh:0,"zh-cn":0,"zh-hk":1,"zh-tw":2,"en-us":3,"en-gb":3,en:3,uz:4,"uz-uz":4,ja:5,"ja-jp":5,ko:6,"ko-kr":6},a="";t.setLanguage=function(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};e.lang&&e.lang.toLowerCase()in o&&(a=e.lang)},t["default"]=function(e,t){var n=(t||a||navigator.language).toLowerCase();return(n&&o[n]?i["default"][e][o[n]]:i["default"][e][o["zh-cn"]])||""}},8129:function(e,t,n){"use strict";var r=n(477),i=n(9367);Object.defineProperty(t,"__esModule",{value:!0}),t.blobToDataURL=void 0,Object.defineProperty(t,"call",{enumerable:!0,get:function(){return p.call}}),t.getHref=t.getFuncVer=t.getCommentsCountApi=t.convertLink=void 0,Object.defineProperty(t,"getQQAvatar",{enumerable:!0,get:function(){return h.getQQAvatar}}),t.getUserAgent=t.getUrl=t.getRecentCommentsApi=void 0,Object.defineProperty(t,"initMarkedOwo",{enumerable:!0,get:function(){return m.initMarkedOwo}}),Object.defineProperty(t,"initOwoEmotions",{enumerable:!0,get:function(){return m.initOwoEmotions}}),t.isNotSet=void 0,Object.defineProperty(t,"isQQ",{enumerable:!0,get:function(){return h.isQQ}}),Object.defineProperty(t,"isUrl",{enumerable:!0,get:function(){return p.isUrl}}),t.logger=void 0,Object.defineProperty(t,"marked",{enumerable:!0,get:function(){return d["default"]}}),Object.defineProperty(t,"normalizeMail",{enumerable:!0,get:function(){return h.normalizeMail}}),t.readAsText=void 0,Object.defineProperty(t,"renderCode",{enumerable:!0,get:function(){return f["default"]}}),t.renderMath=t.renderLinks=void 0,Object.defineProperty(t,"setLanguage",{enumerable:!0,get:function(){return c.setLanguage}}),Object.defineProperty(t,"t",{enumerable:!0,get:function(){return c["default"]}}),Object.defineProperty(t,"timeago",{enumerable:!0,get:function(){return l["default"]}}),t.timestamp=void 0;var o,a=r(n(479)),s=r(n(1819)),u=r(n(4964)),c=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=i(e)&&"function"!=typeof e)return{"default":e};var n=g(t);if(n&&n.has(e))return n.get(e);var r={__proto__:null},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var s=o?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=e[a]}return r["default"]=e,n&&n.set(e,r),r}(n(5878)),l=r(n(7435)),d=r(n(37)),f=r(n(4161)),p=n(585),h=n(7080),m=n(9212);function g(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(g=function(e){return e?n:t})(e)}function v(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return _(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,o=e},f:function(){try{a||null==n["return"]||n["return"]()}finally{if(s)throw o}}}}function _(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&arguments[0]!==undefined?arguments[0]:new Date).getTime()},t.convertLink=function(e){return e?"http"!==e.substring(0,4)?"http://".concat(e):e:""},t.getFuncVer=function(){var e=(0,u["default"])(a["default"].mark((function t(e){return a["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(o){t.next=4;break}return t.next=3,(0,p.call)(e,"GET_FUNC_VERSION");case 3:o=t.sent;case 4:return t.abrupt("return",o);case 5:case"end":return t.stop()}}),t)})));return function(t){return e.apply(this,arguments)}}(),t.getCommentsCountApi=function(){var e=(0,u["default"])(a["default"].mark((function t(e,n){var r;return a["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(n.urls instanceof Array){t.next=2;break}throw new Error("urls 参数有误");case 2:if(0!==n.urls.length){t.next=4;break}return t.abrupt("return",[]);case 4:return t.next=6,(0,p.call)(e,"GET_COMMENTS_COUNT",n);case 6:return r=t.sent,t.abrupt("return",r.result.data);case 8:case"end":return t.stop()}}),t)})));return function(t,n){return e.apply(this,arguments)}}(),t.getRecentCommentsApi=function(){var e=(0,u["default"])(a["default"].mark((function t(e,n){var r,i,o,s;return a["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,(0,p.call)(e,"GET_RECENT_COMMENTS",n);case 2:r=t.sent,i=v(r.result.data);try{for(i.s();!(o=i.n()).done;)(s=o.value).relativeTime=(0,l["default"])(s.created)}catch(a){i.e(a)}finally{i.f()}return t.abrupt("return",r.result.data);case 6:case"end":return t.stop()}}),t)})));return function(t,n){return e.apply(this,arguments)}}(),t.getUserAgent=function(){var e=(0,u["default"])(a["default"].mark((function t(){var e,n,r,i,o,s;return a["default"].wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(e=window.navigator.userAgent,t.prev=1,"Windows"!==(n=navigator.userAgentData.platform)&&"macOS"!==n){t.next=10;break}return t.next=6,navigator.userAgentData.getHighEntropyValues(["platformVersion"]);case 6:r=t.sent,i=r.platformVersion,o=parseInt(i.split(".")[0]),"Windows"===n&&o>=13?e=e.replace(/Windows NT 10\.0/i,"Windows NT ".concat("11.0")):"macOS"===n&&o>=11&&(s=i.replace(/\./g,"_"),e=e.replace(/Mac OS X 10_[0-9]+_[0-9]+/i,"Mac OS X ".concat(s)));case 10:t.next=14;break;case 12:t.prev=12,t.t0=t["catch"](1);case 14:return t.abrupt("return",e);case 15:case"end":return t.stop()}}),t,null,[[1,12]])})));return function(){return e.apply(this,arguments)}}(),t.getUrl=function(e){var t;if(window.TWIKOO_MAGIC_PATH)t=window.TWIKOO_MAGIC_PATH;else if(e&&"string"==typeof e)switch(e){case"location.pathname":case"window.location.pathname":t=window.location.pathname;break;case"location.href":case"window.location.href":t=window.location.href;break;default:t=e}else t=window.location.pathname;return t},t.getHref=function(e){var t,n;return null!==(t=null!==(n=window.TWIKOO_MAGIC_HREF)&&void 0!==n?n:e)&&void 0!==t?t:window.location.href},t.readAsText=function(e){return new Promise((function(t,n){var r=new FileReader;r.readAsText(e),r.onloadend=function(){r.error?n(r.error):t(r.result)}}))},t.renderLinks=function(e){var t=[];e instanceof Array?e.forEach((function(e){var n;(n=t).push.apply(n,(0,s["default"])(e.getElementsByTagName("a")))})):e instanceof Element&&(t=e.getElementsByTagName("a"));var n,r=v(t);try{for(r.s();!(n=r.n()).done;){var i=n.value;i.setAttribute("target","_blank"),i.setAttribute("rel","noopener noreferrer")}}catch(o){r.e(o)}finally{r.f()}},t.renderMath=function(e,t){"function"==typeof renderMathInElement&&renderMathInElement(e,t||{delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],throwOnError:!1})},t.blobToDataURL=function(e){return new Promise((function(t){var n=new FileReader;n.onload=function(e){var n=e.target.result;t(n)},n.readAsDataURL(e)}))}},37:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=void 0;var r=n(78);r.marked.setOptions({renderer:new r.marked.Renderer,gfm:!0,tables:!0,breaks:!0,pedantic:!1,smartLists:!0,smartypants:!0}),t["default"]=r.marked},824:function(e,t,n){"use strict";var r=n(477);Object.defineProperty(t,"__esModule",{value:!0}),t.install=function(e){return d.apply(this,arguments)},t.tcb=void 0;var i=r(n(479)),o=r(n(4964)),a=n(8129);function s(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return u(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,o=e},f:function(){try{a||null==n["return"]||n["return"]()}finally{if(s)throw o}}}}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&r[1]!==undefined?r[1]:{},l.sdk=t,f(n),e.next=5,p(n);case 5:return e.abrupt("return",l);case 6:case"end":return e.stop()}}),e)}))),d.apply(this,arguments)}function f(e){var t,n=[],r=s(c);try{for(r.s();!(t=r.n()).done;){var i=t.value;i["default"]&&(0,a.isNotSet)(e[i.key])?e[i.key]=i["default"]:i.required&&(0,a.isNotSet)(e[i.key])&&n.push(i.key)}}catch(d){r.e(d)}finally{r.f()}if(n.length>0){var o,u=s(n);try{for(u.s();!(o=u.n()).done;){var l=o.value;a.logger.warn("".concat(l," is required"))}}catch(d){u.e(d)}finally{u.f()}throw new Error("Twikoo: failed to init")}}function p(e){return h.apply(this,arguments)}function h(){return(h=(0,o["default"])(i["default"].mark((function e(t){return i["default"].wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return m(t),e.next=3,g();case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function m(e){l.app=l.sdk.init({env:e.envId,region:e.region})}function g(){return v.apply(this,arguments)}function v(){return(v=(0,o["default"])(i["default"].mark((function e(){return i["default"].wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",new Promise((function(e,t){l.auth=l.app.auth({persistence:"local"}),l.auth.hasLoginState()?e():l.auth.anonymousAuthProvider().signIn().then(e)["catch"](t)})));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}},7435:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=void 0;var r=n(8129),i=function(e){var t=o(e.getDate(),2),n=o(e.getMonth()+1,2),r=o(e.getFullYear(),2);return"".concat(r,"-").concat(n,"-").concat(t)},o=function(e,t){for(var n=e.toString();n.length1&&arguments[1]!==undefined?arguments[1]:{};return i["default"].prototype.$tcb=e,i["default"].prototype.$twikoo=n,t.app=c=new i["default"]({render:function(e){return e(o["default"])}}),c.$mount(n.el||"#twikoo"),c}},3723:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,".el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#FFF;border:1px solid #DCDFE6;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button:focus,.el-button:hover{color:#409EFF;border-color:#c6e2ff;background-color:#ecf5ff}.el-button:active{color:#3a8ee6;border-color:#3a8ee6;outline:0}.el-button::-moz-focus-inner{border:0}.el-button [class*=el-icon-]+span{margin-left:5px}.el-button.is-plain:focus,.el-button.is-plain:hover{background:#FFF;border-color:#409EFF;color:#409EFF}.el-button.is-active,.el-button.is-plain:active{color:#3a8ee6;border-color:#3a8ee6}.el-button.is-plain:active{background:#FFF;outline:0}.el-button.is-disabled,.el-button.is-disabled:focus,.el-button.is-disabled:hover{color:#C0C4CC;cursor:not-allowed;background-image:none;background-color:#FFF;border-color:#EBEEF5}.el-button.is-disabled.el-button--text{background-color:transparent}.el-button.is-disabled.is-plain,.el-button.is-disabled.is-plain:focus,.el-button.is-disabled.is-plain:hover{background-color:#FFF;border-color:#EBEEF5;color:#C0C4CC}.el-button.is-loading{position:relative;pointer-events:none}.el-button.is-loading:before{pointer-events:none;content:'';position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:rgba(255,255,255,.35)}.el-button.is-round{border-radius:20px;padding:12px 23px}.el-button.is-circle{border-radius:50%;padding:12px}.el-button--primary{color:#FFF;background-color:#409EFF;border-color:#409EFF}.el-button--primary:focus,.el-button--primary:hover{background:#66b1ff;border-color:#66b1ff;color:#FFF}.el-button--primary:active{background:#3a8ee6;border-color:#3a8ee6;color:#FFF;outline:0}.el-button--primary.is-active{background:#3a8ee6;border-color:#3a8ee6;color:#FFF}.el-button--primary.is-disabled,.el-button--primary.is-disabled:active,.el-button--primary.is-disabled:focus,.el-button--primary.is-disabled:hover{color:#FFF;background-color:#a0cfff;border-color:#a0cfff}.el-button--primary.is-plain{color:#409EFF;background:#ecf5ff;border-color:#b3d8ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#409EFF;border-color:#409EFF;color:#FFF}.el-button--primary.is-plain:active{background:#3a8ee6;border-color:#3a8ee6;color:#FFF;outline:0}.el-button--primary.is-plain.is-disabled,.el-button--primary.is-plain.is-disabled:active,.el-button--primary.is-plain.is-disabled:focus,.el-button--primary.is-plain.is-disabled:hover{color:#8cc5ff;background-color:#ecf5ff;border-color:#d9ecff}.el-button--success{color:#FFF;background-color:#67C23A;border-color:#67C23A}.el-button--success:focus,.el-button--success:hover{background:#85ce61;border-color:#85ce61;color:#FFF}.el-button--success.is-active,.el-button--success:active{background:#5daf34;border-color:#5daf34;color:#FFF}.el-button--success:active{outline:0}.el-button--success.is-disabled,.el-button--success.is-disabled:active,.el-button--success.is-disabled:focus,.el-button--success.is-disabled:hover{color:#FFF;background-color:#b3e19d;border-color:#b3e19d}.el-button--success.is-plain{color:#67C23A;background:#f0f9eb;border-color:#c2e7b0}.el-button--success.is-plain:focus,.el-button--success.is-plain:hover{background:#67C23A;border-color:#67C23A;color:#FFF}.el-button--success.is-plain:active{background:#5daf34;border-color:#5daf34;color:#FFF;outline:0}.el-button--success.is-plain.is-disabled,.el-button--success.is-plain.is-disabled:active,.el-button--success.is-plain.is-disabled:focus,.el-button--success.is-plain.is-disabled:hover{color:#a4da89;background-color:#f0f9eb;border-color:#e1f3d8}.el-button--warning{color:#FFF;background-color:#E6A23C;border-color:#E6A23C}.el-button--warning:focus,.el-button--warning:hover{background:#ebb563;border-color:#ebb563;color:#FFF}.el-button--warning.is-active,.el-button--warning:active{background:#cf9236;border-color:#cf9236;color:#FFF}.el-button--warning:active{outline:0}.el-button--warning.is-disabled,.el-button--warning.is-disabled:active,.el-button--warning.is-disabled:focus,.el-button--warning.is-disabled:hover{color:#FFF;background-color:#f3d19e;border-color:#f3d19e}.el-button--warning.is-plain{color:#E6A23C;background:#fdf6ec;border-color:#f5dab1}.el-button--warning.is-plain:focus,.el-button--warning.is-plain:hover{background:#E6A23C;border-color:#E6A23C;color:#FFF}.el-button--warning.is-plain:active{background:#cf9236;border-color:#cf9236;color:#FFF;outline:0}.el-button--warning.is-plain.is-disabled,.el-button--warning.is-plain.is-disabled:active,.el-button--warning.is-plain.is-disabled:focus,.el-button--warning.is-plain.is-disabled:hover{color:#f0c78a;background-color:#fdf6ec;border-color:#faecd8}.el-button--danger{color:#FFF;background-color:#F56C6C;border-color:#F56C6C}.el-button--danger:focus,.el-button--danger:hover{background:#f78989;border-color:#f78989;color:#FFF}.el-button--danger.is-active,.el-button--danger:active{background:#dd6161;border-color:#dd6161;color:#FFF}.el-button--danger:active{outline:0}.el-button--danger.is-disabled,.el-button--danger.is-disabled:active,.el-button--danger.is-disabled:focus,.el-button--danger.is-disabled:hover{color:#FFF;background-color:#fab6b6;border-color:#fab6b6}.el-button--danger.is-plain{color:#F56C6C;background:#fef0f0;border-color:#fbc4c4}.el-button--danger.is-plain:focus,.el-button--danger.is-plain:hover{background:#F56C6C;border-color:#F56C6C;color:#FFF}.el-button--danger.is-plain:active{background:#dd6161;border-color:#dd6161;color:#FFF;outline:0}.el-button--danger.is-plain.is-disabled,.el-button--danger.is-plain.is-disabled:active,.el-button--danger.is-plain.is-disabled:focus,.el-button--danger.is-plain.is-disabled:hover{color:#f9a7a7;background-color:#fef0f0;border-color:#fde2e2}.el-button--info{color:#FFF;background-color:#909399;border-color:#909399}.el-button--info:focus,.el-button--info:hover{background:#a6a9ad;border-color:#a6a9ad;color:#FFF}.el-button--info.is-active,.el-button--info:active{background:#82848a;border-color:#82848a;color:#FFF}.el-button--info:active{outline:0}.el-button--info.is-disabled,.el-button--info.is-disabled:active,.el-button--info.is-disabled:focus,.el-button--info.is-disabled:hover{color:#FFF;background-color:#c8c9cc;border-color:#c8c9cc}.el-button--info.is-plain{color:#909399;background:#f4f4f5;border-color:#d3d4d6}.el-button--info.is-plain:focus,.el-button--info.is-plain:hover{background:#909399;border-color:#909399;color:#FFF}.el-button--info.is-plain:active{background:#82848a;border-color:#82848a;color:#FFF;outline:0}.el-button--info.is-plain.is-disabled,.el-button--info.is-plain.is-disabled:active,.el-button--info.is-plain.is-disabled:focus,.el-button--info.is-plain.is-disabled:hover{color:#bcbec2;background-color:#f4f4f5;border-color:#e9e9eb}.el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.el-button--mini,.el-button--small{font-size:12px;border-radius:3px}.el-button--medium.is-round{padding:10px 20px}.el-button--medium.is-circle{padding:10px}.el-button--small,.el-button--small.is-round{padding:9px 15px}.el-button--small.is-circle{padding:9px}.el-button--mini,.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{border-color:transparent;color:#409EFF;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#66b1ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#3a8ee6;border-color:transparent;background-color:transparent}.el-button--text.is-disabled,.el-button--text.is-disabled:focus,.el-button--text.is-disabled:hover{border-color:transparent}.el-button-group .el-button--danger:last-child,.el-button-group .el-button--danger:not(:first-child):not(:last-child),.el-button-group .el-button--info:last-child,.el-button-group .el-button--info:not(:first-child):not(:last-child),.el-button-group .el-button--primary:last-child,.el-button-group .el-button--primary:not(:first-child):not(:last-child),.el-button-group .el-button--success:last-child,.el-button-group .el-button--success:not(:first-child):not(:last-child),.el-button-group .el-button--warning:last-child,.el-button-group .el-button--warning:not(:first-child):not(:last-child),.el-button-group>.el-dropdown>.el-button{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child,.el-button-group .el-button--danger:not(:first-child):not(:last-child),.el-button-group .el-button--info:first-child,.el-button-group .el-button--info:not(:first-child):not(:last-child),.el-button-group .el-button--primary:first-child,.el-button-group .el-button--primary:not(:first-child):not(:last-child),.el-button-group .el-button--success:first-child,.el-button-group .el-button--success:not(:first-child):not(:last-child),.el-button-group .el-button--warning:first-child,.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-right-color:rgba(255,255,255,.5)}.el-button-group{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table;content:\"\"}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.el-button-group>.el-button.is-disabled{z-index:1}.el-button-group>.el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.el-button-group>.el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.el-button-group>.el-button:first-child:last-child{border-radius:4px}.el-button-group>.el-button:first-child:last-child.is-round{border-radius:20px}.el-button-group>.el-button:first-child:last-child.is-circle{border-radius:50%}.el-button-group>.el-button:not(:first-child):not(:last-child){border-radius:0}.el-button-group>.el-button:not(:last-child){margin-right:-1px}.el-button-group>.el-button.is-active,.el-button-group>.el-button:not(.is-disabled):active,.el-button-group>.el-button:not(.is-disabled):focus,.el-button-group>.el-button:not(.is-disabled):hover{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0}",""]),t["default"]=a},1315:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,".el-input__inner,.el-textarea__inner{background-image:none;-webkit-box-sizing:border-box;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;box-sizing:border-box;width:100%;font-size:inherit;color:#606266;background-color:#FFF;border:1px solid #DCDFE6;border-radius:4px;transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-textarea__inner::-webkit-input-placeholder{color:#C0C4CC}.el-textarea__inner:-ms-input-placeholder{color:#C0C4CC}.el-textarea__inner::-ms-input-placeholder{color:#C0C4CC}.el-textarea__inner::placeholder{color:#C0C4CC}.el-textarea__inner:hover{border-color:#C0C4CC}.el-textarea__inner:focus{outline:0;border-color:#409EFF}.el-textarea .el-input__count{color:#909399;background:#FFF;position:absolute;font-size:12px;bottom:5px;right:10px}.el-textarea.is-disabled .el-textarea__inner{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner::placeholder{color:#C0C4CC}.el-textarea.is-exceed .el-textarea__inner{border-color:#F56C6C}.el-textarea.is-exceed .el-input__count{color:#F56C6C}.el-input{position:relative;font-size:14px;display:inline-block;width:100%}.el-input::-webkit-scrollbar{z-index:11;width:6px}.el-input::-webkit-scrollbar:horizontal{height:6px}.el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.el-input::-webkit-scrollbar-corner{background:#fff}.el-input::-webkit-scrollbar-track{background:#fff}.el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.el-input .el-input__clear{color:#C0C4CC;font-size:14px;cursor:pointer;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-input .el-input__clear:hover{color:#909399}.el-input .el-input__count{height:100%;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#909399;font-size:12px}.el-input-group__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input,.el-input__inner{font-size:inherit}.el-input .el-input__count .el-input__count-inner{background:#FFF;line-height:initial;display:inline-block;padding:0 5px}.el-input__inner{-webkit-appearance:none;background-color:#FFF;border-radius:4px;border:1px solid #DCDFE6;box-sizing:border-box;color:#606266;display:inline-block;height:40px;line-height:40px;outline:0;padding:0 15px;transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.el-input__prefix,.el-input__suffix{position:absolute;top:0;-webkit-transition:all .3s;text-align:center;height:100%;color:#C0C4CC}.el-input__inner::-ms-reveal{display:none}.el-input__inner::-webkit-input-placeholder{color:#C0C4CC}.el-input__inner:-ms-input-placeholder{color:#C0C4CC}.el-input__inner::-ms-input-placeholder{color:#C0C4CC}.el-input__inner::placeholder{color:#C0C4CC}.el-input__inner:hover{border-color:#C0C4CC}.el-input.is-active .el-input__inner,.el-input__inner:focus{border-color:#409EFF;outline:0}.el-input__suffix{right:5px;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{left:5px;transition:all .3s}.el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.el-input__validateIcon{pointer-events:none}.el-input.is-disabled .el-input__inner{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner::placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__icon{cursor:not-allowed}.el-input.is-exceed .el-input__inner{border-color:#F56C6C}.el-input.is-exceed .el-input__suffix .el-input__count{color:#F56C6C}.el-input--suffix .el-input__inner{padding-right:30px}.el-input--prefix .el-input__inner{padding-left:30px}.el-input--medium{font-size:14px}.el-input--medium .el-input__inner{height:36px;line-height:36px}.el-input--medium .el-input__icon{line-height:36px}.el-input--small{font-size:13px}.el-input--small .el-input__inner{height:32px;line-height:32px}.el-input--small .el-input__icon{line-height:32px}.el-input--mini{font-size:12px}.el-input--mini .el-input__inner{height:28px;line-height:28px}.el-input--mini .el-input__icon{line-height:28px}.el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate;border-spacing:0}.el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.el-input-group__append,.el-input-group__prepend{background-color:#F5F7FA;color:#909399;vertical-align:middle;display:table-cell;position:relative;border:1px solid #DCDFE6;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.el-input-group--prepend .el-input__inner,.el-input-group__append{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--append .el-input__inner,.el-input-group__prepend{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append:focus,.el-input-group__prepend:focus{outline:0}.el-input-group__append .el-button,.el-input-group__append .el-select,.el-input-group__prepend .el-button,.el-input-group__prepend .el-select{display:inline-block;margin:-10px -20px}.el-input-group__append button.el-button,.el-input-group__append div.el-select .el-input__inner,.el-input-group__append div.el-select:hover .el-input__inner,.el-input-group__prepend button.el-button,.el-input-group__prepend div.el-select .el-input__inner,.el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.el-input-group__prepend{border-right:0}.el-input-group__append{border-left:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner,.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}",""]),t["default"]=a},9211:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,".el-loading-parent--relative{position:relative!important}.el-loading-parent--hidden{overflow:hidden!important}.el-loading-mask{position:absolute;z-index:2000;background-color:rgba(255,255,255,.9);margin:0;top:0;right:0;bottom:0;left:0;-webkit-transition:opacity .3s;transition:opacity .3s}.el-loading-mask.is-fullscreen{position:fixed}.el-loading-mask.is-fullscreen .el-loading-spinner{margin-top:-25px}.el-loading-mask.is-fullscreen .el-loading-spinner .circular{height:50px;width:50px}.el-loading-spinner{top:50%;margin-top:-21px;width:100%;text-align:center;position:absolute}.el-loading-spinner .el-loading-text{color:#409EFF;margin:3px 0;font-size:14px}.el-loading-spinner .circular{height:42px;width:42px;-webkit-animation:loading-rotate 2s linear infinite;animation:loading-rotate 2s linear infinite}.el-loading-spinner .path{-webkit-animation:loading-dash 1.5s ease-in-out infinite;animation:loading-dash 1.5s ease-in-out infinite;stroke-dasharray:90,150;stroke-dashoffset:0;stroke-width:2;stroke:#409EFF;stroke-linecap:round}.el-loading-spinner i{color:#409EFF}.el-loading-fade-enter,.el-loading-fade-leave-active{opacity:0}@-webkit-keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}@keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}",""]),t["default"]=a},9737:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.twikoo {\n position: relative;\n}\n.twikoo svg {\n width: 100%;\n height: 100%;\n fill: currentColor;\n}\n\n/* 全局 CSS */\n.tk-expand {\n width: 100%;\n cursor: pointer;\n padding: 0.75em;\n text-align: center;\n transition: all 0.5s;\n}\n.tk-expand:hover {\n background-color: rgba(0,0,0,0.13);\n}\n.tk-expand:active {\n background-color: rgba(0,0,0,0.19);\n}\n.tk-content img {\n max-width: 300px;\n max-height: 300px;\n vertical-align: middle;\n}\n.tk-owo-emotion,\n.twikoo .OwO-item img {\n width: 3em;\n height: auto;\n}\n\n/* element-ui overwrite */\n.twikoo .el-input__inner,\n.twikoo .el-textarea__inner {\n color: currentColor;\n background-color: transparent;\n border-color: rgba(144,147,153,0.31);\n}\n.twikoo .el-input__inner:hover,\n.twikoo .el-textarea__inner:hover {\n border-color: rgba(144,147,153,0.50);\n}\n.twikoo .el-input__inner:focus,\n.twikoo .el-textarea__inner:focus {\n border-color: #409eff;\n}\n.twikoo .el-input-group__append,\n.twikoo .el-input-group__prepend {\n color: currentColor;\n background-clip: padding-box;\n background-color: rgba(144,147,153,0.13);\n border-color: rgba(144,147,153,0.31);\n}\n.twikoo .el-button:not(.el-button--primary):not(.el-button--text) {\n color: currentColor;\n background-color: rgba(144,147,153,0.063);\n border-color: rgba(144,147,153,0.31);\n}\n.twikoo .el-button:not(.el-button--primary):not(.el-button--text):active,\n.twikoo .el-button:not(.el-button--primary):not(.el-button--text):focus,\n.twikoo .el-button:not(.el-button--primary):not(.el-button--text):hover {\n color: #409eff;\n background-color: rgba(64,158,255,0.063);\n border-color: rgba(64,158,255,0.50);\n}\n.twikoo .el-button--primary.is-disabled,\n.twikoo .el-button--primary.is-disabled:active,\n.twikoo .el-button--primary.is-disabled:focus,\n.twikoo .el-button--primary.is-disabled:hover {\n color: rgba(255,255,255,0.63);\n background-color: rgba(64,158,255,0.50);\n border-color: transparent;\n}\n.twikoo .el-loading-mask {\n background-color: transparent;\n backdrop-filter: opacity(20%);\n}\n.twikoo .el-textarea .el-input__count {\n color: currentColor;\n background: transparent;\n}\n.tk-admin-warn {\n padding: 1rem 1.5rem;\n background-color: #fff7d0;\n border-left: 0.5rem solid #e7c000;\n color: #6b5900;\n align-self: stretch;\n}\n",""]),t["default"]=a},6640:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-action {\n display: flex;\n align-items: center;\n}\n.tk-action-link {\n margin-left: 0.5rem;\n color: #409eff;\n text-decoration: none;\n display: flex;\n align-items: center;\n}\n.tk-action-link .tk-action-icon-solid {\n display: none;\n}\n.tk-action-link.tk-liked .tk-action-icon,\n.tk-action-link:hover .tk-action-icon {\n display: none;\n}\n.tk-action-link.tk-liked .tk-action-icon-solid,\n.tk-action-link:hover .tk-action-icon-solid {\n display: block;\n}\n.tk-action-count {\n margin-left: 0.25rem;\n font-size: 0.75rem;\n height: 1.5rem;\n line-height: 1.5rem;\n}\n.tk-action-icon {\n display: inline-block;\n height: 1em;\n width: 1em;\n line-height: 0;\n color: #409eff;\n}\n",""]),t["default"]=a},3514:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-admin-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n overflow: hidden;\n pointer-events: none;\n}\n.tk-admin {\n position: absolute;\n top: 0;\n left: 100%;\n width: 100%;\n height: 100%;\n overflow-y: auto;\n pointer-events: all;\n color: #ffffff;\n background-color: rgba(0,0,0,0.60);\n backdrop-filter: blur(5px);\n transition: all 0.5s ease;\n visibility: hidden;\n}\n.tk-admin::-webkit-scrollbar {\n width: 5px;\n background-color: transparent;\n}\n.tk-admin::-webkit-scrollbar-track {\n background-color: transparent;\n}\n.tk-admin::-webkit-scrollbar-thumb {\n background-color: rgba(255,255,255,0.31);\n}\n.tk-admin.__show {\n left: 0;\n visibility: visible;\n}\n.tk-admin-close {\n position: sticky;\n float: right;\n display: block;\n top: 0;\n right: 0;\n width: 1rem;\n height: 1rem;\n padding: 1rem;\n box-sizing: content-box;\n color: #ffffff;\n}\n.tk-login,\n.tk-regist {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n padding: 0 2rem;\n}\n.tk-login-title {\n color: #ffffff;\n font-size: 1.25rem;\n text-align: center;\n margin-top: 10rem;\n}\n.tk-password,\n.tk-login-msg {\n color: #ffffff;\n width: 80%;\n text-align: center;\n margin-top: 1rem;\n}\n.tk-password .el-input__inner {\n min-width: 100px;\n}\n.tk-login-msg a {\n color: #ffffff;\n margin-left: 1em;\n text-decoration: underline;\n}\n.tk-regist-button {\n margin-top: 1rem;\n}\n.tk-panel {\n color: #ffffff;\n padding: 2rem;\n}\n.tk-panel-title {\n font-size: 1.5rem;\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n}\n.tk-panel-logout {\n color: #ffffff;\n font-size: 1rem;\n text-decoration: underline;\n}\n.tk-panel .tk-tabs {\n display: flex;\n margin-bottom: 1em;\n border-bottom: 2px solid #c0c4cc;\n}\n.tk-panel .tk-tab {\n color: #c0c4cc;\n cursor: pointer;\n line-height: 2em;\n margin-right: 2em;\n margin-bottom: -2px;\n}\n.tk-panel .tk-tab.__active {\n color: #ffffff;\n border-bottom: 2px solid #ffffff;\n}\n",""]),t["default"]=a},3301:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-admin-comment {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n.tk-admin-comment a {\n color: currentColor;\n text-decoration: underline;\n}\n.tk-admin-warn {\n margin-bottom: 1em;\n}\n.tk-admin-comment-filter {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: flex-start;\n}\n.tk-admin-comment-filter-keyword {\n flex: 1;\n}\n.tk-admin-comment-filter-type {\n height: 32px;\n margin: 0 0.5em;\n padding: 0 0.5em;\n color: #ffffff;\n background: none;\n border: 1px solid rgba(144,147,153,0.31);\n border-radius: 4px;\n position: relative;\n -moz-appearance: none;\n -webkit-appearance: none;\n}\n.tk-admin-comment-filter-type:focus {\n border-color: #409eff;\n}\n.tk-admin-comment-filter-type option {\n color: initial;\n}\n.tk-admin-comment-list {\n margin-top: 1em;\n}\n.tk-admin-comment-list,\n.tk-admin-comment-item {\n width: 100%;\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n}\n.tk-admin-comment-meta {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n margin-bottom: 0.5em;\n}\n.tk-admin-comment .tk-avatar {\n margin-right: 0.5em;\n}\n.tk-admin-comment .tk-content {\n max-height: none;\n}\n.tk-admin-actions {\n display: flex;\n margin-bottom: 1em;\n border-bottom: 1px solid rgba(255,255,255,0.5);\n}\n",""]),t["default"]=a},6384:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-admin-config-groups {\n overflow-y: auto;\n padding-right: 0.5em;\n}\n.tk-admin-config-groups .tk-admin-config-group,\n.tk-admin-config-groups .tk-admin-config-group-title {\n background: transparent;\n}\n.tk-admin-config-group-title {\n margin-top: 1em;\n font-size: 1.25rem;\n font-weight: bold;\n}\n.tk-admin-config-item {\n display: grid;\n align-items: center;\n grid-template-columns: 30% 70%;\n margin-top: 1em;\n}\n.tk-admin-config-title {\n text-align: right;\n margin-right: 1em;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.tk-admin-config-desc {\n margin-top: 0.5em;\n font-size: 0.75em;\n overflow-wrap: break-word;\n}\n.tk-admin-config-actions {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-top: 1em;\n}\n.tk-admin-config-message {\n margin-top: 0.5em;\n text-align: center;\n}\n.tk-admin-config-email-test-desc {\n margin: 1em 0;\n}\n",""]),t["default"]=a},8120:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-admin-import {\n display: flex;\n flex-direction: column;\n}\n.tk-admin-import-label {\n margin-top: 1em;\n font-size: 1.25rem;\n font-weight: bold;\n}\n.tk-admin-import select,\n.tk-admin-import input,\n.tk-admin-import .el-button,\n.tk-admin-import .el-textarea {\n margin-top: 1em;\n}\n",""]),t["default"]=a},269:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-avatar {\n flex-shrink: 0;\n height: 2.5rem;\n width: 2.5rem;\n overflow: hidden;\n text-align: center;\n border-radius: 5px;\n margin-right: 1rem;\n}\n.tk-comment .tk-submit .tk-avatar,\n.tk-replies .tk-avatar {\n height: 1.6rem;\n width: 1.6rem;\n}\n.tk-avatar.tk-has-avatar {\n background-color: rgba(144,147,153,0.13);\n}\n.tk-avatar.tk-clickable {\n cursor: pointer;\n}\n.tk-avatar .tk-avatar-img {\n height: 2.5rem;\n color: #c0c4cc;\n}\n.tk-comment .tk-submit .tk-avatar .tk-avatar-img,\n.tk-replies .tk-avatar .tk-avatar-img {\n height: 1.6rem;\n}\n",""]),t["default"]=a},510:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-main {\n flex: 1;\n width: 0;\n}\n.tk-row {\n flex: 1;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n}\n.tk-nick-link {\n color: inherit;\n text-decoration: none;\n}\n.tk-replies .tk-nick-link {\n font-size: .9em;\n}\n.tk-nick-link:hover {\n color: #409eff;\n}\n.tk-actions {\n display: none;\n margin-left: 1em;\n}\n.tk-comment:hover .tk-actions {\n display: inline;\n}\n.tk-extras {\n color: #999999;\n font-size: 0.875em;\n display: flex;\n flex-wrap: wrap;\n}\n.tk-extra {\n margin-top: 0.5rem;\n margin-right: 0.75rem;\n display: flex;\n align-items: center;\n}\n.tk-icon.__comment {\n height: 1em;\n width: 1em;\n line-height: 1;\n}\n.tk-extra-text {\n line-height: 1;\n}\n.tk-tag {\n display: inline-block;\n padding: 0 0.5em;\n font-size: 0.75em;\n background-color: #f2f6fc;\n}\n.tk-tag-green {\n background-color: rgba(103,194,58,0.13);\n border: 1px solid rgba(103,194,58,0.50);\n border-radius: 2px;\n color: #67c23a;\n}\n.tk-tag-yellow {\n background-color: rgba(230,162,60,0.13);\n border: 1px solid rgba(230,162,60,0.50);\n border-radius: 2px;\n color: #e6a23c;\n}\n.tk-tag-blue {\n background-color: rgba(64,158,255,0.13);\n border: 1px solid rgba(64,158,255,0.50);\n border-radius: 2px;\n color: #409eff;\n}\n.tk-tag-red {\n background-color: rgba(245,108,108,0.13);\n border: 1px solid rgba(245,108,108,0.50);\n border-radius: 2px;\n color: #f56c6c;\n}\n.tk-comment {\n margin-top: 1rem;\n display: flex;\n flex-direction: row;\n word-break: break-all;\n}\n.tk-content {\n margin-top: 0.5rem;\n overflow: hidden;\n max-height: 500px;\n position: relative;\n}\n.tk-content-expand {\n max-height: none;\n}\n.tk-replies .tk-content {\n font-size: .9em;\n}\n.tk-comment .vemoji {\n max-height: 2em;\n vertical-align: middle;\n}\n.tk-replies {\n max-height: 200px;\n overflow: hidden;\n position: relative;\n}\n.tk-replies-expand {\n max-height: none;\n overflow: unset;\n}\n.tk-submit {\n margin-top: 1rem;\n}\n.tk-expand {\n font-size: 0.75em;\n}\n.tk-lightbox {\n display: block;\n position: fixed;\n background-color: rgba(0, 0, 0, 0.3);\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n}\n.tk-lightbox-image {\n min-width: 100px;\n min-height: 30px;\n width: auto;\n height: auto;\n max-width: 95%;\n max-height: 95%;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: linear-gradient(90deg, #eeeeee 50%, #e3e3e3 0);\n background-size: 40px 100%;\n}\n",""]),t["default"]=a},3650:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-comments-title {\n font-size: 1.25rem;\n font-weight: bold;\n margin-bottom: 1rem;\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n}\n.tk-comments-count.__hidden {\n visibility: hidden;\n}\n.tk-comments-container {\n min-height: 10rem;\n display: flex;\n flex-direction: column;\n}\n.tk-comments-no {\n flex: 1;\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.tk-comments-error {\n font-size: 0.75em;\n color: #ff0000;\n}\n.tk-icon.__comments {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n vertical-align: sub;\n margin-left: 0.5em;\n height: 0.75em;\n width: 0.75em;\n line-height: 0;\n cursor: pointer;\n color: #409eff;\n}\n.twikoo div.code-toolbar {\n position: relative;\n border-radius: .3em\n}\n.twikoo div.code-toolbar>.toolbar {\n position: absolute;\n right: 4px;\n top: 4px;\n font-size: .8125rem;\n font-weight: 500;\n display: flex;\n}\n.twikoo div.code-toolbar>.toolbar>.toolbar-item {\n margin-left: .3em\n}\n.twikoo div.code-toolbar>.toolbar>.toolbar-item>a,\n.twikoo div.code-toolbar>.toolbar>.toolbar-item>button,\n.twikoo div.code-toolbar>.toolbar>.toolbar-item>span {\n padding: 2px 4px;\n border-radius: .3em;\n}\n.twikoo div.code-toolbar>.toolbar>.toolbar-item>button {\n border: 1px solid rgba(128, 128, 128, 0.31);\n}\n.twikoo div.code-toolbar>.toolbar>.toolbar-item>button:hover {\n cursor: pointer;\n}\n",""]),t["default"]=a},8440:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-footer {\n width: 100%;\n text-align: end;\n font-size: 0.75em;\n color: #999999;\n margin-top: 1em;\n}\n",""]),t["default"]=a},7618:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-meta-input {\n display: flex;\n}\n.tk-meta-input .el-input {\n width: auto;\n width: calc((100% - 1rem) / 3); /* Fix Safari */\n flex: 1;\n}\n.tk-meta-input .el-input + .el-input {\n margin-left: 0.5rem;\n}\n.tk-meta-input .el-input .el-input-group__prepend {\n padding: 0 1rem;\n}\n.tk-meta-input .el-input input:invalid {\n border: 1px solid #f56c6c;\n box-shadow: none;\n}\n@media screen and (max-width: 767px) {\n.tk-meta-input {\n flex-direction: column;\n}\n.tk-meta-input .el-input {\n width: auto;\n}\n.tk-meta-input .el-input + .el-input {\n margin-left: 0;\n margin-top: 0.5rem;\n}\n}\n",""]),t["default"]=a},6785:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-pagination,\n.tk-pagination-pagers {\n display: flex;\n}\n.tk-pagination {\n width: 100%;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n}\n.tk-pagination-options {\n display: flex;\n align-items: center;\n}\n.tk-pagination-pager {\n width: 2em;\n height: 2em;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n}\n.tk-pagination-pager.__current {\n background-color: #409eff;\n pointer-events: none;\n}\n.tk-pagination .el-input {\n width: 50px;\n}\n.tk-pagination .el-input .el-input__inner {\n padding: 0;\n height: 28px;\n text-align: center;\n -moz-appearance: textfield;\n appearance: textfield;\n}\n.tk-pagination .el-input .el-input__inner::-webkit-inner-spin-button,\n.tk-pagination .el-input .el-input__inner::-webkit-outer-spin-button {\n -webkit-appearance: none;\n appearance: none;\n margin: 0;\n}\n",""]),t["default"]=a},7786:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,"\n.tk-submit {\n display: flex;\n flex-direction: column;\n}\n.tk-row {\n display: flex;\n flex-direction: row;\n}\n.tk-col {\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n.tk-meta-input {\n margin-bottom: 0.5rem;\n}\n.tk-row.actions {\n position: relative;\n margin-top: 1rem;\n margin-bottom: 1rem;\n margin-left: 3.5rem;\n align-items: center;\n justify-content: flex-end;\n}\n.tk-row-actions-start {\n flex: 1;\n display: flex;\n align-items: center;\n}\n.tk-submit-action-icon {\n align-self: center;\n display: inline-block;\n width: 1.25em;\n line-height: 0;\n margin-right: 10px;\n cursor: pointer;\n flex-shrink: 0;\n}\n.tk-submit-action-icon svg:hover {\n opacity: 0.8;\n}\n.tk-submit-action-icon.__markdown {\n color: #909399;\n}\n.tk-error-message {\n word-break: break-all;\n color: #ff0000;\n font-size: 0.75em;\n flex-shrink: 1;\n}\n.tk-input-image {\n display: none;\n}\n.tk-input {\n flex: 1;\n}\n.tk-input .el-textarea__inner {\n background-position: right bottom;\n background-repeat: no-repeat;\n}\n.tk-turnstile-container {\n position: absolute;\n right: 0;\n bottom: -75px;\n z-index: 1;\n}\n.tk-turnstile {\n display: flex;\n flex-direction: column;\n}\n.tk-preview-container {\n margin-left: 3rem;\n margin-bottom: 1rem;\n padding: 5px 15px;\n border: 1px solid rgba(128,128,128,0.31);\n border-radius: 4px;\n word-break: break-word;\n}\n.tk-fade-in {\n animation: tkFadeIn .3s;\n}\n@keyframes tkFadeIn {\n0% {\n opacity: 0\n}\nto {\n opacity: 1\n}\n}\n",""]),t["default"]=a},6810:function(e,t,n){"use strict";n.r(t);var r=n(5346),i=n.n(r),o=n(9067),a=n.n(o)()(i());a.push([e.id,'/*!\n * OwO v1.0.2\n * Source: https://github.com/DIYgod/OwO/blob/master/dist/OwO.min.css\n * Author: DIYgod\n * Modified by: iMaeGoo\n * Released under the MIT License.\n */\n\n.OwO {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.OwO.OwO-open .OwO-body {\n display: block;\n}\n\n.OwO .OwO-logo {\n width: 1.125em;\n display: flex;\n}\n\n.OwO .OwO-body {\n display: none;\n position: absolute;\n left: 0;\n right: 0;\n max-width: 500px;\n color: #4a4a4a;\n background-color: #ffffff;\n border: 1px solid rgba(144,147,153,0.31);\n top: 2em;\n border-radius: 0 4px 4px;\n z-index: 1000;\n}\n\n.night .OwO .OwO-body,\n.darkmode .OwO .OwO-body,\n.DarkMode .OwO .OwO-body,\n[data-theme="dark"] .OwO .OwO-body,\n[data-user-color-scheme="dark"] .OwO .OwO-body {\n color: #ffffff;\n background-color: #4a4a4a;\n}\n\n.OwO .OwO-body .OwO-items {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n display: none;\n padding: 10px;\n padding-right: 0;\n margin: 0;\n overflow: auto;\n font-size: 0;\n}\n\n.OwO .OwO-body .OwO-items .OwO-item {\n list-style-type: none;\n padding: 5px 10px;\n border-radius: 5px;\n display: inline-block;\n font-size: 12px;\n line-height: 14px;\n cursor: pointer;\n -webkit-transition: .3s;\n transition: .3s;\n text-align: center;\n}\n\n.OwO .OwO-body .OwO-items .OwO-item:hover {\n background-color: rgba(144,147,153,0.13);\n box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);\n}\n\n.OwO .OwO-body .OwO-items-emoji .OwO-item {\n font-size: 20px;\n line-height: 19px;\n}\n\n.OwO .OwO-body .OwO-items-image .OwO-item {\n width: 14%;\n box-sizing: border-box;\n}\n\n@media screen and (max-width: 600px) {\n #twikoo .OwO-items > .OwO-item {\n width: 16%;\n }\n}\n\n@media screen and (max-width: 460px) {\n #twikoo .OwO-items > .OwO-item {\n width: 20%;\n }\n}\n\n@media screen and (max-width: 400px) {\n #twikoo .OwO-items > .OwO-item {\n width: 25%;\n }\n}\n\n@media screen and (max-width: 330px) {\n #twikoo .OwO-items > .OwO-item {\n width: 33%;\n }\n}\n\n\n.OwO .OwO-body .OwO-items-image .OwO-item img {\n max-width: 100%;\n}\n\n.OwO .OwO-body .OwO-items-show {\n display: block;\n}\n\n.OwO .OwO-body .OwO-bar {\n width: 100%;\n border-top: 1px solid rgba(144,147,153,0.31);\n border-radius: 0 0 4px 4px;\n}\n\n.OwO .OwO-body .OwO-bar .OwO-packages {\n margin: 0;\n padding: 0;\n font-size: 0;\n}\n\n.OwO .OwO-body .OwO-bar .OwO-packages li {\n list-style-type: none;\n display: inline-block;\n line-height: 30px;\n font-size: 14px;\n padding: 0 10px;\n cursor: pointer;\n margin-right: 3px;\n}\n\n.OwO .OwO-body .OwO-bar .OwO-packages li:nth-child(1) {\n border-radius: 0 0 0 3px;\n}\n\n.OwO .OwO-body .OwO-bar .OwO-packages li:hover {\n background-color: rgba(144,147,153,0.13);\n}\n\n.OwO .OwO-body .OwO-bar .OwO-packages .OwO-package-active {\n background-color: rgba(144,147,153,0.13);\n -webkit-transition: .3s;\n transition: .3s;\n}\n',""]),t["default"]=a},6937:function(e){e.exports=''},9396:function(e){e.exports=''},58:function(e){e.exports=''},7051:function(e){e.exports=''},8443:function(e){e.exports=''},3793:function(e){e.exports=''},8974:function(e){e.exports=''},1423:function(e){e.exports=''},740:function(e){e.exports=''},7397:function(e){e.exports=''},2531:function(e){e.exports=''},3491:function(e){e.exports=''},5171:function(e){e.exports=''},6639:function(e){e.exports=''},6359:function(e){e.exports=''},9039:function(e){e.exports=''},504:function(e){e.exports=''},6370:function(e){e.exports=''},3982:function(e){e.exports=''},9966:function(e){e.exports=''},5910:function(e){e.exports=''},9671:function(e){e.exports=''},9587:function(e){e.exports=''},6768:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(1573),i=n(8926),o=i.A,a=(n(1288),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},7454:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(8114),i=n(3397),o=i.A,a=(n(2929),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},2053:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(4576),i=n(4238),o=i.A,a=(n(4797),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},8559:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(3227),i=n(4555),o=i.A,a=(n(7908),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},1140:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(74),i=n(4868),o=i.A,a=(n(7891),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},9097:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(9976),i=n(3396),o=i.A,a=(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports},9985:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(872),i=n(9865),o=i.A,a=(n(8087),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},4785:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(5897),i=n(4064),o=i.A,a=(n(4624),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},9078:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(3072),i=n(3572),o=i.A,a=(n(5489),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},8323:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(2048),i=n(4333),o=i.A,a=(n(3111),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},1452:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(2080),i=n(418),o=i.A,a=(n(3457),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},3415:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(1412),i=n(2362),o=i.A,a=(n(2418),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},6431:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(8675),i=n(9171),o=i.A,a=(n(292),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},5438:function(e,t,n){"use strict";n.r(t),n.d(t,{__esModule:function(){return i.B},"default":function(){return a}});var r=n(9564),i=n(147),o=i.A,a=(n(5107),(0,n(4486).A)(o,r.XX,r.Yp,!1,null,null,null).exports)},4486:function(e,t,n){"use strict";function r(e,t,n,r,i,o,a,s){var u,c="function"==typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),r&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(u=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),i&&i.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=u):i&&(u=s?function(){i.call(this,(c.functional?this.parent:this).$root.$options.shadowRoot)}:i),u)if(c.functional){c._injectStyles=u;var l=c.render;c.render=function(e,t){return u.call(t),l(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,u):[u]}return{exports:e,options:c}}n.d(t,{A:function(){return r}})},622:function(e,t,n){var r=n(3723);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("0e5ef982",r,!0,{})},8848:function(e,t,n){var r=n(1315);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("1a92f302",r,!0,{})},6756:function(e,t,n){var r=n(9211);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("e6b19834",r,!0,{})},1288:function(e,t,n){var r=n(9737);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("5049e71b",r,!0,{})},2929:function(e,t,n){var r=n(6640);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("2e97bedb",r,!0,{})},4797:function(e,t,n){var r=n(3514);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("a49b0590",r,!0,{})},7908:function(e,t,n){var r=n(3301);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("1287f7b8",r,!0,{})},7891:function(e,t,n){var r=n(6384);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("6a83638c",r,!0,{})},8087:function(e,t,n){var r=n(8120);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("59ad6a1e",r,!0,{})},4624:function(e,t,n){var r=n(269);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("5a1fa943",r,!0,{})},5489:function(e,t,n){var r=n(510);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("04e4e82c",r,!0,{})},3111:function(e,t,n){var r=n(3650);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("5dbb03ca",r,!0,{})},3457:function(e,t,n){var r=n(8440);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("042e8a68",r,!0,{})},2418:function(e,t,n){var r=n(7618);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("59ca4f90",r,!0,{})},292:function(e,t,n){var r=n(6785);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("88983344",r,!0,{})},5107:function(e,t,n){var r=n(7786);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("cfea80b2",r,!0,{})},4707:function(e,t,n){var r=n(6810);r.__esModule&&(r=r["default"]),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(5083).A)("8be46386",r,!0,{})},5083:function(e,t,n){"use strict";n.d(t,{A:function(){return h}});var r=n(5547),i="undefined"!=typeof document;if("undefined"!=typeof DEBUG&&DEBUG&&!i)throw new Error("vue-style-loader cannot be used in a non-browser environment. Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.");var o={},a=i&&(document.head||document.getElementsByTagName("head")[0]),s=null,u=0,c=!1,l=function(){},d=null,f="data-vue-ssr-id",p="undefined"!=typeof navigator&&/msie [6-9]\b/.test(navigator.userAgent.toLowerCase());function h(e,t,n,i){c=n,d=i||{};var a=(0,r.A)(e,t);return m(a),function(t){for(var n=[],i=0;in.parts.length&&(r.parts.length=n.parts.length)}else{var a=[];for(i=0;ie.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0;--i){var o=this.tryEntries[i],s=o.completion;if("root"===o.tryLoc)return r("end");if(o.tryLoc<=this.prev){var u=a.call(o,"catchLoc"),c=a.call(o,"finallyLoc");if(u&&c){if(this.prev=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&a.call(r,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),M(n),y}},"catch":function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var i=r.arg;M(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,r){return this.delegate={iterator:P(e),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=t),y}},n}e.exports=i,e.exports.__esModule=!0,e.exports["default"]=e.exports},9272:function(e,t,n){"use strict";var r=n(8554),i=n(4805),o=n(2075),a=n(2971);e.exports=function(e,t){return r(e)||i(e,t)||o(e,t)||a()},e.exports.__esModule=!0,e.exports["default"]=e.exports},1819:function(e,t,n){"use strict";var r=n(8198),i=n(6884),o=n(2075),a=n(5838);e.exports=function(e){return r(e)||i(e)||o(e)||a()},e.exports.__esModule=!0,e.exports["default"]=e.exports},7278:function(e,t,n){"use strict";var r=n(9367)["default"];e.exports=function(e,t){if("object"!=r(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var i=n.call(e,t||"default");if("object"!=r(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)},e.exports.__esModule=!0,e.exports["default"]=e.exports},3987:function(e,t,n){"use strict";var r=n(9367)["default"],i=n(7278);e.exports=function(e){var t=i(e,"string");return"symbol"==r(t)?t:String(t)},e.exports.__esModule=!0,e.exports["default"]=e.exports},9367:function(e){"use strict";function t(n){return e.exports=t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.__esModule=!0,e.exports["default"]=e.exports,t(n)}e.exports=t,e.exports.__esModule=!0,e.exports["default"]=e.exports},2075:function(e,t,n){"use strict";var r=n(6530);e.exports=function(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}},e.exports.__esModule=!0,e.exports["default"]=e.exports},479:function(e,t,n){"use strict";var r=n(477)(n(9367)),i=n(7120)();e.exports=i;try{regeneratorRuntime=i}catch(o){"object"===("undefined"==typeof globalThis?"undefined":(0,r["default"])(globalThis))?globalThis.regeneratorRuntime=i:Function("r","regeneratorRuntime = r")(i)}},5707:function(e){"use strict";e.exports=JSON.parse('{"name":"@cloudbase/js-sdk","version":"1.7.2","description":"cloudbase javascript sdk","main":"dist/index.cjs.js","module":"dist/index.esm.js","miniprogram":"miniprogram_dist","typings":"./index.d.ts","scripts":{"lint":"eslint --fix \\"./src/**/*.ts\\" \\"./database/**/*.ts\\"","build":"rm -rf dist/ && gulp build","build:cdn":"gulp cdn","build:miniapp":"gulp miniapp","build:e2e":"rm -rf dist/ && NODE_ENV=e2e gulp e2e"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"https://github.com/TencentCloudBase/cloudbase-js-sdk"},"keywords":["tcb","cloudbase","Cloudbase","serverless","Serverless","javascript","JavaScript"],"files":["miniprogram_dist","**/dist/","/index.d.ts","**/package.json"],"components":["app","auth","database","functions","storage"],"author":"","license":"ISC","dependencies":{"@cloudbase/analytics":"^1.1.1-alpha.0","@cloudbase/app":"^1.4.1","@cloudbase/auth":"^1.6.1","@cloudbase/database":"0.9.18-next","@cloudbase/functions":"^1.3.4","@cloudbase/realtime":"^1.1.4-alpha.0","@cloudbase/storage":"^1.3.4","@cloudbase/types":"^1.1.3-alpha.0","@cloudbase/utilities":"^1.3.4"},"devDependencies":{"@babel/core":"^7.9.0","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-transform-runtime":"^7.9.0","@babel/preset-env":"^7.9.5","@babel/preset-typescript":"^7.9.0","@typescript-eslint/eslint-plugin":"^3.8.0","@typescript-eslint/parser":"^3.8.0","awesome-typescript-loader":"^5.2.1","babel-loader":"^8.1.0","eslint":"^7.6.0","eslint-config-alloy":"^3.7.4","gulp":"^4.0.2","gulp-clean":"^0.4.0","gulp-rename":"^2.0.0","gulp-sourcemaps":"^2.6.5","gulp-typescript":"^6.0.0-alpha.1","json-loader":"^0.5.7","merge-stream":"^2.0.0","package-json-cleanup-loader":"^1.0.3","typescript":"^3.8.3","webpack":"4.41.3","webpack-cli":"^3.3.11","webpack-node-externals":"^1.7.2","webpack-stream":"^5.2.1","webpack-visualizer-plugin":"^0.1.11"},"browserslist":["last 2 version","> 1%","not dead","chrome 53"],"gitHead":"29ca0bf24318daa1fbb230910edf0b1545e17e7f"}')}},t={};function n(r){var i=t[r];if(i!==undefined)return i.exports;var o=t[r]={id:r,loaded:!1,exports:{}};return e[r](o,o.exports,n),o.loaded=!0,o.exports}n.amdO={},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.nmd=function(e){return e.paths=[],e.children||(e.children=[]),e};var r={};return function(){"use strict";var e=r,t=n(477);Object.defineProperty(e,"__esModule",{value:!0}),e["default"]=void 0,e.getCommentsCount=function(){return m.apply(this,arguments)},e.getRecentComments=function(){return g.apply(this,arguments)},e.init=p,Object.defineProperty(e,"version",{enumerable:!0,get:function(){return a.version}});var i=t(n(479)),o=t(n(4964)),a=n(2199),s=n(824),u=n(1085),c=n(8129),l=t(n(9459));function d(e){return f.apply(this,arguments)}function f(){return(f=(0,o["default"])(i["default"].mark((function e(t){return i["default"].wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,(0,s.install)(l["default"],t);case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function p(){return h.apply(this,arguments)}function h(){return h=(0,o["default"])(i["default"].mark((function e(){var t,n,r=arguments;return i["default"].wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t=r.length>0&&r[0]!==undefined?r[0]:{},!(0,c.isUrl)(t.envId)){e.next=5;break}e.t0=null,e.next=8;break;case 5:return e.next=7,d(t);case 7:e.t0=e.sent;case 8:n=e.t0,(0,c.setLanguage)(t),(0,u.render)(n,t);case 11:case"end":return e.stop()}}),e)}))),h.apply(this,arguments)}function m(){return m=(0,o["default"])(i["default"].mark((function e(){var t,n,r=arguments;return i["default"].wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t=r.length>0&&r[0]!==undefined?r[0]:{},!(0,c.isUrl)(t.envId)){e.next=5;break}e.t0=null,e.next=8;break;case 5:return e.next=7,d(t);case 7:e.t0=e.sent;case 8:return n=e.t0,e.next=11,(0,c.getCommentsCountApi)(n,t);case 11:return e.abrupt("return",e.sent);case 12:case"end":return e.stop()}}),e)}))),m.apply(this,arguments)}function g(){return g=(0,o["default"])(i["default"].mark((function e(){var t,n,r=arguments;return i["default"].wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t=r.length>0&&r[0]!==undefined?r[0]:{},!(0,c.isUrl)(t.envId)){e.next=5;break}e.t0=null,e.next=8;break;case 5:return e.next=7,d(t);case 7:e.t0=e.sent;case 8:return n=e.t0,e.next=11,(0,c.getRecentCommentsApi)(n,t);case 11:return e.abrupt("return",e.sent);case 12:case"end":return e.stop()}}),e)}))),g.apply(this,arguments)}n(9744),n(7441),n(5417),e["default"]=p}(),r}()},"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.twikoo=t():e.twikoo=t(); \ No newline at end of file diff --git a/website/blog/assets/mobile-banner/1.webp b/website/blog/assets/mobile-banner/1.webp deleted file mode 100644 index b5b903d..0000000 Binary files a/website/blog/assets/mobile-banner/1.webp and /dev/null differ diff --git a/website/blog/assets/mobile-banner/2.webp b/website/blog/assets/mobile-banner/2.webp deleted file mode 100644 index f3f654f..0000000 Binary files a/website/blog/assets/mobile-banner/2.webp and /dev/null differ diff --git a/website/blog/assets/mobile-banner/3.webp b/website/blog/assets/mobile-banner/3.webp deleted file mode 100644 index f7acfa4..0000000 Binary files a/website/blog/assets/mobile-banner/3.webp and /dev/null differ diff --git a/website/blog/assets/mobile-banner/4.webp b/website/blog/assets/mobile-banner/4.webp deleted file mode 100644 index 38b7b12..0000000 Binary files a/website/blog/assets/mobile-banner/4.webp and /dev/null differ diff --git a/website/blog/assets/mobile-banner/5.webp b/website/blog/assets/mobile-banner/5.webp deleted file mode 100644 index 3a4ee2c..0000000 Binary files a/website/blog/assets/mobile-banner/5.webp and /dev/null differ diff --git a/website/blog/assets/mobile-banner/6.webp b/website/blog/assets/mobile-banner/6.webp deleted file mode 100644 index 2e0ed87..0000000 Binary files a/website/blog/assets/mobile-banner/6.webp and /dev/null differ diff --git a/website/blog/assets/music/cover/cl.jpg b/website/blog/assets/music/cover/cl.jpg deleted file mode 100644 index 7dcd96c..0000000 Binary files a/website/blog/assets/music/cover/cl.jpg and /dev/null differ diff --git a/website/blog/assets/music/cover/hitori.jpg b/website/blog/assets/music/cover/hitori.jpg deleted file mode 100644 index 88922c1..0000000 Binary files a/website/blog/assets/music/cover/hitori.jpg and /dev/null differ diff --git a/website/blog/assets/music/cover/xryx.jpg b/website/blog/assets/music/cover/xryx.jpg deleted file mode 100644 index 19e6b15..0000000 Binary files a/website/blog/assets/music/cover/xryx.jpg and /dev/null differ diff --git a/website/blog/assets/music/url/cl.mp3 b/website/blog/assets/music/url/cl.mp3 deleted file mode 100644 index 6884596..0000000 Binary files a/website/blog/assets/music/url/cl.mp3 and /dev/null differ diff --git a/website/blog/assets/music/url/hitori.mp3 b/website/blog/assets/music/url/hitori.mp3 deleted file mode 100644 index 0cd8b09..0000000 Binary files a/website/blog/assets/music/url/hitori.mp3 and /dev/null differ diff --git a/website/blog/assets/music/url/xryx.mp3 b/website/blog/assets/music/url/xryx.mp3 deleted file mode 100644 index 9cdd685..0000000 Binary files a/website/blog/assets/music/url/xryx.mp3 and /dev/null differ diff --git a/website/blog/collections/posts.schema.json b/website/blog/collections/posts.schema.json deleted file mode 100644 index 1950d70..0000000 --- a/website/blog/collections/posts.schema.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "$ref": "#/definitions/posts", - "definitions": { - "posts": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "published": { - "anyOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "string", - "format": "date" - }, - { - "type": "integer", - "format": "unix-time" - } - ] - }, - "updated": { - "anyOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "string", - "format": "date" - }, - { - "type": "integer", - "format": "unix-time" - } - ] - }, - "draft": { - "type": "boolean", - "default": false - }, - "description": { - "type": "string", - "default": "" - }, - "image": { - "type": "string", - "default": "" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - }, - "category": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } - ], - "default": "" - }, - "lang": { - "type": "string", - "default": "" - }, - "pinned": { - "type": "boolean", - "default": false - }, - "author": { - "type": "string", - "default": "" - }, - "sourceLink": { - "type": "string", - "default": "" - }, - "licenseName": { - "type": "string", - "default": "" - }, - "licenseUrl": { - "type": "string", - "default": "" - }, - "prevTitle": { - "type": "string", - "default": "" - }, - "prevSlug": { - "type": "string", - "default": "" - }, - "nextTitle": { - "type": "string", - "default": "" - }, - "nextSlug": { - "type": "string", - "default": "" - }, - "$schema": { - "type": "string" - } - }, - "required": [ - "title", - "published" - ], - "additionalProperties": false - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" -} \ No newline at end of file diff --git a/website/blog/collections/spec.schema.json b/website/blog/collections/spec.schema.json deleted file mode 100644 index 062b0c2..0000000 --- a/website/blog/collections/spec.schema.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$ref": "#/definitions/spec", - "definitions": { - "spec": { - "type": "object", - "properties": { - "$schema": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" -} \ No newline at end of file diff --git a/website/blog/content-assets.mjs b/website/blog/content-assets.mjs deleted file mode 100644 index 2b8b823..0000000 --- a/website/blog/content-assets.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/website/blog/content-modules.mjs b/website/blog/content-modules.mjs deleted file mode 100644 index 2b8b823..0000000 --- a/website/blog/content-modules.mjs +++ /dev/null @@ -1 +0,0 @@ -export default new Map(); \ No newline at end of file diff --git a/website/blog/diary/index.html b/website/blog/diary/index.html deleted file mode 100644 index b47ab3a..0000000 --- a/website/blog/diary/index.html +++ /dev/null @@ -1,722 +0,0 @@ - 日记 - FutureOSS Docs - - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video

    日记

    随时随地,分享生活

    1 条短文

    樱花下落速度的每秒五厘米!

    图片
    图片

    🕐 450天前
    只展示最近30条日记
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/favicon/favicon-dark-128.png b/website/blog/favicon/favicon-dark-128.png deleted file mode 100644 index 7422ce8..0000000 Binary files a/website/blog/favicon/favicon-dark-128.png and /dev/null differ diff --git a/website/blog/favicon/favicon-dark-180.png b/website/blog/favicon/favicon-dark-180.png deleted file mode 100644 index de0f89b..0000000 Binary files a/website/blog/favicon/favicon-dark-180.png and /dev/null differ diff --git a/website/blog/favicon/favicon-dark-192.png b/website/blog/favicon/favicon-dark-192.png deleted file mode 100644 index e8d4a2d..0000000 Binary files a/website/blog/favicon/favicon-dark-192.png and /dev/null differ diff --git a/website/blog/favicon/favicon-dark-32.png b/website/blog/favicon/favicon-dark-32.png deleted file mode 100644 index fce9b80..0000000 Binary files a/website/blog/favicon/favicon-dark-32.png and /dev/null differ diff --git a/website/blog/favicon/favicon-light-128.png b/website/blog/favicon/favicon-light-128.png deleted file mode 100644 index 83dc7c7..0000000 Binary files a/website/blog/favicon/favicon-light-128.png and /dev/null differ diff --git a/website/blog/favicon/favicon-light-180.png b/website/blog/favicon/favicon-light-180.png deleted file mode 100644 index bbb666b..0000000 Binary files a/website/blog/favicon/favicon-light-180.png and /dev/null differ diff --git a/website/blog/favicon/favicon-light-192.png b/website/blog/favicon/favicon-light-192.png deleted file mode 100644 index 2853594..0000000 Binary files a/website/blog/favicon/favicon-light-192.png and /dev/null differ diff --git a/website/blog/favicon/favicon-light-32.png b/website/blog/favicon/favicon-light-32.png deleted file mode 100644 index 327ee0b..0000000 Binary files a/website/blog/favicon/favicon-light-32.png and /dev/null differ diff --git a/website/blog/friends/index.html b/website/blog/friends/index.html deleted file mode 100644 index bec5709..0000000 --- a/website/blog/friends/index.html +++ /dev/null @@ -1,729 +0,0 @@ - 友链 - FutureOSS Docs - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video
    站点头像
    Mizuki Docs
    Mizuki User Manual
    -/ -
    - Docs
    站点头像
    Astro
    The web framework for content-driven websites. ⭐️ Star to support our work!
    -/ -
    - Framework
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/gallery/index.html b/website/blog/gallery/index.html deleted file mode 100644 index aaf832d..0000000 --- a/website/blog/gallery/index.html +++ /dev/null @@ -1,726 +0,0 @@ - 相册 - FutureOSS Docs - - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video

    相册

    记录和分享美好瞬间

    1

    8

    3

    Anime

    Anime

    8 张图片

    Anime is a genre of Japanese animation that features vibrant colors, complex characters, and imaginative worlds.

    2025年8月20日
    Anime Character Scene
    Anime - 图片 1
    Anime - 图片 2
    Anime - 图片 3
    Anime - 图片 4
    Anime - 图片 5
    Anime - 图片 6
    Anime - 图片 7
    Anime - 图片 8
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/images/diary/1.jpg b/website/blog/images/diary/1.jpg deleted file mode 100644 index 4e06a40..0000000 Binary files a/website/blog/images/diary/1.jpg and /dev/null differ diff --git a/website/blog/images/diary/sakura.jpg b/website/blog/images/diary/sakura.jpg deleted file mode 100644 index 43dfdb8..0000000 Binary files a/website/blog/images/diary/sakura.jpg and /dev/null differ diff --git a/website/blog/images/gallery/anime/pc/1.jpg b/website/blog/images/gallery/anime/pc/1.jpg deleted file mode 100644 index 23df2f0..0000000 Binary files a/website/blog/images/gallery/anime/pc/1.jpg and /dev/null differ diff --git a/website/blog/images/gallery/anime/pc/2.jpg b/website/blog/images/gallery/anime/pc/2.jpg deleted file mode 100644 index 89e1aa8..0000000 Binary files a/website/blog/images/gallery/anime/pc/2.jpg and /dev/null differ diff --git a/website/blog/images/gallery/anime/pc/3.jpg b/website/blog/images/gallery/anime/pc/3.jpg deleted file mode 100644 index 67a4ca1..0000000 Binary files a/website/blog/images/gallery/anime/pc/3.jpg and /dev/null differ diff --git a/website/blog/images/gallery/anime/pc/4.jpg b/website/blog/images/gallery/anime/pc/4.jpg deleted file mode 100644 index 236ea85..0000000 Binary files a/website/blog/images/gallery/anime/pc/4.jpg and /dev/null differ diff --git a/website/blog/images/gallery/anime/pe/1.webp b/website/blog/images/gallery/anime/pe/1.webp deleted file mode 100644 index b30b588..0000000 Binary files a/website/blog/images/gallery/anime/pe/1.webp and /dev/null differ diff --git a/website/blog/images/gallery/anime/pe/2.jpg b/website/blog/images/gallery/anime/pe/2.jpg deleted file mode 100644 index 7d67216..0000000 Binary files a/website/blog/images/gallery/anime/pe/2.jpg and /dev/null differ diff --git a/website/blog/images/gallery/anime/pe/3.jpg b/website/blog/images/gallery/anime/pe/3.jpg deleted file mode 100644 index 5584297..0000000 Binary files a/website/blog/images/gallery/anime/pe/3.jpg and /dev/null differ diff --git a/website/blog/images/gallery/anime/pe/4.jpg b/website/blog/images/gallery/anime/pe/4.jpg deleted file mode 100644 index b1302d1..0000000 Binary files a/website/blog/images/gallery/anime/pe/4.jpg and /dev/null differ diff --git a/website/blog/index.html b/website/blog/index.html deleted file mode 100644 index 03a33f8..0000000 --- a/website/blog/index.html +++ /dev/null @@ -1,776 +0,0 @@ - FutureOSS Docs - 一切皆为插件的开发者工具运行时框架 - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video
    Markdown Tutorial
    2025-01-20
    Examples
    /
    - Markdown
    /
    - Blogging
    A simple example of a Markdown blog post.
    1700 字
    |
    9 分钟
    Markdown Mermaid
    2023-10-01
    Examples
    /
    - Markdown
    /
    - Blogging
    /
    - Mermaid
    A simple example of a Markdown blog post with Mermaid.
    578 字
    |
    3 分钟
    Markdown Example
    2023-10-01
    Examples
    /
    - Markdown
    /
    - Blogging
    A simple example of a Markdown blog post.
    438 字
    |
    2 分钟
    Include Video in the Posts
    2022-08-01
    Examples
    /
    - Example
    /
    - Video
    This post demonstrates how to include embedded video in a blog post.
    62 字
    |
    1 分钟
    1
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/pagefind/fragment/zh-cn_3c11ccf.pf_fragment b/website/blog/pagefind/fragment/zh-cn_3c11ccf.pf_fragment deleted file mode 100644 index c242ee9..0000000 Binary files a/website/blog/pagefind/fragment/zh-cn_3c11ccf.pf_fragment and /dev/null differ diff --git a/website/blog/pagefind/fragment/zh-cn_78c4e2f.pf_fragment b/website/blog/pagefind/fragment/zh-cn_78c4e2f.pf_fragment deleted file mode 100644 index 2208488..0000000 Binary files a/website/blog/pagefind/fragment/zh-cn_78c4e2f.pf_fragment and /dev/null differ diff --git a/website/blog/pagefind/fragment/zh-cn_837d02c.pf_fragment b/website/blog/pagefind/fragment/zh-cn_837d02c.pf_fragment deleted file mode 100644 index c3d41bc..0000000 Binary files a/website/blog/pagefind/fragment/zh-cn_837d02c.pf_fragment and /dev/null differ diff --git a/website/blog/pagefind/fragment/zh-cn_eb9c87e.pf_fragment b/website/blog/pagefind/fragment/zh-cn_eb9c87e.pf_fragment deleted file mode 100644 index c22ddd4..0000000 Binary files a/website/blog/pagefind/fragment/zh-cn_eb9c87e.pf_fragment and /dev/null differ diff --git a/website/blog/pagefind/fragment/zh-cn_f6428b6.pf_fragment b/website/blog/pagefind/fragment/zh-cn_f6428b6.pf_fragment deleted file mode 100644 index 0ef5689..0000000 Binary files a/website/blog/pagefind/fragment/zh-cn_f6428b6.pf_fragment and /dev/null differ diff --git a/website/blog/pagefind/index/zh-cn_77d216d.pf_index b/website/blog/pagefind/index/zh-cn_77d216d.pf_index deleted file mode 100644 index 3a52621..0000000 Binary files a/website/blog/pagefind/index/zh-cn_77d216d.pf_index and /dev/null differ diff --git a/website/blog/pagefind/pagefind-component-ui.css b/website/blog/pagefind/pagefind-component-ui.css deleted file mode 100644 index 5e9ef59..0000000 --- a/website/blog/pagefind/pagefind-component-ui.css +++ /dev/null @@ -1,1509 +0,0 @@ -/* - * Why all the :is(*, #\#) prefixes? - * - * These components are embedded in who-knows-what sites with unpredictable CSS. - * We need our styles to win against host page selectors like `.content p` or - * `article a:hover` without using !important everywhere. - * - * The :is(*, #\#) trick adds ID-level specificity (0,1,0) without requiring - * an actual ID in the DOM. Chaining it (2x or 3x) builds enough specificity - * to beat most host selectors. - * - * The #\# is an escaped # character, creating an invalid-but-harmless ID - * selector that never matches, but still contributes specificity via :is(). - * - * We also need these overrides to only affect the Component UI elements themselves. - * Users can provide custom templates to the results and searchbox components, - * and these must inherit their styles without having to fight ours. - * - * It's admittedly a bit of a hack but it does provide best effort styling consistency - * for the Component UI out in the wild. - */ - -:root { - --pf-text: #1a1a1a; - --pf-text-secondary: #666; - --pf-text-muted: #767676; - --pf-background: #fff; - --pf-border: #e0e0e0; - --pf-border-focus: #999; - --pf-skeleton: #eee; - --pf-skeleton-shine: #f5f5f5; - --pf-hover: #f5f5f5; - --pf-mark: #1a1a1a; - --pf-scroll-shadow: rgba(0, 0, 0, 0.08); - - --pf-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.06); - --pf-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1); - --pf-shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.2); - - --pf-error-bg: #fef2f2; - --pf-error-border: #fecaca; - --pf-error-text: #dc2626; - --pf-error-text-secondary: #b91c1c; - - --pf-outline-focus: #0969da; - --pf-outline-width: 2px; - --pf-outline-offset: 2px; - - --pf-font: - -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, - sans-serif; - - --pf-input-height: 36px; - --pf-input-font-size: 16px; - --pf-summary-font-size: 12px; - --pf-result-title-font-size: 14px; - --pf-result-excerpt-font-size: 13px; - --pf-modal-backdrop: rgba(0, 0, 0, 0.5); - --pf-results-display: flex; - --pf-results-flex-direction: column; - --pf-results-flex-wrap: nowrap; - --pf-results-columns: none; - --pf-results-gap: 8px; - - --pf-border-radius: 6px; - --pf-image-width: 64px; - --pf-image-height: 48px; - - --pf-icon-search: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A"); - --pf-icon-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23000' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); - - --pf-dropdown-z-index: 9999; - - --pf-modal-max-width: 560px; - --pf-modal-max-height: min(80dvh, 800px); - --pf-modal-top: 10dvh; - - --pf-searchbox-max-width: 480px; - --pf-searchbox-dropdown-max-height: 320px; - - --pf-dropdown-max-height: 280px; -} - -[data-pf-theme="dark"] { - --pf-text: #e5e5e5; - --pf-text-secondary: #a0a0a0; - --pf-text-muted: #949494; - --pf-background: #1a1a1a; - --pf-border: #333; - --pf-border-focus: #555; - --pf-skeleton: #2a2a2a; - --pf-skeleton-shine: #333; - --pf-hover: #252525; - --pf-mark: #e5e5e5; - --pf-scroll-shadow: rgba(255, 255, 255, 0.1); - - --pf-outline-focus: #58a6ff; - - --pf-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); - --pf-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4); - --pf-shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.5); - - --pf-error-bg: #2a1a1a; - --pf-error-border: #5c2828; - --pf-error-text: #f87171; - --pf-error-text-secondary: #ef4444; - - --pf-modal-backdrop: rgba(0, 0, 0, 0.7); -} - -pagefind-config, -pagefind-filter-dropdown, -pagefind-filter-pane, -pagefind-input, -pagefind-keyboard-hints, -pagefind-modal, -pagefind-modal-body, -pagefind-modal-footer, -pagefind-modal-header, -pagefind-modal-trigger, -pagefind-results, -pagefind-searchbox, -pagefind-summary { - all: initial; - display: block; - box-sizing: border-box; - - /* Typography baseline */ - font-family: - var(--pf-font, - system-ui, - -apple-system, - BlinkMacSystemFont, - "Segoe UI", - Roboto, - sans-serif); - font-size: 16px; - line-height: 1.5; - color: CanvasText; - contain: layout style; -} - -pagefind-searchbox, -pagefind-filter-dropdown { - position: relative; -} - -pagefind-searchbox:has(.pf-searchbox.open), -pagefind-filter-dropdown:has(.pf-dropdown-trigger.open) { - z-index: var(--pf-dropdown-z-index); -} - -pagefind-config { - display: none; -} - -pagefind-modal-trigger { - display: inline-block; -} - -:is(*, #\#):is(*, #\#) :is([class^="pf-"], [class*=" pf-"]):not(svg, svg *) { - all: revert; - box-sizing: border-box; -} - -:is(*, #\#):is(*, #\#) :is([class^="pf-"], [class*=" pf-"]):not(svg, svg *)::before, -:is(*, #\#):is(*, #\#) :is([class^="pf-"], [class*=" pf-"]):not(svg, svg *)::after { - box-sizing: border-box; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) [class^="pf-"][hidden], -:is(*, #\#):is(*, #\#):is(*, #\#) [class*=" pf-"][hidden] { - display: none; -} - -[data-pf-hidden] { - display: none !important; -} - -[data-pf-suppressed] { - opacity: 0 !important; - pointer-events: none !important; -} - -[data-pf-sr-hidden] { - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - height: 1px !important; - overflow: hidden !important; - position: absolute !important; - white-space: nowrap !important; - width: 1px !important; -} - -/* -* Suppress native browser outlines. -* This is only okay because we exhaustively -* provide our own high-contrast custom focus styles. -*/ -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-clear:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-clear:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-link:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-link:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-link:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-link:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-checkbox-input:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-checkbox-input:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-btn:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-btn:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-close:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-close:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-options:focus, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-options:focus-visible { - outline: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-clear:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-clear:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-btn:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-close:focus-visible { - outline: var(--pf-outline-width) solid var(--pf-outline-focus); - outline-offset: var(--pf-outline-offset); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-key, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-key, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-footer-key, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-keyboard-key, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-footer-key { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0 4px; - background: var(--pf-hover); - border: 1px solid var(--pf-border); - border-radius: 3px; - font-weight: 500; - color: var(--pf-text-secondary); - font-family: var(--pf-font); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-key--sm, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-footer-key { - min-width: 16px; - height: 16px; - font-size: 9px; - padding: 0 3px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-wrapper { - position: relative; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-wrapper::before, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input-wrapper::before { - content: ""; - position: absolute; - background-color: var(--pf-text-muted); - width: 14px; - height: 14px; - top: calc((var(--pf-input-height) - 14px) / 2); - inset-inline-start: 10px; - -webkit-mask-image: var(--pf-icon-search); - mask-image: var(--pf-icon-search); - -webkit-mask-size: 100%; - mask-size: 100%; - pointer-events: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input-wrapper::before { - z-index: 1; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input { - width: 100%; - height: var(--pf-input-height); - background-color: var(--pf-background); - border: 1px solid var(--pf-border); - border-radius: var(--pf-border-radius); - font-family: var(--pf-font, inherit); - font-size: var(--pf-input-font-size); - color: var(--pf-text); - box-sizing: border-box; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input { - padding: 0; - padding-inline-start: 32px; - padding-inline-end: 36px; - font-weight: 400; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input:focus-visible, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input:focus-visible { - border-color: var(--pf-outline-focus); - box-shadow: 0 0 0 var(--pf-outline-width) var(--pf-outline-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input::placeholder, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input::placeholder { - color: var(--pf-text-muted); -} - -/* Hide native search clear button - we have our own */ -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input::-webkit-search-decoration, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input::-webkit-search-cancel-button, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input::-webkit-search-results-button, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input::-webkit-search-results-decoration { - display: none; - appearance: none; - -webkit-appearance: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-clear { - position: absolute; - inset-inline-end: 2px; - top: 50%; - transform: translateY(-50%); - height: calc(100% - 4px); - min-width: 44px; - padding: 0 8px; - background: none; - border: none; - font-size: 12px; - color: var(--pf-text-muted); - cursor: pointer; - border-radius: 4px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-clear:hover { - background: var(--pf-hover); - color: var(--pf-text-secondary); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-clear[data-pf-suppressed] { - display: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-summary { - font-size: var(--pf-summary-font-size); - color: var(--pf-text-muted); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-results { - list-style: none; - padding: 0; - margin: 0; - display: var(--pf-results-display); - flex-direction: var(--pf-results-flex-direction); - flex-wrap: var(--pf-results-flex-wrap); - grid-template-columns: var(--pf-results-columns); - gap: var(--pf-results-gap); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result { - display: flex; - flex-direction: column; - gap: 8px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-card { - position: relative; - display: flex; - gap: 12px; - padding: 12px; - background: var(--pf-background); - border: 1px solid var(--pf-border); - border-radius: var(--pf-border-radius); - transition: - border-color 0.15s, - box-shadow 0.15s; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-card:hover { - border-color: var(--pf-border-focus); - box-shadow: var(--pf-shadow-sm); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-result-card:has(.pf-result-link:focus-visible) { - border-color: var(--pf-outline-focus); - box-shadow: 0 0 0 var(--pf-outline-width) var(--pf-outline-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-card:has([data-pf-selected]) { - border-color: var(--pf-border-focus); - background: var(--pf-hover); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-image { - width: var(--pf-image-width); - height: var(--pf-image-height); - border-radius: 4px; - object-fit: cover; - background: var(--pf-skeleton); - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-content { - flex: 1; - min-width: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-title { - font-size: var(--pf-result-title-font-size); - font-weight: 500; - margin: 0; - line-height: 1.4; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-link { - color: var(--pf-text); - text-decoration: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-link::after { - content: ""; - position: absolute; - inset: 0; - border-radius: inherit; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-link:hover { - text-decoration: underline; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-excerpt { - font-size: var(--pf-result-excerpt-font-size); - color: var(--pf-text-secondary); - margin: 4px 0 0 0; - line-height: 1.5; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-result-excerpt mark, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-excerpt mark, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result-excerpt mark { - background: transparent; - font-weight: 500; - color: var(--pf-mark); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-skeleton { - background: var(--pf-skeleton); - border-radius: 4px; -} - -@media (prefers-reduced-motion: no-preference) { - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-skeleton { - background: linear-gradient( - 90deg, - var(--pf-skeleton) 25%, - var(--pf-skeleton-shine) 50%, - var(--pf-skeleton) 75% - ); - background-size: 200% 100%; - animation: pf-shimmer 1.5s infinite; - } - - @keyframes pf-shimmer { - 0% { - background-position: 200% 0; - } - 100% { - background-position: -200% 0; - } - } -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-skeleton-title { - height: 14px; - width: 60%; - margin-bottom: 8px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-skeleton-excerpt { - height: 13px; - width: 90%; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-skeleton-image { - width: var(--pf-image-width); - height: var(--pf-image-height); - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-empty { - text-align: center; - padding: 32px 16px; - color: var(--pf-text-muted); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-empty-icon { - font-size: 24px; - margin-bottom: 8px; - opacity: 0.4; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-empty-text { - font-size: 14px; - margin: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-error { - padding: 12px 16px; - background: var(--pf-error-bg); - border: 1px solid var(--pf-error-border); - border-radius: var(--pf-border-radius); - color: var(--pf-error-text); - font-size: 13px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-error strong { - font-weight: 600; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-error small { - display: block; - margin-top: 4px; - color: var(--pf-error-text-secondary); - font-size: 12px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-chips { - display: flex; - flex-direction: column; - gap: 6px; - margin: 0; - padding: 0; - padding-inline-start: 12px; - list-style: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-chip { - display: inline-flex; - flex-direction: column; - gap: 2px; - padding: 8px 10px; - background: var(--pf-background); - border: 1px solid var(--pf-border); - border-radius: 6px; - font-size: 12px; - transition: - border-color 0.15s, - box-shadow 0.15s; - position: relative; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-chip:hover { - border-color: var(--pf-border-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-heading-chip:has(.pf-heading-link:focus-visible) { - border-color: var(--pf-outline-focus); - box-shadow: 0 0 0 var(--pf-outline-width) var(--pf-outline-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-chip:has([data-pf-selected]) { - border-color: var(--pf-border-focus); - background: var(--pf-hover); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-link { - color: var(--pf-text); - font-weight: 500; - text-decoration: none; - line-height: 1.3; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-link::before { - content: "#"; - color: var(--pf-text-muted); - margin-inline-end: 4px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-link::after { - content: ""; - position: absolute; - inset: 0; - border-radius: inherit; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-link:hover { - text-decoration: underline; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-heading-excerpt { - margin: 0; - font-size: 12px; - color: var(--pf-text-secondary); - line-height: 1.4; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-pane { - display: flex; - flex-direction: column; - gap: 20px; - padding: 16px; - background: var(--pf-skeleton); - border-radius: var(--pf-border-radius); - border: 1px solid var(--pf-border); - overflow: hidden; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-group { - display: flex; - flex-direction: column; - gap: 8px; - border: none; - padding: 0; - margin: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) details.pf-filter-group { - display: block; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) details.pf-filter-group > .pf-filter-options { - margin-top: 8px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - details.pf-filter-group - > .pf-filter-fieldset { - margin-top: 8px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-fieldset { - border: none; - padding: 0; - margin: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-group-title { - font-size: 11px; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.3px; - color: var(--pf-text-muted); - margin: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-group-name, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger-label, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option-label { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - min-width: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) summary.pf-filter-group-title { - cursor: pointer; - list-style: none; - display: flex; - align-items: center; - padding: 4px 0; - margin: -4px 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - summary.pf-filter-group-title::-webkit-details-marker { - display: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) summary.pf-filter-group-title::after { - content: ""; - width: 10px; - height: 6px; - flex-shrink: 0; - margin-inline-start: 8px; - background: var(--pf-text-muted); - -webkit-mask-image: var(--pf-icon-arrow); - mask-image: var(--pf-icon-arrow); - -webkit-mask-size: 100% 100%; - mask-size: 100% 100%; - transition: transform 0.15s; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - details.pf-filter-group:not([open]) - > summary.pf-filter-group-title::after { - transform: rotate(-90deg); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - [dir="rtl"] - details.pf-filter-group:not([open]) - > summary.pf-filter-group-title::after { - transform: rotate(90deg); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) summary.pf-filter-group-title:hover { - color: var(--pf-text-secondary); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-group-count, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-selected-badge { - display: inline-flex; - align-items: center; - justify-content: center; - background: var(--pf-text); - color: var(--pf-background); - font-size: 11px; - font-weight: 500; - height: 18px; - min-width: 18px; - padding: 0 5px; - border-radius: 9px; - flex-shrink: 0; - box-sizing: border-box; - font-variant-numeric: tabular-nums; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-group-count { - margin-inline-start: auto; - text-transform: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#):is(*, #\#) - .pf-filter-group-count[data-pf-hidden], -:is(*, #\#):is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-selected-badge[data-pf-hidden] { - display: inline-flex !important; - visibility: hidden; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-options { - display: flex; - flex-direction: column; - gap: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-checkbox { - display: flex; - align-items: center; - gap: 8px; - min-height: 30px; - cursor: pointer; - font-size: 13px; - color: var(--pf-text-secondary); -} - -@media (pointer: coarse) { - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-checkbox { - min-height: 44px; - } -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-checkbox:hover { - color: var(--pf-text); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-checkbox-input { - width: 16px; - height: 16px; - margin: 0; - accent-color: var(--pf-text); - cursor: pointer; - color-scheme: light; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) [data-pf-theme="dark"] .pf-checkbox-input { - color-scheme: dark; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-filter-checkbox:has(.pf-checkbox-input:focus-visible) { - outline: var(--pf-outline-width) solid var(--pf-outline-focus); - outline-offset: var(--pf-outline-offset); - border-radius: 4px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-checkbox-count { - margin-inline-start: auto; - font-size: 11px; - color: var(--pf-text-muted); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-wrapper { - position: relative; - display: inline-flex; - align-items: center; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger { - display: inline-flex; - align-items: center; - gap: 8px; - height: var(--pf-input-height); - padding: 0 12px; - background: var(--pf-background); - border: 1px solid var(--pf-border); - border-radius: var(--pf-border-radius); - font-size: 13px; - color: var(--pf-text-secondary); - cursor: pointer; - transition: border-color 0.15s; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger:hover { - border-color: var(--pf-border-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger.open { - border-color: var(--pf-border-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger.wrap { - height: auto; - min-height: var(--pf-input-height); - padding-top: 6px; - padding-bottom: 6px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger-label.wrap, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option-label.wrap { - white-space: normal; - line-height: 1.3; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-arrow { - width: 10px; - height: 6px; - flex-shrink: 0; - background: var(--pf-text-muted); - -webkit-mask-image: var(--pf-icon-arrow); - mask-image: var(--pf-icon-arrow); - -webkit-mask-size: 100% 100%; - mask-size: 100% 100%; - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger.open .pf-dropdown-arrow { - transform: rotate(180deg); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-menu { - position: absolute; - top: calc(100% + 4px); - inset-inline-start: 0; - min-width: 180px; - max-height: var(--pf-dropdown-max-height); - overflow-y: auto; - border: 1px solid var(--pf-border); - border-radius: var(--pf-border-radius); - box-shadow: var(--pf-shadow-md); - padding: 4px; - z-index: 100; - - background: - /* Top shadow cover (moves with content) */ - linear-gradient(var(--pf-background) 30%, transparent) center top, - /* Bottom shadow cover (moves with content) */ - linear-gradient(transparent, var(--pf-background) 70%) center bottom, - /* Top shadow (stays fixed) */ - linear-gradient(var(--pf-scroll-shadow), transparent) center top, - /* Bottom shadow (stays fixed) */ - linear-gradient(transparent, var(--pf-scroll-shadow)) center bottom, - var(--pf-background); - background-size: - 100% 40px, - 100% 40px, - 100% 14px, - 100% 14px, - 100% 100%; - background-repeat: no-repeat; - background-attachment: local, local, scroll, scroll, scroll; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option { - display: flex; - align-items: center; - gap: 8px; - padding: 12px 10px; - min-height: 44px; - font-size: 13px; - color: var(--pf-text-secondary); - border-radius: 4px; - cursor: pointer; - box-sizing: border-box; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option:hover { - background: var(--pf-hover); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option.pf-dropdown-option-focused { - outline: var(--pf-outline-width) solid var(--pf-outline-focus); - outline-offset: -2px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option.wrap { - align-items: flex-start; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-checkbox { - width: 16px; - height: 16px; - flex-shrink: 0; - border: 1px solid var(--pf-border); - border-radius: 3px; - background: var(--pf-background); - position: relative; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option.wrap - .pf-dropdown-checkbox { - margin-top: 2px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option[aria-selected="true"] - .pf-dropdown-checkbox { - background: var(--pf-text); - border-color: var(--pf-text); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option[aria-selected="true"] - .pf-dropdown-checkbox::after { - content: ""; - position: absolute; - inset-inline-start: 5px; - top: 2px; - width: 4px; - height: 8px; - border: solid var(--pf-background); - border-width: 0 2px 2px 0; - transform: rotate(45deg); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option-label { - flex: 1; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option-count { - margin-inline-start: auto; - font-size: 11px; - color: var(--pf-text-muted); - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option.wrap - .pf-dropdown-option-count { - margin-top: 2px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-option-loading { - pointer-events: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option-loading - .pf-dropdown-checkbox { - width: 16px; - height: 16px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option-loading - .pf-dropdown-option-label { - height: 13px; - border-radius: 4px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-error { - padding: 12px 10px; - font-size: 13px; - color: var(--pf-error-text); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-clear { - display: inline-flex; - align-items: center; - height: 44px; - padding: 0 10px; - margin-inline-start: 4px; - background: transparent; - border: 1px solid transparent; - border-radius: var(--pf-border-radius); - font-size: 12px; - color: var(--pf-text-secondary); - cursor: pointer; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-clear:hover:not([aria-disabled="true"]) { - background: var(--pf-hover); - border-color: var(--pf-border); - color: var(--pf-text); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-clear[aria-disabled="true"] { - color: var(--pf-text-muted); - cursor: default; - opacity: 0.4; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-options { - max-height: var(--pf-dropdown-max-height); - overflow-y: auto; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-btn { - display: inline-flex; - align-items: center; - gap: 8px; - width: 100%; - height: var(--pf-input-height); - padding: 0 14px; - background: var(--pf-background); - border: 1px solid var(--pf-border); - border-radius: var(--pf-border-radius); - font-size: 14px; - color: var(--pf-text-muted); - cursor: pointer; - transition: - border-color 0.15s, - box-shadow 0.15s; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-btn:hover { - border-color: var(--pf-border-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-icon { - width: 14px; - height: 14px; - background: var(--pf-text-muted); - -webkit-mask-image: var(--pf-icon-search); - mask-image: var(--pf-icon-search); - -webkit-mask-size: 100%; - mask-size: 100%; - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-text { - flex: 1; - text-align: start; - color: var(--pf-text-muted); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-shortcut { - display: inline-flex; - align-items: center; - gap: 2px; - margin-inline-start: 8px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-key { - min-width: 20px; - height: 18px; - font-size: 11px; - border-radius: 4px; -} - -/* - NB: Background scrolling is prevented with the overscroll-behavior: contain - values below, plus overflow: hidden on the backdrop. - As of writing, this only works on Chrome 144. Tracking: - https://bugzilla.mozilla.org/show_bug.cgi?id=1837436 - https://bugs.webkit.org/show_bug.cgi?id=243452 -*/ - -:is(*, #\#):is(*, #\#):is(*, #\#) dialog.pf-modal { - position: fixed; - width: 100%; - max-width: var(--pf-modal-max-width); - max-height: var(--pf-modal-max-height); - margin: var(--pf-modal-top) auto; - padding: 0; - background: var(--pf-background); - border: none; - border-radius: 12px; - box-shadow: var(--pf-shadow-lg); - flex-direction: column; - overflow: hidden; - overscroll-behavior: contain; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) dialog.pf-modal::backdrop { - background: var(--pf-modal-backdrop); - overflow: hidden; - overscroll-behavior: contain; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) dialog.pf-modal[open] { - display: flex; -} - -@media (prefers-reduced-motion: no-preference) { - :is(*, #\#):is(*, #\#):is(*, #\#) dialog.pf-modal[open] { - animation: pf-modal-appear 0.15s ease-out; - } - - @keyframes pf-modal-appear { - from { - opacity: 0; - transform: scale(0.95); - } - to { - opacity: 1; - transform: scale(1); - } - } -} - -@media (max-width: 640px) { - :is(*, #\#):is(*, #\#):is(*, #\#) dialog.pf-modal[open] { - top: 0; - left: 0; - width: 100vw; - height: 100dvh; - max-width: none; - max-height: none; - margin: 0; - padding: 0; - border-radius: 0; - animation: none; - } - - :is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-header, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-header { - padding-top: max(16px, env(safe-area-inset-top)); - padding-left: max(16px, env(safe-area-inset-left)); - padding-right: max(16px, env(safe-area-inset-right)); - } - - :is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-body, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-body { - padding-left: max(16px, env(safe-area-inset-left)); - padding-right: max(16px, env(safe-area-inset-right)); - } - - :is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-footer, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-footer { - padding-bottom: max(12px, env(safe-area-inset-bottom)); - padding-left: max(16px, env(safe-area-inset-left)); - padding-right: max(16px, env(safe-area-inset-right)); - } -} - -:is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-header, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-header { - display: flex; - align-items: center; - gap: 8px; - padding: 16px; - border-bottom: 1px solid var(--pf-border); - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-header-content { - flex: 1; - min-width: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-close { - display: none; - align-items: center; - justify-content: center; - width: 40px; - height: 40px; - padding: 0; - background: transparent; - border: none; - border-radius: 8px; - color: var(--pf-text-secondary); - cursor: pointer; - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-close:hover { - background: var(--pf-hover); - color: var(--pf-text); -} - -@media (max-width: 640px) { - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-close { - display: flex; - } -} - -:is(*, #\#):is(*, #\#):is(*, #\#) - pagefind-modal-header - .pf-input-wrapper::before, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-header .pf-input-wrapper::before { - top: 50%; - transform: translateY(-50%); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-header .pf-input, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-header .pf-input { - border: none; - background: transparent; - font-size: var(--pf-input-font-size); - height: 40px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-body, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-body { - flex: 1 1 auto; - overflow-y: auto; - overscroll-behavior: contain; - padding: 8px 16px 16px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-body .pf-summary, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-body .pf-summary { - margin-bottom: 8px; -} - -/* Modal body uses the base card styles - only minor adjustments needed */ -:is(*, #\#):is(*, #\#):is(*, #\#) - pagefind-modal-body - .pf-result-card:has([data-pf-selected]), -:is(*, #\#):is(*, #\#):is(*, #\#) - .pf-modal-body - .pf-result-card:has([data-pf-selected]) { - background: var(--pf-skeleton); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) pagefind-modal-footer, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-footer { - padding: 10px 16px; - border-top: 1px solid var(--pf-border); - display: flex; - align-items: center; - gap: 16px; - font-size: 12px; - color: var(--pf-text-muted); - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-footer-hint, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-keyboard-hint { - display: flex; - align-items: center; - gap: 6px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-footer-key, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-keyboard-key { - min-width: 18px; - height: 18px; - font-size: 10px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) pagefind-keyboard-hints, -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-keyboard-hints { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 16px; - font-size: 12px; - color: var(--pf-text-muted); - min-height: 20px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox { - position: relative; - display: inline-block; - width: 100%; - max-width: var(--pf-searchbox-max-width); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input-wrapper { - position: relative; -} - -/* Override trigger-shortcut positioning when inside searchbox */ -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input-wrapper .pf-trigger-shortcut { - position: absolute; - inset-inline-end: 12px; - top: 50%; - transform: translateY(-50%); - pointer-events: none; - margin-inline-start: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input { - padding: 0; - padding-inline-start: 32px; - padding-inline-end: 12px; -} - -/* Add padding when shortcut is present */ -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input-wrapper:has(.pf-trigger-shortcut) .pf-searchbox-input { - padding-inline-end: 72px; -} - -/* Hide shortcut badge when input is focused */ -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input:focus ~ .pf-trigger-shortcut { - display: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input:focus { - padding-inline-end: 12px; - border-color: var(--pf-border-focus); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox.open .pf-searchbox-input { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - border-bottom-color: var(--pf-border); -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-dropdown { - display: none; - flex-direction: column; - position: absolute; - top: 100%; - left: 0; - right: 0; - background: var(--pf-background); - border: 1px solid var(--pf-border); - border-top: none; - border-radius: 0 0 var(--pf-border-radius) var(--pf-border-radius); - box-shadow: var(--pf-shadow-md); - max-height: var(--pf-searchbox-dropdown-max-height); - z-index: 100; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox.open .pf-searchbox-dropdown { - display: flex; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-results { - list-style: none; - padding: 4px; - margin: 0; - flex: 1; - overflow-y: auto; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result { - display: block; - padding: 12px 10px; - min-height: 44px; - border-radius: 4px; - cursor: pointer; - text-decoration: none; - color: inherit; - box-sizing: border-box; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result:hover { - background: var(--pf-hover); -} - -/* Placeholder skeleton - non-interactive */ -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-placeholder { - cursor: default; - pointer-events: none; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-placeholder:hover { - background: transparent; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result[data-pf-selected] { - background: var(--pf-hover); - outline: var(--pf-outline-width) solid var(--pf-outline-focus); - outline-offset: -2px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result-title { - font-size: 13px; - font-weight: 500; - color: var(--pf-text); - margin: 0; - line-height: 1.3; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result-excerpt { - font-size: 12px; - color: var(--pf-text-secondary); - margin: 2px 0 0 0; - line-height: 1.4; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-subresult { - padding-inline-start: 20px; - border-inline-start: 2px solid var(--pf-border); - margin-inline-start: 10px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result-meta { - display: flex; - align-items: center; - gap: 6px; - margin-top: 4px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-footer { - padding: 8px 10px; - border-top: 1px solid var(--pf-border); - display: flex; - align-items: center; - justify-content: flex-end; - gap: 12px; - font-size: 11px; - color: var(--pf-text-muted); - flex-shrink: 0; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-footer-hint { - display: flex; - align-items: center; - gap: 4px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-empty { - padding: 20px 10px; - text-align: center; - color: var(--pf-text-muted); - font-size: 13px; -} - -:is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-loading { - padding: 16px 10px; - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - color: var(--pf-text-muted); - font-size: 13px; -} - -/* Ensure focus indicators are visible in Windows High Contrast Mode */ -@media (forced-colors: active) { - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-input:focus-visible, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-input:focus-visible, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-input-clear:focus-visible, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-trigger-btn:focus-visible, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-close:focus-visible, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-trigger:focus-visible, - :is(*, #\#):is(*, #\#):is(*, #\#) - .pf-result-card:has(.pf-result-link:focus-visible), - :is(*, #\#):is(*, #\#):is(*, #\#) - .pf-heading-chip:has(.pf-heading-link:focus-visible), - :is(*, #\#):is(*, #\#):is(*, #\#) - .pf-filter-checkbox:has(.pf-checkbox-input:focus-visible), - :is(*, #\#):is(*, #\#):is(*, #\#) - .pf-dropdown-option.pf-dropdown-option-focused, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-result[data-pf-selected] { - outline: 2px solid CanvasText; - outline-offset: 2px; - } -} - -/* Hide keyboard hints on touch-only devices (no hover capability) */ -@media (hover: none) { - :is(*, #\#):is(*, #\#):is(*, #\#) pagefind-keyboard-hints, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-keyboard-hints, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-footer, - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-modal-footer-hint { - display: none; - } -} - -@media (max-width: 640px) { - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-dropdown-menu { - min-width: unset; - width: max(180px, calc(100vw - 32px)); - max-width: calc(100vw - 32px); - inset-inline-start: unset; - left: 50%; - transform: translateX(-50%); - max-height: min(var(--pf-dropdown-max-height), 50vh); - } - - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-searchbox-dropdown { - max-height: min(var(--pf-searchbox-dropdown-max-height), 60vh); - } - - :is(*, #\#):is(*, #\#):is(*, #\#) .pf-filter-pane { - padding: 12px; - gap: 16px; - } -} diff --git a/website/blog/pagefind/pagefind-component-ui.js b/website/blog/pagefind/pagefind-component-ui.js deleted file mode 100644 index d8c1351..0000000 --- a/website/blog/pagefind/pagefind-component-ui.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict";(()=>{var ls=Object.defineProperty;var h=(n,s)=>{for(var e in s)ls(n,e,{get:s[e],enumerable:!0})};var Bt={};h(Bt,{PagefindConfig:()=>Re,PagefindElement:()=>f,PagefindFilterDropdown:()=>Me,PagefindFilterPane:()=>Ne,PagefindInput:()=>ke,PagefindKeyboardHints:()=>Le,PagefindModal:()=>Oe,PagefindModalBody:()=>Ie,PagefindModalFooter:()=>Ue,PagefindModalHeader:()=>we,PagefindModalTrigger:()=>He,PagefindResults:()=>Se,PagefindSearchbox:()=>Fe,PagefindSummary:()=>Ae,configureInstance:()=>Qt,getInstanceManager:()=>Ce});var os="a[href], button, input, [tabindex]";function Kt(n){let s=n.querySelectorAll(os);for(let e of s)if(!(e.tabIndex<0)&&!e.disabled&&!e.hasAttribute("hidden")&&window.getComputedStyle(e).display!=="none")return!0;return!1}function $t(n,s){let e=null;for(let t of s)t.contains(n)||!(n.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING)||Kt(t)&&(e===null||t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING)&&(e=t);return e}function Pe(n,s){let e=null;for(let t of s)t.contains(n)||!(n.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_PRECEDING)||Kt(t)&&(e===null||t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_PRECEDING)&&(e=t);return e}var Ve={};h(Ve,{comments:()=>us,default:()=>ps,direction:()=>ds,strings:()=>hs,thanks_to:()=>cs});var cs="Jan Claasen ",us="",ds="ltr",hs={placeholder:"Soek",clear_search:"Opruim",load_more:"Laai nog resultate",search_label:"Soek hierdie webwerf",filters_label:"Filters",zero_results:"Geen resultate vir [SEARCH_TERM]",many_results:"[COUNT] resultate vir [SEARCH_TERM]",one_result:"[COUNT] resultate vir [SEARCH_TERM]",total_zero_results:"Geen resultate",total_one_result:"[COUNT] resultaat",total_many_results:"[COUNT] resultate",alt_search:"Geen resultate vir [SEARCH_TERM]. Toon resultate vir [DIFFERENT_TERM] in plaas daarvan",search_suggestion:"Geen resultate vir [SEARCH_TERM]. Probeer eerder een van die volgende terme:",searching:"Soek vir [SEARCH_TERM]",results_label:"Soekresultate",keyboard_navigate:"navigeer",keyboard_select:"kies",keyboard_clear:"wis",keyboard_close:"sluit",keyboard_search:"soek",error_search:"Soek het misluk",filter_selected_one:"[COUNT] gekies",filter_selected_many:"[COUNT] gekies",input_hint:"Resultate sal verskyn terwyl jy tik",loading:"Laai"},ps={thanks_to:cs,comments:us,direction:ds,strings:hs};var qe={};h(qe,{comments:()=>_s,default:()=>Es,direction:()=>fs,strings:()=>gs,thanks_to:()=>ms});var ms="Jermanuts",_s="",fs="rtl",gs={placeholder:"\u0628\u062D\u062B",clear_search:"\u0627\u0645\u0633\u062D",load_more:"\u062D\u0645\u0651\u0650\u0644 \u0627\u0644\u0645\u0632\u064A\u062F \u0645\u0646 \u0627\u0644\u0646\u062A\u0627\u0626\u062C",search_label:"\u0627\u0628\u062D\u062B \u0641\u064A \u0647\u0630\u0627 \u0627\u0644\u0645\u0648\u0642\u0639",filters_label:"\u062A\u0635\u0641\u064A\u0627\u062A",zero_results:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]",many_results:"[COUNT] \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]",one_result:"[COUNT] \u0646\u062A\u064A\u062C\u0629 \u0644 [SEARCH_TERM]",total_zero_results:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C",total_one_result:"[COUNT] \u0646\u062A\u064A\u062C\u0629",total_many_results:"[COUNT] \u0646\u062A\u0627\u0626\u062C",alt_search:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]. \u064A\u0639\u0631\u0636 \u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0644 [DIFFERENT_TERM] \u0628\u062F\u0644\u0627\u064B \u0645\u0646 \u0630\u0644\u0643",search_suggestion:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]. \u062C\u0631\u0628 \u0623\u062D\u062F \u0639\u0645\u0644\u064A\u0627\u062A \u0627\u0644\u0628\u062D\u062B \u0627\u0644\u062A\u0627\u0644\u064A\u0629:",searching:"\u064A\u0628\u062D\u062B \u0639\u0646 [SEARCH_TERM]...",results_label:"\u0646\u062A\u0627\u0626\u062C \u0627\u0644\u0628\u062D\u062B",keyboard_navigate:"\u062A\u0646\u0642\u0644",keyboard_select:"\u0627\u062E\u062A\u064A\u0627\u0631",keyboard_clear:"\u0627\u0645\u0633\u062D",keyboard_close:"\u0625\u063A\u0644\u0627\u0642",keyboard_search:"\u0628\u062D\u062B",error_search:"\u0641\u0634\u0644 \u0627\u0644\u0628\u062D\u062B",filter_selected_one:"[COUNT] \u0645\u062D\u062F\u062F",filter_selected_many:"[COUNT] \u0645\u062D\u062F\u062F",input_hint:"\u0633\u062A\u0638\u0647\u0631 \u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0643\u062A\u0627\u0628\u0629",loading:"\u062C\u0627\u0631\u064D \u0627\u0644\u062A\u062D\u0645\u064A\u0644"},Es={thanks_to:ms,comments:_s,direction:fs,strings:gs};var Ge={};h(Ge,{comments:()=>Ts,default:()=>vs,direction:()=>Cs,strings:()=>ys,thanks_to:()=>bs});var bs="Maruf Alom ",Ts="",Cs="ltr",ys={placeholder:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",clear_search:"\u09AE\u09C1\u099B\u09C7 \u09AB\u09C7\u09B2\u09C1\u09A8",load_more:"\u0986\u09B0\u09CB \u09AB\u09B2\u09BE\u09AB\u09B2 \u09A6\u09C7\u0996\u09C1\u09A8",search_label:"\u098F\u0987 \u0993\u09AF\u09BC\u09C7\u09AC\u09B8\u09BE\u0987\u099F\u09C7 \u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",filters_label:"\u09AB\u09BF\u09B2\u09CD\u099F\u09BE\u09B0",zero_results:"[SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF",many_results:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u0997\u09BF\u09AF\u09BC\u09C7\u099B\u09C7 [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF",one_result:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u0997\u09BF\u09AF\u09BC\u09C7\u099B\u09C7 [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF",total_zero_results:"\u0995\u09CB\u09A8 \u09AB\u09B2\u09BE\u09AB\u09B2 \u09A8\u09C7\u0987",total_one_result:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2",total_many_results:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2",alt_search:"\u0995\u09CB\u09A8 \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF. \u09AA\u09B0\u09BF\u09AC\u09B0\u09CD\u09A4\u09C7 [DIFFERENT_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF \u09A6\u09C7\u0996\u09BE\u09A8\u09CB \u09B9\u099A\u09CD\u099B\u09C7",search_suggestion:"\u0995\u09CB\u09A8 \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF [SEARCH_TERM] \u098F\u09B0 \u09AC\u09BF\u09B7\u09AF\u09BC\u09C7. \u09A8\u09BF\u09A8\u09CD\u09AE\u09C7\u09B0 \u09AC\u09BF\u09B7\u09AF\u09BC\u09AC\u09B8\u09CD\u09A4\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09A6\u09C7\u0996\u09C1\u09A8:",searching:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u099A\u09B2\u099B\u09C7 [SEARCH_TERM]...",results_label:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8\u09C7\u09B0 \u09AB\u09B2\u09BE\u09AB\u09B2",keyboard_navigate:"\u09A8\u09C7\u09AD\u09BF\u0997\u09C7\u099F",keyboard_select:"\u09A8\u09BF\u09B0\u09CD\u09AC\u09BE\u099A\u09A8",keyboard_clear:"\u09AE\u09C1\u099B\u09C1\u09A8",keyboard_close:"\u09AC\u09A8\u09CD\u09A7",keyboard_search:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8",error_search:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u09AC\u09CD\u09AF\u09B0\u09CD\u09A5",filter_selected_one:"[COUNT]-\u099F\u09BF \u09A8\u09BF\u09B0\u09CD\u09AC\u09BE\u099A\u09BF\u09A4",filter_selected_many:"[COUNT]-\u099F\u09BF \u09A8\u09BF\u09B0\u09CD\u09AC\u09BE\u099A\u09BF\u09A4",input_hint:"\u099F\u09BE\u0987\u09AA \u0995\u09B0\u09BE\u09B0 \u09B8\u09BE\u09A5\u09C7 \u09B8\u09BE\u09A5\u09C7 \u09AB\u09B2\u09BE\u09AB\u09B2 \u09A6\u09C7\u0996\u09BE \u09AF\u09BE\u09AC\u09C7",loading:"\u09B2\u09CB\u09A1 \u09B9\u099A\u09CD\u099B\u09C7"},vs={thanks_to:bs,comments:Ts,direction:Cs,strings:ys};var We={};h(We,{comments:()=>ks,default:()=>Ns,direction:()=>As,strings:()=>Ss,thanks_to:()=>Rs});var Rs="Pablo Villaverde ",ks="",As="ltr",Ss={placeholder:"Cerca",clear_search:"Netejar",load_more:"Veure m\xE9s resultats",search_label:"Cerca en aquest lloc",filters_label:"Filtres",zero_results:"No es van trobar resultats per [SEARCH_TERM]",many_results:"[COUNT] resultats trobats per [SEARCH_TERM]",one_result:"[COUNT] resultat trobat per [SEARCH_TERM]",total_zero_results:"Sense resultats",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultats",alt_search:"No es van trobar resultats per [SEARCH_TERM]. Mostrant al seu lloc resultats per [DIFFERENT_TERM]",search_suggestion:"No es van trobar resultats per [SEARCH_TERM]. Proveu una de les cerques seg\xFCents:",searching:"Cercant [SEARCH_TERM]...",results_label:"Resultats de la cerca",keyboard_navigate:"navegar",keyboard_select:"triar",keyboard_clear:"netejar",keyboard_close:"tancar",keyboard_search:"cercar",error_search:"Error en la cerca",filter_selected_one:"[COUNT] seleccionat",filter_selected_many:"[COUNT] seleccionats",input_hint:"Els resultats apareixeran mentre escriviu",loading:"Carregant"},Ns={thanks_to:Rs,comments:ks,direction:As,strings:Ss};var Ye={};h(Ye,{comments:()=>Os,default:()=>ws,direction:()=>xs,strings:()=>Hs,thanks_to:()=>Ms});var Ms="Dalibor Hon ",Os="",xs="ltr",Hs={placeholder:"Hledat",clear_search:"Smazat",load_more:"Na\u010D\xEDst dal\u0161\xED v\xFDsledky",search_label:"Prohledat tuto str\xE1nku",filters_label:"Filtry",zero_results:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]",many_results:"[COUNT] v\xFDsledk\u016F pro [SEARCH_TERM]",one_result:"[COUNT] v\xFDsledek pro [SEARCH_TERM]",total_zero_results:"\u017D\xE1dn\xE9 v\xFDsledky",total_one_result:"[COUNT] v\xFDsledek",total_many_results:"[COUNT] v\xFDsledk\u016F",alt_search:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]. Zobrazuj\xED se v\xFDsledky pro [DIFFERENT_TERM]",search_suggestion:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]. Souvisej\xEDc\xED v\xFDsledky hled\xE1n\xED:",searching:"Hled\xE1m [SEARCH_TERM]...",results_label:"V\xFDsledky hled\xE1n\xED",keyboard_navigate:"navigovat",keyboard_select:"vybrat",keyboard_clear:"smazat",keyboard_close:"zav\u0159\xEDt",keyboard_search:"hledat",error_search:"Hled\xE1n\xED selhalo",filter_selected_one:"[COUNT] vybran\xFD",filter_selected_many:"[COUNT] vybran\xFDch",input_hint:"V\xFDsledky se zobraz\xED b\u011Bhem psan\xED",loading:"Na\u010D\xEDt\xE1n\xED"},ws={thanks_to:Ms,comments:Os,direction:xs,strings:Hs};var Je={};h(Je,{comments:()=>Us,default:()=>Ps,direction:()=>Ls,strings:()=>Fs,thanks_to:()=>Is});var Is="Jonas Smedegaard ",Us="",Ls="ltr",Fs={placeholder:"S\xF8g",clear_search:"Nulstil",load_more:"Indl\xE6s flere resultater",search_label:"S\xF8g p\xE5 dette website",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultater",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultater",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v et af disse s\xF8geord i stedet:",searching:"S\xF8ger efter [SEARCH_TERM]...",results_label:"S\xF8geresultater",keyboard_navigate:"naviger",keyboard_select:"v\xE6lg",keyboard_clear:"ryd",keyboard_close:"luk",keyboard_search:"s\xF8g",error_search:"S\xF8gning mislykkedes",filter_selected_one:"[COUNT] valgt",filter_selected_many:"[COUNT] valgte",input_hint:"Resultater vises mens du skriver",loading:"Indl\xE6ser"},Ps={thanks_to:Is,comments:Us,direction:Ls,strings:Fs};var Ze={};h(Ze,{comments:()=>Ds,default:()=>Ks,direction:()=>js,strings:()=>Bs,thanks_to:()=>zs});var zs="Jan Claasen ",Ds="",js="ltr",Bs={placeholder:"Suche",clear_search:"L\xF6schen",load_more:"Mehr Ergebnisse laden",search_label:"Suche diese Seite",filters_label:"Filter",zero_results:"Keine Ergebnisse f\xFCr [SEARCH_TERM]",many_results:"[COUNT] Ergebnisse f\xFCr [SEARCH_TERM]",one_result:"[COUNT] Ergebnis f\xFCr [SEARCH_TERM]",total_zero_results:"Keine Ergebnisse",total_one_result:"[COUNT] Ergebnis",total_many_results:"[COUNT] Ergebnisse",alt_search:"Keine Ergebnisse f\xFCr [SEARCH_TERM]. Stattdessen werden Ergebnisse f\xFCr [DIFFERENT_TERM] angezeigt",search_suggestion:"Keine Ergebnisse f\xFCr [SEARCH_TERM]. Versuchen Sie eine der folgenden Suchen:",searching:"Suche nach [SEARCH_TERM]\u202F\u2026",results_label:"Suchergebnisse",keyboard_navigate:"navigieren",keyboard_select:"ausw\xE4hlen",keyboard_clear:"l\xF6schen",keyboard_close:"schlie\xDFen",keyboard_search:"suchen",error_search:"Suche fehlgeschlagen",filter_selected_one:"[COUNT] ausgew\xE4hlt",filter_selected_many:"[COUNT] ausgew\xE4hlt",input_hint:"Ergebnisse werden w\xE4hrend der Eingabe angezeigt",loading:"Wird geladen"},Ks={thanks_to:zs,comments:Ds,direction:js,strings:Bs};var Xe={};h(Xe,{comments:()=>Vs,default:()=>Ws,direction:()=>qs,strings:()=>Gs,thanks_to:()=>$s});var $s="George Papadopoulos",Vs="",qs="ltr",Gs={placeholder:"\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7",clear_search:"\u039A\u03B1\u03B8\u03B1\u03C1\u03B9\u03C3\u03BC\u03CC\u03C2",load_more:"\u03A6\u03CC\u03C1\u03C4\u03C9\u03C3\u03B7 \u03C0\u03B5\u03C1\u03B9\u03C3\u03C3\u03CC\u03C4\u03B5\u03C1\u03C9\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03B5\u03C3\u03BC\u03AC\u03C4\u03C9\u03BD",search_label:"\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03C3\u03B5 \u03B1\u03C5\u03C4\u03CC\u03BD \u03C4\u03BF\u03BD \u03B9\u03C3\u03C4\u03CC\u03C4\u03BF\u03C0\u03BF",filters_label:"\u03A6\u03AF\u03BB\u03C4\u03C1\u03B1",zero_results:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]",many_results:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]",one_result:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03AD\u03BB\u03B5\u03C3\u03BC\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]",total_zero_results:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1",total_one_result:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03AD\u03BB\u03B5\u03C3\u03BC\u03B1",total_many_results:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1",alt_search:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]. \u0395\u03BC\u03C6\u03B1\u03BD\u03AF\u03B6\u03BF\u03BD\u03C4\u03B1\u03B9 \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [DIFFERENT_TERM]",search_suggestion:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]. \u0394\u03BF\u03BA\u03B9\u03BC\u03AC\u03C3\u03C4\u03B5 \u03BC\u03AF\u03B1 \u03B1\u03C0\u03CC \u03C4\u03B9\u03C2 \u03C0\u03B1\u03C1\u03B1\u03BA\u03AC\u03C4\u03C9 \u03B1\u03BD\u03B1\u03B6\u03B7\u03C4\u03AE\u03C3\u03B5\u03B9\u03C2:",searching:"\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03B3\u03B9\u03B1 [SEARCH_TERM]...",results_label:"\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B1\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7\u03C2",keyboard_navigate:"\u03C0\u03BB\u03BF\u03AE\u03B3\u03B7\u03C3\u03B7",keyboard_select:"\u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE",keyboard_clear:"\u03BA\u03B1\u03B8\u03B1\u03C1\u03B9\u03C3\u03BC\u03CC\u03C2",keyboard_close:"\u03BA\u03BB\u03B5\u03AF\u03C3\u03B9\u03BC\u03BF",keyboard_search:"\u03B1\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7",error_search:"\u0397 \u03B1\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03B1\u03C0\u03AD\u03C4\u03C5\u03C7\u03B5",filter_selected_one:"[COUNT] \u03B5\u03C0\u03B9\u03BB\u03B5\u03B3\u03BC\u03AD\u03BD\u03BF",filter_selected_many:"[COUNT] \u03B5\u03C0\u03B9\u03BB\u03B5\u03B3\u03BC\u03AD\u03BD\u03B1",input_hint:"\u03A4\u03B1 \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B8\u03B1 \u03B5\u03BC\u03C6\u03B1\u03BD\u03AF\u03B6\u03BF\u03BD\u03C4\u03B1\u03B9 \u03BA\u03B1\u03B8\u03CE\u03C2 \u03C0\u03BB\u03B7\u03BA\u03C4\u03C1\u03BF\u03BB\u03BF\u03B3\u03B5\u03AF\u03C4\u03B5",loading:"\u03A6\u03CC\u03C1\u03C4\u03C9\u03C3\u03B7"},Ws={thanks_to:$s,comments:Vs,direction:qs,strings:Gs};var Qe={};h(Qe,{comments:()=>Js,default:()=>Qs,direction:()=>Zs,strings:()=>Xs,thanks_to:()=>Ys});var Ys="Liam Bigelow ",Js="",Zs="ltr",Xs={placeholder:"Search",clear_search:"Clear",load_more:"Load more results",search_label:"Search this site",filters_label:"Filters",zero_results:"No results for [SEARCH_TERM]",many_results:"[COUNT] results for [SEARCH_TERM]",one_result:"[COUNT] result for [SEARCH_TERM]",total_zero_results:"No results",total_one_result:"[COUNT] result",total_many_results:"[COUNT] results",alt_search:"No results for [SEARCH_TERM]. Showing results for [DIFFERENT_TERM] instead",search_suggestion:"No results for [SEARCH_TERM]. Try one of the following searches:",searching:"Searching for [SEARCH_TERM]...",results_label:"Search results",keyboard_navigate:"navigate",keyboard_select:"select",keyboard_clear:"clear",keyboard_close:"close",keyboard_search:"search",error_search:"Search failed",filter_selected_one:"[COUNT] selected",filter_selected_many:"[COUNT] selected",input_hint:"Results will appear as you type",loading:"Loading"},Qs={thanks_to:Ys,comments:Js,direction:Zs,strings:Xs};var et={};h(et,{comments:()=>tr,default:()=>ir,direction:()=>sr,strings:()=>rr,thanks_to:()=>er});var er="Pablo Villaverde ",tr="",sr="ltr",rr={placeholder:"Buscar",clear_search:"Limpiar",load_more:"Ver m\xE1s resultados",search_label:"Buscar en este sitio",filters_label:"Filtros",zero_results:"No se encontraron resultados para [SEARCH_TERM]",many_results:"[COUNT] resultados encontrados para [SEARCH_TERM]",one_result:"[COUNT] resultado encontrado para [SEARCH_TERM]",total_zero_results:"Sin resultados",total_one_result:"[COUNT] resultado",total_many_results:"[COUNT] resultados",alt_search:"No se encontraron resultados para [SEARCH_TERM]. Mostrando en su lugar resultados para [DIFFERENT_TERM]",search_suggestion:"No se encontraron resultados para [SEARCH_TERM]. Prueba una de las siguientes b\xFAsquedas:",searching:"Buscando [SEARCH_TERM]...",results_label:"Resultados de b\xFAsqueda",keyboard_navigate:"navegar",keyboard_select:"elegir",keyboard_clear:"limpiar",keyboard_close:"cerrar",keyboard_search:"buscar",error_search:"Error en la b\xFAsqueda",filter_selected_one:"[COUNT] seleccionado",filter_selected_many:"[COUNT] seleccionados",input_hint:"Los resultados aparecer\xE1n mientras escribe",loading:"Cargando"},ir={thanks_to:er,comments:tr,direction:sr,strings:rr};var tt={};h(tt,{comments:()=>ar,default:()=>cr,direction:()=>lr,strings:()=>or,thanks_to:()=>nr});var nr="Mikel Larreategi ",ar="",lr="ltr",or={placeholder:"Bilatu",clear_search:"Garbitu",load_more:"Kargatu emaitza gehiagi",search_label:"Bilatu",filters_label:"Iragazkiak",zero_results:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat",many_results:"[COUNT] emaitza [SEARCH_TERM] bilaketarentzat",one_result:"Emaitza bat [COUNT] [SEARCH_TERM] bilaketarentzat",total_zero_results:"Emaitzarik ez",total_one_result:"[COUNT] emaitza",total_many_results:"[COUNT] emaitza",alt_search:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat. [DIFFERENT_TERM] bilaketaren emaitzak erakusten",search_suggestion:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat. Saiatu hauetako beste bateikin:",searching:"[SEARCH_TERM] bilatzen...",results_label:"Bilaketaren emaitzak",keyboard_navigate:"nabigatu",keyboard_select:"hautatu",keyboard_clear:"garbitu",keyboard_close:"itxi",keyboard_search:"bilatu",error_search:"Bilaketak huts egin du",filter_selected_one:"[COUNT] hautatuta",filter_selected_many:"[COUNT] hautatuta",input_hint:"Emaitzak idatzi ahala agertuko dira",loading:"Kargatzen"},cr={thanks_to:nr,comments:ar,direction:lr,strings:or};var st={};h(st,{comments:()=>dr,default:()=>mr,direction:()=>hr,strings:()=>pr,thanks_to:()=>ur});var ur="Ali Khaleqi Yekta ",dr="",hr="rtl",pr={placeholder:"\u062C\u0633\u062A\u062C\u0648",clear_search:"\u067E\u0627\u06A9\u0633\u0627\u0632\u06CC",load_more:"\u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u062A\u0627\u06CC\u062C \u0628\u06CC\u0634\u062A\u0631",search_label:"\u062C\u0633\u062A\u062C\u0648 \u062F\u0631 \u0633\u0627\u06CC\u062A",filters_label:"\u0641\u06CC\u0644\u062A\u0631\u0647\u0627",zero_results:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F",many_results:"[COUNT] \u0646\u062A\u06CC\u062C\u0647 \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0634\u062F",one_result:"[COUNT] \u0646\u062A\u06CC\u062C\u0647 \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0634\u062F",total_zero_results:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u06CC\u0627\u0641\u062A \u0646\u0634\u062F",total_one_result:"[COUNT] \u0646\u062A\u06CC\u062C\u0647",total_many_results:"[COUNT] \u0646\u062A\u06CC\u062C\u0647",alt_search:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F. \u062F\u0631 \u0639\u0648\u0636 \u0646\u062A\u0627\u06CC\u062C \u0628\u0631\u0627\u06CC [DIFFERENT_TERM] \u0646\u0645\u0627\u06CC\u0634 \u062F\u0627\u062F\u0647 \u0645\u06CC\u200C\u0634\u0648\u062F",search_suggestion:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F. \u06CC\u06A9\u06CC \u0627\u0632 \u062C\u0633\u062A\u062C\u0648\u0647\u0627\u06CC \u0632\u06CC\u0631 \u0631\u0627 \u0627\u0645\u062A\u062D\u0627\u0646 \u06A9\u0646\u06CC\u062F:",searching:"\u062F\u0631 \u062D\u0627\u0644 \u062C\u0633\u062A\u062C\u0648\u06CC [SEARCH_TERM]...",results_label:"\u0646\u062A\u0627\u06CC\u062C \u062C\u0633\u062A\u062C\u0648",keyboard_navigate:"\u067E\u06CC\u0645\u0627\u06CC\u0634",keyboard_select:"\u0627\u0646\u062A\u062E\u0627\u0628",keyboard_clear:"\u067E\u0627\u06A9\u0633\u0627\u0632\u06CC",keyboard_close:"\u0628\u0633\u062A\u0646",keyboard_search:"\u062C\u0633\u062A\u062C\u0648",error_search:"\u062C\u0633\u062A\u062C\u0648 \u0646\u0627\u0645\u0648\u0641\u0642 \u0628\u0648\u062F",filter_selected_one:"[COUNT] \u0627\u0646\u062A\u062E\u0627\u0628 \u0634\u062F\u0647",filter_selected_many:"[COUNT] \u0627\u0646\u062A\u062E\u0627\u0628 \u0634\u062F\u0647",input_hint:"\u0646\u062A\u0627\u06CC\u062C \u0647\u0646\u06AF\u0627\u0645 \u062A\u0627\u06CC\u067E \u0646\u0645\u0627\u06CC\u0634 \u062F\u0627\u062F\u0647 \u0645\u06CC\u200C\u0634\u0648\u0646\u062F",loading:"\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC"},mr={thanks_to:ur,comments:dr,direction:hr,strings:pr};var rt={};h(rt,{comments:()=>fr,default:()=>br,direction:()=>gr,strings:()=>Er,thanks_to:()=>_r});var _r="Valtteri Laitinen ",fr="",gr="ltr",Er={placeholder:"Haku",clear_search:"Tyhjenn\xE4",load_more:"Lataa lis\xE4\xE4 tuloksia",search_label:"Hae t\xE4lt\xE4 sivustolta",filters_label:"Suodattimet",zero_results:"Ei tuloksia haulle [SEARCH_TERM]",many_results:"[COUNT] tulosta haulle [SEARCH_TERM]",one_result:"[COUNT] tulos haulle [SEARCH_TERM]",total_zero_results:"Ei tuloksia",total_one_result:"[COUNT] tulos",total_many_results:"[COUNT] tulosta",alt_search:"Ei tuloksia haulle [SEARCH_TERM]. N\xE4ytet\xE4\xE4n tulokset sen sijaan haulle [DIFFERENT_TERM]",search_suggestion:"Ei tuloksia haulle [SEARCH_TERM]. Kokeile jotain seuraavista:",searching:"Haetaan [SEARCH_TERM]...",results_label:"Hakutulokset",keyboard_navigate:"siirry",keyboard_select:"valitse",keyboard_clear:"tyhjenn\xE4",keyboard_close:"sulje",keyboard_search:"hae",error_search:"Haku ep\xE4onnistui",filter_selected_one:"[COUNT] valittu",filter_selected_many:"[COUNT] valittu",input_hint:"Tulokset n\xE4kyv\xE4t kirjoittaessasi",loading:"Ladataan"},br={thanks_to:_r,comments:fr,direction:gr,strings:Er};var it={};h(it,{comments:()=>Cr,default:()=>Rr,direction:()=>yr,strings:()=>vr,thanks_to:()=>Tr});var Tr="Nicolas Friedli ",Cr="",yr="ltr",vr={placeholder:"Rechercher",clear_search:"Nettoyer",load_more:"Charger plus de r\xE9sultats",search_label:"Recherche sur ce site",filters_label:"Filtres",zero_results:"Pas de r\xE9sultat pour [SEARCH_TERM]",many_results:"[COUNT] r\xE9sultats pour [SEARCH_TERM]",one_result:"[COUNT] r\xE9sultat pour [SEARCH_TERM]",total_zero_results:"Pas de r\xE9sultat",total_one_result:"[COUNT] r\xE9sultat",total_many_results:"[COUNT] r\xE9sultats",alt_search:"Pas de r\xE9sultat pour [SEARCH_TERM]. Montre les r\xE9sultats pour [DIFFERENT_TERM] \xE0 la place",search_suggestion:"Pas de r\xE9sultat pour [SEARCH_TERM]. Essayer une des recherches suivantes:",searching:"Recherche [SEARCH_TERM]...",results_label:"R\xE9sultats de recherche",keyboard_navigate:"naviguer",keyboard_select:"choisir",keyboard_clear:"effacer",keyboard_close:"fermer",keyboard_search:"rechercher",error_search:"\xC9chec de la recherche",filter_selected_one:"[COUNT] s\xE9lectionn\xE9",filter_selected_many:"[COUNT] s\xE9lectionn\xE9s",input_hint:"Les r\xE9sultats appara\xEEtront au fur et \xE0 mesure de la saisie",loading:"Chargement"},Rr={thanks_to:Tr,comments:Cr,direction:yr,strings:vr};var nt={};h(nt,{comments:()=>Ar,default:()=>Mr,direction:()=>Sr,strings:()=>Nr,thanks_to:()=>kr});var kr="Pablo Villaverde ",Ar="",Sr="ltr",Nr={placeholder:"Buscar",clear_search:"Limpar",load_more:"Ver m\xE1is resultados",search_label:"Buscar neste sitio",filters_label:"Filtros",zero_results:"Non se atoparon resultados para [SEARCH_TERM]",many_results:"[COUNT] resultados atopados para [SEARCH_TERM]",one_result:"[COUNT] resultado atopado para [SEARCH_TERM]",total_zero_results:"Sen resultados",total_one_result:"[COUNT] resultado",total_many_results:"[COUNT] resultados",alt_search:"Non se atoparon resultados para [SEARCH_TERM]. Amosando no seu lugar resultados para [DIFFERENT_TERM]",search_suggestion:"Non se atoparon resultados para [SEARCH_TERM]. Probe unha das seguintes pesquisas:",searching:"Buscando [SEARCH_TERM]...",results_label:"Resultados da busca",keyboard_navigate:"navegar",keyboard_select:"escoller",keyboard_clear:"limpar",keyboard_close:"pechar",keyboard_search:"buscar",error_search:"Erro na busca",filter_selected_one:"[COUNT] seleccionado",filter_selected_many:"[COUNT] seleccionados",input_hint:"Os resultados aparecer\xE1n mentres escribe",loading:"Cargando"},Mr={thanks_to:kr,comments:Ar,direction:Sr,strings:Nr};var at={};h(at,{comments:()=>xr,default:()=>Ir,direction:()=>Hr,strings:()=>wr,thanks_to:()=>Or});var Or="Nir Tamir ",xr="",Hr="rtl",wr={placeholder:"\u05D7\u05D9\u05E4\u05D5\u05E9",clear_search:"\u05E0\u05D9\u05E7\u05D5\u05D9",load_more:"\u05E2\u05D5\u05D3 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA",search_label:"\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05D0\u05EA\u05E8 \u05D6\u05D4",filters_label:"\u05DE\u05E1\u05E0\u05E0\u05D9\u05DD",zero_results:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",many_results:"\u05E0\u05DE\u05E6\u05D0\u05D5 [COUNT] \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",one_result:"\u05E0\u05DE\u05E6\u05D0\u05D4 \u05EA\u05D5\u05E6\u05D0\u05D4 \u05D0\u05D7\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",total_zero_results:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA",total_one_result:"\u05EA\u05D5\u05E6\u05D0\u05D4 [COUNT]",total_many_results:"[COUNT] \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA",alt_search:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]. \u05DE\u05D5\u05E6\u05D2\u05D5\u05EA \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [DIFFERENT_TERM]",search_suggestion:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]. \u05E0\u05E1\u05D5 \u05D0\u05D7\u05D3 \u05DE\u05D4\u05D7\u05D9\u05E4\u05D5\u05E9\u05D9\u05DD \u05D4\u05D1\u05D0\u05D9\u05DD:",searching:"\u05DE\u05D7\u05E4\u05E9 \u05D0\u05EA [SEARCH_TERM]...",results_label:"\u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05D7\u05D9\u05E4\u05D5\u05E9",keyboard_navigate:"\u05E0\u05D9\u05D5\u05D5\u05D8",keyboard_select:"\u05D1\u05D7\u05D9\u05E8\u05D4",keyboard_clear:"\u05E0\u05D9\u05E7\u05D5\u05D9",keyboard_close:"\u05E1\u05D2\u05D9\u05E8\u05D4",keyboard_search:"\u05D7\u05D9\u05E4\u05D5\u05E9",error_search:"\u05D4\u05D7\u05D9\u05E4\u05D5\u05E9 \u05E0\u05DB\u05E9\u05DC",filter_selected_one:"[COUNT] \u05E0\u05D1\u05D7\u05E8",filter_selected_many:"[COUNT] \u05E0\u05D1\u05D7\u05E8\u05D5",input_hint:"\u05D4\u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05D9\u05D5\u05E4\u05D9\u05E2\u05D5 \u05EA\u05D5\u05DA \u05DB\u05D3\u05D9 \u05D4\u05E7\u05DC\u05D3\u05D4",loading:"\u05D8\u05D5\u05E2\u05DF"},Ir={thanks_to:Or,comments:xr,direction:Hr,strings:wr};var lt={};h(lt,{comments:()=>Lr,default:()=>zr,direction:()=>Fr,strings:()=>Pr,thanks_to:()=>Ur});var Ur="Amit Yadav ",Lr="",Fr="ltr",Pr={placeholder:"\u0916\u094B\u091C\u0947\u0902",clear_search:"\u0938\u093E\u092B \u0915\u0930\u0947\u0902",load_more:"\u0914\u0930 \u0905\u0927\u093F\u0915 \u092A\u0930\u093F\u0923\u093E\u092E \u0932\u094B\u0921 \u0915\u0930\u0947\u0902",search_label:"\u0907\u0938 \u0938\u093E\u0907\u091F \u092E\u0947\u0902 \u0916\u094B\u091C\u0947\u0902",filters_label:"\u092B\u093C\u093F\u0932\u094D\u091F\u0930",zero_results:"\u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E",many_results:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u092E\u093F\u0932\u0947",one_result:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u092E\u093F\u0932\u093E",total_zero_results:"\u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902",total_one_result:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E",total_many_results:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E",alt_search:"[SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E\u0964 \u0907\u0938\u0915\u0947 \u092C\u091C\u093E\u092F [DIFFERENT_TERM] \u0915\u0947 \u0932\u093F\u090F \u092A\u0930\u093F\u0923\u093E\u092E \u0926\u093F\u0916\u093E \u0930\u0939\u093E \u0939\u0948",search_suggestion:"[SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E\u0964 \u0928\u093F\u092E\u094D\u0928\u0932\u093F\u0916\u093F\u0924 \u0916\u094B\u091C\u094B\u0902 \u092E\u0947\u0902 \u0938\u0947 \u0915\u094B\u0908 \u090F\u0915 \u0906\u091C\u093C\u092E\u093E\u090F\u0902:",searching:"[SEARCH_TERM] \u0915\u0940 \u0916\u094B\u091C \u0915\u0940 \u091C\u093E \u0930\u0939\u0940 \u0939\u0948...",results_label:"\u0916\u094B\u091C \u092A\u0930\u093F\u0923\u093E\u092E",keyboard_navigate:"\u0928\u0947\u0935\u093F\u0917\u0947\u091F",keyboard_select:"\u091A\u0941\u0928\u0947\u0902",keyboard_clear:"\u0938\u093E\u092B\u093C \u0915\u0930\u0947\u0902",keyboard_close:"\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",keyboard_search:"\u0916\u094B\u091C\u0947\u0902",error_search:"\u0916\u094B\u091C \u0935\u093F\u092B\u0932",filter_selected_one:"[COUNT] \u091A\u092F\u0928\u093F\u0924",filter_selected_many:"[COUNT] \u091A\u092F\u0928\u093F\u0924",input_hint:"\u091F\u093E\u0907\u092A \u0915\u0930\u0924\u0947 \u0938\u092E\u092F \u092A\u0930\u093F\u0923\u093E\u092E \u0926\u093F\u0916\u093E\u0908 \u0926\u0947\u0902\u0917\u0947",loading:"\u0932\u094B\u0921 \u0939\u094B \u0930\u0939\u093E \u0939\u0948"},zr={thanks_to:Ur,comments:Lr,direction:Fr,strings:Pr};var ot={};h(ot,{comments:()=>jr,default:()=>$r,direction:()=>Br,strings:()=>Kr,thanks_to:()=>Dr});var Dr="Diomed ",jr="",Br="ltr",Kr={placeholder:"Tra\u017Ei",clear_search:"O\u010Disti",load_more:"U\u010Ditaj vi\u0161e rezultata",search_label:"Pretra\u017Ei ovu stranicu",filters_label:"Filteri",zero_results:"Nema rezultata za [SEARCH_TERM]",many_results:"[COUNT] rezultata za [SEARCH_TERM]",one_result:"[COUNT] rezultat za [SEARCH_TERM]",total_zero_results:"Nema rezultata",total_one_result:"[COUNT] rezultat",total_many_results:"[COUNT] rezultata",alt_search:"Nema rezultata za [SEARCH_TERM]. Prikazujem rezultate za [DIFFERENT_TERM]",search_suggestion:"Nema rezultata za [SEARCH_TERM]. Poku\u0161aj s jednom od ovih pretraga:",searching:"Pretra\u017Eujem [SEARCH_TERM]...",results_label:"Rezultati pretrage",keyboard_navigate:"navigiraj",keyboard_select:"odaberi",keyboard_clear:"o\u010Disti",keyboard_close:"zatvori",keyboard_search:"tra\u017Ei",error_search:"Pretraga nije uspjela",filter_selected_one:"[COUNT] odabran",filter_selected_many:"[COUNT] odabranih",input_hint:"Rezultati \u0107e se pojaviti dok tipkate",loading:"U\u010Ditavanje"},$r={thanks_to:Dr,comments:jr,direction:Br,strings:Kr};var ct={};h(ct,{comments:()=>qr,default:()=>Yr,direction:()=>Gr,strings:()=>Wr,thanks_to:()=>Vr});var Vr="Adam Laki ",qr="",Gr="ltr",Wr={placeholder:"Keres\xE9s",clear_search:"T\xF6rl\xE9s",load_more:"Tov\xE1bbi tal\xE1latok bet\xF6lt\xE9se",search_label:"Keres\xE9s az oldalon",filters_label:"Sz\u0171r\xE9s",zero_results:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",many_results:"[COUNT] db tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",one_result:"[COUNT] db tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",total_zero_results:"Nincs tal\xE1lat",total_one_result:"[COUNT] tal\xE1lat",total_many_results:"[COUNT] tal\xE1lat",alt_search:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre. Tal\xE1latok mutat\xE1sa ink\xE1bb a(z) [DIFFERENT_TERM] kifejez\xE9sre",search_suggestion:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre. Pr\xF3b\xE1ld meg a k\xF6vetkez\u0151 keres\xE9sek egyik\xE9t:",searching:"Keres\xE9s a(z) [SEARCH_TERM] kifejez\xE9sre...",results_label:"Keres\xE9si tal\xE1latok",keyboard_navigate:"navig\xE1l\xE1s",keyboard_select:"kiv\xE1laszt\xE1s",keyboard_clear:"t\xF6rl\xE9s",keyboard_close:"bez\xE1r\xE1s",keyboard_search:"keres\xE9s",error_search:"A keres\xE9s sikertelen",filter_selected_one:"[COUNT] kiv\xE1lasztva",filter_selected_many:"[COUNT] kiv\xE1lasztva",input_hint:"A tal\xE1latok g\xE9pel\xE9s k\xF6zben jelennek meg",loading:"Bet\xF6lt\xE9s"},Yr={thanks_to:Vr,comments:qr,direction:Gr,strings:Wr};var ut={};h(ut,{comments:()=>Zr,default:()=>ei,direction:()=>Xr,strings:()=>Qr,thanks_to:()=>Jr});var Jr="Nixentric",Zr="",Xr="ltr",Qr={placeholder:"Cari",clear_search:"Bersihkan",load_more:"Muat lebih banyak hasil",search_label:"Telusuri situs ini",filters_label:"Filter",zero_results:"[SEARCH_TERM] tidak ditemukan",many_results:"Ditemukan [COUNT] hasil untuk [SEARCH_TERM]",one_result:"Ditemukan [COUNT] hasil untuk [SEARCH_TERM]",total_zero_results:"Tidak ada hasil",total_one_result:"[COUNT] hasil",total_many_results:"[COUNT] hasil",alt_search:"[SEARCH_TERM] tidak ditemukan. Menampilkan hasil [DIFFERENT_TERM] sebagai gantinya",search_suggestion:"[SEARCH_TERM] tidak ditemukan. Coba salah satu pencarian berikut ini:",searching:"Mencari [SEARCH_TERM]...",results_label:"Hasil pencarian",keyboard_navigate:"navigasi",keyboard_select:"pilih",keyboard_clear:"bersihkan",keyboard_close:"tutup",keyboard_search:"cari",error_search:"Pencarian gagal",filter_selected_one:"[COUNT] dipilih",filter_selected_many:"[COUNT] dipilih",input_hint:"Hasil akan muncul saat Anda mengetik",loading:"Memuat"},ei={thanks_to:Jr,comments:Zr,direction:Xr,strings:Qr};var dt={};h(dt,{comments:()=>si,default:()=>ni,direction:()=>ri,strings:()=>ii,thanks_to:()=>ti});var ti="Cosette Bruhns Alonso, Andrew Janco ",si="",ri="ltr",ii={placeholder:"Cerca",clear_search:"Cancella la cronologia",load_more:"Mostra pi\xF9 risultati",search_label:"Cerca nel sito",filters_label:"Filtri di ricerca",zero_results:"Nessun risultato per [SEARCH_TERM]",many_results:"[COUNT] risultati per [SEARCH_TERM]",one_result:"[COUNT] risultato per [SEARCH_TERM]",total_zero_results:"Nessun risultato",total_one_result:"[COUNT] risultato",total_many_results:"[COUNT] risultati",alt_search:"Nessun risultato per [SEARCH_TERM]. Mostrando risultati per [DIFFERENT_TERM] come alternativa.",search_suggestion:"Nessun risultato per [SEARCH_TERM]. Prova una delle seguenti ricerche:",searching:"Cercando [SEARCH_TERM]...",results_label:"Risultati della ricerca",keyboard_navigate:"naviga",keyboard_select:"seleziona",keyboard_clear:"cancella",keyboard_close:"chiudi",keyboard_search:"cerca",error_search:"Ricerca fallita",filter_selected_one:"[COUNT] selezionato",filter_selected_many:"[COUNT] selezionati",input_hint:"I risultati appariranno durante la digitazione",loading:"Caricamento"},ni={thanks_to:ti,comments:si,direction:ri,strings:ii};var ht={};h(ht,{comments:()=>li,default:()=>ui,direction:()=>oi,strings:()=>ci,thanks_to:()=>ai});var ai="Tate",li="",oi="ltr",ci={placeholder:"\u691C\u7D22",clear_search:"\u30AF\u30EA\u30A2",load_more:"\u6B21\u3092\u8AAD\u307F\u8FBC\u3080",search_label:"\u3053\u306E\u30B5\u30A4\u30C8\u3092\u691C\u7D22",filters_label:"\u30D5\u30A3\u30EB\u30BF",zero_results:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F",many_results:"[SEARCH_TERM]\u306E[COUNT]\u4EF6\u306E\u691C\u7D22\u7D50\u679C",one_result:"[SEARCH_TERM]\u306E[COUNT]\u4EF6\u306E\u691C\u7D22\u7D50\u679C",total_zero_results:"\u7D50\u679C\u306A\u3057",total_one_result:"[COUNT]\u4EF6\u306E\u7D50\u679C",total_many_results:"[COUNT]\u4EF6\u306E\u7D50\u679C",alt_search:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002[DIFFERENT_TERM]\u306E\u691C\u7D22\u7D50\u679C\u3092\u8868\u793A\u3057\u3066\u3044\u307E\u3059",search_suggestion:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u6B21\u306E\u3044\u305A\u308C\u304B\u306E\u691C\u7D22\u3092\u8A66\u3057\u3066\u304F\u3060\u3055\u3044",searching:"[SEARCH_TERM]\u3092\u691C\u7D22\u3057\u3066\u3044\u307E\u3059",results_label:"\u691C\u7D22\u7D50\u679C",keyboard_navigate:"\u79FB\u52D5",keyboard_select:"\u9078\u629E",keyboard_clear:"\u30AF\u30EA\u30A2",keyboard_close:"\u9589\u3058\u308B",keyboard_search:"\u691C\u7D22",error_search:"\u691C\u7D22\u306B\u5931\u6557\u3057\u307E\u3057\u305F",filter_selected_one:"[COUNT]\u4EF6\u9078\u629E\u4E2D",filter_selected_many:"[COUNT]\u4EF6\u9078\u629E\u4E2D",input_hint:"\u5165\u529B\u4E2D\u306B\u691C\u7D22\u7D50\u679C\u304C\u8868\u793A\u3055\u308C\u307E\u3059",loading:"\u8AAD\u307F\u8FBC\u307F\u4E2D"},ui={thanks_to:ai,comments:li,direction:oi,strings:ci};var pt={};h(pt,{comments:()=>hi,default:()=>_i,direction:()=>pi,strings:()=>mi,thanks_to:()=>di});var di="Seokho Son ",hi="",pi="ltr",mi={placeholder:"\uAC80\uC0C9\uC5B4",clear_search:"\uBE44\uC6B0\uAE30",load_more:"\uAC80\uC0C9 \uACB0\uACFC \uB354 \uBCF4\uAE30",search_label:"\uC0AC\uC774\uD2B8 \uAC80\uC0C9",filters_label:"\uD544\uD130",zero_results:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C",many_results:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC [COUNT]\uAC74",one_result:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC [COUNT]\uAC74",total_zero_results:"\uACB0\uACFC \uC5C6\uC74C",total_one_result:"\uACB0\uACFC [COUNT]\uAC74",total_many_results:"\uACB0\uACFC [COUNT]\uAC74",alt_search:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C. [DIFFERENT_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC",search_suggestion:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C. \uCD94\uCC9C \uAC80\uC0C9\uC5B4: ",searching:"[SEARCH_TERM] \uAC80\uC0C9 \uC911...",results_label:"\uAC80\uC0C9 \uACB0\uACFC",keyboard_navigate:"\uC774\uB3D9",keyboard_select:"\uC120\uD0DD",keyboard_clear:"\uBE44\uC6B0\uAE30",keyboard_close:"\uB2EB\uAE30",keyboard_search:"\uAC80\uC0C9",error_search:"\uAC80\uC0C9 \uC2E4\uD328",filter_selected_one:"[COUNT]\uAC1C \uC120\uD0DD\uB428",filter_selected_many:"[COUNT]\uAC1C \uC120\uD0DD\uB428",input_hint:"\uC785\uB825\uD558\uB294 \uB3D9\uC548 \uACB0\uACFC\uAC00 \uD45C\uC2DC\uB429\uB2C8\uB2E4",loading:"\uB85C\uB529 \uC911"},_i={thanks_to:di,comments:hi,direction:pi,strings:mi};var mt={};h(mt,{comments:()=>gi,default:()=>Ti,direction:()=>Ei,strings:()=>bi,thanks_to:()=>fi});var fi="",gi="",Ei="ltr",bi={placeholder:"Rapu",clear_search:"Whakakore",load_more:"Whakauta \u0113tahi otinga k\u0113",search_label:"Rapu",filters_label:"T\u0101tari",zero_results:"Otinga kore ki [SEARCH_TERM]",many_results:"[COUNT] otinga ki [SEARCH_TERM]",one_result:"[COUNT] otinga ki [SEARCH_TERM]",total_zero_results:"K\u0101ore he otinga",total_one_result:"[COUNT] otinga",total_many_results:"[COUNT] ng\u0101 otinga",alt_search:"Otinga kore ki [SEARCH_TERM]. Otinga k\u0113 ki [DIFFERENT_TERM]",search_suggestion:"Otinga kore ki [SEARCH_TERM]. whakam\u0101tau ki ng\u0101 mea atu:",searching:"Rapu ki [SEARCH_TERM]...",results_label:"Ng\u0101 otinga rapu",keyboard_navigate:"whakatere",keyboard_select:"t\u012Bpako",keyboard_clear:"whakakore",keyboard_close:"kati",keyboard_search:"rapu",error_search:"K\u0101ore i eke te rapu",filter_selected_one:"[COUNT] kua t\u012Bpakohia",filter_selected_many:"[COUNT] kua t\u012Bpakohia",input_hint:"Ka puta ng\u0101 otinga i a koe e patopato ana",loading:"E uta ana"},Ti={thanks_to:fi,comments:gi,direction:Ei,strings:bi};var _t={};h(_t,{comments:()=>yi,default:()=>ki,direction:()=>vi,strings:()=>Ri,thanks_to:()=>Ci});var Ci="Harry Min Khant ",yi="",vi="ltr",Ri={placeholder:"\u101B\u103E\u102C\u101B\u1014\u103A",clear_search:"\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F\u1000\u102D\u102F \u101B\u103E\u1004\u103A\u1038\u101C\u1004\u103A\u1038\u1015\u102B\u104B",load_more:"\u1014\u1031\u102C\u1000\u103A\u1011\u1015\u103A\u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038\u1000\u102D\u102F \u1010\u1004\u103A\u1015\u102B\u104B",search_label:"\u1024\u1006\u102D\u102F\u1000\u103A\u1010\u103D\u1004\u103A\u101B\u103E\u102C\u1016\u103D\u1031\u1015\u102B\u104B",filters_label:"\u1005\u1005\u103A\u1011\u102F\u1010\u103A\u1019\u103E\u102F\u1019\u103B\u102C\u1038",zero_results:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038 \u1019\u101B\u103E\u102D\u1015\u102B",many_results:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A [COUNT] \u1001\u102F",one_result:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A [COUNT]",total_zero_results:"\u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038 \u1019\u101B\u103E\u102D\u1015\u102B",total_one_result:"\u101B\u101C\u1012\u103A [COUNT] \u1001\u102F",total_many_results:"\u101B\u101C\u1012\u103A [COUNT] \u1001\u102F",alt_search:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u101B\u103E\u102D\u1015\u102B\u104B \u104E\u1004\u103A\u1038\u1021\u1005\u102C\u1038 [DIFFERENT_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038\u1000\u102D\u102F \u1015\u103C\u101E\u101E\u100A\u103A\u104B",search_suggestion:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u101B\u103E\u102D\u1015\u102B\u104B \u1021\u1031\u102C\u1000\u103A\u1015\u102B\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F\u1019\u103B\u102C\u1038\u1011\u1032\u1019\u103E \u1010\u1005\u103A\u1001\u102F\u1000\u102D\u102F \u1005\u1019\u103A\u1038\u1000\u103C\u100A\u1037\u103A\u1015\u102B:",searching:"[SEARCH_TERM] \u1000\u102D\u102F \u101B\u103E\u102C\u1016\u103D\u1031\u1014\u1031\u101E\u100A\u103A...",results_label:"\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038",keyboard_navigate:"\u101C\u1019\u103A\u1038\u100A\u103D\u103E\u1014\u103A",keyboard_select:"\u101B\u103D\u1031\u1038\u1001\u103B\u101A\u103A",keyboard_clear:"\u101B\u103E\u1004\u103A\u1038\u101C\u1004\u103A\u1038",keyboard_close:"\u1015\u102D\u1010\u103A",keyboard_search:"\u101B\u103E\u102C\u101B\u1014\u103A",error_search:"\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F \u1019\u1021\u1031\u102C\u1004\u103A\u1019\u103C\u1004\u103A\u1015\u102B",filter_selected_one:"[COUNT] \u1001\u102F \u101B\u103D\u1031\u1038\u1001\u103B\u101A\u103A\u1011\u102C\u1038\u101E\u100A\u103A",filter_selected_many:"[COUNT] \u1001\u102F \u101B\u103D\u1031\u1038\u1001\u103B\u101A\u103A\u1011\u102C\u1038\u101E\u100A\u103A",input_hint:"\u101B\u102D\u102F\u1000\u103A\u1014\u1031\u1005\u1009\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038 \u1015\u1031\u102B\u103A\u101C\u102C\u1015\u102B\u1019\u100A\u103A",loading:"\u1010\u1004\u103A\u1014\u1031\u101E\u100A\u103A"},ki={thanks_to:Ci,comments:yi,direction:vi,strings:Ri};var ft={};h(ft,{comments:()=>Si,default:()=>Oi,direction:()=>Ni,strings:()=>Mi,thanks_to:()=>Ai});var Ai="Eirik Mikkelsen",Si="",Ni="ltr",Mi={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last flere resultater",search_label:"S\xF8k p\xE5 denne siden",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultater",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultater",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v en av disse s\xF8keordene i stedet:",searching:"S\xF8ker etter [SEARCH_TERM]",results_label:"S\xF8keresultater",keyboard_navigate:"naviger",keyboard_select:"velg",keyboard_clear:"fjern",keyboard_close:"lukk",keyboard_search:"s\xF8k",error_search:"S\xF8k feilet",filter_selected_one:"[COUNT] valgt",filter_selected_many:"[COUNT] valgte",input_hint:"Resultater vises mens du skriver",loading:"Laster"},Oi={thanks_to:Ai,comments:Si,direction:Ni,strings:Mi};var gt={};h(gt,{comments:()=>Hi,default:()=>Ui,direction:()=>wi,strings:()=>Ii,thanks_to:()=>xi});var xi="Paul van Brouwershaven",Hi="",wi="ltr",Ii={placeholder:"Zoeken",clear_search:"Reset",load_more:"Meer resultaten laden",search_label:"Doorzoek deze site",filters_label:"Filters",zero_results:"Geen resultaten voor [SEARCH_TERM]",many_results:"[COUNT] resultaten voor [SEARCH_TERM]",one_result:"[COUNT] resultaat voor [SEARCH_TERM]",total_zero_results:"Geen resultaten",total_one_result:"[COUNT] resultaat",total_many_results:"[COUNT] resultaten",alt_search:"Geen resultaten voor [SEARCH_TERM]. In plaats daarvan worden resultaten voor [DIFFERENT_TERM] weergegeven",search_suggestion:"Geen resultaten voor [SEARCH_TERM]. Probeer een van de volgende zoekopdrachten:",searching:"Zoeken naar [SEARCH_TERM]...",results_label:"Zoekresultaten",keyboard_navigate:"navigeren",keyboard_select:"selecteren",keyboard_clear:"wissen",keyboard_close:"sluiten",keyboard_search:"zoeken",error_search:"Zoeken mislukt",filter_selected_one:"[COUNT] geselecteerd",filter_selected_many:"[COUNT] geselecteerd",input_hint:"Resultaten verschijnen terwijl u typt",loading:"Laden"},Ui={thanks_to:xi,comments:Hi,direction:wi,strings:Ii};var Et={};h(Et,{comments:()=>Fi,default:()=>Di,direction:()=>Pi,strings:()=>zi,thanks_to:()=>Li});var Li="Eirik Mikkelsen",Fi="",Pi="ltr",zi={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last fleire resultat",search_label:"S\xF8k p\xE5 denne sida",filters_label:"Filter",zero_results:"Ingen resultat for [SEARCH_TERM]",many_results:"[COUNT] resultat for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultat",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultat",alt_search:"Ingen resultat for [SEARCH_TERM]. Viser resultat for [DIFFERENT_TERM] i staden",search_suggestion:"Ingen resultat for [SEARCH_TERM]. Pr\xF8v eitt av desse s\xF8keorda i staden:",searching:"S\xF8ker etter [SEARCH_TERM]",results_label:"S\xF8keresultat",keyboard_navigate:"naviger",keyboard_select:"vel",keyboard_clear:"fjern",keyboard_close:"lukk",keyboard_search:"s\xF8k",error_search:"S\xF8k feila",filter_selected_one:"[COUNT] vald",filter_selected_many:"[COUNT] valde",input_hint:"Resultat visast medan du skriv",loading:"Lastar"},Di={thanks_to:Li,comments:Fi,direction:Pi,strings:zi};var bt={};h(bt,{comments:()=>Bi,default:()=>Vi,direction:()=>Ki,strings:()=>$i,thanks_to:()=>ji});var ji="Christopher Wingate",Bi="",Ki="ltr",$i={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last flere resultater",search_label:"S\xF8k p\xE5 denne siden",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultater",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultater",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v en av disse s\xF8keordene i stedet:",searching:"S\xF8ker etter [SEARCH_TERM]",results_label:"S\xF8keresultater",keyboard_navigate:"naviger",keyboard_select:"velg",keyboard_clear:"fjern",keyboard_close:"lukk",keyboard_search:"s\xF8k",error_search:"S\xF8k feilet",filter_selected_one:"[COUNT] valgt",filter_selected_many:"[COUNT] valgte",input_hint:"Resultater vises mens du skriver",loading:"Laster"},Vi={thanks_to:ji,comments:Bi,direction:Ki,strings:$i};var Tt={};h(Tt,{comments:()=>Gi,default:()=>Ji,direction:()=>Wi,strings:()=>Yi,thanks_to:()=>qi});var qi="",Gi="",Wi="ltr",Yi={placeholder:"Szukaj",clear_search:"Wyczy\u015B\u0107",load_more:"Za\u0142aduj wi\u0119cej",search_label:"Przeszukaj t\u0119 stron\u0119",filters_label:"Filtry",zero_results:"Brak wynik\xF3w dla [SEARCH_TERM]",many_results:"[COUNT] wynik\xF3w dla [SEARCH_TERM]",one_result:"[COUNT] wynik dla [SEARCH_TERM]",total_zero_results:"Brak wynik\xF3w",total_one_result:"[COUNT] wynik",total_many_results:"[COUNT] wynik\xF3w",alt_search:"Brak wynik\xF3w dla [SEARCH_TERM]. Wy\u015Bwietlam wyniki dla [DIFFERENT_TERM]",search_suggestion:"Brak wynik\xF3w dla [SEARCH_TERM]. Pokrewne wyniki wyszukiwania:",searching:"Szukam [SEARCH_TERM]...",results_label:"Wyniki wyszukiwania",keyboard_navigate:"nawiguj",keyboard_select:"wybierz",keyboard_clear:"wyczy\u015B\u0107",keyboard_close:"zamknij",keyboard_search:"szukaj",error_search:"Wyszukiwanie nie powiod\u0142o si\u0119",filter_selected_one:"[COUNT] wybrany",filter_selected_many:"[COUNT] wybranych",input_hint:"Wyniki pojawi\u0105 si\u0119 podczas pisania",loading:"\u0141adowanie"},Ji={thanks_to:qi,comments:Gi,direction:Wi,strings:Yi};var Ct={};h(Ct,{comments:()=>Xi,default:()=>tn,direction:()=>Qi,strings:()=>en,thanks_to:()=>Zi});var Zi="Jonatah",Xi="",Qi="ltr",en={placeholder:"Pesquisar",clear_search:"Limpar",load_more:"Ver mais resultados",search_label:"Pesquisar",filters_label:"Filtros",zero_results:"Nenhum resultado encontrado para [SEARCH_TERM]",many_results:"[COUNT] resultados encontrados para [SEARCH_TERM]",one_result:"[COUNT] resultado encontrado para [SEARCH_TERM]",total_zero_results:"Nenhum resultado",total_one_result:"[COUNT] resultado",total_many_results:"[COUNT] resultados",alt_search:"Nenhum resultado encontrado para [SEARCH_TERM]. Exibindo resultados para [DIFFERENT_TERM]",search_suggestion:"Nenhum resultado encontrado para [SEARCH_TERM]. Tente uma das seguintes pesquisas:",searching:"Pesquisando por [SEARCH_TERM]...",results_label:"Resultados da pesquisa",keyboard_navigate:"navegar",keyboard_select:"selecionar",keyboard_clear:"limpar",keyboard_close:"fechar",keyboard_search:"pesquisar",error_search:"Falha na pesquisa",filter_selected_one:"[COUNT] selecionado",filter_selected_many:"[COUNT] selecionados",input_hint:"Os resultados aparecer\xE3o enquanto voc\xEA digita",loading:"Carregando"},tn={thanks_to:Zi,comments:Xi,direction:Qi,strings:en};var yt={};h(yt,{comments:()=>rn,default:()=>ln,direction:()=>nn,strings:()=>an,thanks_to:()=>sn});var sn="Bogdan Mateescu ",rn="",nn="ltr",an={placeholder:"C\u0103utare",clear_search:"\u015Eterge\u0163i",load_more:"\xCEnc\u0103rca\u021Bi mai multe rezultate",search_label:"C\u0103uta\u021Bi \xEEn acest site",filters_label:"Filtre",zero_results:"Niciun rezultat pentru [SEARCH_TERM]",many_results:"[COUNT] rezultate pentru [SEARCH_TERM]",one_result:"[COUNT] rezultat pentru [SEARCH_TERM]",total_zero_results:"Niciun rezultat",total_one_result:"[COUNT] rezultat",total_many_results:"[COUNT] rezultate",alt_search:"Niciun rezultat pentru [SEARCH_TERM]. Se afi\u0219eaz\u0103 \xEEn schimb rezultatele pentru [DIFFERENT_TERM]",search_suggestion:"Niciun rezultat pentru [SEARCH_TERM]. \xCEncerca\u021Bi una dintre urm\u0103toarele c\u0103ut\u0103ri:",searching:"Se caut\u0103 dup\u0103: [SEARCH_TERM]...",results_label:"Rezultatele c\u0103ut\u0103rii",keyboard_navigate:"navigare",keyboard_select:"selectare",keyboard_clear:"\u0219tergere",keyboard_close:"\xEEnchidere",keyboard_search:"c\u0103utare",error_search:"C\u0103utarea a e\u0219uat",filter_selected_one:"[COUNT] selectat",filter_selected_many:"[COUNT] selectate",input_hint:"Rezultatele vor ap\u0103rea pe m\u0103sur\u0103 ce tasta\u021Bi",loading:"Se \xEEncarc\u0103"},ln={thanks_to:sn,comments:rn,direction:nn,strings:an};var vt={};h(vt,{comments:()=>cn,default:()=>hn,direction:()=>un,strings:()=>dn,thanks_to:()=>on});var on="Aleksandr Gordeev",cn="",un="ltr",dn={placeholder:"\u041F\u043E\u0438\u0441\u043A",clear_search:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u043F\u043E\u043B\u0435",load_more:"\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0449\u0435",search_label:"\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u0441\u0430\u0439\u0442\u0443",filters_label:"\u0424\u0438\u043B\u044C\u0442\u0440\u044B",zero_results:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432 \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",total_zero_results:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E",total_one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442",total_many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432",alt_search:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]. \u041F\u043E\u043A\u0430\u0437\u0430\u043D\u044B \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [DIFFERENT_TERM]",search_suggestion:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043E\u0434\u0438\u043D \u0438\u0437 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u0432",searching:"\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",results_label:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043F\u043E\u0438\u0441\u043A\u0430",keyboard_navigate:"\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044F",keyboard_select:"\u0432\u044B\u0431\u0440\u0430\u0442\u044C",keyboard_clear:"\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",keyboard_close:"\u0437\u0430\u043A\u0440\u044B\u0442\u044C",keyboard_search:"\u043F\u043E\u0438\u0441\u043A",error_search:"\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u043E\u0438\u0441\u043A\u0430",filter_selected_one:"[COUNT] \u0432\u044B\u0431\u0440\u0430\u043D",filter_selected_many:"[COUNT] \u0432\u044B\u0431\u0440\u0430\u043D\u043E",input_hint:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u044F\u0432\u043B\u044F\u0442\u044C\u0441\u044F \u043F\u043E \u043C\u0435\u0440\u0435 \u0432\u0432\u043E\u0434\u0430",loading:"\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430"},hn={thanks_to:on,comments:cn,direction:un,strings:dn};var Rt={};h(Rt,{comments:()=>mn,default:()=>gn,direction:()=>_n,strings:()=>fn,thanks_to:()=>pn});var pn="Andrija Sagicc",mn="",_n="ltr",fn={placeholder:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430",clear_search:"\u0411\u0440\u0438\u0441\u0430\u045A\u0435",load_more:"\u041F\u0440\u0438\u043A\u0430\u0437 \u0432\u0438\u0448\u0435 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430",search_label:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u0441\u0430\u0458\u0442\u0430",filters_label:"\u0424\u0438\u043B\u0442\u0435\u0440\u0438",zero_results:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",total_zero_results:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430",total_one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442",total_many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430",alt_search:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]. \u041F\u0440\u0438\u043A\u0430\u0437 \u0434\u043E\u0434\u0430\u0442\u043D\u0438\u043A \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [DIFFERENT_TERM]",search_suggestion:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]. \u041F\u043E\u043A\u0443\u0448\u0430\u0458\u0442\u0435 \u0441\u0430 \u043D\u0435\u043A\u043E\u043C \u043E\u0434 \u0441\u043B\u0435\u0434\u0435\u045B\u0438\u0445 \u043F\u0440\u0435\u0442\u0440\u0430\u0433\u0430:",searching:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u0442\u0435\u0440\u043C\u0438\u043D\u0430 [SEARCH_TERM]...",results_label:"\u0420\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0438 \u043F\u0440\u0435\u0442\u0440\u0430\u0433\u0435",keyboard_navigate:"\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0458\u0430",keyboard_select:"\u0438\u0437\u0430\u0431\u0435\u0440\u0438",keyboard_clear:"\u043E\u0431\u0440\u0438\u0448\u0438",keyboard_close:"\u0437\u0430\u0442\u0432\u043E\u0440\u0438",keyboard_search:"\u043F\u0440\u0435\u0442\u0440\u0430\u0433\u0430",error_search:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u0430",filter_selected_one:"[COUNT] \u0438\u0437\u0430\u0431\u0440\u0430\u043D",filter_selected_many:"[COUNT] \u0438\u0437\u0430\u0431\u0440\u0430\u043D\u0438\u0445",input_hint:"\u0420\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0438 \u045B\u0435 \u0441\u0435 \u043F\u043E\u0458\u0430\u0432\u0459\u0438\u0432\u0430\u0442\u0438 \u0434\u043E\u043A \u043A\u0443\u0446\u0430\u0442\u0435",loading:"\u0423\u0447\u0438\u0442\u0430\u0432\u0430\u045A\u0435"},gn={thanks_to:pn,comments:mn,direction:_n,strings:fn};var kt={};h(kt,{comments:()=>bn,default:()=>yn,direction:()=>Tn,strings:()=>Cn,thanks_to:()=>En});var En="Montazar Al-Jaber ",bn="",Tn="ltr",Cn={placeholder:"S\xF6k",clear_search:"Rensa",load_more:"Visa fler tr\xE4ffar",search_label:"S\xF6k p\xE5 denna sida",filters_label:"Filter",zero_results:"[SEARCH_TERM] gav inga tr\xE4ffar",many_results:"[SEARCH_TERM] gav [COUNT] tr\xE4ffar",one_result:"[SEARCH_TERM] gav [COUNT] tr\xE4ff",total_zero_results:"Inga tr\xE4ffar",total_one_result:"[COUNT] tr\xE4ff",total_many_results:"[COUNT] tr\xE4ffar",alt_search:"[SEARCH_TERM] gav inga tr\xE4ffar. Visar resultat f\xF6r [DIFFERENT_TERM] ist\xE4llet",search_suggestion:"[SEARCH_TERM] gav inga tr\xE4ffar. F\xF6rs\xF6k igen med en av f\xF6ljande s\xF6kord:",searching:"S\xF6ker efter [SEARCH_TERM]...",results_label:"S\xF6kresultat",keyboard_navigate:"navigera",keyboard_select:"v\xE4lj",keyboard_clear:"rensa",keyboard_close:"st\xE4ng",keyboard_search:"s\xF6k",error_search:"S\xF6kningen misslyckades",filter_selected_one:"[COUNT] vald",filter_selected_many:"[COUNT] valda",input_hint:"Resultat visas medan du skriver",loading:"L\xE4ser in"},yn={thanks_to:En,comments:bn,direction:Tn,strings:Cn};var At={};h(At,{comments:()=>Rn,default:()=>Sn,direction:()=>kn,strings:()=>An,thanks_to:()=>vn});var vn="Anonymous",Rn="",kn="ltr",An={placeholder:"Tafuta",clear_search:"Futa",load_more:"Pakia matokeo zaidi",search_label:"Tafuta tovuti hii",filters_label:"Vichujio",zero_results:"Hakuna matokeo ya [SEARCH_TERM]",many_results:"Matokeo [COUNT] ya [SEARCH_TERM]",one_result:"Tokeo [COUNT] la [SEARCH_TERM]",total_zero_results:"Hakuna matokeo",total_one_result:"Tokeo [COUNT]",total_many_results:"Matokeo [COUNT]",alt_search:"Hakuna mayokeo ya [SEARCH_TERM]. Badala yake, inaonyesha matokeo ya [DIFFERENT_TERM]",search_suggestion:"Hakuna matokeo ya [SEARCH_TERM]. Jaribu mojawapo ya utafutaji ufuatao:",searching:"Kutafuta [SEARCH_TERM]...",results_label:"Matokeo ya utafutaji",keyboard_navigate:"sogeza",keyboard_select:"chagua",keyboard_clear:"futa",keyboard_close:"funga",keyboard_search:"tafuta",error_search:"Utafutaji umeshindwa",filter_selected_one:"[COUNT] imechaguliwa",filter_selected_many:"[COUNT] zimechaguliwa",input_hint:"Matokeo yataonekana unapoandika",loading:"Inapakia"},Sn={thanks_to:vn,comments:Rn,direction:kn,strings:An};var St={};h(St,{comments:()=>Mn,default:()=>Hn,direction:()=>On,strings:()=>xn,thanks_to:()=>Nn});var Nn="",Mn="",On="ltr",xn={placeholder:"\u0BA4\u0BC7\u0B9F\u0BC1\u0B95",clear_search:"\u0B85\u0BB4\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0B95",load_more:"\u0BAE\u0BC7\u0BB2\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BC8\u0B95\u0BCD \u0B95\u0BBE\u0B9F\u0BCD\u0B9F\u0BC1\u0B95",search_label:"\u0B87\u0BA8\u0BCD\u0BA4 \u0BA4\u0BB3\u0BA4\u0BCD\u0BA4\u0BBF\u0BB2\u0BCD \u0BA4\u0BC7\u0B9F\u0BC1\u0B95",filters_label:"\u0BB5\u0B9F\u0BBF\u0B95\u0B9F\u0BCD\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BCD",zero_results:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8",many_results:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 [COUNT] \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD",one_result:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1",total_zero_results:"\u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8",total_one_result:"[COUNT] \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1",total_many_results:"[COUNT] \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD",alt_search:"[SEARCH_TERM] \u0B87\u0BA4\u0BCD\u0BA4\u0BC7\u0B9F\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8, \u0B87\u0BA8\u0BCD\u0BA4 \u0BA4\u0BC7\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B92\u0BA4\u0BCD\u0BA4 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD [DIFFERENT_TERM]",search_suggestion:"[SEARCH_TERM] \u0B87\u0BA4\u0BCD \u0BA4\u0BC7\u0B9F\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8.\u0B87\u0BA4\u0BB1\u0BCD\u0B95\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC0\u0B9F\u0BBE\u0BA9 \u0BA4\u0BC7\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BC8 \u0BA4\u0BC7\u0B9F\u0BC1\u0B95:",searching:"[SEARCH_TERM] \u0BA4\u0BC7\u0B9F\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0B95\u0BBF\u0BA9\u0BCD\u0BB1\u0BA4\u0BC1",results_label:"\u0BA4\u0BC7\u0B9F\u0BB2\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD",keyboard_navigate:"\u0BB5\u0BB4\u0BBF\u0BA8\u0B9F\u0BA4\u0BCD\u0BA4\u0BC1",keyboard_select:"\u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1",keyboard_clear:"\u0B85\u0BB4\u0BBF",keyboard_close:"\u0BAE\u0BC2\u0B9F\u0BC1",keyboard_search:"\u0BA4\u0BC7\u0B9F\u0BC1",error_search:"\u0BA4\u0BC7\u0B9F\u0BB2\u0BCD \u0BA4\u0BCB\u0BB2\u0BCD\u0BB5\u0BBF",filter_selected_one:"[COUNT] \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1",filter_selected_many:"[COUNT] \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA9",input_hint:"\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BA4\u0B9F\u0BCD\u0B9F\u0B9A\u0BCD\u0B9A\u0BC1 \u0B9A\u0BC6\u0BAF\u0BCD\u0BAF\u0BC1\u0BAE\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0BA4\u0BCB\u0BA9\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD",loading:"\u0B8F\u0BB1\u0BCD\u0BB1\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1"},Hn={thanks_to:Nn,comments:Mn,direction:On,strings:xn};var Nt={};h(Nt,{comments:()=>In,default:()=>Fn,direction:()=>Un,strings:()=>Ln,thanks_to:()=>wn});var wn="Patiphon Loetsuthakun ",In="",Un="ltr",Ln={placeholder:"\u0E04\u0E49\u0E19\u0E2B\u0E32",clear_search:"\u0E25\u0E49\u0E32\u0E07",load_more:"\u0E42\u0E2B\u0E25\u0E14\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E40\u0E15\u0E34\u0E21",search_label:"\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E1A\u0E19\u0E40\u0E27\u0E47\u0E1A\u0E44\u0E0B\u0E15\u0E4C",filters_label:"\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07",zero_results:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",many_results:"\u0E1E\u0E1A [COUNT] \u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",one_result:"\u0E1E\u0E1A [COUNT] \u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",total_zero_results:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C",total_one_result:"[COUNT] \u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C",total_many_results:"[COUNT] \u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C",alt_search:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM] \u0E41\u0E2A\u0E14\u0E07\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E08\u0E32\u0E01\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32 [DIFFERENT_TERM] \u0E41\u0E17\u0E19",search_suggestion:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM] \u0E25\u0E2D\u0E07\u0E04\u0E33\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E40\u0E2B\u0E25\u0E48\u0E32\u0E19\u0E35\u0E49\u0E41\u0E17\u0E19:",searching:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E04\u0E49\u0E19\u0E2B\u0E32 [SEARCH_TERM]...",results_label:"\u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32",keyboard_navigate:"\u0E19\u0E33\u0E17\u0E32\u0E07",keyboard_select:"\u0E40\u0E25\u0E37\u0E2D\u0E01",keyboard_clear:"\u0E25\u0E49\u0E32\u0E07",keyboard_close:"\u0E1B\u0E34\u0E14",keyboard_search:"\u0E04\u0E49\u0E19\u0E2B\u0E32",error_search:"\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27",filter_selected_one:"\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27 [COUNT] \u0E23\u0E32\u0E22\u0E01\u0E32\u0E23",filter_selected_many:"\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27 [COUNT] \u0E23\u0E32\u0E22\u0E01\u0E32\u0E23",input_hint:"\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E08\u0E30\u0E1B\u0E23\u0E32\u0E01\u0E0F\u0E02\u0E13\u0E30\u0E17\u0E35\u0E48\u0E04\u0E38\u0E13\u0E1E\u0E34\u0E21\u0E1E\u0E4C",loading:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14"},Fn={thanks_to:wn,comments:In,direction:Un,strings:Ln};var Mt={};h(Mt,{comments:()=>zn,default:()=>Bn,direction:()=>Dn,strings:()=>jn,thanks_to:()=>Pn});var Pn="Taylan \xD6zg\xFCr Bildik",zn="",Dn="ltr",jn={placeholder:"Ara\u015Ft\u0131r",clear_search:"Temizle",load_more:"Daha fazla sonu\xE7",search_label:"Site genelinde arama",filters_label:"Filtreler",zero_results:"[SEARCH_TERM] i\xE7in sonu\xE7 yok",many_results:"[SEARCH_TERM] i\xE7in [COUNT] sonu\xE7 bulundu",one_result:"[SEARCH_TERM] i\xE7in [COUNT] sonu\xE7 bulundu",total_zero_results:"Sonu\xE7 yok",total_one_result:"[COUNT] sonu\xE7",total_many_results:"[COUNT] sonu\xE7",alt_search:"[SEARCH_TERM] i\xE7in sonu\xE7 yok. Bunun yerine [DIFFERENT_TERM] i\xE7in sonu\xE7lar g\xF6steriliyor",search_suggestion:"[SEARCH_TERM] i\xE7in sonu\xE7 yok. Alternatif olarak a\u015Fa\u011F\u0131daki kelimelerden birini deneyebilirsiniz:",searching:"[SEARCH_TERM] ara\u015Ft\u0131r\u0131l\u0131yor...",results_label:"Arama sonu\xE7lar\u0131",keyboard_navigate:"gezin",keyboard_select:"se\xE7",keyboard_clear:"temizle",keyboard_close:"kapat",keyboard_search:"ara",error_search:"Arama ba\u015Far\u0131s\u0131z",filter_selected_one:"[COUNT] se\xE7ili",filter_selected_many:"[COUNT] se\xE7ili",input_hint:"Sonu\xE7lar siz yazarken g\xF6r\xFCnecektir",loading:"Y\xFCkleniyor"},Bn={thanks_to:Pn,comments:zn,direction:Dn,strings:jn};var Ot={};h(Ot,{comments:()=>$n,default:()=>Gn,direction:()=>Vn,strings:()=>qn,thanks_to:()=>Kn});var Kn="Vladyslav Lyshenko ",$n="",Vn="ltr",qn={placeholder:"\u041F\u043E\u0448\u0443\u043A",clear_search:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u043F\u043E\u043B\u0435",load_more:"\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0449\u0435",search_label:"\u041F\u043E\u0448\u0443\u043A \u043F\u043E \u0441\u0430\u0439\u0442\u0443",filters_label:"\u0424\u0456\u043B\u044C\u0442\u0440\u0438",zero_results:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0456\u0432 \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",total_zero_results:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E",total_one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442",total_many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0456\u0432",alt_search:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]. \u041F\u043E\u043A\u0430\u0437\u0430\u043D\u043E \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0438 \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [DIFFERENT_TERM]",search_suggestion:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]. \u0421\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043E\u0434\u0438\u043D \u0456\u0437 \u0442\u0430\u043A\u0438\u0445 \u0432\u0430\u0440\u0456\u0430\u043D\u0442\u0456\u0432",searching:"\u041F\u043E\u0448\u0443\u043A \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",results_label:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0438 \u043F\u043E\u0448\u0443\u043A\u0443",keyboard_navigate:"\u043D\u0430\u0432\u0456\u0433\u0430\u0446\u0456\u044F",keyboard_select:"\u0432\u0438\u0431\u0440\u0430\u0442\u0438",keyboard_clear:"\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u0438",keyboard_close:"\u0437\u0430\u043A\u0440\u0438\u0442\u0438",keyboard_search:"\u043F\u043E\u0448\u0443\u043A",error_search:"\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u043E\u0448\u0443\u043A\u0443",filter_selected_one:"[COUNT] \u0432\u0438\u0431\u0440\u0430\u043D\u043E",filter_selected_many:"[COUNT] \u0432\u0438\u0431\u0440\u0430\u043D\u043E",input_hint:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0438 \u0437'\u044F\u0432\u043B\u044F\u0442\u0438\u043C\u0443\u0442\u044C\u0441\u044F \u043F\u0456\u0434 \u0447\u0430\u0441 \u0432\u0432\u0435\u0434\u0435\u043D\u043D\u044F",loading:"\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F"},Gn={thanks_to:Kn,comments:$n,direction:Vn,strings:qn};var xt={};h(xt,{comments:()=>Yn,default:()=>Xn,direction:()=>Jn,strings:()=>Zn,thanks_to:()=>Wn});var Wn="Long Nhat Nguyen",Yn="",Jn="ltr",Zn={placeholder:"T\xECm ki\u1EBFm",clear_search:"X\xF3a",load_more:"Nhi\u1EC1u k\u1EBFt qu\u1EA3 h\u01A1n",search_label:"T\xECm ki\u1EBFm trong trang n\xE0y",filters_label:"B\u1ED9 l\u1ECDc",zero_results:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",many_results:"[COUNT] k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",one_result:"[COUNT] k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",total_zero_results:"Kh\xF4ng c\xF3 k\u1EBFt qu\u1EA3",total_one_result:"[COUNT] k\u1EBFt qu\u1EA3",total_many_results:"[COUNT] k\u1EBFt qu\u1EA3",alt_search:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]. Ki\u1EC3m th\u1ECB k\u1EBFt qu\u1EA3 thay th\u1EBF v\u1EDBi [DIFFERENT_TERM]",search_suggestion:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]. Th\u1EED m\u1ED9t trong c\xE1c t\xECm ki\u1EBFm:",searching:"\u0110ang t\xECm ki\u1EBFm cho [SEARCH_TERM]...",results_label:"K\u1EBFt qu\u1EA3 t\xECm ki\u1EBFm",keyboard_navigate:"chuy\u1EC3n",keyboard_select:"ch\u1ECDn",keyboard_clear:"x\xF3a",keyboard_close:"\u0111\xF3ng",keyboard_search:"t\xECm ki\u1EBFm",error_search:"T\xECm ki\u1EBFm th\u1EA5t b\u1EA1i",filter_selected_one:"\u0110\xE3 ch\u1ECDn [COUNT]",filter_selected_many:"\u0110\xE3 ch\u1ECDn [COUNT]",input_hint:"K\u1EBFt qu\u1EA3 s\u1EBD xu\u1EA5t hi\u1EC7n khi b\u1EA1n nh\u1EADp",loading:"\u0110ang t\u1EA3i"},Xn={thanks_to:Wn,comments:Yn,direction:Jn,strings:Zn};var Ht={};h(Ht,{comments:()=>ea,default:()=>ra,direction:()=>ta,strings:()=>sa,thanks_to:()=>Qn});var Qn="Amber Song",ea="",ta="ltr",sa={placeholder:"\u641C\u7D22",clear_search:"\u6E05\u9664",load_more:"\u52A0\u8F7D\u66F4\u591A\u7ED3\u679C",search_label:"\u7AD9\u5185\u641C\u7D22",filters_label:"\u7B5B\u9009",zero_results:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",many_results:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",one_result:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",total_zero_results:"\u65E0\u7ED3\u679C",total_one_result:"[COUNT] \u4E2A\u7ED3\u679C",total_many_results:"[COUNT] \u4E2A\u7ED3\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u6539\u4E3A\u663E\u793A [DIFFERENT_TERM] \u7684\u76F8\u5173\u7ED3\u679C",search_suggestion:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u8BF7\u5C1D\u8BD5\u4EE5\u4E0B\u641C\u7D22\u3002",searching:"\u6B63\u5728\u641C\u7D22 [SEARCH_TERM]...",results_label:"\u641C\u7D22\u7ED3\u679C",keyboard_navigate:"\u5BFC\u822A",keyboard_select:"\u9009\u62E9",keyboard_clear:"\u6E05\u9664",keyboard_close:"\u5173\u95ED",keyboard_search:"\u641C\u7D22",error_search:"\u641C\u7D22\u5931\u8D25",filter_selected_one:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",filter_selected_many:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",input_hint:"\u8F93\u5165\u65F6\u5C06\u663E\u793A\u7ED3\u679C",loading:"\u52A0\u8F7D\u4E2D"},ra={thanks_to:Qn,comments:ea,direction:ta,strings:sa};var wt={};h(wt,{comments:()=>na,default:()=>oa,direction:()=>aa,strings:()=>la,thanks_to:()=>ia});var ia="Amber Song",na="",aa="ltr",la={placeholder:"\u641C\u5C0B",clear_search:"\u6E05\u9664",load_more:"\u8F09\u5165\u66F4\u591A\u7D50\u679C",search_label:"\u7AD9\u5167\u641C\u5C0B",filters_label:"\u7BE9\u9078",zero_results:"\u627E\u4E0D\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",many_results:"\u627E\u5230 [COUNT] \u500B [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",one_result:"\u627E\u5230 [COUNT] \u500B [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",total_zero_results:"\u7121\u7D50\u679C",total_one_result:"[COUNT] \u500B\u7D50\u679C",total_many_results:"[COUNT] \u500B\u7D50\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C\u3002\u6539\u70BA\u986F\u793A [DIFFERENT_TERM] \u7684\u76F8\u95DC\u7D50\u679C",search_suggestion:"\u627E\u4E0D\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C\u3002\u8ACB\u5617\u8A66\u4EE5\u4E0B\u7684\u5EFA\u8B70\u4E4B\u4E00\u3002",searching:"\u6B63\u5728\u641C\u5C0B[SEARCH_TERM]...",results_label:"\u641C\u5C0B\u7D50\u679C",keyboard_navigate:"\u5C0E\u89BD",keyboard_select:"\u9078\u64C7",keyboard_clear:"\u6E05\u9664",keyboard_close:"\u95DC\u9589",keyboard_search:"\u641C\u5C0B",error_search:"\u641C\u5C0B\u5931\u6557",filter_selected_one:"\u5DF2\u9078\u64C7 [COUNT] \u500B",filter_selected_many:"\u5DF2\u9078\u64C7 [COUNT] \u500B",input_hint:"\u8F38\u5165\u6642\u5C07\u986F\u793A\u7D50\u679C",loading:"\u8F09\u5165\u4E2D"},oa={thanks_to:ia,comments:na,direction:aa,strings:la};var It={};h(It,{comments:()=>ua,default:()=>pa,direction:()=>da,strings:()=>ha,thanks_to:()=>ca});var ca="Amber Song",ua="",da="ltr",ha={placeholder:"\u641C\u7D22",clear_search:"\u6E05\u9664",load_more:"\u52A0\u8F7D\u66F4\u591A\u7ED3\u679C",search_label:"\u7AD9\u5185\u641C\u7D22",filters_label:"\u7B5B\u9009",zero_results:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",many_results:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",one_result:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",total_zero_results:"\u65E0\u7ED3\u679C",total_one_result:"[COUNT] \u4E2A\u7ED3\u679C",total_many_results:"[COUNT] \u4E2A\u7ED3\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u6539\u4E3A\u663E\u793A [DIFFERENT_TERM] \u7684\u76F8\u5173\u7ED3\u679C",search_suggestion:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u8BF7\u5C1D\u8BD5\u4EE5\u4E0B\u641C\u7D22\u3002",searching:"\u6B63\u5728\u641C\u7D22 [SEARCH_TERM]...",results_label:"\u641C\u7D22\u7ED3\u679C",keyboard_navigate:"\u5BFC\u822A",keyboard_select:"\u9009\u62E9",keyboard_clear:"\u6E05\u9664",keyboard_close:"\u5173\u95ED",keyboard_search:"\u641C\u7D22",error_search:"\u641C\u7D22\u5931\u8D25",filter_selected_one:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",filter_selected_many:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",input_hint:"\u8F93\u5165\u65F6\u5C06\u663E\u793A\u7ED3\u679C",loading:"\u52A0\u8F7D\u4E2D"},pa={thanks_to:ca,comments:ua,direction:da,strings:ha};var ma=[Ve,qe,Ge,We,Ye,Je,Ze,Xe,Qe,et,tt,st,rt,it,nt,at,lt,ot,ct,ut,dt,ht,pt,mt,_t,ft,gt,Et,bt,Tt,Ct,yt,vt,Rt,kt,At,St,Nt,Mt,Ot,xt,Ht,wt,It],Vt=ma,qt=["../../translations/af.json","../../translations/ar.json","../../translations/bn.json","../../translations/ca.json","../../translations/cs.json","../../translations/da.json","../../translations/de.json","../../translations/el.json","../../translations/en.json","../../translations/es.json","../../translations/eu.json","../../translations/fa.json","../../translations/fi.json","../../translations/fr.json","../../translations/gl.json","../../translations/he.json","../../translations/hi.json","../../translations/hr.json","../../translations/hu.json","../../translations/id.json","../../translations/it.json","../../translations/ja.json","../../translations/ko.json","../../translations/mi.json","../../translations/my.json","../../translations/nb.json","../../translations/nl.json","../../translations/nn.json","../../translations/no.json","../../translations/pl.json","../../translations/pt.json","../../translations/ro.json","../../translations/ru.json","../../translations/sr.json","../../translations/sv.json","../../translations/sw.json","../../translations/ta.json","../../translations/th.json","../../translations/tr.json","../../translations/uk.json","../../translations/vi.json","../../translations/zh-cn.json","../../translations/zh-tw.json","../../translations/zh.json"];function b(n){let s=typeof n=="string"?n.charCodeAt(0):n;return s>=97&&s<=122||s>=65&&s<=90}function A(n){let s=typeof n=="string"?n.charCodeAt(0):n;return s>=48&&s<=57}function k(n){return b(n)||A(n)}var Gt=["art-lojban","cel-gaulish","no-bok","no-nyn","zh-guoyu","zh-hakka","zh-min","zh-min-nan","zh-xiang"];var Ut={"en-gb-oed":"en-GB-oxendict","i-ami":"ami","i-bnn":"bnn","i-default":null,"i-enochian":null,"i-hak":"hak","i-klingon":"tlh","i-lux":"lb","i-mingo":null,"i-navajo":"nv","i-pwn":"pwn","i-tao":"tao","i-tay":"tay","i-tsu":"tsu","sgn-be-fr":"sfb","sgn-be-nl":"vgt","sgn-ch-de":"sgg","art-lojban":"jbo","cel-gaulish":null,"no-bok":"nb","no-nyn":"nn","zh-guoyu":"cmn","zh-hakka":"hak","zh-min":null,"zh-min-nan":"nan","zh-xiang":"hsn"};var fa={}.hasOwnProperty;function ze(n,s={}){let e=Wt(),t=String(n),r=t.toLowerCase(),i=0;if(n==null)throw new Error("Expected string, got `"+n+"`");if(fa.call(Ut,r)){let l=Ut[r];return(s.normalize===void 0||s.normalize===null||s.normalize)&&typeof l=="string"?ze(l):(e[Gt.includes(r)?"regular":"irregular"]=t,e)}for(;b(r.charCodeAt(i))&&i<9;)i++;if(i>1&&i<9){if(e.language=t.slice(0,i),i<4){let l=0;for(;r.charCodeAt(i)===45&&b(r.charCodeAt(i+1))&&b(r.charCodeAt(i+2))&&b(r.charCodeAt(i+3))&&!b(r.charCodeAt(i+4));){if(l>2)return a(i,3,"Too many extended language subtags, expected at most 3 subtags");e.extendedLanguageSubtags.push(t.slice(i+1,i+4)),i+=4,l++}}for(r.charCodeAt(i)===45&&b(r.charCodeAt(i+1))&&b(r.charCodeAt(i+2))&&b(r.charCodeAt(i+3))&&b(r.charCodeAt(i+4))&&!b(r.charCodeAt(i+5))&&(e.script=t.slice(i+1,i+5),i+=5),r.charCodeAt(i)===45&&(b(r.charCodeAt(i+1))&&b(r.charCodeAt(i+2))&&!b(r.charCodeAt(i+3))?(e.region=t.slice(i+1,i+3),i+=3):A(r.charCodeAt(i+1))&&A(r.charCodeAt(i+2))&&A(r.charCodeAt(i+3))&&!A(r.charCodeAt(i+4))&&(e.region=t.slice(i+1,i+4),i+=4));r.charCodeAt(i)===45;){let l=i+1,o=l;for(;k(r.charCodeAt(o));){if(o-l>7)return a(o,1,"Too long variant, expected at most 8 characters");o++}if(o-l>4||o-l>3&&A(r.charCodeAt(l)))e.variants.push(t.slice(l,o)),i=o;else break}for(;r.charCodeAt(i)===45&&!(r.charCodeAt(i+1)===120||!k(r.charCodeAt(i+1))||r.charCodeAt(i+2)!==45||!k(r.charCodeAt(i+3)));){let l=i+2,o=0;for(;r.charCodeAt(l)===45&&k(r.charCodeAt(l+1))&&k(r.charCodeAt(l+2));){let c=l+1;for(l=c+2,o++;k(r.charCodeAt(l));){if(l-c>7)return a(l,2,"Too long extension, expected at most 8 characters");l++}}if(!o)return a(l,4,"Empty extension, extensions must have at least 2 characters of content");e.extensions.push({singleton:t.charAt(i+1),extensions:t.slice(i+3,l).split("-")}),i=l}}else i=0;if(i===0&&r.charCodeAt(i)===120||r.charCodeAt(i)===45&&r.charCodeAt(i+1)===120){i=i?i+2:1;let l=i;for(;r.charCodeAt(l)===45&&k(r.charCodeAt(l+1));){let o=i+1;for(l=o;k(r.charCodeAt(l));){if(l-o>7)return a(l,5,"Too long private-use area, expected at most 8 characters");l++}e.privateuse.push(t.slice(i+1,l)),i=l}}if(i!==t.length)return a(i,6,"Found superfluous content after tag");return e;function a(l,o,c){return s.warning&&s.warning(c,o,l),s.forgiving?e:Wt()}}function Wt(){return{language:null,extendedLanguageSubtags:[],script:null,region:null,variants:[],extensions:[],privateuse:[],irregular:null,regular:null}}var be={},Yt=qt,Jt=Vt;for(let n=0;n"u")return;let s=document.createElement("div");s.id=this.containerId,s.setAttribute("data-pagefind-announcer","");let e=t=>{let r=[];for(let i=0;i<2;i++){let a=document.createElement("div");a.id=this.idGenerator(`pf-${t}-region`),a.setAttribute("role","status"),a.setAttribute("aria-live",t),a.setAttribute("aria-atomic","true"),a.setAttribute("data-pf-sr-hidden",""),s.appendChild(a),r.push(a)}return r};this.regions={polite:e("polite"),assertive:e("assertive")},document.body.appendChild(s)}announce(s,e="polite"){if(!this.regions||!s)return;this.clearTimeoutId&&(clearTimeout(this.clearTimeoutId),this.clearTimeoutId=null);let t=e==="polite"?this.politeIndex:this.assertiveIndex,r=this.regions[e][t];e==="polite"?this.politeIndex=t===0?1:0:this.assertiveIndex=t===0?1:0;let i=e==="polite"?this.politeIndex:this.assertiveIndex;this.regions[e][i].textContent="",setTimeout(()=>{r.textContent=s,this.clearTimeoutId=setTimeout(()=>{r.textContent="",this.clearTimeoutId=null},350)},100)}clear(){if(this.regions){this.clearTimeoutId&&(clearTimeout(this.clearTimeoutId),this.clearTimeoutId=null);for(let s of["polite","assertive"])for(let e of this.regions[s])e.textContent=""}}destroy(){if(this.clear(),typeof document<"u"){let s=document.getElementById(this.containerId);s&&s.remove()}this.regions=null}};var Lt;try{if(document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"){let n=new URL(document.currentScript.src).pathname.match(/^(.*\/)(?:pagefind[-_])?component[-_]?ui.js.*$/);n&&(Lt=n[1])}}catch{Lt="/pagefind/"}var Te=class{constructor(s,e={}){this.__pagefind__=null;this.__loadPromise__=null;this.__searchID__=0;this._translations=null;this._userTranslations={};this._direction="ltr";this._languageSet=!1;this.components=[];this.componentsByType={};this.searchTerm="";this.searchFilters={};this.searchResult={results:[]};this.availableFilters=null;this.totalFilters=null;this.activeShortcuts=[];this.faceted=!1;this.generatedIds=new Set;this.name=s,this.__hooks__={search:[],filters:[],loading:[],results:[],error:[],translations:[]},this.options={bundlePath:e.bundlePath??Lt??"/pagefind/",mergeIndex:e.mergeIndex??[]};let t={...e};delete t.bundlePath,delete t.mergeIndex,this.pagefindOptions=t,this._announcer=new De(this.generateId.bind(this))}generateId(s,e=2){let t="abcdef",r=(o=3)=>{let c="";for(let u=0;ur()).join("-"),l=`${s}-${i}${a}`;return this.generatedIds.has(l)||document.getElementById(l)?this.generateId(s,e+1):(this.generatedIds.add(l),l)}add(s){s?.register?.(this),this.components.push(s)}registerInput(s,e={}){this._registerComponent(s,"input",null,e)}registerResults(s,e={}){this._registerComponent(s,"results",null,e)}registerSummary(s,e={}){this._registerComponent(s,"summary",null,e)}registerFilter(s,e={}){this._registerComponent(s,"filter",null,e)}registerSort(s,e={}){this._registerComponent(s,"sort",null,e)}registerUtility(s,e=null,t={}){this._registerComponent(s,"utility",e,t)}_registerComponent(s,e,t=null,r={}){if(this.componentsByType[e]||(this.componentsByType[e]=[]),this._languageSet||this.setLanguage(),this.components.includes(s)){s.capabilities=r,this.reconcileAria();return}s.componentType=e,s.componentSubtype=t,s.capabilities=r,this.componentsByType[e].push(s),this.components.push(s),this.reconcileAria()}getInputs(s=null){let e=this.componentsByType.input||[];return s?e.filter(t=>t.capabilities?.[s]):e}getResults(s=null){let e=this.componentsByType.results||[];return s?e.filter(t=>t.capabilities?.[s]):e}getSummaries(s=null){let e=this.componentsByType.summary||[];return s?e.filter(t=>t.capabilities?.[s]):e}getFilters(s=null){let e=this.componentsByType.filter||[];return s?e.filter(t=>t.capabilities?.[s]):e}getSorts(s=null){let e=this.componentsByType.sort||[];return s?e.filter(t=>t.capabilities?.[s]):e}getUtilities(s=null,e=null){let t=this.componentsByType.utility||[];return s!==null&&(t=t.filter(r=>r.componentSubtype===s)),e&&(t=t.filter(r=>r.capabilities?.[e])),t}hasAnnouncementCapability(){return this.components.some(s=>s.capabilities?.announcements===!0)}registerShortcut(s,e){let t={...s,owner:e};this.activeShortcuts.push(t),this.notifyShortcutsChanged()}deregisterShortcut(s,e){this.activeShortcuts=this.activeShortcuts.filter(t=>!(t.label===s&&t.owner===e)),this.notifyShortcutsChanged()}deregisterAllShortcuts(s){this.activeShortcuts=this.activeShortcuts.filter(e=>e.owner!==s),this.notifyShortcutsChanged()}getActiveShortcuts(){return this.activeShortcuts}notifyShortcutsChanged(){this.getUtilities("keyboard-hints").forEach(e=>e.render?.())}focusNextResults(s){let e=this.getResults("keyboardNavigation"),t=$t(s,e);if(!t)return!1;let r=t.querySelector("a");return r?(r.focus(),!0):!1}focusPreviousInput(s){let e=this.getInputs("keyboardNavigation"),t=Pe(s,e);if(!t)return!1;if(t.focus)return t.focus(),!0;let r=t.querySelector("input");return r?(r.focus(),!0):!1}focusInputAndType(s,e){let t=this.getInputs("keyboardNavigation"),r=Pe(s,t),i=r?.inputEl||r?.querySelector("input");i&&(i.value+=e,i.focus(),i.dispatchEvent(new Event("input",{bubbles:!0})))}focusInputAndDelete(s){let e=this.getInputs("keyboardNavigation"),t=Pe(s,e),r=t?.inputEl||t?.querySelector("input");r&&(r.value=r.value.slice(0,-1),r.focus(),r.dispatchEvent(new Event("input",{bubbles:!0})))}reconcileAria(){this.components.forEach(s=>s.reconcileAria?.())}get direction(){return this._direction}setLanguage(s){s||(s=document?.documentElement?.lang||"en"),this._translations=Zt(s),this._direction=this._translations.direction||"ltr",this._languageSet=!0,this.__dispatch__("translations",this._translations,this._direction)}setTranslations(s){this._userTranslations={...this._userTranslations,...s},this.__dispatch__("translations",this._translations,this._direction)}translate(s,e={}){let t=this._userTranslations[s]??this._translations?.[s];return Xt(typeof t=="string"?t:void 0,e,this._translations?.language)}announce(s,e={},t="polite"){let r=this.translate(s,e);r&&this._announcer.announce(r,t)}announceRaw(s,e="polite"){this._announcer.announce(s,e)}clearAnnouncements(){this._announcer.clear()}on(s,e,t=null){if(!this.__hooks__[s]){let r=Object.keys(this.__hooks__).join(", ");console.error(`[Pagefind Component UI]: Unknown event type ${s}. Supported events: [${r}]`);return}if(typeof e!="function"){console.error(`[Pagefind Component UI]: Expected callback to be a function, received ${typeof e}`);return}if(t){let r=this.__hooks__[s].findIndex(i=>typeof i=="object"&&i.owner===t);if(r!==-1){this.__hooks__[s][r]={callback:e,owner:t};return}this.__hooks__[s].push({callback:e,owner:t})}else this.__hooks__[s].push(e)}triggerLoad(){return this.__load__()}triggerSearch(s){this.searchTerm=s,this.__dispatch__("search",s,this.searchFilters),this.__search__(s,this.searchFilters)}triggerSearchWithFilters(s,e){this.searchTerm=s,this.searchFilters=e,this.__dispatch__("search",s,e),this.__search__(s,e)}triggerFilters(s){this.searchFilters=s,this.__dispatch__("search",this.searchTerm,s),this.__search__(this.searchTerm,s)}triggerFilter(s,e){this.searchFilters=this.searchFilters||{},this.searchFilters[s]=e,this.__dispatch__("search",this.searchTerm,this.searchFilters),this.__search__(this.searchTerm,this.searchFilters)}__dispatch__(s,...e){this.__hooks__[s]?.forEach(t=>{typeof t=="function"?t(...e):t?.callback&&t.callback(...e)})}async __clear__(){this.__dispatch__("results",{results:[],unfilteredTotalCount:0}),this.__pagefind__&&(this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters}))}async __search__(s,e){this.__dispatch__("loading"),await this.__load__();let t=++this.__searchID__;if((!s||!s.length)&&!this.faceted)return this.__clear__();if(!this.__pagefind__)return;let r=s&&s.length?s:null,i=await this.__pagefind__.search(r,{filters:e});if(i&&this.__searchID__===t&&(i.filters&&Object.keys(i.filters)?.length&&(this.availableFilters=i.filters,this.totalFilters=i.totalFilters??null,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})),this.searchResult=i,this.__dispatch__("results",this.searchResult),!this.hasAnnouncementCapability()&&s)){let a=i.results?.length??0,l=a===0?"zero_results":a===1?"one_result":"many_results",o=a===0?"assertive":"polite";this.announce(l,{SEARCH_TERM:s,COUNT:a},o)}}async __load__(){if(!this.__pagefind__){if(this.__loadPromise__)return this.__loadPromise__;this.__loadPromise__=this.__doLoad__();try{await this.__loadPromise__}finally{this.__loadPromise__=null}}}async __doLoad__(){if(this.__pagefind__)return;let s;try{s=await import(`${this.options.bundlePath}pagefind.js`)}catch(t){console.error(t),console.error([`Pagefind couldn't be loaded from ${this.options.bundlePath}pagefind.js`,"You can configure this by passing a bundlePath option to the Pagefind Component UI"].join(` -`)),document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?console.error(`[DEBUG: Loaded from ${document.currentScript?.src??"bad script location"}]`):console.error("no known script location"),this.__dispatch__("error",{type:"bundle_load_failed",message:"Could not load search bundle",bundlePath:this.options.bundlePath,error:t}),this.hasAnnouncementCapability()||this.announce("error_search",{},"assertive");return}let e=s.createInstance(this.pagefindOptions||{});for(let t of this.options.mergeIndex){if(!t.bundlePath)throw new Error("mergeIndex requires a bundlePath parameter");let{bundlePath:r,...i}=t;await e.mergeIndex(r,i)}this.__pagefind__=e,this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters}),this.faceted&&this.__searchID__===0&&this.triggerSearch("")}thinSubResults(s,e=3){if(s.length<=e)return s;let t=[...s].sort((r,i)=>(i.locations?.length??0)-(r.locations?.length??0)).slice(0,e).map(r=>r.url);return s.filter(r=>t.includes(r.url))}getDisplaySubResults(s,e=3){if(!Array.isArray(s.sub_results))return[];let r=s.sub_results[0]?.url===(s.meta?.url||s.url)?s.sub_results.slice(1):s.sub_results;return this.thinSubResults(r,e)}};var Pt=class{constructor(){this.instances=new Map;this.defaultOptions={bundlePath:this.detectBundlePath()}}detectBundlePath(){try{if(document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"){let s=new URL(document.currentScript.src).pathname.match(/^(.*\/)(?:pagefind[-_])?.*\.js.*$/);if(s)return s[1]}}catch{}return"/pagefind/"}getInstance(s="default",e={}){let t=this.instances.get(s);if(t)return t;let r={...this.defaultOptions,...e},i=new Te(s,r);return this.instances.set(s,i),i}hasInstance(s){return this.instances.has(s)}removeInstance(s){this.instances.delete(s)}getInstanceNames(){return Array.from(this.instances.keys())}},Ft=null;function Ce(){return Ft||(Ft=new Pt),Ft}function Qt(n,s){let e=Ce();return e.hasInstance(n)?(console.warn(`[Pagefind Component UI]: Instance "${n}" already exists, configuration ignored`),e.getInstance(n)):e.getInstance(n,s)}var ye=n=>!(n==null||n===!1||n===0||n===""||Number.isNaN(n)||Array.isArray(n)&&n.length===0||typeof n=="object"&&n!==null&&!Array.isArray(n)&&Object.keys(n).length===0),T=(n,s,e)=>n.lengthT(s,2,"eq")??m(s[0],n)===m(s[1],n),ne:(n,...s)=>T(s,2,"ne")??m(s[0],n)!==m(s[1],n),gt:(n,...s)=>T(s,2,"gt")??Number(m(s[0],n))>Number(m(s[1],n)),lt:(n,...s)=>T(s,2,"lt")??Number(m(s[0],n))T(s,2,"gte")??Number(m(s[0],n))>=Number(m(s[1],n)),lte:(n,...s)=>T(s,2,"lte")??Number(m(s[0],n))<=Number(m(s[1],n)),and:(n,...s)=>{let e=!0;for(let t of s)if(e=m(t,n),!ye(e))return e;return e},or:(n,...s)=>{let e=!1;for(let t of s)if(e=m(t,n),ye(e))return e;return e},not:(n,...s)=>T(s,1,"not")??!ye(m(s[0],n)),lowercase:(n,...s)=>String(m(s[0],n)).toLowerCase(),uppercase:(n,...s)=>String(m(s[0],n)).toUpperCase(),trim:(n,...s)=>String(m(s[0],n)).trim(),truncate:(n,...s)=>{let e=T(s,2,"truncate");if(e)return e;let t=String(m(s[0],n)),r=Number(m(s[1],n)),i=s[2]?String(m(s[2],n)):"...";return t.length>r?t.slice(0,r)+i:t},replace:(n,...s)=>T(s,3,"replace")??String(m(s[0],n)).split(String(m(s[1],n))).join(String(m(s[2],n))),limit:(n,...s)=>{let e=T(s,2,"limit");if(e)return e;let t=m(s[0],n),r=m(s[1],n);return Array.isArray(t)?t.slice(0,r<0?0:r):t},first:(n,...s)=>{let e=T(s,1,"first");if(e)return e;let t=m(s[0],n);return Array.isArray(t)?t[0]:t},last:(n,...s)=>{let e=T(s,1,"last");if(e)return e;let t=m(s[0],n);return Array.isArray(t)?t[t.length-1]:t},length:(n,...s)=>{let e=T(s,1,"length");if(e)return e;let t=m(s[0],n);return Array.isArray(t)?t.length:String(t).length},join:(n,...s)=>T(s,2,"join")??(e=>Array.isArray(e)?e.join(String(m(s[1],n))):String(e))(m(s[0],n)),default:(n,...s)=>{let e=T(s,2,"default");if(e)return e;let t=m(s[0],n);return ye(t)?t:m(s[1],n)},safeUrl:(n,...s)=>{let e=String(m(s[0],n)??"").trim();return e&&/^(?:\.{0,2}\/|[#?]|(?:https?|ftp):\/\/|(?:mailto|tel):)/i.test(e)?e:""}},m=(n,s)=>{if(!n)return;if(n.t==="L")return n.val;if(n.t==="V"){let t=(i,a)=>Object.prototype.hasOwnProperty.call(i,a),r=s;for(let i of n.path){if(r==null||!t(r,i))return;r=r[i]}return r}let e=es[n.fn];return e?n.t==="C"?e(s,...n.args):e(s,n.left,...n.args):`[Error: unknown ${n.fn}()]`},ga=n=>n.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'"),ve=(n,s)=>{let e="";for(let t of n){if(t.t==="T"){e+=t.val;continue}if(t.t==="I"){let r=m(t.expr,s);if(Array.isArray(r))e+="[Error: use #each for arrays]";else if(typeof r=="object"&&r!==null)e+="[Error: cannot render object]";else{let i=String(r??"");e+=t.raw?i:ga(i)}continue}if(t.t==="F"){let r=!1;for(let i of t.branches)if(ye(m(i.cond,s))){e+=ve(i.body,s),r=!0;break}!r&&t.else&&(e+=ve(t.else,s));continue}if(t.t==="E"){let r=m(t.arr,s);if(!Array.isArray(r)){e+="[Error: #each needs array]";continue}if(!r.length&&t.else)e+=ve(t.else,s);else for(let i=0;i{let s=n,e=0,t=()=>{for(;es.slice(e,e+u.length)===u,i=u=>{r(u)&&(e+=u.length)},a=()=>{let u="";for(;e{t();let u=e,d,_=s[e];if(_==='"'||_==="'"){let p=s[e++],g="";for(;e{let d=[];e:for(;eve(c,u)};var ts=(n,s)=>{es[n]=(e,...t)=>s(...t.map(r=>m(r,e)))};var f=class extends HTMLElement{constructor(){super();this.instance=null;this._initialized=!1}connectedCallback(){if(this._initialized)return;this._initialized=!0;let e=this.getAttribute("instance")||"default",t=Ce();this.instance=t.getInstance(e),this.init(),this.register&&typeof this.register=="function"&&this.register(this.instance)}disconnectedCallback(){this.cleanup&&typeof this.cleanup=="function"&&this.cleanup(),this._initialized=!1}attributeChangedCallback(e,t,r){if(!this._initialized||t===r)return;let i=this.kebabToCamel(e);r==="false"?this[i]=!1:r==="true"?this[i]=!0:r==null?this[i]=!1:this[i]=r,this.update&&typeof this.update=="function"&&this.update()}kebabToCamel(e){return e.replace(/-([a-z])/g,t=>t[1].toUpperCase())}ensureId(e="pagefind"){return!this.id&&this.instance&&(this.id=this.instance.generateId(e)),this.id}init(){}reconcileAria(){}register(e){}cleanup(){}update(){}showError(e){let t=document.createElement("div");t.className="pf-error",t.innerHTML=` - Pagefind Error: ${this.escapeHtml(e.message||"Unknown error")} - ${e.details?`
    ${this.escapeHtml(e.details)}`:""} - `,this.appendChild(t),this.dispatchEvent(new CustomEvent("pagefind-error",{detail:e,bubbles:!0,composed:!0}))}escapeHtml(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}};var Re=class extends f{init(){this.setAttribute("hidden","")}register(s){s.registerUtility(this);let e=this.getAttribute("bundle-path");e&&(s.options.bundlePath=e);let t=this.getAttribute("base-url");t&&(s.pagefindOptions.baseUrl=t);let r=this.getAttribute("excerpt-length");r&&(s.pagefindOptions.excerptLength=parseInt(r,10));let i=this.getAttribute("lang");i&&s.setLanguage(i);let a=this.getAttribute("meta-cache-tag");a&&(s.pagefindOptions.metaCacheTag=a);let l=this.getAttribute("highlight-param");l&&(s.pagefindOptions.highlightParam=l),this.hasAttribute("exact-diacritics")&&(s.pagefindOptions.exactDiacritics=!0),this.hasAttribute("no-worker")&&(s.pagefindOptions.noWorker=!0),this.hasAttribute("faceted")&&(s.faceted=!0),this.hasAttribute("preload")&&s.triggerLoad()}};customElements.get("pagefind-config")||customElements.define("pagefind-config",Re);var Ea=(n=100)=>new Promise(s=>setTimeout(s,n)),ke=class extends f{constructor(){super();this.inputEl=null;this.clearEl=null;this.searchID=0;this.placeholder="";this.debounce=300;this.autofocus=!1}static get observedAttributes(){return["placeholder","debounce","autofocus"]}readAttributes(){this.hasAttribute("placeholder")&&(this.placeholder=this.getAttribute("placeholder")||""),this.hasAttribute("debounce")&&(this.debounce=parseInt(this.getAttribute("debounce")||"300",10)||300),this.hasAttribute("autofocus")&&(this.autofocus=this.hasAttribute("autofocus"))}init(){this.readAttributes(),this.render()}render(){this.innerHTML="";let e=this.instance.generateId("pfmod-input"),t=this.instance?.translate("search_label")||"Search this site",r=this.instance?.translate("clear_search")||"Clear",i=this.placeholder||this.instance?.translate("placeholder")||"Search";this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir");let a=document.createElement("search");a.className="pf-input-wrapper",a.setAttribute("role","search"),a.setAttribute("aria-label",t);let l=document.createElement("label");l.setAttribute("for",e),l.setAttribute("data-pf-sr-hidden","true"),l.textContent=t,a.appendChild(l),this.inputEl=document.createElement("input"),this.inputEl.id=e,this.inputEl.className="pf-input",this.inputEl.setAttribute("type","search"),this.inputEl.setAttribute("autocomplete","off"),this.inputEl.setAttribute("autocapitalize","none"),this.inputEl.setAttribute("enterkeyhint","search"),this.inputEl.setAttribute("placeholder",i),this.autofocus&&this.inputEl.setAttribute("autofocus","autofocus");let o=this.instance.generateId("pf-input-hint"),c=this.instance?.translate("input_hint")||"Results will appear as you type",u=document.createElement("span");u.id=o,u.setAttribute("data-pf-sr-hidden","true"),u.textContent=c,this.inputEl.setAttribute("aria-describedby",o),a.appendChild(this.inputEl),a.appendChild(u),this.clearEl=document.createElement("button"),this.clearEl.className="pf-input-clear",this.clearEl.setAttribute("type","button"),this.clearEl.setAttribute("data-pf-suppressed","true"),this.clearEl.textContent=r,a.appendChild(this.clearEl),this.appendChild(a),this.setupEventHandlers()}setupEventHandlers(){!this.inputEl||!this.clearEl||(this.inputEl.addEventListener("input",async e=>{let t=e.target;if(this.instance&&typeof t?.value=="string"){this.updateState(t.value);let r=++this.searchID;if(await Ea(this.debounce),r!==this.searchID)return;this.instance?.triggerSearch(t.value)}}),this.inputEl.addEventListener("keydown",e=>{e.key==="Escape"&&(++this.searchID,this.inputEl&&(this.inputEl.value=""),this.instance?.triggerSearch(""),this.updateState("")),e.key==="ArrowDown"&&(e.preventDefault(),this.inputEl&&this.instance?.focusNextResults(this.inputEl))}),this.inputEl.addEventListener("focus",()=>{this.instance?.triggerLoad();let e=this.instance?.translate("keyboard_navigate")||"navigate",t=this.instance?.translate("keyboard_clear")||"clear";this.instance?.registerShortcut({label:"\u2193",description:e},this),this.instance?.registerShortcut({label:"esc",description:t},this)}),this.inputEl.addEventListener("blur",()=>{this.instance?.deregisterAllShortcuts(this)}),this.clearEl.addEventListener("click",()=>{this.inputEl&&(this.inputEl.value="",this.instance?.triggerSearch(""),this.updateState(""),this.inputEl.focus())}))}updateState(e){this.clearEl&&(e&&e?.length?this.clearEl.removeAttribute("data-pf-suppressed"):this.clearEl.setAttribute("data-pf-suppressed","true"))}register(e){e.registerInput(this,{keyboardNavigation:!0}),e.on("search",t=>{this.inputEl&&document.activeElement!==this.inputEl&&(this.inputEl.value=t,this.updateState(t))},this),e.on("error",t=>{let r=t;this.showError({message:r.message||"Search initialization failed",details:r.bundlePath?`Bundle path: ${r.bundlePath}`:void 0})},this),e.on("translations",()=>{let t=this.inputEl?.value||"";this.render(),this.inputEl&&t&&(this.inputEl.value=t,this.updateState(t))},this)}update(){this.render()}focus(){this.inputEl&&this.inputEl.focus()}};customElements.get("pagefind-input")||customElements.define("pagefind-input",ke);var Ae=class extends f{constructor(){super();this.containerEl=null;this.term="";this.defaultMessage=""}static get observedAttributes(){return["default-message"]}init(){this.hasAttribute("default-message")&&(this.defaultMessage=this.getAttribute("default-message")||""),this.render()}render(){this.innerHTML="",this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir"),this.containerEl=document.createElement("div"),this.containerEl.className="pf-summary",this.containerEl.textContent=this.defaultMessage,this.appendChild(this.containerEl)}reconcileAria(){}register(e){e.registerSummary(this),e.on("search",t=>{this.term=t},this),e.on("results",t=>{if(!this.containerEl||!t)return;let i=t?.results?.length??0;if(!this.term){if(e.faceted){let o=i===0?"total_zero_results":i===1?"total_one_result":"total_many_results",c=e.translate(o,{COUNT:i});this.containerEl.textContent=c||`${i} result${i===1?"":"s"}`}else this.containerEl.textContent=this.defaultMessage;return}let a=i===0?"zero_results":i===1?"one_result":"many_results",l=e.translate(a,{SEARCH_TERM:this.term,COUNT:i});this.containerEl.textContent=l||`${i} result${i===1?"":"s"} for ${this.term}`},this),e.on("loading",()=>{if(!this.containerEl)return;let t=e.translate("searching",{SEARCH_TERM:this.term});this.containerEl.textContent=t||`Searching for ${this.term}...`},this),e.on("error",t=>{if(!this.containerEl)return;let r=t,i=e.translate("error_search")||"Search failed";this.containerEl.textContent=`Error: ${r.message||i}`},this),e.on("translations",()=>{this.render()},this)}update(){this.hasAttribute("default-message")&&(this.defaultMessage=this.getAttribute("default-message")||"",!this.term&&this.containerEl&&(this.containerEl.textContent=this.defaultMessage))}};customElements.get("pagefind-summary")||customElements.define("pagefind-summary",Ae);var ss=n=>{if(n instanceof Element)return[n];if(Array.isArray(n)&&n.every(s=>s instanceof Element))return n;if(typeof n=="string"||n instanceof String){let s=document.createElement("div");return s.innerHTML=n,[...s.childNodes]}return console.error(`[Pagefind Results]: Expected template to return HTML element or string, got ${typeof n}`),[]},ba=`
  • -
    - {{#if and(options.show_images, meta.image)}} - {{ meta.image_alt | default(meta.title) }} - {{/if}} -
    -

    - {{ meta.title }} -

    - {{#if excerpt}} -

    {{+ excerpt +}}

    - {{/if}} -
    -
    - {{#if sub_results}} -
      - {{#each sub_results as sub}} -
    • - {{ sub.title }} -

      {{+ sub.excerpt +}}

      -
    • - {{/each}} -
    - {{/if}} -
  • `,Ta=`
  • -
    -
    -
    -

    -

    -
    -
    -
  • `,Ca=R(ba),ya=R(Ta),rs=(n,s)=>{for(let e of n)if(e instanceof Element){e.setAttribute("data-pf-result-index",String(s));break}},zt=n=>{if(!(n instanceof HTMLElement))return null;let s=window.getComputedStyle(n).overflowY;return s!=="visible"&&s!=="hidden"?n:zt(n.parentNode)},Dt=class{constructor(s){this.result=null;this.loading=!1;this.observer=null;this.rawResult=s.result,this.index=s.index,this.placeholderNodes=s.placeholderNodes,this.resultFn=s.resultFn,this.intersectionEl=s.intersectionEl,this.showImages=s.showImages,this.showSubResults=s.showSubResults,this.maxSubResults=s.maxSubResults,this.linkTarget=s.linkTarget,this.onLoad=s.onLoad,this.setupObserver()}setupObserver(){if(this.result!==null||this.observer!==null||!this.placeholderNodes?.length)return;let s={root:this.intersectionEl,rootMargin:"50px",threshold:.01};this.observer=new IntersectionObserver((e,t)=>{this.result===null&&e?.[0]?.isIntersecting&&(this.load(),t.disconnect(),this.observer=null)},s),this.observer.observe(this.placeholderNodes[0])}async load(){if(this.placeholderNodes?.length&&!(this.result!==null||this.loading)){this.loading=!0;try{this.result=await this.rawResult.data();let s=this.resultFn(this.result,{showImages:this.showImages,showSubResults:this.showSubResults,maxSubResults:this.maxSubResults,linkTarget:this.linkTarget}),e=ss(s);for(rs(e,this.index);this.placeholderNodes.length>1;){let r=this.placeholderNodes.pop();r instanceof Element&&r.remove()}let t=this.placeholderNodes[0];t instanceof Element&&t.replaceWith(...e)}catch{this.loading=!1}this.onLoad?.()}}cleanup(){this.observer&&(this.observer.disconnect(),this.observer=null)}},Se=class extends f{constructor(){super();this.containerEl=null;this.intersectionEl=document.body;this.results=[];this.showImages=!1;this.hideSubResults=!1;this.maxSubResults=3;this.maxResults=0;this.linkTarget=null;this.resultTemplate=null;this.compiledResultTemplate=null;this.compiledPlaceholderTemplate=null;this.selectedIndex=-1;this.selectedAnchor=null;this.loadingAnnouncementTimeout=null}static get observedAttributes(){return["show-images","hide-sub-results","max-sub-results","max-results","link-target"]}init(){this.hasAttribute("show-images")&&(this.showImages=this.getAttribute("show-images")!=="false"),this.hasAttribute("hide-sub-results")&&(this.hideSubResults=this.getAttribute("hide-sub-results")!=="false"),this.hasAttribute("max-sub-results")&&(this.maxSubResults=parseInt(this.getAttribute("max-sub-results")||"3",10)||3),this.hasAttribute("max-results")&&(this.maxResults=parseInt(this.getAttribute("max-results")||"0",10)),this.hasAttribute("link-target")&&(this.linkTarget=this.getAttribute("link-target")),this.checkForTemplates(),this.render()}checkForTemplates(){let e=this.querySelector('script[type="text/pagefind-template"]:not([data-template]), script[type="text/pagefind-template"][data-template="result"]');e&&(this.compiledResultTemplate=R((e.textContent||"").trim()));let t=this.querySelector('script[type="text/pagefind-template"][data-template="placeholder"]');t&&(this.compiledPlaceholderTemplate=R((t.textContent||"").trim()))}buildTemplateData(e,t){let r=t.showSubResults?this.instance.getDisplaySubResults(e,t.maxSubResults):[];return{meta:e.meta||{},excerpt:e.excerpt||"",url:e.url||"",sub_results:r.map(i=>({title:i.title,url:i.url,excerpt:i.excerpt})),options:{link_target:t.linkTarget,show_images:t.showImages}}}getResultRenderer(){if(this.resultTemplate){let e=this.resultTemplate;return(t,r)=>e(t)}if(this.compiledResultTemplate){let e=this.compiledResultTemplate;return(t,r)=>{let i=this.buildTemplateData(t,r);return e(i)}}return(e,t)=>{let r=this.buildTemplateData(e,t);return Ca(r)}}getPlaceholder(){return this.compiledPlaceholderTemplate?this.compiledPlaceholderTemplate({}):ya({})}render(){let e=[];this.querySelectorAll('script[type="text/pagefind-template"]').forEach(r=>{e.push(r)}),this.innerHTML="",e.forEach(r=>this.appendChild(r));let t=this.instance?.translate("results_label")||"Search results";this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir"),this.containerEl=document.createElement("ul"),this.containerEl.className="pf-results",this.containerEl.setAttribute("aria-label",t),this.containerEl.setAttribute("aria-busy","false"),this.appendChild(this.containerEl),this.setupKeyboardHandlers()}appendResults(e){if(this.containerEl)for(let t of e)this.containerEl.appendChild(t)}register(e){e.registerResults(this,{keyboardNavigation:!0,announcements:!0}),e.on("results",t=>{if(!this.containerEl)return;let r=t;for(let c of this.results)c.cleanup();this.containerEl.innerHTML="",this.containerEl.setAttribute("aria-busy","false"),this.intersectionEl=zt(this.containerEl),this.selectedIndex=-1,this.selectedAnchor=null;let i=this.maxResults>0?r.results.slice(0,this.maxResults):r.results,a=i.length,l=e.searchTerm;if(l){let c=a===0?"zero_results":a===1?"one_result":"many_results",u=a===0?"assertive":"polite";e.announce(c,{SEARCH_TERM:l,COUNT:a},u)}else if(e.faceted){let c=a===0?"total_zero_results":a===1?"total_one_result":"total_many_results",u=a===0?"assertive":"polite";e.announce(c,{COUNT:a},u)}let o=this.getResultRenderer();this.results=i.map((c,u)=>{let d=ss(this.getPlaceholder());rs(d,u),this.appendResults(d);let _=new Dt({result:c,index:u,placeholderNodes:d,resultFn:o,intersectionEl:this.intersectionEl,showImages:this.showImages,showSubResults:!this.hideSubResults,maxSubResults:this.maxSubResults,linkTarget:this.linkTarget,onLoad:()=>{_.result&&this.clearLoadingAnnouncement()}});return _})},this),e.on("loading",()=>{this.containerEl&&(this.containerEl.innerHTML="",this.containerEl.setAttribute("aria-busy","true"),this.selectedIndex=-1,this.selectedAnchor=null)},this),e.on("error",t=>{let r=t;this.containerEl&&this.containerEl.setAttribute("aria-busy","false"),e.announce("error_search",{},"assertive"),this.showError({message:r.message||e.translate("error_search")||"Failed to load search results",details:r.bundlePath?`Bundle path: ${r.bundlePath}`:void 0})},this),e.on("translations",()=>{this.render()},this)}findNeighborAnchor(e,t){if(!this.containerEl)return null;let r=document.createTreeWalker(this.containerEl,NodeFilter.SHOW_ELEMENT,{acceptNode:l=>l.tagName==="A"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP});r.currentNode=e;let i=t>0?r.nextNode():r.previousNode();if(!i||!(i instanceof HTMLAnchorElement))return null;let a=this.resultIndexForNode(i);return{anchor:i,resultIndex:a}}resultIndexForNode(e){if(!this.containerEl)return-1;let t=e;for(;t&&t.parentNode!==this.containerEl;)t=t.parentNode;if(!t||!(t instanceof Element))return-1;let r=t.getAttribute("data-pf-result-index");if(r===null)return-1;let i=parseInt(r,10);return Number.isNaN(i)?-1:i}setupKeyboardHandlers(){this.containerEl&&(this.containerEl.addEventListener("keydown",e=>{let t=e.target.closest("a");if(t)if(e.key==="ArrowDown"){e.preventDefault();let r=this.findNeighborAnchor(t,1);if(r)r.anchor.focus(),this.scrollToCenter(r.anchor,e.repeat),r.resultIndex!==-1&&this.preloadAhead(r.resultIndex,1);else{let a=this.resultIndexForNode(t)+1;if(a>0&&a{let t=e.target.closest("a");if(!t)return;this.clearSelection(),t.setAttribute("data-pf-selected",""),this.selectedAnchor=t;let r=this.instance?.translate("keyboard_navigate")||"navigate",i=this.instance?.translate("keyboard_select")||"select",a=this.instance?.translate("keyboard_search")||"search";this.instance?.registerShortcut({label:"\u2191\u2193",description:r},this),this.instance?.registerShortcut({label:"\u21B5",description:i},this),this.instance?.registerShortcut({label:"/",description:a},this)}),this.containerEl.addEventListener("focusout",e=>{let t=e;this.containerEl?.contains(t.relatedTarget)||(this.clearSelection(),this.instance?.deregisterAllShortcuts(this))}))}scrollToCenter(e,t=!1){let r=this.intersectionEl||zt(e);if(!r||!(r instanceof HTMLElement)||r===document.body||r===document.documentElement)return;let i=e.getBoundingClientRect(),a=r.getBoundingClientRect(),o=i.top-a.top+r.scrollTop-r.clientHeight/2+e.offsetHeight/2;r.scrollTo({top:o,behavior:t?"instant":"smooth"})}preloadAhead(e,t){let r=t>0?1:-1;for(let i=1;i<=3;i++){let a=e+r*i;if(a>=0&&a{this.loadingAnnouncementTimeout=null,this.instance?.announce("loading",{},"polite")},800))}clearLoadingAnnouncement(){this.loadingAnnouncementTimeout&&(clearTimeout(this.loadingAnnouncementTimeout),this.loadingAnnouncementTimeout=null)}clearSelection(){this.selectedAnchor&&(this.selectedAnchor.removeAttribute("data-pf-selected"),this.selectedAnchor=null)}cleanup(){this.clearLoadingAnnouncement();for(let e of this.results)e.cleanup();this.results=[],this.selectedAnchor=null}update(){this.render()}};customElements.get("pagefind-results")||customElements.define("pagefind-results",Se);var Ne=class extends f{constructor(){super();this.containerEl=null;this.showEmpty=!1;this.expanded=!1;this.openFilters=[];this.sortOption="default";this.autoOpenThreshold=6;this.selectedFilters={};this.availableFilters=null;this.totalFilters=null;this.filterElements=new Map;this.groupElements=new Map;this.groupVisibleCounts=new Map;this.isRendered=!1}static get observedAttributes(){return["show-empty","expanded","open","sort","auto-open-threshold"]}init(){if(this.hasAttribute("show-empty")&&(this.showEmpty=this.getAttribute("show-empty")!=="false"),this.hasAttribute("expanded")&&(this.expanded=this.getAttribute("expanded")!=="false"),this.hasAttribute("open")&&(this.openFilters=(this.getAttribute("open")||"").split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)),this.hasAttribute("sort")){let e=this.getAttribute("sort");["default","alphabetical","count-desc","count-asc"].includes(e)&&(this.sortOption=e)}this.hasAttribute("auto-open-threshold")&&(this.autoOpenThreshold=parseInt(this.getAttribute("auto-open-threshold")||"6",10)),this.render()}sortValues(e,t){if(this.sortOption==="default")return e;let r=[...e];switch(this.sortOption){case"alphabetical":r.sort((i,a)=>i[0].localeCompare(a[0]));break;case"count-desc":r.sort((i,a)=>{let l=t[i[0]]??i[1];return(t[a[0]]??a[1])-l});break;case"count-asc":r.sort((i,a)=>{let l=t[i[0]]??i[1],o=t[a[0]]??a[1];return l-o});break}return r}render(){this.innerHTML="",this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir"),this.containerEl=document.createElement("div"),this.containerEl.className="pf-filter-pane",this.appendChild(this.containerEl)}getSelectedText(e){return String(e)}shouldGroupStartOpen(e,t,r){return this.openFilters.length>0?this.openFilters.includes(e.toLowerCase()):this.autoOpenThreshold>0&&r===1&&t<=this.autoOpenThreshold}hasStructureChanged(){if(!this.totalFilters)return!1;let e=new Set(Object.keys(this.totalFilters)),t=new Set(this.groupElements.keys());if(e.size!==t.size)return!0;for(let r of e)if(!t.has(r))return!0;for(let[r,i]of Object.entries(this.totalFilters)){let a=new Set(Object.keys(i));for(let l of a)if(!this.filterElements.has(`${r}:${l}`))return!0}return!1}handleFiltersUpdate(){if(!this.containerEl||!this.totalFilters)return;if(Object.keys(this.totalFilters).length===0){this.containerEl.setAttribute("data-pf-hidden","true");return}this.containerEl.removeAttribute("data-pf-hidden"),!this.isRendered||this.hasStructureChanged()?this.renderFilters():this.updateFilters()}renderFilters(){if(!this.containerEl||!this.totalFilters)return;this.containerEl.innerHTML="",this.filterElements.clear(),this.groupElements.clear(),this.groupVisibleCounts.clear();let e=Object.keys(this.totalFilters);for(let t of e){let r=this.totalFilters[t],i=this.availableFilters?.[t]||{},a=this.renderFilterGroup(t,r,i,e.length);a&&this.containerEl.appendChild(a)}this.isRendered=!0}updateFilters(){for(let[e,t]of this.filterElements){let r=e.indexOf(":"),i=e.slice(0,r),a=e.slice(r+1),l=this.availableFilters?.[i]?.[a]??0,o=this.totalFilters?.[i]?.[a]??0,c=this.selectedFilters[i]?.has(a),u=c?o:l;t.countSpan.textContent=String(u);let d=this.showEmpty||l>0||c,_=t.label.hasAttribute("data-pf-hidden");t.label.toggleAttribute("data-pf-hidden",!d),d&&_?this.groupVisibleCounts.set(i,(this.groupVisibleCounts.get(i)??0)+1):!d&&!_&&this.groupVisibleCounts.set(i,(this.groupVisibleCounts.get(i)??1)-1),t.checkbox.checked=c||!1}for(let[e,t]of this.groupElements){let r=this.selectedFilters[e]?.size||0;t.selectedCountSpan&&(r>0?(t.selectedCountSpan.textContent=this.getSelectedText(r),t.selectedCountSpan.removeAttribute("data-pf-hidden")):t.selectedCountSpan.setAttribute("data-pf-hidden","true"));let i=this.groupVisibleCounts.get(e)??0;t.group.toggleAttribute("data-pf-hidden",i===0)}}renderFilterGroup(e,t,r,i){let a=Object.entries(t);if(a.length===0)return null;let l=this.sortValues(a,r),o=e.charAt(0).toUpperCase()+e.slice(1),c=this.selectedFilters[e]?.size||0,u=this.expanded||this.shouldGroupStartOpen(e,l.length,i),d,_,p=null;if(this.expanded){d=document.createElement("fieldset"),d.className="pf-filter-group";let E=document.createElement("legend");E.className="pf-filter-group-title";let C=document.createElement("span");C.className="pf-filter-group-name",C.textContent=o,E.appendChild(C),d.appendChild(E),_=document.createElement("div"),_.className="pf-filter-options",d.appendChild(_)}else{d=document.createElement("details"),d.className="pf-filter-group",d.dataset.filterName=e,u&&(d.open=!0);let E=document.createElement("summary");E.className="pf-filter-group-title";let C=document.createElement("span");C.className="pf-filter-group-name",C.textContent=o,E.appendChild(C),p=document.createElement("span"),p.className="pf-filter-group-count",p.setAttribute("aria-hidden","true"),c>0?p.textContent=this.getSelectedText(c):p.setAttribute("data-pf-hidden","true"),E.appendChild(p),d.appendChild(E);let y=document.createElement("fieldset");y.className="pf-filter-fieldset";let v=document.createElement("legend");v.setAttribute("data-pf-sr-hidden",""),v.textContent=o,y.appendChild(v),_=document.createElement("div"),_.className="pf-filter-options",y.appendChild(_),d.appendChild(y)}this.groupElements.set(e,{group:d,optionsContainer:_,selectedCountSpan:p});let g=0;for(let[E,C]of l){let y=r[E]??0,v=this.selectedFilters[e]?.has(E)||!1,$e=v?C:y,N=this.showEmpty||y>0||v;N&&g++,this.renderCheckbox(_,e,E,$e,v,N)}return this.groupVisibleCounts.set(e,g),d}renderCheckbox(e,t,r,i,a,l){let o=this.instance.generateId(`pf-filter-${t}-${r}`),c=document.createElement("label");c.className="pf-filter-checkbox",c.setAttribute("for",o),l||c.setAttribute("data-pf-hidden","true");let u=document.createElement("input");u.type="checkbox",u.className="pf-checkbox-input",u.id=o,u.name=t,u.value=r,u.checked=a,u.addEventListener("change",p=>{this.handleCheckboxChange(t,r,p.target.checked)}),c.appendChild(u);let d=document.createTextNode(r);c.appendChild(d);let _=document.createElement("span");_.className="pf-filter-checkbox-count",_.textContent=String(i),c.appendChild(_),e.appendChild(c),this.filterElements.set(`${t}:${r}`,{label:c,countSpan:_,checkbox:u})}handleCheckboxChange(e,t,r){this.selectedFilters[e]||(this.selectedFilters[e]=new Set),r?this.selectedFilters[e].add(t):this.selectedFilters[e].delete(t);let i=this.groupElements.get(e);if(i?.selectedCountSpan){let l=this.selectedFilters[e].size;l>0?(i.selectedCountSpan.textContent=this.getSelectedText(l),i.selectedCountSpan.removeAttribute("data-pf-hidden")):i.selectedCountSpan.setAttribute("data-pf-hidden","true")}let a=Array.from(this.selectedFilters[e]);if(a.length===0){delete this.selectedFilters[e];let l={};for(let[o,c]of Object.entries(this.selectedFilters))l[o]=Array.from(c);this.instance?.triggerFilters(l)}else this.instance?.triggerFilter(e,a)}register(e){e.registerFilter(this),e.on("filters",t=>{let r=t;this.availableFilters=r.available,this.totalFilters=r.total,this.handleFiltersUpdate()},this),e.on("search",(t,r)=>{this.selectedFilters={};let i=r;if(i)for(let[a,l]of Object.entries(i))Array.isArray(l)&&l.length>0&&(this.selectedFilters[a]=new Set(l));this.isRendered&&this.updateFilters()},this),e.on("error",t=>{let r=t;this.showError({message:r.message||"Failed to load filters",details:r.bundlePath?`Bundle path: ${r.bundlePath}`:void 0})},this),e.on("translations",()=>{this.render(),this.isRendered=!1,this.handleFiltersUpdate()},this)}update(){this.hasAttribute("show-empty")&&(this.showEmpty=this.getAttribute("show-empty")!=="false"),this.hasAttribute("expanded")&&(this.expanded=this.getAttribute("expanded")!=="false"),this.hasAttribute("open")&&(this.openFilters=(this.getAttribute("open")||"").split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)),this.isRendered&&(this.isRendered=!1,this.handleFiltersUpdate())}};customElements.get("pagefind-filter-pane")||customElements.define("pagefind-filter-pane",Ne);var Me=class extends f{constructor(){super();this.isOpen=!1;this.activeIndex=-1;this.selectedValues=new Set;this.isRendered=!1;this.filtersLoaded=!1;this.filterName=null;this.availableFilters={};this.totalFilters={};this.singleSelect=!1;this.showEmpty=!1;this.wrapLabels=!1;this.hideClear=!1;this.sortOption="default";this.wrapperEl=null;this.triggerEl=null;this.menuEl=null;this.optionsEl=null;this.clearEl=null;this.badgeEl=null;this.optionElements=[];this.focusedOptionEl=null;this.typeAheadBuffer="";this.typeAheadTimeout=null;this._handleClickOutside=this._handleClickOutside.bind(this)}static get observedAttributes(){return["filter","label","single-select","show-empty","wrap","sort","hide-clear"]}init(){if(this.filterName=this.getAttribute("filter"),!this.filterName){this.showError({message:"filter attribute is required on "});return}if(this.singleSelect=this.hasAttribute("single-select"),this.showEmpty=this.hasAttribute("show-empty"),this.wrapLabels=this.hasAttribute("wrap"),this.hideClear=this.hasAttribute("hide-clear"),this.hasAttribute("sort")){let e=this.getAttribute("sort");["default","alphabetical","count-desc","count-asc"].includes(e)&&(this.sortOption=e)}this.render()}sortValues(e){if(this.sortOption==="default")return e;let t=[...e];switch(this.sortOption){case"alphabetical":t.sort((r,i)=>r.localeCompare(i));break;case"count-desc":t.sort((r,i)=>{let a=this.availableFilters[r]??this.totalFilters[r]??0;return(this.availableFilters[i]??this.totalFilters[i]??0)-a});break;case"count-asc":t.sort((r,i)=>{let a=this.availableFilters[r]??this.totalFilters[r]??0,l=this.availableFilters[i]??this.totalFilters[i]??0;return a-l});break}return t}render(){this.innerHTML="";let e=this.ensureId("pf-dropdown"),t=`${e}-trigger`,r=`${e}-menu`;this.wrapperEl=document.createElement("div"),this.wrapperEl.className="pf-dropdown-wrapper",this.triggerEl=document.createElement("button"),this.triggerEl.type="button",this.triggerEl.id=t,this.triggerEl.className="pf-dropdown-trigger",this.wrapLabels&&this.triggerEl.classList.add("wrap"),this.triggerEl.setAttribute("role","combobox"),this.triggerEl.setAttribute("aria-haspopup","listbox"),this.triggerEl.setAttribute("aria-expanded","false"),this.triggerEl.setAttribute("aria-controls",r);let i=document.createElement("span");i.className="pf-dropdown-trigger-label",this.wrapLabels&&i.classList.add("wrap"),i.textContent=this.getAttribute("label")||this.filterName||"",this.triggerEl.appendChild(i),this.badgeEl=document.createElement("span"),this.badgeEl.className="pf-dropdown-selected-badge",this.badgeEl.setAttribute("data-pf-hidden","true"),this.badgeEl.setAttribute("aria-hidden","true"),this.badgeEl.textContent="0",this.triggerEl.appendChild(this.badgeEl);let a=document.createElement("span");a.className="pf-dropdown-arrow",a.setAttribute("aria-hidden","true"),this.triggerEl.appendChild(a),this.wrapperEl.appendChild(this.triggerEl),this.menuEl=document.createElement("div"),this.menuEl.id=r,this.menuEl.className="pf-dropdown-menu",this.menuEl.hidden=!0,this.optionsEl=document.createElement("div"),this.optionsEl.className="pf-dropdown-options",this.optionsEl.setAttribute("role","listbox"),this.optionsEl.setAttribute("aria-multiselectable",this.singleSelect?"false":"true"),this.optionsEl.setAttribute("aria-labelledby",t),this.menuEl.appendChild(this.optionsEl),this.wrapperEl.appendChild(this.menuEl),this.hideClear||(this.clearEl=document.createElement("button"),this.clearEl.type="button",this.clearEl.className="pf-dropdown-clear",this.clearEl.setAttribute("aria-disabled","true"),this.clearEl.setAttribute("aria-label",(this.instance?.translate("clear_search")||"Clear")+" "+(this.getAttribute("label")||this.filterName||"")),this.clearEl.textContent=this.instance?.translate("clear_search")||"Clear",this.wrapperEl.appendChild(this.clearEl),this.clearEl.addEventListener("click",()=>this.clearAll())),this.appendChild(this.wrapperEl),this.triggerEl.addEventListener("click",()=>this.toggle()),this.triggerEl.addEventListener("focus",()=>this.instance?.triggerLoad()),this.triggerEl.addEventListener("keydown",l=>{this.isOpen?this.handleMenuKeydown(l):this.handleTriggerKeydown(l)}),this.isRendered=!0}toggle(){this.isOpen?this.close():this.open()}open(){if(this.instance?.triggerLoad(),this.isOpen||!this.menuEl||!this.triggerEl||!this.optionsEl)return;if(this.isOpen=!0,this.filtersLoaded||this.showLoadingState(),this.menuEl.hidden=!1,this.triggerEl.setAttribute("aria-expanded","true"),this.triggerEl.classList.add("open"),this.optionElements.length>0){let i=this.activeIndex>=0?this.activeIndex:0;this.setActiveIndex(i)}let e=this.instance?.translate("keyboard_navigate")||"navigate",t=this.instance?.translate("keyboard_select")||"select",r=this.instance?.translate("keyboard_close")||"close";this.instance?.registerShortcut({label:"\u2191\u2193",description:e},this),this.instance?.registerShortcut({label:"\u21B5",description:t},this),this.instance?.registerShortcut({label:"esc",description:r},this),setTimeout(()=>{document.addEventListener("click",this._handleClickOutside)},0)}close(e=!0){!this.isOpen||!this.menuEl||!this.triggerEl||!this.optionsEl||(this.isOpen=!1,this.menuEl.hidden=!0,this.triggerEl.setAttribute("aria-expanded","false"),this.triggerEl.classList.remove("open"),this.triggerEl?.removeAttribute("aria-activedescendant"),this.focusedOptionEl&&(this.focusedOptionEl.classList.remove("pf-dropdown-option-focused"),this.focusedOptionEl=null),this.instance?.deregisterAllShortcuts(this),document.removeEventListener("click",this._handleClickOutside),e&&this.triggerEl.focus())}_handleClickOutside(e){this.wrapperEl&&!this.wrapperEl.contains(e.target)&&this.close(!1)}handleTriggerKeydown(e){switch(e.key){case"Enter":case" ":e.preventDefault(),this.open();break;case"ArrowDown":e.preventDefault(),this.open(),this.setActiveIndex(0);break;case"ArrowUp":e.preventDefault(),this.open(),this.setActiveIndex(this.optionElements.length-1);break}}handleMenuKeydown(e){switch(e.key){case"ArrowDown":e.preventDefault(),this.moveActiveIndex(1);break;case"ArrowUp":e.preventDefault(),this.moveActiveIndex(-1);break;case"Home":e.preventDefault(),this.setActiveIndex(0);break;case"End":e.preventDefault(),this.setActiveIndex(this.optionElements.length-1);break;case"Enter":case" ":if(e.preventDefault(),this.activeIndex>=0&&this.activeIndex=this.optionElements.length||!this.optionsEl)return;this.focusedOptionEl&&this.focusedOptionEl.classList.remove("pf-dropdown-option-focused"),this.activeIndex=e;let t=this.optionElements[e];t.el.classList.add("pf-dropdown-option-focused"),this.focusedOptionEl=t.el,this.triggerEl?.setAttribute("aria-activedescendant",t.el.id),this.scrollToCenter(t.el)}scrollToCenter(e){if(!this.optionsEl)return;let t=this.optionsEl,r=e.offsetTop,i=e.offsetHeight,a=t.clientHeight,l=r-a/2+i/2;t.scrollTo({top:l,behavior:"smooth"})}moveActiveIndex(e){let t=this.activeIndex+e;t<0?t=this.optionElements.length-1:t>=this.optionElements.length&&(t=0),this.setActiveIndex(t)}handleTypeAhead(e){this.typeAheadBuffer+=e.toLowerCase(),this.typeAheadTimeout&&clearTimeout(this.typeAheadTimeout);let t=this.optionElements.findIndex(({value:r})=>r.toLowerCase().startsWith(this.typeAheadBuffer));t>=0&&this.setActiveIndex(t),this.typeAheadTimeout=setTimeout(()=>{this.typeAheadBuffer=""},500)}showLoadingState(){if(!this.optionsEl)return;this.optionsEl.innerHTML="",this.optionsEl.setAttribute("aria-busy","true");let e=document.createElement("div");e.setAttribute("data-pf-sr-hidden","true"),e.textContent="Loading filter options...",this.optionsEl.appendChild(e);for(let t=0;t<3;t++){let r=document.createElement("div");r.className="pf-dropdown-option pf-dropdown-option-loading",r.setAttribute("aria-hidden","true");let i=document.createElement("span");i.className="pf-dropdown-checkbox pf-skeleton",r.appendChild(i);let a=document.createElement("span");a.className="pf-dropdown-option-label pf-skeleton",a.style.width=`${60+t*15}%`,a.innerHTML=" ",r.appendChild(a),this.optionsEl.appendChild(r)}}updateOptions(){if(!this.optionsEl)return;this.filtersLoaded=!0,this.optionsEl.removeAttribute("aria-busy");let e=Object.keys(this.totalFilters||{}),t=this.sortValues(e);if(e.length===0){this.optionsEl.innerHTML="";let i=document.createElement("div");i.className="pf-dropdown-error",i.setAttribute("role","alert"),i.textContent=`No filter "${this.filterName}" found`,this.optionsEl.appendChild(i),this.optionElements=[],this.focusedOptionEl=null;return}this.wrapperEl?.removeAttribute("data-pf-hidden"),this.optionsEl.innerHTML="",this.optionElements=[],this.focusedOptionEl=null;let r=this.id||this.ensureId("pf-dropdown");t.forEach((i,a)=>{let l=this.availableFilters?.[i]??0,o=this.totalFilters[i]??0,c=this.selectedValues.has(i);if(!(this.showEmpty||l>0||c))return;let d=c?o:l,_=`${r}-option-${a}`,p=this.createOption(_,i,d,c);this.optionsEl.appendChild(p),this.optionElements.push({el:p,value:i})}),this.isOpen&&this.optionElements.length>0&&(this.activeIndex>=this.optionElements.length?this.setActiveIndex(this.optionElements.length-1):this.activeIndex<0?this.setActiveIndex(0):this.setActiveIndex(this.activeIndex)),this.updateBadge()}createOption(e,t,r,i){let a=document.createElement("div");a.id=e,a.className="pf-dropdown-option",this.wrapLabels&&a.classList.add("wrap"),a.setAttribute("role","option"),a.setAttribute("aria-selected",String(i)),a.dataset.value=t;let l=document.createElement("span");l.className="pf-dropdown-checkbox",l.setAttribute("aria-hidden","true"),a.appendChild(l);let o=document.createElement("span");o.className="pf-dropdown-option-label",this.wrapLabels&&o.classList.add("wrap"),o.textContent=t,a.appendChild(o);let c=document.createElement("span");c.className="pf-dropdown-option-count",c.setAttribute("aria-hidden","true"),c.textContent=String(r),a.appendChild(c);let u=r===1?"result":"results";return a.setAttribute("aria-label",`${t}, ${r} ${u}`),a.addEventListener("click",d=>{d.stopPropagation(),this.toggleOption(t)}),a}toggleOption(e){let t=this.selectedValues.has(e);this.singleSelect?(this.selectedValues.has(e)?this.selectedValues.clear():(this.selectedValues.clear(),this.selectedValues.add(e)),this.close()):this.selectedValues.has(e)?this.selectedValues.delete(e):this.selectedValues.add(e);let r=this.selectedValues.has(e);if(r!==t){let i=r?"selected":"deselected";this.instance?.announceRaw(`${e} ${i}`)}this.updateOptionStates(),this.updateBadge(),this.dispatchFilterChange()}clearAll(){this.selectedValues.size!==0&&(this.selectedValues.clear(),this.updateOptionStates(),this.updateBadge(),this.dispatchFilterChange())}dispatchFilterChange(){if(!this.filterName)return;let e=Array.from(this.selectedValues);e.length===0?this.instance?.triggerFilter(this.filterName,[]):this.instance?.triggerFilter(this.filterName,e)}updateBadge(){if(!this.badgeEl||!this.triggerEl)return;let e=this.selectedValues.size;if(e>0){this.badgeEl.textContent=String(e),this.badgeEl.removeAttribute("data-pf-hidden");let t=this.getAttribute("label")||this.filterName||"",r=e===1?"filter":"filters";this.triggerEl.setAttribute("aria-label",`${t}, ${e} ${r} selected`),this.clearEl&&this.clearEl.removeAttribute("aria-disabled")}else this.badgeEl.setAttribute("data-pf-hidden","true"),this.triggerEl.removeAttribute("aria-label"),this.clearEl&&this.clearEl.setAttribute("aria-disabled","true")}updateOptionStates(){for(let{el:e,value:t}of this.optionElements){let r=this.selectedValues.has(t);e.setAttribute("aria-selected",String(r))}}register(e){this.filterName&&(e.registerFilter(this),e.on("filters",t=>{let r=t;this.availableFilters=r.available?.[this.filterName]||{},this.totalFilters=r.total?.[this.filterName]||{},this.isRendered&&this.updateOptions()},this),e.on("search",(t,r)=>{let a=r?.[this.filterName]||[];this.selectedValues=new Set(a),this.isRendered&&(this.updateOptionStates(),this.updateBadge())},this),e.on("error",t=>{let r=t;this.showError({message:r.message||"Failed to load filters",details:r.bundlePath?`Bundle path: ${r.bundlePath}`:void 0})},this))}update(){let e=this.getAttribute("filter");if(e!==this.filterName&&(this.filterName=e,this.selectedValues.clear(),this.updateOptions()),this.singleSelect=this.hasAttribute("single-select"),this.showEmpty=this.hasAttribute("show-empty"),this.wrapLabels=this.hasAttribute("wrap"),this.hideClear=this.hasAttribute("hide-clear"),this.hasAttribute("sort")){let r=this.getAttribute("sort");["default","alphabetical","count-desc","count-asc"].includes(r)&&(this.sortOption=r)}else this.sortOption="default";this.optionsEl&&this.optionsEl.setAttribute("aria-multiselectable",this.singleSelect?"false":"true");let t=this.triggerEl?.querySelector(".pf-dropdown-trigger-label");t&&(t.textContent=this.getAttribute("label")||this.filterName||""),this.updateOptions()}cleanup(){document.removeEventListener("click",this._handleClickOutside),this.instance?.deregisterAllShortcuts(this),this.focusedOptionEl=null,this.typeAheadTimeout&&clearTimeout(this.typeAheadTimeout)}};customElements.get("pagefind-filter-dropdown")||customElements.define("pagefind-filter-dropdown",Me);var Oe=class extends f{constructor(){super();this.dialogEl=null;this.resetOnClose=!1;this._isOpen=!1;this._closeHandler=null}static get observedAttributes(){return["reset-on-close"]}init(){this.hasAttribute("reset-on-close")&&(this.resetOnClose=this.getAttribute("reset-on-close")!=="false"),this.render()}render(){let e=this.children.length>0,t=e?Array.from(this.children):null;this.innerHTML="";let r=this.id||this.instance.generateId("pagefind-modal"),i=this.instance?.translate("keyboard_search")||"search";if(this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir"),this.dialogEl=document.createElement("dialog"),this.dialogEl.className="pf-modal",this.dialogEl.id=r,this.dialogEl.setAttribute("aria-label",i),e&&t)t.forEach(a=>this.dialogEl.appendChild(a));else{let a=this.getAttribute("instance"),l=document.createElement("pagefind-modal-header"),o=document.createElement("pagefind-input");a&&o.setAttribute("instance",a),l.appendChild(o);let c=document.createElement("pagefind-modal-body"),u=document.createElement("pagefind-summary"),d=document.createElement("pagefind-results");a&&(u.setAttribute("instance",a),d.setAttribute("instance",a)),c.append(u,d);let _=document.createElement("pagefind-modal-footer"),p=document.createElement("pagefind-keyboard-hints");a&&p.setAttribute("instance",a),_.appendChild(p),this.dialogEl.append(l,c,_)}this.appendChild(this.dialogEl),this.setupEventHandlers()}setupEventHandlers(){this.dialogEl&&(this._closeHandler=()=>{this._isOpen=!1,this.handleClose()},this.dialogEl.addEventListener("close",this._closeHandler),this.dialogEl.addEventListener("keydown",e=>{e.key==="Escape"&&(e.preventDefault(),e.stopPropagation(),this.close())},!0),this.dialogEl.addEventListener("click",e=>{e.target===this.dialogEl&&this.close()}))}open(){if(this._isOpen||!this.dialogEl)return;this._isOpen=!0,this.dialogEl.showModal();let e=this.instance?.translate("keyboard_close")||"close";this.instance?.registerShortcut({label:"esc",description:e},this),requestAnimationFrame(()=>{let r=this.querySelector("pagefind-input");if(r&&typeof r.focus=="function")r.focus();else{let i=this.querySelector("input");i&&i.focus()}}),(this.instance?.getUtilities("modal-trigger")||[]).forEach(r=>r.buttonEl?.setAttribute("aria-expanded","true"))}close(){!this._isOpen||!this.dialogEl||this.dialogEl.close()}handleClose(){this.instance?.deregisterAllShortcuts(this),this.resetOnClose&&this.instance&&this.instance.triggerSearch("");let t=(this.instance?.getUtilities("modal-trigger")||[])[0];t&&typeof t.handleModalClose=="function"&&t.handleModalClose()}get isOpen(){return this._isOpen}register(e){e.registerUtility(this,"modal"),e.on("translations",()=>{let t=this._isOpen;this.render(),t&&this.open()},this)}reconcileAria(){(this.instance?.getUtilities("modal-trigger")||[]).forEach(t=>{t.buttonEl&&this.dialogEl?.id&&t.buttonEl.setAttribute("aria-controls",this.dialogEl.id)})}cleanup(){this.dialogEl&&this._closeHandler&&this.dialogEl.removeEventListener("close",this._closeHandler),this.instance?.deregisterAllShortcuts(this)}update(){this.hasAttribute("reset-on-close")&&(this.resetOnClose=this.getAttribute("reset-on-close")!=="false")}};customElements.get("pagefind-modal")||customElements.define("pagefind-modal",Oe);var S=null;function is(){if(S!==null)return S;try{let n=navigator.userAgentData;if(n?.platform)return S=n.platform.toLowerCase().includes("mac"),S}catch{}return S=/mac/i.test(navigator.userAgent),S}function je(n){let s=n.toLowerCase().split("+"),e={mod:!1,ctrl:!1,shift:!1,alt:!1,meta:!1,key:""};for(let t of s)switch(t){case"mod":e.mod=!0;break;case"ctrl":e.ctrl=!0;break;case"shift":e.shift=!0;break;case"alt":e.alt=!0;break;case"meta":case"cmd":case"command":e.meta=!0;break;default:e.key=t}return e}function Be(n,s){let e=is(),t=s.key.toLowerCase()===n.key,r=n.mod?!e:n.ctrl,i=n.mod?e:n.meta,a=r?s.ctrlKey:!s.ctrlKey,l=i?s.metaKey:!s.metaKey,o=n.shift?s.shiftKey:!s.shiftKey,c=n.alt?s.altKey:!s.altKey;return t&&a&&l&&o&&c}function xe(n){let s=is(),e=[],t=[];return n.mod&&(e.push(s?"\u2318":"Ctrl"),t.push(s?"Meta":"Control")),n.meta&&(e.push(s?"\u2318":"Win"),t.push("Meta")),n.ctrl&&(e.push("Ctrl"),t.push("Control")),n.shift&&(e.push("Shift"),t.push("Shift")),n.alt&&(e.push("Alt"),t.push("Alt")),e.push(n.key.toUpperCase()),t.push(n.key),{keys:e,aria:t.join("+")}}var He=class extends f{constructor(){super();this.buttonEl=null;this._userPlaceholder=null;this.shortcut="mod+k";this.hideShortcut=!1;this.compact=!1;this._keydownHandler=null;this._keyBinding=null}static get observedAttributes(){return["placeholder","shortcut","hide-shortcut","compact"]}get placeholder(){return this._userPlaceholder||this.instance?.translate("keyboard_search")||"Search"}init(){this.readAttributes(),this.render(),this.setupKeyboardShortcut()}readAttributes(){this.hasAttribute("placeholder")&&(this._userPlaceholder=this.getAttribute("placeholder")),this.hasAttribute("shortcut")&&(this.shortcut=this.getAttribute("shortcut")||"mod+k"),this.hasAttribute("hide-shortcut")&&(this.hideShortcut=this.getAttribute("hide-shortcut")!=="false"),this.hasAttribute("compact")&&(this.compact=this.getAttribute("compact")!=="false"),this._keyBinding=je(this.shortcut)}render(){if(this.innerHTML="",this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir"),this.buttonEl=document.createElement("button"),this.buttonEl.className="pf-trigger-btn",this.buttonEl.type="button",this.buttonEl.setAttribute("aria-haspopup","dialog"),this.buttonEl.setAttribute("aria-expanded","false"),this.buttonEl.setAttribute("aria-label",this.placeholder||"Search"),this._keyBinding){let t=xe(this._keyBinding);this.buttonEl.setAttribute("aria-keyshortcuts",t.aria)}let e=document.createElement("span");if(e.className="pf-trigger-icon",e.setAttribute("aria-hidden","true"),this.buttonEl.appendChild(e),!this.compact){let t=document.createElement("span");t.className="pf-trigger-text",t.textContent=this.placeholder,this.buttonEl.appendChild(t)}if(!this.hideShortcut&&this._keyBinding){let t=document.createElement("span");t.className="pf-trigger-shortcut",t.setAttribute("aria-hidden","true");let r=xe(this._keyBinding);for(let i of r.keys){let a=document.createElement("span");a.className="pf-trigger-key",a.textContent=i,t.appendChild(a)}this.buttonEl.appendChild(t)}this.appendChild(this.buttonEl),this.buttonEl.addEventListener("click",()=>{this.openModal()})}setupKeyboardShortcut(){this._keydownHandler=e=>{if(!this._keyBinding||!Be(this._keyBinding,e))return;let t=document.activeElement;t&&(t.tagName==="INPUT"||t.tagName==="TEXTAREA"||t.isContentEditable)||(e.preventDefault(),this.openModal())},document.addEventListener("keydown",this._keydownHandler)}openModal(){let t=(this.instance?.getUtilities("modal")||[])[0];t&&typeof t.open=="function"&&(t.open(),this.buttonEl&&this.buttonEl.setAttribute("aria-expanded","true"))}handleModalClose(){this.buttonEl&&(this.buttonEl.setAttribute("aria-expanded","false"),this.buttonEl.focus())}register(e){e.registerUtility(this,"modal-trigger"),e.on("translations",()=>{this.render()},this)}reconcileAria(){let t=(this.instance?.getUtilities("modal")||[])[0];t?.dialogEl?.id&&this.buttonEl&&this.buttonEl.setAttribute("aria-controls",t.dialogEl.id)}cleanup(){this._keydownHandler&&(document.removeEventListener("keydown",this._keydownHandler),this._keydownHandler=null)}update(){this.readAttributes(),this.render()}};customElements.get("pagefind-modal-trigger")||customElements.define("pagefind-modal-trigger",He);var we=class extends f{constructor(){super(...arguments);this.closeBtn=null}init(){this.classList.add("pf-modal-header");let e=document.createElement("div");for(e.className="pf-modal-header-content";this.firstChild;)e.appendChild(this.firstChild);this.closeBtn=document.createElement("button"),this.closeBtn.type="button",this.closeBtn.className="pf-modal-close",this.closeBtn.setAttribute("aria-label",this.instance?.translate("keyboard_close")||"Close"),this.closeBtn.innerHTML='',this.closeBtn.addEventListener("click",()=>{let t=this.closest("pagefind-modal");t&&typeof t.close=="function"&&t.close()}),this.append(e,this.closeBtn)}register(e){e.registerUtility(this,"modal-header"),e.on("translations",()=>{this.closeBtn&&this.closeBtn.setAttribute("aria-label",e.translate("keyboard_close")||"Close")},this)}};customElements.get("pagefind-modal-header")||customElements.define("pagefind-modal-header",we);var Ie=class extends f{init(){this.classList.add("pf-modal-body"),this.setAttribute("tabindex","-1")}register(s){}};customElements.get("pagefind-modal-body")||customElements.define("pagefind-modal-body",Ie);var Ue=class extends f{init(){this.classList.add("pf-modal-footer")}register(s){}};customElements.get("pagefind-modal-footer")||customElements.define("pagefind-modal-footer",Ue);var Le=class extends f{init(){this.classList.add("pf-keyboard-hints"),this.setAttribute("aria-hidden","true")}render(){this.innerHTML="",this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir");let s=this.instance?.getActiveShortcuts()||[];if(s.length===0)return;let e=new Set;for(let t of s){if(e.has(t.label))continue;e.add(t.label);let r=document.createElement("div");r.className="pf-keyboard-hint";let i=document.createElement("kbd");i.className="pf-keyboard-key",i.textContent=t.label,r.appendChild(i),r.appendChild(document.createTextNode(` ${t.description}`)),this.appendChild(r)}}register(s){s.registerUtility(this,"keyboard-hints"),this.render(),s.on("translations",()=>{this.render()},this)}};customElements.get("pagefind-keyboard-hints")||customElements.define("pagefind-keyboard-hints",Le);var va=(n=100)=>new Promise(s=>setTimeout(s,n)),as=(n,s)=>{let e=n.getAttribute("role")==="option"?[n]:Array.from(n.querySelectorAll('[role="option"]'));for(let t=0;t{if(n instanceof Element)return[n];if(Array.isArray(n)&&n.every(s=>s instanceof Element))return n;if(typeof n=="string"||n instanceof String){let s=document.createElement("div");return s.innerHTML=n,[...s.childNodes]}return console.error(`[Pagefind Searchbox]: Expected template to return HTML element or string, got ${typeof n}`),[]},Ra=`{{#if and(options.show_sub_results, sub_results)}}
    {{/if}} -

    {{ meta.title | default("Untitled") }}

    - {{#if excerpt}} -

    {{+ excerpt +}}

    - {{/if}} -
    {{#if and(options.show_sub_results, sub_results)}} -{{#each sub_results as sub}} - -

    {{ sub.title | default("Section") }}

    - {{#if sub.excerpt}} -

    {{+ sub.excerpt +}}

    - {{/if}} -
    -{{/each}} -
    {{/if}}`,ns=R(Ra),ka=`
    -

    -

    -
    `,Aa=R(ka),jt=class{constructor(s){this.data=null;this.cachedOptions=null;this.loading=!1;this.retryDelay=0;this.observer=null;this.rawResult=s.rawResult,this.placeholderEl=s.placeholderEl,this.renderFn=s.renderFn,this.intersectionRoot=s.intersectionRoot,this.index=s.index,this.onLoad=s.onLoad,this.setupObserver()}setupObserver(){if(this.data!==null||this.observer!==null)return;let s={root:this.intersectionRoot,rootMargin:"50px",threshold:.01};this.observer=new IntersectionObserver((e,t)=>{this.data===null&&e?.[0]?.isIntersecting&&(this.load(),t.disconnect(),this.observer=null)},s),this.observer.observe(this.placeholderEl)}async load(){if(!(this.data!==null||this.loading)){this.loading=!0;try{this.data=await this.rawResult.data();let s=this.renderFn(this.data),e=Ke(s);if(e.length>0&&this.placeholderEl.parentNode){let t=e.find(r=>r instanceof Element);this.placeholderEl.replaceWith(...e),t instanceof Element&&(this.placeholderEl=t,as(t,this.index),this.cacheOptions())}}catch{await new Promise(s=>setTimeout(s,this.retryDelay||100)),this.retryDelay=Math.min((this.retryDelay||100)*2,1e4),this.loading=!1}this.onLoad?.()}}cacheOptions(){if(!this.data||!this.placeholderEl){this.cachedOptions=null;return}this.placeholderEl.getAttribute("role")==="group"?this.cachedOptions=Array.from(this.placeholderEl.querySelectorAll('[role="option"]')):this.placeholderEl.getAttribute("role")==="option"?this.cachedOptions=[this.placeholderEl]:this.cachedOptions=[]}cleanup(){this.observer&&(this.observer.disconnect(),this.observer=null),this.cachedOptions=null}},Fe=class extends f{constructor(){super();this.containerEl=null;this.inputEl=null;this.dropdownEl=null;this.resultsEl=null;this.statusEl=null;this.footerEl=null;this.isOpen=!1;this.isLoading=!1;this.results=[];this.activeIndex=-1;this.activeOptionOffset=0;this.searchID=0;this.searchTerm="";this.pendingNavigation=0;this.loadingAnnouncementTimeout=null;this.selectedEl=null;this._userPlaceholder=null;this.debounce=150;this.autofocus=!1;this.showSubResults=!1;this.maxResults=0;this.showKeyboardHints=!0;this.shortcut="mod+k";this.hideShortcut=!1;this.resultTemplate=null;this.compiledResultTemplate=null;this.compiledPlaceholderTemplate=null;this._documentClickHandler=null;this._shortcutKeyHandler=null;this._keyBinding=null;this._shortcutEl=null}static get observedAttributes(){return["placeholder","debounce","autofocus","show-sub-results","max-results","show-keyboard-hints","shortcut","hide-shortcut"]}get placeholder(){return this._userPlaceholder||this.instance?.translate("placeholder")||"Search..."}readAttributes(){this.hasAttribute("placeholder")&&(this._userPlaceholder=this.getAttribute("placeholder")),this.hasAttribute("debounce")&&(this.debounce=parseInt(this.getAttribute("debounce")||"150",10)||150),this.hasAttribute("autofocus")&&(this.autofocus=this.hasAttribute("autofocus")),this.hasAttribute("show-sub-results")&&(this.showSubResults=this.getAttribute("show-sub-results")!=="false"),this.hasAttribute("max-results")&&(this.maxResults=parseInt(this.getAttribute("max-results")||"0",10)),this.hasAttribute("show-keyboard-hints")&&(this.showKeyboardHints=this.getAttribute("show-keyboard-hints")!=="false"),this.hasAttribute("shortcut")&&(this.shortcut=this.getAttribute("shortcut")||"mod+k"),this.hasAttribute("hide-shortcut")&&(this.hideShortcut=this.getAttribute("hide-shortcut")!=="false"),this._keyBinding=je(this.shortcut)}init(){this.readAttributes(),this.checkForTemplates(),this.render(),this.setupOutsideClickHandler(),this.setupShortcutHandler()}checkForTemplates(){let e=this.querySelector('script[type="text/pagefind-template"]:not([data-template]), script[type="text/pagefind-template"][data-template="result"]');e&&(this.compiledResultTemplate=R((e.textContent||"").trim()));let t=this.querySelector('script[type="text/pagefind-template"][data-template="placeholder"]');t&&(this.compiledPlaceholderTemplate=R((t.textContent||"").trim()))}getPlaceholder(){return this.compiledPlaceholderTemplate?this.compiledPlaceholderTemplate({}):Aa({})}render(){let e=[];this.querySelectorAll('script[type="text/pagefind-template"]').forEach(l=>{e.push(l)}),this.innerHTML="",e.forEach(l=>this.appendChild(l));let t=this.instance.generateId("pf-sb-input"),r=this.instance.generateId("pf-sb-results");this.containerEl=document.createElement("div"),this.containerEl.className="pf-searchbox",this.appendChild(this.containerEl);let i=document.createElement("div");if(i.className="pf-searchbox-input-wrapper",this.containerEl.appendChild(i),this.inputEl=document.createElement("input"),this.inputEl.id=t,this.inputEl.className="pf-searchbox-input",this.inputEl.type="text",this.inputEl.setAttribute("role","combobox"),this.inputEl.setAttribute("aria-autocomplete","list"),this.inputEl.setAttribute("aria-controls",r),this.inputEl.setAttribute("aria-expanded","false"),this.inputEl.setAttribute("autocomplete","off"),this.inputEl.setAttribute("autocapitalize","none"),this.inputEl.placeholder=this.placeholder,this.autofocus&&this.inputEl.setAttribute("autofocus","autofocus"),i.appendChild(this.inputEl),!this.hideShortcut&&this._keyBinding){this._shortcutEl=document.createElement("span"),this._shortcutEl.className="pf-trigger-shortcut",this._shortcutEl.setAttribute("aria-hidden","true");let l=xe(this._keyBinding);for(let o of l.keys){let c=document.createElement("span");c.className="pf-trigger-key",c.textContent=o,this._shortcutEl.appendChild(c)}i.appendChild(this._shortcutEl),this.inputEl.setAttribute("aria-keyshortcuts",l.aria)}this.dropdownEl=document.createElement("div"),this.dropdownEl.className="pf-searchbox-dropdown",this.containerEl.appendChild(this.dropdownEl);let a=this.instance?.translate("results_label")||"Search results";this.instance?.direction==="rtl"?this.setAttribute("dir","rtl"):this.removeAttribute("dir"),this.resultsEl=document.createElement("div"),this.resultsEl.id=r,this.resultsEl.className="pf-searchbox-results",this.resultsEl.setAttribute("role","listbox"),this.resultsEl.setAttribute("aria-label",a),this.dropdownEl.appendChild(this.resultsEl),this.statusEl=document.createElement("div"),this.statusEl.className="pf-searchbox-status",this.statusEl.hidden=!0,this.dropdownEl.appendChild(this.statusEl),this.showKeyboardHints&&(this.footerEl=document.createElement("div"),this.footerEl.className="pf-searchbox-footer",this.footerEl.setAttribute("aria-hidden","true"),this.dropdownEl.appendChild(this.footerEl),this.renderFooterHints()),this.setupEventHandlers()}renderFooterHints(){if(!this.footerEl)return;this.footerEl.innerHTML="";let e=this.instance?.translate("keyboard_navigate")||"navigate",t=this.instance?.translate("keyboard_select")||"select",r=this.instance?.translate("keyboard_close")||"close",i=document.createElement("div");i.className="pf-searchbox-footer-hint";let a=document.createElement("span");a.className="pf-searchbox-footer-key",a.textContent="\u2191",i.appendChild(a);let l=document.createElement("span");l.className="pf-searchbox-footer-key",l.textContent="\u2193",i.appendChild(l),i.appendChild(document.createTextNode(` ${e}`)),this.footerEl.appendChild(i);let o=document.createElement("div");o.className="pf-searchbox-footer-hint";let c=document.createElement("span");c.className="pf-searchbox-footer-key",c.textContent="\u21B5",o.appendChild(c),o.appendChild(document.createTextNode(` ${t}`)),this.footerEl.appendChild(o);let u=document.createElement("div");u.className="pf-searchbox-footer-hint";let d=document.createElement("span");d.className="pf-searchbox-footer-key",d.textContent="esc",u.appendChild(d),u.appendChild(document.createTextNode(` ${r}`)),this.footerEl.appendChild(u)}setupEventHandlers(){!this.inputEl||!this.resultsEl||(this.inputEl.addEventListener("input",async e=>{let t=e.target.value;if(this.searchTerm=t,!t||!t.trim()){this.closeDropdown(),this.results=[],this.instance?.triggerSearch("");return}this.openDropdown(),this.showLoadingState();let r=++this.searchID;await va(this.debounce),r===this.searchID&&this.instance?.triggerSearch(t)}),this.inputEl.addEventListener("keydown",e=>{switch(e.key){case"ArrowDown":e.preventDefault(),!this.isOpen&&this.inputEl?.value.trim()&&this.openDropdown(),this.isOpen&&this.results.length>0&&this.moveSelection(1);break;case"ArrowUp":e.preventDefault(),this.isOpen&&this.results.length>0&&this.moveSelection(-1);break;case"Enter":this.isOpen&&this.activeIndex>=0?(e.preventDefault(),this.activateCurrentSelection(e)):!this.isOpen&&this.inputEl?.value.trim()&&(e.preventDefault(),this.openDropdown(),this.results.length>0?(this.rerenderLoadedResults(),this.activeIndex=0,this.activeOptionOffset=0,this.updateSelectionUI()):this.instance?.triggerSearch(this.inputEl.value));break;case"Escape":this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.isOpen&&(e.preventDefault(),this.closeDropdown());break;case"Tab":this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.isOpen&&this.closeDropdown();break}}),this.inputEl.addEventListener("focus",()=>{this.instance?.triggerLoad()}),this.resultsEl.addEventListener("click",e=>{e.target.closest("a")&&this.closeDropdown()}),this.resultsEl.addEventListener("mousemove",e=>{let t=e.target.closest("a");if(t){let r=this.getResultAndOffsetFromElement(t);r&&(r.resultIndex!==this.activeIndex||r.optionOffset!==this.activeOptionOffset)&&(this.activeIndex=r.resultIndex,this.activeOptionOffset=r.optionOffset,this.updateSelectionUI(!1))}}))}setupOutsideClickHandler(){this._documentClickHandler=e=>{this.isOpen&&!this.contains(e.target)&&this.closeDropdown()},document.addEventListener("click",this._documentClickHandler)}setupShortcutHandler(){this._keyBinding&&(this._shortcutKeyHandler=e=>{if(!this._keyBinding||!Be(this._keyBinding,e))return;let t=document.activeElement;t&&(t.tagName==="INPUT"||t.tagName==="TEXTAREA"||t.isContentEditable)||(e.preventDefault(),this.inputEl?.focus())},document.addEventListener("keydown",this._shortcutKeyHandler))}openDropdown(){this.isOpen||!this.containerEl||!this.inputEl||(this.isOpen=!0,this.containerEl.classList.add("open"),this.inputEl.setAttribute("aria-expanded","true"))}closeDropdown(){!this.isOpen||!this.containerEl||!this.inputEl||(this.isOpen=!1,this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.containerEl.classList.remove("open"),this.inputEl.setAttribute("aria-expanded","false"),this.inputEl.removeAttribute("aria-activedescendant"),this.activeIndex=-1,this.activeOptionOffset=0,this.selectedEl=null)}showLoadingState(){if(!this.resultsEl||!this.statusEl)return;this.isLoading=!0,this.resultsEl.innerHTML="",this.selectedEl=null,this.resultsEl.setAttribute("aria-busy","true");let e=this.instance?.translate("searching",{SEARCH_TERM:this.searchTerm})||"Searching...";this.statusEl.textContent=e,this.statusEl.className="pf-searchbox-status pf-searchbox-loading",this.statusEl.hidden=!1}showEmptyState(){if(!this.resultsEl||!this.statusEl)return;this.resultsEl.innerHTML="",this.selectedEl=null,this.resultsEl.removeAttribute("aria-busy");let e=this.instance?.translate("zero_results",{SEARCH_TERM:this.searchTerm})||`No results for "${this.searchTerm}"`;this.statusEl.textContent=e,this.statusEl.className="pf-searchbox-status pf-searchbox-empty",this.statusEl.hidden=!1,this.instance?.announce("zero_results",{SEARCH_TERM:this.searchTerm},"assertive")}getOptionsForResult(e){return e.cachedOptions!==null?e.cachedOptions:!e.data||!e.placeholderEl?[]:e.placeholderEl.getAttribute("role")==="group"?Array.from(e.placeholderEl.querySelectorAll('[role="option"]')):e.placeholderEl.getAttribute("role")==="option"?[e.placeholderEl]:[]}moveSelection(e){let t=this.results.length;if(t===0)return;if(e<0){if(this.activeIndex===-1)return;if(this.activeOptionOffset>0){this.activeOptionOffset--,this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.updateSelectionUI(!0);return}let o=this.activeIndex-1;if(o<0){this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.activeIndex=-1,this.activeOptionOffset=0,this.updateSelectionUI(!0);return}let c=this.results[o];if(!c||!c.data)return;let u=this.getOptionsForResult(c);this.activeIndex=o,this.activeOptionOffset=Math.max(0,u.length-1),this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.updateSelectionUI(!0),this.preloadAhead(o,e);return}if(this.activeIndex===-1){if(this.results[0]&&!this.results[0].data){this.pendingNavigation+=e,this.results[0].load(),this.scheduleLoadingAnnouncement(),this.preloadAhead(0,e);return}this.activeIndex=0,this.activeOptionOffset=0,this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.updateSelectionUI(!0),this.preloadAhead(0,e);return}let r=this.results[this.activeIndex];if(!r?.data){r&&(this.pendingNavigation+=e,r.load(),this.scheduleLoadingAnnouncement(),this.preloadAhead(this.activeIndex,e));return}let i=this.getOptionsForResult(r);if(this.activeOptionOffset=t)return;let l=this.results[a];if(l&&!l.data){this.pendingNavigation+=e,l.load(),this.scheduleLoadingAnnouncement(),this.preloadAhead(a,e);return}this.activeIndex=a,this.activeOptionOffset=0,this.pendingNavigation=0,this.clearLoadingAnnouncement(),this.updateSelectionUI(!0),this.preloadAhead(a,e)}preloadAhead(e,t){let r=t>0?1:-1,i=Math.abs(this.pendingNavigation)+3;for(let a=1;a<=i;a++){let l=e+r*a;if(l>=0&&l{this.loadingAnnouncementTimeout=null,this.instance?.announce("loading",{},"polite")},800))}clearLoadingAnnouncement(){this.loadingAnnouncementTimeout&&(clearTimeout(this.loadingAnnouncementTimeout),this.loadingAnnouncementTimeout=null)}handleResultLoaded(){if(this.clearLoadingAnnouncement(),this.pendingNavigation===0){this.updateSelectionUI();return}let e=this.pendingNavigation>0?1:-1,t=this.activeIndex,r=this.activeOptionOffset;for(;this.pendingNavigation!==0;)if(e>0){let i=this.results[t];if(i?.data){let o=this.getOptionsForResult(i);if(r=this.results.length){this.pendingNavigation=0;break}let l=this.results[a];if(l?.data)t=a,r=0,this.pendingNavigation--;else{l&&(l.load(),this.scheduleLoadingAnnouncement(),this.preloadAhead(a,e));break}}else{if(r>0){r--,this.pendingNavigation++;continue}let i=t-1;if(i<0){this.pendingNavigation=0;break}let a=this.results[i];if(a?.data){let l=this.getOptionsForResult(a);t=i,r=Math.max(0,l.length-1),this.pendingNavigation++}else break}(t!==this.activeIndex||r!==this.activeOptionOffset)&&(this.activeIndex=t,this.activeOptionOffset=r,this.updateSelectionUI(!0))}updateSelectionUI(e=!1){if(!this.resultsEl||!this.inputEl)return;this.selectedEl&&(this.selectedEl.removeAttribute("data-pf-selected"),this.selectedEl.setAttribute("aria-selected","false"),this.selectedEl=null);let t=this.activeIndex>=0?this.results[this.activeIndex]:null,i=(t?this.getOptionsForResult(t):[])[this.activeOptionOffset];i?(i.setAttribute("data-pf-selected",""),i.setAttribute("aria-selected","true"),this.selectedEl=i,this.inputEl.setAttribute("aria-activedescendant",i.id),e&&this.scrollToCenter(i)):this.inputEl.removeAttribute("aria-activedescendant")}scrollToCenter(e){if(!this.resultsEl)return;let t=this.resultsEl,r=e.offsetTop,i=e.offsetHeight,a=t.clientHeight,l=r-a/2+i/2;t.scrollTo({top:l,behavior:"smooth"})}getResultAndOffsetFromElement(e){let t=e.closest("[data-pf-result-index]");if(!t)return null;let r=parseInt(t.getAttribute("data-pf-result-index"),10),i=parseInt(t.getAttribute("data-pf-option-offset")||"0",10);return Number.isNaN(r)||Number.isNaN(i)?null:{resultIndex:r,optionOffset:i}}activateCurrentSelection(e){if(this.activeIndex<0||this.activeIndex>=this.results.length)return;let t=this.results[this.activeIndex];if(!t||!t.data)return;let i=this.getOptionsForResult(t)[this.activeOptionOffset];!i||!i.href||(e.metaKey||e.ctrlKey||e.shiftKey?window.open(i.href,"_blank"):window.location.href=i.href,this.closeDropdown())}handleResults(e){this.isLoading=!1,this.resultsEl&&this.resultsEl.removeAttribute("aria-busy"),this.statusEl&&(this.statusEl.hidden=!0);for(let i of this.results)i.cleanup();if(this.pendingNavigation=0,this.clearLoadingAnnouncement(),!e.results||e.results.length===0){this.results=[],this.showEmptyState();return}let t=this.maxResults>0?e.results.slice(0,this.maxResults):e.results;this.resultsEl&&(this.resultsEl.innerHTML="",this.selectedEl=null);let r=this.getResultRenderer();this.results=t.map((i,a)=>{let l=this.getPlaceholder(),c=Ke(l)[0];this.resultsEl&&c&&this.resultsEl.appendChild(c);let u=new jt({rawResult:i,placeholderEl:c,renderFn:r,intersectionRoot:this.resultsEl,index:a,onLoad:()=>{this.results[a]===u&&this.handleResultLoaded()}});return u}),this.activeIndex=0,this.activeOptionOffset=0,this.updateSelectionUI(),this.announceResults()}buildTemplateData(e){let t=this.showSubResults?this.instance.getDisplaySubResults(e):[],r=this.instance.generateId("pf-sb-result");return{meta:e.meta||{},excerpt:e.excerpt||"",url:e.url||"",sub_results:t.map(i=>{let a=this.instance.generateId("pf-sb-result");return{title:i.title,url:i.url,excerpt:i.excerpt,aria:{result_id:a,title_id:`${a}-title`,excerpt_id:`${a}-excerpt`}}}),options:{show_sub_results:this.showSubResults},aria:{result_id:r,title_id:`${r}-title`,excerpt_id:`${r}-excerpt`}}}getResultRenderer(){if(this.resultTemplate)return this.resultTemplate;if(this.compiledResultTemplate){let e=this.compiledResultTemplate;return t=>{let r=this.buildTemplateData(t);return e(r)}}return e=>{let t=this.buildTemplateData(e);return ns(t)}}rerenderLoadedResults(){if(this.resultsEl){this.resultsEl.innerHTML="",this.selectedEl=null;for(let e=0;e{this.searchTerm&&this.searchTerm.trim()&&(this.openDropdown(),this.showLoadingState())},this),e.on("results",t=>{this.handleResults(t)},this),e.on("error",t=>{let r=t;this.isLoading=!1;let i=e.translate("error_search")||"Search failed";this.showError({message:r.message||i,details:r.bundlePath?`Bundle path: ${r.bundlePath}`:void 0}),e.announce("error_search",{},"assertive")},this),e.on("search",t=>{this.inputEl&&document.activeElement!==this.inputEl&&(this.inputEl.value=t,this.searchTerm=t)},this),e.on("translations",()=>{let t=this.inputEl?.value||"",r=this.isOpen;this.render(),this.inputEl&&t&&(this.inputEl.value=t),r&&(this.openDropdown(),this.results.length>0&&(this.rerenderLoadedResults(),this.updateSelectionUI()))},this)}cleanup(){this.clearLoadingAnnouncement();for(let e of this.results)e.cleanup();this.results=[],this.selectedEl=null,this._documentClickHandler&&(document.removeEventListener("click",this._documentClickHandler),this._documentClickHandler=null),this._shortcutKeyHandler&&(document.removeEventListener("keydown",this._shortcutKeyHandler),this._shortcutKeyHandler=null)}update(){this.readAttributes(),this._documentClickHandler&&(document.removeEventListener("click",this._documentClickHandler),this._documentClickHandler=null),this._shortcutKeyHandler&&(document.removeEventListener("keydown",this._shortcutKeyHandler),this._shortcutKeyHandler=null),this.render(),this.setupOutsideClickHandler(),this.setupShortcutHandler()}focus(){this.inputEl&&this.inputEl.focus()}};customElements.get("pagefind-searchbox")||customElements.define("pagefind-searchbox",Fe);ts("resolveUrl",(n,s)=>{let e=String(n??"");if(!e||/^[a-z][a-z0-9+.-]*:/i.test(e)||/^\/\//.test(e)||e.startsWith("/"))return e;try{return new URL(e,new URL(String(s??"/"),"https://p")).pathname}catch{return e}});typeof window<"u"&&(window.PagefindComponents=Bt);})(); diff --git a/website/blog/pagefind/pagefind-entry.json b/website/blog/pagefind/pagefind-entry.json deleted file mode 100644 index 32b9392..0000000 --- a/website/blog/pagefind/pagefind-entry.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.5.0","languages":{"zh-cn":{"hash":"zh-cn_b823138fb9571","wasm":null,"page_count":5}},"include_characters":["_","‿","⁀","⁔","︳","︴","﹍","﹎","﹏","_"]} \ No newline at end of file diff --git a/website/blog/pagefind/pagefind-highlight.js b/website/blog/pagefind/pagefind-highlight.js deleted file mode 100644 index 0e538a5..0000000 --- a/website/blog/pagefind/pagefind-highlight.js +++ /dev/null @@ -1,1070 +0,0 @@ -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; -var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); -var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); - -// node_modules/mark.js/dist/mark.js -var require_mark = __commonJS({ - "node_modules/mark.js/dist/mark.js"(exports, module) { - (function(global, factory) { - typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global.Mark = factory(); - })(exports, (function() { - "use strict"; - var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) { - return typeof obj; - } : function(obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - var classCallCheck = function(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - }; - var createClass = /* @__PURE__ */ (function() { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - return function(Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - })(); - var _extends = Object.assign || function(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; - var DOMIterator = (function() { - function DOMIterator2(ctx) { - var iframes = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true; - var exclude = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : []; - var iframesTimeout = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 5e3; - classCallCheck(this, DOMIterator2); - this.ctx = ctx; - this.iframes = iframes; - this.exclude = exclude; - this.iframesTimeout = iframesTimeout; - } - createClass(DOMIterator2, [{ - key: "getContexts", - value: function getContexts() { - var ctx = void 0, filteredCtx = []; - if (typeof this.ctx === "undefined" || !this.ctx) { - ctx = []; - } else if (NodeList.prototype.isPrototypeOf(this.ctx)) { - ctx = Array.prototype.slice.call(this.ctx); - } else if (Array.isArray(this.ctx)) { - ctx = this.ctx; - } else if (typeof this.ctx === "string") { - ctx = Array.prototype.slice.call(document.querySelectorAll(this.ctx)); - } else { - ctx = [this.ctx]; - } - ctx.forEach(function(ctx2) { - var isDescendant = filteredCtx.filter(function(contexts) { - return contexts.contains(ctx2); - }).length > 0; - if (filteredCtx.indexOf(ctx2) === -1 && !isDescendant) { - filteredCtx.push(ctx2); - } - }); - return filteredCtx; - } - }, { - key: "getIframeContents", - value: function getIframeContents(ifr, successFn) { - var errorFn = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : function() { - }; - var doc = void 0; - try { - var ifrWin = ifr.contentWindow; - doc = ifrWin.document; - if (!ifrWin || !doc) { - throw new Error("iframe inaccessible"); - } - } catch (e) { - errorFn(); - } - if (doc) { - successFn(doc); - } - } - }, { - key: "isIframeBlank", - value: function isIframeBlank(ifr) { - var bl = "about:blank", src = ifr.getAttribute("src").trim(), href = ifr.contentWindow.location.href; - return href === bl && src !== bl && src; - } - }, { - key: "observeIframeLoad", - value: function observeIframeLoad(ifr, successFn, errorFn) { - var _this = this; - var called = false, tout = null; - var listener = function listener2() { - if (called) { - return; - } - called = true; - clearTimeout(tout); - try { - if (!_this.isIframeBlank(ifr)) { - ifr.removeEventListener("load", listener2); - _this.getIframeContents(ifr, successFn, errorFn); - } - } catch (e) { - errorFn(); - } - }; - ifr.addEventListener("load", listener); - tout = setTimeout(listener, this.iframesTimeout); - } - }, { - key: "onIframeReady", - value: function onIframeReady(ifr, successFn, errorFn) { - try { - if (ifr.contentWindow.document.readyState === "complete") { - if (this.isIframeBlank(ifr)) { - this.observeIframeLoad(ifr, successFn, errorFn); - } else { - this.getIframeContents(ifr, successFn, errorFn); - } - } else { - this.observeIframeLoad(ifr, successFn, errorFn); - } - } catch (e) { - errorFn(); - } - } - }, { - key: "waitForIframes", - value: function waitForIframes(ctx, done) { - var _this2 = this; - var eachCalled = 0; - this.forEachIframe(ctx, function() { - return true; - }, function(ifr) { - eachCalled++; - _this2.waitForIframes(ifr.querySelector("html"), function() { - if (!--eachCalled) { - done(); - } - }); - }, function(handled) { - if (!handled) { - done(); - } - }); - } - }, { - key: "forEachIframe", - value: function forEachIframe(ctx, filter, each) { - var _this3 = this; - var end = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : function() { - }; - var ifr = ctx.querySelectorAll("iframe"), open = ifr.length, handled = 0; - ifr = Array.prototype.slice.call(ifr); - var checkEnd = function checkEnd2() { - if (--open <= 0) { - end(handled); - } - }; - if (!open) { - checkEnd(); - } - ifr.forEach(function(ifr2) { - if (DOMIterator2.matches(ifr2, _this3.exclude)) { - checkEnd(); - } else { - _this3.onIframeReady(ifr2, function(con) { - if (filter(ifr2)) { - handled++; - each(con); - } - checkEnd(); - }, checkEnd); - } - }); - } - }, { - key: "createIterator", - value: function createIterator(ctx, whatToShow, filter) { - return document.createNodeIterator(ctx, whatToShow, filter, false); - } - }, { - key: "createInstanceOnIframe", - value: function createInstanceOnIframe(contents) { - return new DOMIterator2(contents.querySelector("html"), this.iframes); - } - }, { - key: "compareNodeIframe", - value: function compareNodeIframe(node, prevNode, ifr) { - var compCurr = node.compareDocumentPosition(ifr), prev = Node.DOCUMENT_POSITION_PRECEDING; - if (compCurr & prev) { - if (prevNode !== null) { - var compPrev = prevNode.compareDocumentPosition(ifr), after = Node.DOCUMENT_POSITION_FOLLOWING; - if (compPrev & after) { - return true; - } - } else { - return true; - } - } - return false; - } - }, { - key: "getIteratorNode", - value: function getIteratorNode(itr) { - var prevNode = itr.previousNode(); - var node = void 0; - if (prevNode === null) { - node = itr.nextNode(); - } else { - node = itr.nextNode() && itr.nextNode(); - } - return { - prevNode, - node - }; - } - }, { - key: "checkIframeFilter", - value: function checkIframeFilter(node, prevNode, currIfr, ifr) { - var key = false, handled = false; - ifr.forEach(function(ifrDict, i) { - if (ifrDict.val === currIfr) { - key = i; - handled = ifrDict.handled; - } - }); - if (this.compareNodeIframe(node, prevNode, currIfr)) { - if (key === false && !handled) { - ifr.push({ - val: currIfr, - handled: true - }); - } else if (key !== false && !handled) { - ifr[key].handled = true; - } - return true; - } - if (key === false) { - ifr.push({ - val: currIfr, - handled: false - }); - } - return false; - } - }, { - key: "handleOpenIframes", - value: function handleOpenIframes(ifr, whatToShow, eCb, fCb) { - var _this4 = this; - ifr.forEach(function(ifrDict) { - if (!ifrDict.handled) { - _this4.getIframeContents(ifrDict.val, function(con) { - _this4.createInstanceOnIframe(con).forEachNode(whatToShow, eCb, fCb); - }); - } - }); - } - }, { - key: "iterateThroughNodes", - value: function iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) { - var _this5 = this; - var itr = this.createIterator(ctx, whatToShow, filterCb); - var ifr = [], elements = [], node = void 0, prevNode = void 0, retrieveNodes = function retrieveNodes2() { - var _getIteratorNode = _this5.getIteratorNode(itr); - prevNode = _getIteratorNode.prevNode; - node = _getIteratorNode.node; - return node; - }; - while (retrieveNodes()) { - if (this.iframes) { - this.forEachIframe(ctx, function(currIfr) { - return _this5.checkIframeFilter(node, prevNode, currIfr, ifr); - }, function(con) { - _this5.createInstanceOnIframe(con).forEachNode(whatToShow, function(ifrNode) { - return elements.push(ifrNode); - }, filterCb); - }); - } - elements.push(node); - } - elements.forEach(function(node2) { - eachCb(node2); - }); - if (this.iframes) { - this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb); - } - doneCb(); - } - }, { - key: "forEachNode", - value: function forEachNode(whatToShow, each, filter) { - var _this6 = this; - var done = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : function() { - }; - var contexts = this.getContexts(); - var open = contexts.length; - if (!open) { - done(); - } - contexts.forEach(function(ctx) { - var ready = function ready2() { - _this6.iterateThroughNodes(whatToShow, ctx, each, filter, function() { - if (--open <= 0) { - done(); - } - }); - }; - if (_this6.iframes) { - _this6.waitForIframes(ctx, ready); - } else { - ready(); - } - }); - } - }], [{ - key: "matches", - value: function matches(element, selector) { - var selectors = typeof selector === "string" ? [selector] : selector, fn = element.matches || element.matchesSelector || element.msMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector || element.webkitMatchesSelector; - if (fn) { - var match = false; - selectors.every(function(sel) { - if (fn.call(element, sel)) { - match = true; - return false; - } - return true; - }); - return match; - } else { - return false; - } - } - }]); - return DOMIterator2; - })(); - var Mark$1 = (function() { - function Mark3(ctx) { - classCallCheck(this, Mark3); - this.ctx = ctx; - this.ie = false; - var ua = window.navigator.userAgent; - if (ua.indexOf("MSIE") > -1 || ua.indexOf("Trident") > -1) { - this.ie = true; - } - } - createClass(Mark3, [{ - key: "log", - value: function log(msg) { - var level = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "debug"; - var log2 = this.opt.log; - if (!this.opt.debug) { - return; - } - if ((typeof log2 === "undefined" ? "undefined" : _typeof(log2)) === "object" && typeof log2[level] === "function") { - log2[level]("mark.js: " + msg); - } - } - }, { - key: "escapeStr", - value: function escapeStr(str) { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - } - }, { - key: "createRegExp", - value: function createRegExp(str) { - if (this.opt.wildcards !== "disabled") { - str = this.setupWildcardsRegExp(str); - } - str = this.escapeStr(str); - if (Object.keys(this.opt.synonyms).length) { - str = this.createSynonymsRegExp(str); - } - if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { - str = this.setupIgnoreJoinersRegExp(str); - } - if (this.opt.diacritics) { - str = this.createDiacriticsRegExp(str); - } - str = this.createMergedBlanksRegExp(str); - if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { - str = this.createJoinersRegExp(str); - } - if (this.opt.wildcards !== "disabled") { - str = this.createWildcardsRegExp(str); - } - str = this.createAccuracyRegExp(str); - return str; - } - }, { - key: "createSynonymsRegExp", - value: function createSynonymsRegExp(str) { - var syn = this.opt.synonyms, sens = this.opt.caseSensitive ? "" : "i", joinerPlaceholder = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? "\0" : ""; - for (var index in syn) { - if (syn.hasOwnProperty(index)) { - var value = syn[index], k1 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(index) : this.escapeStr(index), k2 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(value) : this.escapeStr(value); - if (k1 !== "" && k2 !== "") { - str = str.replace(new RegExp("(" + this.escapeStr(k1) + "|" + this.escapeStr(k2) + ")", "gm" + sens), joinerPlaceholder + ("(" + this.processSynomyms(k1) + "|") + (this.processSynomyms(k2) + ")") + joinerPlaceholder); - } - } - } - return str; - } - }, { - key: "processSynomyms", - value: function processSynomyms(str) { - if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { - str = this.setupIgnoreJoinersRegExp(str); - } - return str; - } - }, { - key: "setupWildcardsRegExp", - value: function setupWildcardsRegExp(str) { - str = str.replace(/(?:\\)*\?/g, function(val) { - return val.charAt(0) === "\\" ? "?" : ""; - }); - return str.replace(/(?:\\)*\*/g, function(val) { - return val.charAt(0) === "\\" ? "*" : ""; - }); - } - }, { - key: "createWildcardsRegExp", - value: function createWildcardsRegExp(str) { - var spaces = this.opt.wildcards === "withSpaces"; - return str.replace(/\u0001/g, spaces ? "[\\S\\s]?" : "\\S?").replace(/\u0002/g, spaces ? "[\\S\\s]*?" : "\\S*"); - } - }, { - key: "setupIgnoreJoinersRegExp", - value: function setupIgnoreJoinersRegExp(str) { - return str.replace(/[^(|)\\]/g, function(val, indx, original) { - var nextChar = original.charAt(indx + 1); - if (/[(|)\\]/.test(nextChar) || nextChar === "") { - return val; - } else { - return val + "\0"; - } - }); - } - }, { - key: "createJoinersRegExp", - value: function createJoinersRegExp(str) { - var joiner = []; - var ignorePunctuation = this.opt.ignorePunctuation; - if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) { - joiner.push(this.escapeStr(ignorePunctuation.join(""))); - } - if (this.opt.ignoreJoiners) { - joiner.push("\\u00ad\\u200b\\u200c\\u200d"); - } - return joiner.length ? str.split(/\u0000+/).join("[" + joiner.join("") + "]*") : str; - } - }, { - key: "createDiacriticsRegExp", - value: function createDiacriticsRegExp(str) { - var sens = this.opt.caseSensitive ? "" : "i", dct = this.opt.caseSensitive ? ["a\xE0\xE1\u1EA3\xE3\u1EA1\u0103\u1EB1\u1EAF\u1EB3\u1EB5\u1EB7\xE2\u1EA7\u1EA5\u1EA9\u1EAB\u1EAD\xE4\xE5\u0101\u0105", "A\xC0\xC1\u1EA2\xC3\u1EA0\u0102\u1EB0\u1EAE\u1EB2\u1EB4\u1EB6\xC2\u1EA6\u1EA4\u1EA8\u1EAA\u1EAC\xC4\xC5\u0100\u0104", "c\xE7\u0107\u010D", "C\xC7\u0106\u010C", "d\u0111\u010F", "D\u0110\u010E", "e\xE8\xE9\u1EBB\u1EBD\u1EB9\xEA\u1EC1\u1EBF\u1EC3\u1EC5\u1EC7\xEB\u011B\u0113\u0119", "E\xC8\xC9\u1EBA\u1EBC\u1EB8\xCA\u1EC0\u1EBE\u1EC2\u1EC4\u1EC6\xCB\u011A\u0112\u0118", "i\xEC\xED\u1EC9\u0129\u1ECB\xEE\xEF\u012B", "I\xCC\xCD\u1EC8\u0128\u1ECA\xCE\xCF\u012A", "l\u0142", "L\u0141", "n\xF1\u0148\u0144", "N\xD1\u0147\u0143", "o\xF2\xF3\u1ECF\xF5\u1ECD\xF4\u1ED3\u1ED1\u1ED5\u1ED7\u1ED9\u01A1\u1EDF\u1EE1\u1EDB\u1EDD\u1EE3\xF6\xF8\u014D", "O\xD2\xD3\u1ECE\xD5\u1ECC\xD4\u1ED2\u1ED0\u1ED4\u1ED6\u1ED8\u01A0\u1EDE\u1EE0\u1EDA\u1EDC\u1EE2\xD6\xD8\u014C", "r\u0159", "R\u0158", "s\u0161\u015B\u0219\u015F", "S\u0160\u015A\u0218\u015E", "t\u0165\u021B\u0163", "T\u0164\u021A\u0162", "u\xF9\xFA\u1EE7\u0169\u1EE5\u01B0\u1EEB\u1EE9\u1EED\u1EEF\u1EF1\xFB\xFC\u016F\u016B", "U\xD9\xDA\u1EE6\u0168\u1EE4\u01AF\u1EEA\u1EE8\u1EEC\u1EEE\u1EF0\xDB\xDC\u016E\u016A", "y\xFD\u1EF3\u1EF7\u1EF9\u1EF5\xFF", "Y\xDD\u1EF2\u1EF6\u1EF8\u1EF4\u0178", "z\u017E\u017C\u017A", "Z\u017D\u017B\u0179"] : ["a\xE0\xE1\u1EA3\xE3\u1EA1\u0103\u1EB1\u1EAF\u1EB3\u1EB5\u1EB7\xE2\u1EA7\u1EA5\u1EA9\u1EAB\u1EAD\xE4\xE5\u0101\u0105A\xC0\xC1\u1EA2\xC3\u1EA0\u0102\u1EB0\u1EAE\u1EB2\u1EB4\u1EB6\xC2\u1EA6\u1EA4\u1EA8\u1EAA\u1EAC\xC4\xC5\u0100\u0104", "c\xE7\u0107\u010DC\xC7\u0106\u010C", "d\u0111\u010FD\u0110\u010E", "e\xE8\xE9\u1EBB\u1EBD\u1EB9\xEA\u1EC1\u1EBF\u1EC3\u1EC5\u1EC7\xEB\u011B\u0113\u0119E\xC8\xC9\u1EBA\u1EBC\u1EB8\xCA\u1EC0\u1EBE\u1EC2\u1EC4\u1EC6\xCB\u011A\u0112\u0118", "i\xEC\xED\u1EC9\u0129\u1ECB\xEE\xEF\u012BI\xCC\xCD\u1EC8\u0128\u1ECA\xCE\xCF\u012A", "l\u0142L\u0141", "n\xF1\u0148\u0144N\xD1\u0147\u0143", "o\xF2\xF3\u1ECF\xF5\u1ECD\xF4\u1ED3\u1ED1\u1ED5\u1ED7\u1ED9\u01A1\u1EDF\u1EE1\u1EDB\u1EDD\u1EE3\xF6\xF8\u014DO\xD2\xD3\u1ECE\xD5\u1ECC\xD4\u1ED2\u1ED0\u1ED4\u1ED6\u1ED8\u01A0\u1EDE\u1EE0\u1EDA\u1EDC\u1EE2\xD6\xD8\u014C", "r\u0159R\u0158", "s\u0161\u015B\u0219\u015FS\u0160\u015A\u0218\u015E", "t\u0165\u021B\u0163T\u0164\u021A\u0162", "u\xF9\xFA\u1EE7\u0169\u1EE5\u01B0\u1EEB\u1EE9\u1EED\u1EEF\u1EF1\xFB\xFC\u016F\u016BU\xD9\xDA\u1EE6\u0168\u1EE4\u01AF\u1EEA\u1EE8\u1EEC\u1EEE\u1EF0\xDB\xDC\u016E\u016A", "y\xFD\u1EF3\u1EF7\u1EF9\u1EF5\xFFY\xDD\u1EF2\u1EF6\u1EF8\u1EF4\u0178", "z\u017E\u017C\u017AZ\u017D\u017B\u0179"]; - var handled = []; - str.split("").forEach(function(ch) { - dct.every(function(dct2) { - if (dct2.indexOf(ch) !== -1) { - if (handled.indexOf(dct2) > -1) { - return false; - } - str = str.replace(new RegExp("[" + dct2 + "]", "gm" + sens), "[" + dct2 + "]"); - handled.push(dct2); - } - return true; - }); - }); - return str; - } - }, { - key: "createMergedBlanksRegExp", - value: function createMergedBlanksRegExp(str) { - return str.replace(/[\s]+/gmi, "[\\s]+"); - } - }, { - key: "createAccuracyRegExp", - value: function createAccuracyRegExp(str) { - var _this = this; - var chars = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\xA1\xBF"; - var acc = this.opt.accuracy, val = typeof acc === "string" ? acc : acc.value, ls = typeof acc === "string" ? [] : acc.limiters, lsJoin = ""; - ls.forEach(function(limiter) { - lsJoin += "|" + _this.escapeStr(limiter); - }); - switch (val) { - case "partially": - default: - return "()(" + str + ")"; - case "complementary": - lsJoin = "\\s" + (lsJoin ? lsJoin : this.escapeStr(chars)); - return "()([^" + lsJoin + "]*" + str + "[^" + lsJoin + "]*)"; - case "exactly": - return "(^|\\s" + lsJoin + ")(" + str + ")(?=$|\\s" + lsJoin + ")"; - } - } - }, { - key: "getSeparatedKeywords", - value: function getSeparatedKeywords(sv) { - var _this2 = this; - var stack = []; - sv.forEach(function(kw) { - if (!_this2.opt.separateWordSearch) { - if (kw.trim() && stack.indexOf(kw) === -1) { - stack.push(kw); - } - } else { - kw.split(" ").forEach(function(kwSplitted) { - if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) { - stack.push(kwSplitted); - } - }); - } - }); - return { - "keywords": stack.sort(function(a, b) { - return b.length - a.length; - }), - "length": stack.length - }; - } - }, { - key: "isNumeric", - value: function isNumeric(value) { - return Number(parseFloat(value)) == value; - } - }, { - key: "checkRanges", - value: function checkRanges(array) { - var _this3 = this; - if (!Array.isArray(array) || Object.prototype.toString.call(array[0]) !== "[object Object]") { - this.log("markRanges() will only accept an array of objects"); - this.opt.noMatch(array); - return []; - } - var stack = []; - var last = 0; - array.sort(function(a, b) { - return a.start - b.start; - }).forEach(function(item) { - var _callNoMatchOnInvalid = _this3.callNoMatchOnInvalidRanges(item, last), start = _callNoMatchOnInvalid.start, end = _callNoMatchOnInvalid.end, valid = _callNoMatchOnInvalid.valid; - if (valid) { - item.start = start; - item.length = end - start; - stack.push(item); - last = end; - } - }); - return stack; - } - }, { - key: "callNoMatchOnInvalidRanges", - value: function callNoMatchOnInvalidRanges(range, last) { - var start = void 0, end = void 0, valid = false; - if (range && typeof range.start !== "undefined") { - start = parseInt(range.start, 10); - end = start + parseInt(range.length, 10); - if (this.isNumeric(range.start) && this.isNumeric(range.length) && end - last > 0 && end - start > 0) { - valid = true; - } else { - this.log("Ignoring invalid or overlapping range: " + ("" + JSON.stringify(range))); - this.opt.noMatch(range); - } - } else { - this.log("Ignoring invalid range: " + JSON.stringify(range)); - this.opt.noMatch(range); - } - return { - start, - end, - valid - }; - } - }, { - key: "checkWhitespaceRanges", - value: function checkWhitespaceRanges(range, originalLength, string) { - var end = void 0, valid = true, max = string.length, offset = originalLength - max, start = parseInt(range.start, 10) - offset; - start = start > max ? max : start; - end = start + parseInt(range.length, 10); - if (end > max) { - end = max; - this.log("End range automatically set to the max value of " + max); - } - if (start < 0 || end - start < 0 || start > max || end > max) { - valid = false; - this.log("Invalid range: " + JSON.stringify(range)); - this.opt.noMatch(range); - } else if (string.substring(start, end).replace(/\s+/g, "") === "") { - valid = false; - this.log("Skipping whitespace only range: " + JSON.stringify(range)); - this.opt.noMatch(range); - } - return { - start, - end, - valid - }; - } - }, { - key: "getTextNodes", - value: function getTextNodes(cb) { - var _this4 = this; - var val = "", nodes = []; - this.iterator.forEachNode(NodeFilter.SHOW_TEXT, function(node) { - nodes.push({ - start: val.length, - end: (val += node.textContent).length, - node - }); - }, function(node) { - if (_this4.matchesExclude(node.parentNode)) { - return NodeFilter.FILTER_REJECT; - } else { - return NodeFilter.FILTER_ACCEPT; - } - }, function() { - cb({ - value: val, - nodes - }); - }); - } - }, { - key: "matchesExclude", - value: function matchesExclude(el) { - return DOMIterator.matches(el, this.opt.exclude.concat(["script", "style", "title", "head", "html"])); - } - }, { - key: "wrapRangeInTextNode", - value: function wrapRangeInTextNode(node, start, end) { - var hEl = !this.opt.element ? "mark" : this.opt.element, startNode = node.splitText(start), ret = startNode.splitText(end - start); - var repl = document.createElement(hEl); - repl.setAttribute("data-markjs", "true"); - if (this.opt.className) { - repl.setAttribute("class", this.opt.className); - } - repl.textContent = startNode.textContent; - startNode.parentNode.replaceChild(repl, startNode); - return ret; - } - }, { - key: "wrapRangeInMappedTextNode", - value: function wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) { - var _this5 = this; - dict.nodes.every(function(n, i) { - var sibl = dict.nodes[i + 1]; - if (typeof sibl === "undefined" || sibl.start > start) { - if (!filterCb(n.node)) { - return false; - } - var s = start - n.start, e = (end > n.end ? n.end : end) - n.start, startStr = dict.value.substr(0, n.start), endStr = dict.value.substr(e + n.start); - n.node = _this5.wrapRangeInTextNode(n.node, s, e); - dict.value = startStr + endStr; - dict.nodes.forEach(function(k, j) { - if (j >= i) { - if (dict.nodes[j].start > 0 && j !== i) { - dict.nodes[j].start -= e; - } - dict.nodes[j].end -= e; - } - }); - end -= e; - eachCb(n.node.previousSibling, n.start); - if (end > n.end) { - start = n.end; - } else { - return false; - } - } - return true; - }); - } - }, { - key: "wrapMatches", - value: function wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) { - var _this6 = this; - var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1; - this.getTextNodes(function(dict) { - dict.nodes.forEach(function(node) { - node = node.node; - var match = void 0; - while ((match = regex.exec(node.textContent)) !== null && match[matchIdx] !== "") { - if (!filterCb(match[matchIdx], node)) { - continue; - } - var pos = match.index; - if (matchIdx !== 0) { - for (var i = 1; i < matchIdx; i++) { - pos += match[i].length; - } - } - node = _this6.wrapRangeInTextNode(node, pos, pos + match[matchIdx].length); - eachCb(node.previousSibling); - regex.lastIndex = 0; - } - }); - endCb(); - }); - } - }, { - key: "wrapMatchesAcrossElements", - value: function wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) { - var _this7 = this; - var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1; - this.getTextNodes(function(dict) { - var match = void 0; - while ((match = regex.exec(dict.value)) !== null && match[matchIdx] !== "") { - var start = match.index; - if (matchIdx !== 0) { - for (var i = 1; i < matchIdx; i++) { - start += match[i].length; - } - } - var end = start + match[matchIdx].length; - _this7.wrapRangeInMappedTextNode(dict, start, end, function(node) { - return filterCb(match[matchIdx], node); - }, function(node, lastIndex) { - regex.lastIndex = lastIndex; - eachCb(node); - }); - } - endCb(); - }); - } - }, { - key: "wrapRangeFromIndex", - value: function wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) { - var _this8 = this; - this.getTextNodes(function(dict) { - var originalLength = dict.value.length; - ranges.forEach(function(range, counter) { - var _checkWhitespaceRange = _this8.checkWhitespaceRanges(range, originalLength, dict.value), start = _checkWhitespaceRange.start, end = _checkWhitespaceRange.end, valid = _checkWhitespaceRange.valid; - if (valid) { - _this8.wrapRangeInMappedTextNode(dict, start, end, function(node) { - return filterCb(node, range, dict.value.substring(start, end), counter); - }, function(node) { - eachCb(node, range); - }); - } - }); - endCb(); - }); - } - }, { - key: "unwrapMatches", - value: function unwrapMatches(node) { - var parent = node.parentNode; - var docFrag = document.createDocumentFragment(); - while (node.firstChild) { - docFrag.appendChild(node.removeChild(node.firstChild)); - } - parent.replaceChild(docFrag, node); - if (!this.ie) { - parent.normalize(); - } else { - this.normalizeTextNode(parent); - } - } - }, { - key: "normalizeTextNode", - value: function normalizeTextNode(node) { - if (!node) { - return; - } - if (node.nodeType === 3) { - while (node.nextSibling && node.nextSibling.nodeType === 3) { - node.nodeValue += node.nextSibling.nodeValue; - node.parentNode.removeChild(node.nextSibling); - } - } else { - this.normalizeTextNode(node.firstChild); - } - this.normalizeTextNode(node.nextSibling); - } - }, { - key: "markRegExp", - value: function markRegExp(regexp, opt) { - var _this9 = this; - this.opt = opt; - this.log('Searching with expression "' + regexp + '"'); - var totalMatches = 0, fn = "wrapMatches"; - var eachCb = function eachCb2(element) { - totalMatches++; - _this9.opt.each(element); - }; - if (this.opt.acrossElements) { - fn = "wrapMatchesAcrossElements"; - } - this[fn](regexp, this.opt.ignoreGroups, function(match, node) { - return _this9.opt.filter(node, match, totalMatches); - }, eachCb, function() { - if (totalMatches === 0) { - _this9.opt.noMatch(regexp); - } - _this9.opt.done(totalMatches); - }); - } - }, { - key: "mark", - value: function mark(sv, opt) { - var _this10 = this; - this.opt = opt; - var totalMatches = 0, fn = "wrapMatches"; - var _getSeparatedKeywords = this.getSeparatedKeywords(typeof sv === "string" ? [sv] : sv), kwArr = _getSeparatedKeywords.keywords, kwArrLen = _getSeparatedKeywords.length, sens = this.opt.caseSensitive ? "" : "i", handler = function handler2(kw) { - var regex = new RegExp(_this10.createRegExp(kw), "gm" + sens), matches = 0; - _this10.log('Searching with expression "' + regex + '"'); - _this10[fn](regex, 1, function(term, node) { - return _this10.opt.filter(node, kw, totalMatches, matches); - }, function(element) { - matches++; - totalMatches++; - _this10.opt.each(element); - }, function() { - if (matches === 0) { - _this10.opt.noMatch(kw); - } - if (kwArr[kwArrLen - 1] === kw) { - _this10.opt.done(totalMatches); - } else { - handler2(kwArr[kwArr.indexOf(kw) + 1]); - } - }); - }; - if (this.opt.acrossElements) { - fn = "wrapMatchesAcrossElements"; - } - if (kwArrLen === 0) { - this.opt.done(totalMatches); - } else { - handler(kwArr[0]); - } - } - }, { - key: "markRanges", - value: function markRanges(rawRanges, opt) { - var _this11 = this; - this.opt = opt; - var totalMatches = 0, ranges = this.checkRanges(rawRanges); - if (ranges && ranges.length) { - this.log("Starting to mark with the following ranges: " + JSON.stringify(ranges)); - this.wrapRangeFromIndex(ranges, function(node, range, match, counter) { - return _this11.opt.filter(node, range, match, counter); - }, function(element, range) { - totalMatches++; - _this11.opt.each(element, range); - }, function() { - _this11.opt.done(totalMatches); - }); - } else { - this.opt.done(totalMatches); - } - } - }, { - key: "unmark", - value: function unmark(opt) { - var _this12 = this; - this.opt = opt; - var sel = this.opt.element ? this.opt.element : "*"; - sel += "[data-markjs]"; - if (this.opt.className) { - sel += "." + this.opt.className; - } - this.log('Removal selector "' + sel + '"'); - this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT, function(node) { - _this12.unwrapMatches(node); - }, function(node) { - var matchesSel = DOMIterator.matches(node, sel), matchesExclude = _this12.matchesExclude(node); - if (!matchesSel || matchesExclude) { - return NodeFilter.FILTER_REJECT; - } else { - return NodeFilter.FILTER_ACCEPT; - } - }, this.opt.done); - } - }, { - key: "opt", - set: function set$$1(val) { - this._opt = _extends({}, { - "element": "", - "className": "", - "exclude": [], - "iframes": false, - "iframesTimeout": 5e3, - "separateWordSearch": true, - "diacritics": true, - "synonyms": {}, - "accuracy": "partially", - "acrossElements": false, - "caseSensitive": false, - "ignoreJoiners": false, - "ignoreGroups": 0, - "ignorePunctuation": [], - "wildcards": "disabled", - "each": function each() { - }, - "noMatch": function noMatch() { - }, - "filter": function filter() { - return true; - }, - "done": function done() { - }, - "debug": false, - "log": window.console - }, val); - }, - get: function get$$1() { - return this._opt; - } - }, { - key: "iterator", - get: function get$$1() { - return new DOMIterator(this.ctx, this.opt.iframes, this.opt.exclude, this.opt.iframesTimeout); - } - }]); - return Mark3; - })(); - function Mark2(ctx) { - var _this = this; - var instance = new Mark$1(ctx); - this.mark = function(sv, opt) { - instance.mark(sv, opt); - return _this; - }; - this.markRegExp = function(sv, opt) { - instance.markRegExp(sv, opt); - return _this; - }; - this.markRanges = function(sv, opt) { - instance.markRanges(sv, opt); - return _this; - }; - this.unmark = function(opt) { - instance.unmark(opt); - return _this; - }; - return this; - } - return Mark2; - })); - } -}); - -// lib/highlight.ts -var import_mark = __toESM(require_mark(), 1); -var PagefindHighlight = class { - constructor(options = { - markContext: null, - highlightParam: "pagefind-highlight", - markOptions: { - className: "pagefind-highlight", - exclude: ["[data-pagefind-ignore]", "[data-pagefind-ignore] *"] - }, - addStyles: true - }) { - __publicField(this, "highlightParam"); - __publicField(this, "markContext"); - __publicField(this, "markOptions"); - __publicField(this, "addStyles"); - var _a, _b; - const { highlightParam, markContext, markOptions, addStyles } = options; - this.highlightParam = highlightParam ?? "pagefind-highlight"; - this.addStyles = addStyles ?? true; - this.markContext = markContext !== void 0 ? markContext : null; - this.markOptions = markOptions !== void 0 ? markOptions : { - className: "pagefind-highlight", - exclude: ["[data-pagefind-ignore]", "[data-pagefind-ignore] *"] - }; - (_a = this.markOptions).className ?? (_a.className = "pagefind__highlight"); - (_b = this.markOptions).exclude ?? (_b.exclude = [ - "[data-pagefind-ignore]", - "[data-pagefind-ignore] *" - ]); - this.markOptions.separateWordSearch = false; - this.highlight(); - } - getHighlightParams(paramName) { - const urlParams = new URLSearchParams(window.location.search); - return urlParams.getAll(paramName); - } - // Inline styles might be too hard to override - addHighlightStyles(className) { - if (!className) return; - const styleElement = document.createElement("style"); - styleElement.innerText = `:where(.${className}) { background-color: yellow; color: black; }`; - document.head.appendChild(styleElement); - } - createMarkInstance() { - if (this.markContext) { - return new import_mark.default(this.markContext); - } - const pagefindBody = document.querySelectorAll("[data-pagefind-body]"); - if (pagefindBody.length !== 0) { - return new import_mark.default(pagefindBody); - } else { - return new import_mark.default(document.body); - } - } - markText(instance, text) { - instance.mark(text, this.markOptions); - } - highlight() { - const params = this.getHighlightParams(this.highlightParam); - if (!params || params.length === 0) return; - this.addStyles && this.addHighlightStyles(this.markOptions.className); - const markInstance = this.createMarkInstance(); - this.markText(markInstance, params); - } -}; -window.PagefindHighlight = PagefindHighlight; -export { - PagefindHighlight as default -}; -/*! Bundled license information: - -mark.js/dist/mark.js: - (*!*************************************************** - * mark.js v8.11.1 - * https://markjs.io/ - * Copyright (c) 2014–2018, Julian Kühnel - * Released under the MIT license https://git.io/vwTVl - *****************************************************) -*/ diff --git a/website/blog/pagefind/pagefind-modular-ui.css b/website/blog/pagefind/pagefind-modular-ui.css deleted file mode 100644 index 9c6793e..0000000 --- a/website/blog/pagefind/pagefind-modular-ui.css +++ /dev/null @@ -1,214 +0,0 @@ -:root { - --pagefind-ui-scale: 0.8; - --pagefind-ui-primary: #034AD8; - --pagefind-ui-fade: #707070; - --pagefind-ui-text: #393939; - --pagefind-ui-background: #ffffff; - --pagefind-ui-border: #eeeeee; - --pagefind-ui-tag: #eeeeee; - --pagefind-ui-border-width: 2px; - --pagefind-ui-border-radius: 8px; - --pagefind-ui-image-border-radius: 8px; - --pagefind-ui-image-box-ratio: 3 / 2; - --pagefind-ui-font: system, -apple-system, ".SFNSText-Regular", - "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", - "Lucida Grande", sans-serif; -} - -[data-pfmod-hidden] { - display: none !important; -} - -[data-pfmod-suppressed] { - opacity: 0 !important; - pointer-events: none !important; -} - -[data-pfmod-sr-hidden] { - -webkit-clip: rect(0 0 0 0) !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - height: 1px !important; - overflow: hidden !important; - overflow: clip !important; - position: absolute !important; - white-space: nowrap !important; - width: 1px !important; -} - -[data-pfmod-loading] { - color: var(--pagefind-ui-text); - background-color: var(--pagefind-ui-text); - border-radius: var(--pagefind-ui-border-radius); - opacity: 0.1; - pointer-events: none; -} - -/* Input */ - -.pagefind-modular-input-wrapper { - position: relative; -} - -.pagefind-modular-input-wrapper::before { - background-color: var(--pagefind-ui-text); - width: calc(18px * var(--pagefind-ui-scale)); - height: calc(18px * var(--pagefind-ui-scale)); - top: calc(23px * var(--pagefind-ui-scale)); - left: calc(20px * var(--pagefind-ui-scale)); - content: ""; - position: absolute; - display: block; - opacity: 0.7; - -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A"); - mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A"); - -webkit-mask-size: 100%; - mask-size: 100%; - z-index: 9; - pointer-events: none; -} - -.pagefind-modular-input { - height: calc(64px * var(--pagefind-ui-scale)); - padding: 0 calc(70px * var(--pagefind-ui-scale)) 0 calc(54px * var(--pagefind-ui-scale)); - background-color: var(--pagefind-ui-background); - border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border); - border-radius: var(--pagefind-ui-border-radius); - font-size: calc(21px * var(--pagefind-ui-scale)); - position: relative; - appearance: none; - -webkit-appearance: none; - display: flex; - width: 100%; - box-sizing: border-box; - font-weight: 700; -} - -.pagefind-modular-input::placeholder { - opacity: 0.2; -} - -.pagefind-modular-input-clear { - position: absolute; - top: calc(2px * var(--pagefind-ui-scale)); - right: calc(2px * var(--pagefind-ui-scale)); - height: calc(60px * var(--pagefind-ui-scale)); - border-radius: var(--pagefind-ui-border-radius); - padding: 0 calc(15px * var(--pagefind-ui-scale)) 0 calc(2px * var(--pagefind-ui-scale)); - color: var(--pagefind-ui-text); - font-size: calc(14px * var(--pagefind-ui-scale)); - cursor: pointer; - background-color: var(--pagefind-ui-background); - border: none; - appearance: none; -} - -/* ResultList */ - -.pagefind-modular-list-result { - list-style-type: none; - display: flex; - align-items: flex-start; - gap: min(calc(40px * var(--pagefind-ui-scale)), 3%); - padding: calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale)); - border-top: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border); -} - -.pagefind-modular-list-result:last-of-type { - border-bottom: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border); -} - -.pagefind-modular-list-thumb { - width: min(30%, - calc((30% - (100px * var(--pagefind-ui-scale))) * 100000)); - max-width: calc(120px * var(--pagefind-ui-scale)); - margin-top: calc(10px * var(--pagefind-ui-scale)); - aspect-ratio: var(--pagefind-ui-image-box-ratio); - position: relative; -} - -.pagefind-modular-list-image { - display: block; - position: absolute; - left: 50%; - transform: translateX(-50%); - font-size: 0; - width: auto; - height: auto; - max-width: 100%; - max-height: 100%; - border-radius: var(--pagefind-ui-image-border-radius); -} - -.pagefind-modular-list-inner { - flex: 1; - display: flex; - flex-direction: column; - align-items: flex-start; - margin-top: calc(10px * var(--pagefind-ui-scale)); -} - -.pagefind-modular-list-title { - display: inline-block; - font-weight: 700; - font-size: calc(21px * var(--pagefind-ui-scale)); - margin-top: 0; - margin-bottom: 0; -} - -.pagefind-modular-list-link { - color: var(--pagefind-ui-text); - text-decoration: none; -} - -.pagefind-modular-list-link:hover { - text-decoration: underline; -} - -.pagefind-modular-list-excerpt { - display: inline-block; - font-weight: 400; - font-size: calc(16px * var(--pagefind-ui-scale)); - margin-top: calc(4px * var(--pagefind-ui-scale)); - margin-bottom: 0; - min-width: calc(250px * var(--pagefind-ui-scale)); -} - -/* FilterPills */ - -.pagefind-modular-filter-pills-wrapper { - overflow-x: scroll; - padding: 15px 0; -} - -.pagefind-modular-filter-pills { - display: flex; - gap: 6px; -} - -.pagefind-modular-filter-pill { - display: flex; - justify-content: center; - align-items: center; - border: none; - appearance: none; - padding: 0 calc(24px * var(--pagefind-ui-scale)); - background-color: var(--pagefind-ui-background); - color: var(--pagefind-ui-fade); - border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border); - border-radius: calc(25px * var(--pagefind-ui-scale)); - font-size: calc(18px * var(--pagefind-ui-scale)); - height: calc(50px * var(--pagefind-ui-scale)); - cursor: pointer; - white-space: nowrap; -} - -.pagefind-modular-filter-pill:hover { - border-color: var(--pagefind-ui-primary); -} - -.pagefind-modular-filter-pill[aria-pressed="true"] { - border-color: var(--pagefind-ui-primary); - color: var(--pagefind-ui-primary); -} \ No newline at end of file diff --git a/website/blog/pagefind/pagefind-modular-ui.js b/website/blog/pagefind/pagefind-modular-ui.js deleted file mode 100644 index 6caacd6..0000000 --- a/website/blog/pagefind/pagefind-modular-ui.js +++ /dev/null @@ -1,8 +0,0 @@ -(()=>{var w=Object.defineProperty;var b=(i,e)=>{for(var t in e)w(i,t,{get:e[t],enumerable:!0})};var f={};b(f,{FilterPills:()=>c,Input:()=>a,Instance:()=>p,ResultList:()=>o,Summary:()=>h});var r=class i{constructor(e){this.element=document.createElement(e)}id(e){return this.element.id=e,this}class(e){return this.element.classList.add(e),this}attrs(e){for(let[t,s]of Object.entries(e))this.element.setAttribute(t,s);return this}text(e){return this.element.innerText=e,this}html(e){return this.element.innerHTML=e,this}handle(e,t){return this.element.addEventListener(e,t),this}addTo(e){return e instanceof i?e.element.appendChild(this.element):e.appendChild(this.element),this.element}};var T=async(i=100)=>new Promise(e=>setTimeout(e,i)),a=class{constructor(e={}){if(this.inputEl=null,this.clearEl=null,this.instance=null,this.searchID=0,this.debounceTimeoutMs=e.debounceTimeoutMs??300,e.inputElement){if(e.containerElement){console.warn("[Pagefind Input component]: inputElement and containerElement both supplied. Ignoring the container option.");return}this.initExisting(e.inputElement)}else if(e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind Input component]: No selector supplied for containerElement or inputElement");return}this.inputEl.addEventListener("input",async t=>{if(this.instance&&typeof t?.target?.value=="string"){this.updateState(t.target.value);let s=++this.searchID;if(await T(this.debounceTimeoutMs),s!==this.searchID)return null;this.instance?.triggerSearch(t.target.value)}}),this.inputEl.addEventListener("keydown",t=>{t.key==="Escape"&&(++this.searchID,this.inputEl.value="",this.instance?.triggerSearch(""),this.updateState("")),t.key==="Enter"&&t.preventDefault()}),this.inputEl.addEventListener("focus",()=>{this.instance?.triggerLoad()})}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Input component]: No container found for ${e} selector`);return}if(t.tagName==="INPUT")console.warn(`[Pagefind Input component]: Encountered input element for ${e} when a container was expected`),console.warn("[Pagefind Input component]: Treating containerElement option as inputElement and proceeding"),this.initExisting(e);else{t.innerHTML="";let s=0;for(;document.querySelector(`#pfmod-input-${s}`);)s+=1;let n=new r("form").class("pagefind-modular-input-wrapper").attrs({role:"search","aria-label":"Search this site",action:"javascript:void(0);"});new r("label").attrs({for:`pfmod-input-${s}`,"data-pfmod-sr-hidden":"true"}).text("Search this site").addTo(n),this.inputEl=new r("input").id(`pfmod-input-${s}`).class("pagefind-modular-input").attrs({autocapitalize:"none",enterkeyhint:"search"}).addTo(n),this.clearEl=new r("button").class("pagefind-modular-input-clear").attrs({"data-pfmod-suppressed":"true"}).text("Clear").handle("click",()=>{this.inputEl.value="",this.instance.triggerSearch(""),this.updateState("")}).addTo(n),n.addTo(t)}}initExisting(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Input component]: No input element found for ${e} selector`);return}if(t.tagName!=="INPUT"){console.error(`[Pagefind Input component]: Expected ${e} to be an element`);return}this.inputEl=t}updateState(e){this.clearEl&&(e&&e?.length?this.clearEl.removeAttribute("data-pfmod-suppressed"):this.clearEl.setAttribute("data-pfmod-suppressed","true"))}register(e){this.instance=e,this.instance.on("search",(t,s)=>{this.inputEl&&document.activeElement!==this.inputEl&&(this.inputEl.value=t,this.updateState(t))})}focus(){this.inputEl&&this.inputEl.focus()}};var g=i=>{if(i instanceof Element)return[i];if(Array.isArray(i)&&i.every(e=>e instanceof Element))return i;if(typeof i=="string"||i instanceof String){let e=document.createElement("div");return e.innerHTML=i,[...e.childNodes]}else return console.error(`[Pagefind ResultList component]: Expected template function to return an HTML element or string, got ${typeof i}`),[]},v=()=>{let i=(e=30)=>". ".repeat(Math.floor(10+Math.random()*e));return`
  • -
    -
    -

    ${i(30)}

    -

    ${i(40)}

    -
    -
  • `},y=(i,e)=>{let t=new r("li").class("pagefind-modular-list-result");if(e){let l=new r("div").class("pagefind-modular-list-thumb").addTo(t);i?.meta?.image&&new r("img").class("pagefind-modular-list-image").attrs({src:i.meta.image,alt:i.meta.image_alt||i.meta.title}).addTo(l)}let s=new r("div").class("pagefind-modular-list-inner").addTo(t),n=new r("p").class("pagefind-modular-list-title").addTo(s);return new r("a").class("pagefind-modular-list-link").text(i.meta?.title).attrs({href:i.meta?.url||i.url}).addTo(n),new r("p").class("pagefind-modular-list-excerpt").html(i.excerpt).addTo(s),t.element},E=i=>{if(!(i instanceof HTMLElement))return null;let e=window.getComputedStyle(i).overflowY;return e!=="visible"&&e!=="hidden"?i:E(i.parentNode)},d=class{constructor(e={}){this.rawResult=e.result,this.placeholderNodes=e.placeholderNodes,this.resultFn=e.resultFn,this.intersectionEl=e.intersectionEl,this.showImages=e.showImages,this.result=null,this.waitForIntersection()}waitForIntersection(){if(!this.placeholderNodes?.length)return;let e={root:this.intersectionEl,rootMargin:"0px",threshold:.01};new IntersectionObserver((s,n)=>{this.result===null&&s?.[0]?.isIntersecting&&(this.load(),n.disconnect())},e).observe(this.placeholderNodes[0])}async load(){if(!this.placeholderNodes?.length)return;this.result=await this.rawResult.data();let e=this.resultFn(this.result,this.showImages),t=g(e);for(;this.placeholderNodes.length>1;)this.placeholderNodes.pop().remove();this.placeholderNodes[0].replaceWith(...t)}},o=class{constructor(e){if(this.intersectionEl=document.body,this.containerEl=null,this.results=[],this.placeholderTemplate=e.placeholderTemplate??v,this.resultTemplate=e.resultTemplate??y,this.showImages=e.showImages??!0,e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind ResultList component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind ResultList component]: No container found for ${e} selector`);return}this.containerEl=t}append(e){for(let t of e)this.containerEl.appendChild(t)}register(e){e.on("results",t=>{this.containerEl&&(this.containerEl.innerHTML="",this.intersectionEl=E(this.containerEl),this.results=t.results.map(s=>{let n=g(this.placeholderTemplate());return this.append(n),new d({result:s,placeholderNodes:n,resultFn:this.resultTemplate,intersectionEl:this.intersectionEl,showImages:this.showImages})}))}),e.on("loading",()=>{this.containerEl&&(this.containerEl.innerHTML="")})}};var h=class{constructor(e={}){if(this.containerEl=null,this.defaultMessage=e.defaultMessage??"",this.term="",e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind Summary component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Summary component]: No container found for ${e} selector`);return}this.containerEl=t,this.containerEl.innerText=this.defaultMessage}register(e){e.on("search",(t,s)=>{this.term=t}),e.on("results",t=>{if(!this.containerEl||!t)return;if(!this.term){this.containerEl.innerText=this.defaultMessage;return}let s=t?.results?.length??0;this.containerEl.innerText=`${s} result${s===1?"":"s"} for ${this.term}`}),e.on("loading",()=>{this.containerEl&&(this.containerEl.innerText=`Searching for ${this.term}...`)})}};var c=class{constructor(e={}){if(this.instance=null,this.wrapper=null,this.pillContainer=null,this.available={},this.selected=["All"],this.total=0,this.filterMemo="",this.filter=e.filter,this.ordering=e.ordering??null,this.alwaysShow=e.alwaysShow??!1,this.selectMultiple=e.selectMultiple??!1,!this.filter?.length){console.error("[Pagefind FilterPills component]: No filter option supplied, nothing to display");return}if(e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind FilterPills component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind FilterPills component]: No container found for ${e} selector`);return}t.innerHTML="";let s=`pagefind_modular_filter_pills_${this.filter}`,n=new r("div").class("pagefind-modular-filter-pills-wrapper").attrs({role:"group","aria-labelledby":s});this.alwaysShow||n.attrs({"data-pfmod-hidden":!0}),new r("div").id(s).class("pagefind-modular-filter-pills-label").attrs({"data-pfmod-sr-hidden":!0}).text(`Filter results by ${this.filter}`).addTo(n),this.pillContainer=new r("div").class("pagefind-modular-filter-pills").addTo(n),this.wrapper=n.addTo(t)}update(){let e=this.available.map(t=>t[0]).join("~");e==this.filterMemo?this.updateExisting():(this.renderNew(),this.filterMemo=e)}pushFilters(){let e=this.selected.filter(t=>t!=="All");this.instance.triggerFilter(this.filter,e)}pillInner(e,t){return this.total?`${e} (${t})`:`${e}`}renderNew(){this.available.forEach(([e,t])=>{new r("button").class("pagefind-modular-filter-pill").html(this.pillInner(e,t)).attrs({"aria-pressed":this.selected.includes(e),type:"button"}).handle("click",()=>{e==="All"?this.selected=["All"]:this.selected.includes(e)?this.selected=this.selected.filter(s=>s!==e):this.selectMultiple?this.selected.push(e):this.selected=[e],this.selected?.length?this.selected?.length>1&&(this.selected=this.selected.filter(s=>s!=="All")):this.selected=["All"],this.update(),this.pushFilters()}).addTo(this.pillContainer)})}updateExisting(){let e=[...this.pillContainer.childNodes];this.available.forEach(([t,s],n)=>{e[n].innerHTML=this.pillInner(t,s),e[n].setAttribute("aria-pressed",this.selected.includes(t))})}register(e){this.instance=e,this.instance.on("filters",t=>{if(!this.pillContainer)return;this.selectMultiple?t=t.available:t=t.total;let s=t[this.filter];if(!s){console.warn(`[Pagefind FilterPills component]: No possible values found for the ${this.filter} filter`);return}this.available=Object.entries(s),Array.isArray(this.ordering)?this.available.sort((n,l)=>{let m=this.ordering.indexOf(n[0]),_=this.ordering.indexOf(l[0]);return(m===-1?1/0:m)-(_===-1?1/0:_)}):this.available.sort((n,l)=>n[0].localeCompare(l[0])),this.available.unshift(["All",this.total]),this.update()}),e.on("results",t=>{this.pillContainer&&(this.total=t?.unfilteredResultCount||0,this.available?.[0]?.[0]==="All"&&(this.available[0][1]=this.total),this.total||this.alwaysShow?this.wrapper.removeAttribute("data-pfmod-hidden"):this.wrapper.setAttribute("data-pfmod-hidden","true"),this.update())})}};var P=async(i=50)=>await new Promise(e=>setTimeout(e,i)),u;try{document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&(u=new URL(document.currentScript.src).pathname.match(/^(.*\/)(?:pagefind-)?modular-ui.js.*$/)[1])}catch{u="/pagefind/"}var p=class{constructor(e={}){this.__pagefind__=null,this.__initializing__=null,this.__searchID__=0,this.__hooks__={search:[],filters:[],loading:[],results:[]},this.components=[],this.searchTerm="",this.searchFilters={},this.searchResult={},this.availableFilters=null,this.totalFilters=null,this.options={bundlePath:e.bundlePath??u,mergeIndex:e.mergeIndex??[]},delete e.bundlePath,delete e.resetStyles,delete e.processResult,delete e.processTerm,delete e.debounceTimeoutMs,delete e.mergeIndex,delete e.translations,this.pagefindOptions=e}add(e){e?.register?.(this),this.components.push(e)}on(e,t){if(!this.__hooks__[e]){let s=Object.keys(this.__hooks__).join(", ");console.error(`[Pagefind Composable]: Unknown event type ${e}. Supported events: [${s}]`);return}if(typeof t!="function"){console.error(`[Pagefind Composable]: Expected callback to be a function, received ${typeof t}`);return}this.__hooks__[e].push(t)}triggerLoad(){this.__load__()}triggerSearch(e){this.searchTerm=e,this.__dispatch__("search",e,this.searchFilters),this.__search__(e,this.searchFilters)}triggerSearchWithFilters(e,t){this.searchTerm=e,this.searchFilters=t,this.__dispatch__("search",e,t),this.__search__(e,t)}triggerFilters(e){this.searchFilters=e,this.__dispatch__("search",this.searchTerm,e),this.__search__(this.searchTerm,e)}triggerFilter(e,t){this.searchFilters=this.searchFilters||{},this.searchFilters[e]=t,this.__dispatch__("search",this.searchTerm,this.searchFilters),this.__search__(this.searchTerm,this.searchFilters)}__dispatch__(e,...t){this.__hooks__[e]?.forEach(s=>s?.(...t))}async __clear__(){this.__dispatch__("results",{results:[],unfilteredTotalCount:0}),this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})}async __search__(e,t){this.__dispatch__("loading"),await this.__load__();let s=++this.__searchID__;if(!e||!e.length)return this.__clear__();let n=await this.__pagefind__.search(e,{filters:t});n&&this.__searchID__===s&&(n.filters&&Object.keys(n.filters)?.length&&(this.availableFilters=n.filters,this.totalFilters=n.totalFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})),this.searchResult=n,this.__dispatch__("results",this.searchResult))}async __load__(){if(this.__initializing__){for(;!this.__pagefind__;)await P(50);return}if(this.__initializing__=!0,!this.__pagefind__){let e;try{e=await import(`${this.options.bundlePath}pagefind.js`)}catch(t){console.error(t),console.error([`Pagefind couldn't be loaded from ${this.options.bundlePath}pagefind.js`,"You can configure this by passing a bundlePath option to PagefindComposable Instance"].join(` -`)),document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?console.error(`[DEBUG: Loaded from ${document.currentScript?.src??"bad script location"}]`):console.error("no known script location")}await e.options(this.pagefindOptions||{});for(let t of this.options.mergeIndex){if(!t.bundlePath)throw new Error("mergeIndex requires a bundlePath parameter");let s=t.bundlePath;delete t.bundlePath,await e.mergeIndex(s,t)}this.__pagefind__=e}this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})}};window.PagefindModularUI=f;})(); diff --git a/website/blog/pagefind/pagefind-ui.css b/website/blog/pagefind/pagefind-ui.css deleted file mode 100644 index c17a1d4..0000000 --- a/website/blog/pagefind/pagefind-ui.css +++ /dev/null @@ -1 +0,0 @@ -.pagefind-ui__result.svelte-j9e30.svelte-j9e30{list-style-type:none;display:flex;align-items:flex-start;gap:min(calc(40px * var(--pagefind-ui-scale)),3%);padding:calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale));border-top:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result.svelte-j9e30.svelte-j9e30:last-of-type{border-bottom:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result-thumb.svelte-j9e30.svelte-j9e30{width:min(30%,calc((30% - (100px * var(--pagefind-ui-scale))) * 100000));max-width:calc(120px * var(--pagefind-ui-scale));margin-top:calc(10px * var(--pagefind-ui-scale));aspect-ratio:var(--pagefind-ui-image-box-ratio);position:relative}.pagefind-ui__result-image.svelte-j9e30.svelte-j9e30{display:block;position:absolute;left:50%;transform:translate(-50%);font-size:0;width:auto;height:auto;max-width:100%;max-height:100%;border-radius:var(--pagefind-ui-image-border-radius)}.pagefind-ui__result-inner.svelte-j9e30.svelte-j9e30{flex:1;display:flex;flex-direction:column;align-items:flex-start;margin-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-title.svelte-j9e30.svelte-j9e30{display:inline-block;font-weight:700;font-size:calc(21px * var(--pagefind-ui-scale));margin-top:0;margin-bottom:0}.pagefind-ui__result-title.svelte-j9e30 .pagefind-ui__result-link.svelte-j9e30{color:var(--pagefind-ui-text);text-decoration:none}.pagefind-ui__result-title.svelte-j9e30 .pagefind-ui__result-link.svelte-j9e30:hover{text-decoration:underline}.pagefind-ui__result-excerpt.svelte-j9e30.svelte-j9e30{display:inline-block;font-weight:400;font-size:calc(16px * var(--pagefind-ui-scale));margin-top:calc(4px * var(--pagefind-ui-scale));margin-bottom:0;min-width:calc(250px * var(--pagefind-ui-scale))}.pagefind-ui__loading.svelte-j9e30.svelte-j9e30{color:var(--pagefind-ui-text);background-color:var(--pagefind-ui-text);border-radius:var(--pagefind-ui-border-radius);opacity:.1;pointer-events:none}.pagefind-ui__result-tags.svelte-j9e30.svelte-j9e30{list-style-type:none;padding:0;display:flex;gap:calc(20px * var(--pagefind-ui-scale));flex-wrap:wrap;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-tag.svelte-j9e30.svelte-j9e30{padding:calc(4px * var(--pagefind-ui-scale)) calc(8px * var(--pagefind-ui-scale));font-size:calc(14px * var(--pagefind-ui-scale));border-radius:var(--pagefind-ui-border-radius);background-color:var(--pagefind-ui-tag)}.pagefind-ui__result.svelte-4xnkmf.svelte-4xnkmf{list-style-type:none;display:flex;align-items:flex-start;gap:min(calc(40px * var(--pagefind-ui-scale)),3%);padding:calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale));border-top:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result.svelte-4xnkmf.svelte-4xnkmf:last-of-type{border-bottom:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result-nested.svelte-4xnkmf.svelte-4xnkmf{display:flex;flex-direction:column;padding-left:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-nested.svelte-4xnkmf.svelte-4xnkmf:first-of-type{padding-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-nested.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf{font-size:.9em;position:relative}.pagefind-ui__result-nested.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf:before{content:"\2937 ";position:absolute;top:0;right:calc(100% + .1em)}.pagefind-ui__result-thumb.svelte-4xnkmf.svelte-4xnkmf{width:min(30%,calc((30% - (100px * var(--pagefind-ui-scale))) * 100000));max-width:calc(120px * var(--pagefind-ui-scale));margin-top:calc(10px * var(--pagefind-ui-scale));aspect-ratio:var(--pagefind-ui-image-box-ratio);position:relative}.pagefind-ui__result-image.svelte-4xnkmf.svelte-4xnkmf{display:block;position:absolute;left:50%;transform:translate(-50%);font-size:0;width:auto;height:auto;max-width:100%;max-height:100%;border-radius:var(--pagefind-ui-image-border-radius)}.pagefind-ui__result-inner.svelte-4xnkmf.svelte-4xnkmf{flex:1;display:flex;flex-direction:column;align-items:flex-start;margin-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-title.svelte-4xnkmf.svelte-4xnkmf{display:inline-block;font-weight:700;font-size:calc(21px * var(--pagefind-ui-scale));margin-top:0;margin-bottom:0}.pagefind-ui__result-title.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf{color:var(--pagefind-ui-text);text-decoration:none}.pagefind-ui__result-title.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf:hover{text-decoration:underline}.pagefind-ui__result-excerpt.svelte-4xnkmf.svelte-4xnkmf{display:inline-block;font-weight:400;font-size:calc(16px * var(--pagefind-ui-scale));margin-top:calc(4px * var(--pagefind-ui-scale));margin-bottom:0;min-width:calc(250px * var(--pagefind-ui-scale))}.pagefind-ui__loading.svelte-4xnkmf.svelte-4xnkmf{color:var(--pagefind-ui-text);background-color:var(--pagefind-ui-text);border-radius:var(--pagefind-ui-border-radius);opacity:.1;pointer-events:none}.pagefind-ui__result-tags.svelte-4xnkmf.svelte-4xnkmf{list-style-type:none;padding:0;display:flex;gap:calc(20px * var(--pagefind-ui-scale));flex-wrap:wrap;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-tag.svelte-4xnkmf.svelte-4xnkmf{padding:calc(4px * var(--pagefind-ui-scale)) calc(8px * var(--pagefind-ui-scale));font-size:calc(14px * var(--pagefind-ui-scale));border-radius:var(--pagefind-ui-border-radius);background-color:var(--pagefind-ui-tag)}legend.svelte-1v2r7ls.svelte-1v2r7ls{position:absolute;clip:rect(0 0 0 0)}.pagefind-ui__filter-panel.svelte-1v2r7ls.svelte-1v2r7ls{min-width:min(calc(260px * var(--pagefind-ui-scale)),100%);flex:1;display:flex;flex-direction:column;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__filter-group.svelte-1v2r7ls.svelte-1v2r7ls{border:0;padding:0}.pagefind-ui__filter-block.svelte-1v2r7ls.svelte-1v2r7ls{padding:0;display:block;border-bottom:solid calc(2px * var(--pagefind-ui-scale)) var(--pagefind-ui-border);padding:calc(20px * var(--pagefind-ui-scale)) 0}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls{font-size:calc(16px * var(--pagefind-ui-scale));position:relative;display:flex;align-items:center;list-style:none;font-weight:700;cursor:pointer;height:calc(24px * var(--pagefind-ui-scale))}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls::-webkit-details-marker{display:none}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls:after{position:absolute;content:"";right:calc(6px * var(--pagefind-ui-scale));top:50%;width:calc(8px * var(--pagefind-ui-scale));height:calc(8px * var(--pagefind-ui-scale));border:solid calc(2px * var(--pagefind-ui-scale)) currentColor;border-right:0;border-top:0;transform:translateY(-70%) rotate(-45deg)}.pagefind-ui__filter-block[open].svelte-1v2r7ls .pagefind-ui__filter-name.svelte-1v2r7ls:after{transform:translateY(-70%) rotate(-225deg)}.pagefind-ui__filter-group.svelte-1v2r7ls.svelte-1v2r7ls{display:flex;flex-direction:column;gap:calc(20px * var(--pagefind-ui-scale));padding-top:calc(30px * var(--pagefind-ui-scale))}.pagefind-ui__filter-value.svelte-1v2r7ls.svelte-1v2r7ls{position:relative;display:flex;align-items:center;gap:calc(8px * var(--pagefind-ui-scale))}.pagefind-ui__filter-value.svelte-1v2r7ls.svelte-1v2r7ls:before{position:absolute;content:"";top:50%;left:calc(8px * var(--pagefind-ui-scale));width:0px;height:0px;border:solid 1px #fff;opacity:0;transform:translate(calc(4.5px * var(--pagefind-ui-scale) * -1),calc(.8px * var(--pagefind-ui-scale))) skew(-5deg) rotate(-45deg);transform-origin:top left;border-top:0;border-right:0;pointer-events:none}.pagefind-ui__filter-value.pagefind-ui__filter-value--checked.svelte-1v2r7ls.svelte-1v2r7ls:before{opacity:1;width:calc(9px * var(--pagefind-ui-scale));height:calc(4px * var(--pagefind-ui-scale));transition:width .1s ease-out .1s,height .1s ease-in}.pagefind-ui__filter-checkbox.svelte-1v2r7ls.svelte-1v2r7ls{margin:0;width:calc(16px * var(--pagefind-ui-scale));height:calc(16px * var(--pagefind-ui-scale));border:solid 1px var(--pagefind-ui-border);appearance:none;-webkit-appearance:none;border-radius:calc(var(--pagefind-ui-border-radius) / 2);background-color:var(--pagefind-ui-background);cursor:pointer}.pagefind-ui__filter-checkbox.svelte-1v2r7ls.svelte-1v2r7ls:checked{background-color:var(--pagefind-ui-primary);border:solid 1px var(--pagefind-ui-primary)}.pagefind-ui__filter-label.svelte-1v2r7ls.svelte-1v2r7ls{cursor:pointer;font-size:calc(16px * var(--pagefind-ui-scale));font-weight:400}.pagefind-ui--reset *:where(:not(html,iframe,canvas,img,svg,video):not(svg *,symbol *)){all:unset;display:revert;outline:revert}.pagefind-ui--reset *,.pagefind-ui--reset *:before,.pagefind-ui--reset *:after{box-sizing:border-box}.pagefind-ui--reset a,.pagefind-ui--reset button{cursor:revert}.pagefind-ui--reset ol,.pagefind-ui--reset ul,.pagefind-ui--reset menu{list-style:none}.pagefind-ui--reset img{max-width:100%}.pagefind-ui--reset table{border-collapse:collapse}.pagefind-ui--reset input,.pagefind-ui--reset textarea{-webkit-user-select:auto}.pagefind-ui--reset textarea{white-space:revert}.pagefind-ui--reset meter{-webkit-appearance:revert;appearance:revert}.pagefind-ui--reset ::placeholder{color:unset}.pagefind-ui--reset :where([hidden]){display:none}.pagefind-ui--reset :where([contenteditable]:not([contenteditable=false])){-moz-user-modify:read-write;-webkit-user-modify:read-write;overflow-wrap:break-word;-webkit-line-break:after-white-space;-webkit-user-select:auto}.pagefind-ui--reset :where([draggable=true]){-webkit-user-drag:element}.pagefind-ui--reset mark{all:revert}:root{--pagefind-ui-scale:.8;--pagefind-ui-primary:#393939;--pagefind-ui-text:#393939;--pagefind-ui-background:#ffffff;--pagefind-ui-border:#eeeeee;--pagefind-ui-tag:#eeeeee;--pagefind-ui-border-width:2px;--pagefind-ui-border-radius:8px;--pagefind-ui-image-border-radius:8px;--pagefind-ui-image-box-ratio:3 / 2;--pagefind-ui-font:system, -apple-system, "BlinkMacSystemFont", ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", "Ubuntu", "arial", sans-serif}.pagefind-ui.svelte-e9gkc3{width:100%;color:var(--pagefind-ui-text);font-family:var(--pagefind-ui-font)}.pagefind-ui__hidden.svelte-e9gkc3{display:none!important}.pagefind-ui__suppressed.svelte-e9gkc3{opacity:0;pointer-events:none}.pagefind-ui__form.svelte-e9gkc3{position:relative}.pagefind-ui__form.svelte-e9gkc3:before{background-color:var(--pagefind-ui-text);width:calc(18px * var(--pagefind-ui-scale));height:calc(18px * var(--pagefind-ui-scale));top:calc(23px * var(--pagefind-ui-scale));left:calc(20px * var(--pagefind-ui-scale));content:"";position:absolute;display:block;opacity:.7;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");mask-image:url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");-webkit-mask-size:100%;mask-size:100%;z-index:9;pointer-events:none}.pagefind-ui__search-input.svelte-e9gkc3{height:calc(64px * var(--pagefind-ui-scale));padding:0 calc(70px * var(--pagefind-ui-scale)) 0 calc(54px * var(--pagefind-ui-scale));background-color:var(--pagefind-ui-background);border:var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);border-radius:var(--pagefind-ui-border-radius);font-size:calc(21px * var(--pagefind-ui-scale));position:relative;appearance:none;-webkit-appearance:none;display:flex;width:100%;box-sizing:border-box;font-weight:700}.pagefind-ui__search-input.svelte-e9gkc3::placeholder{opacity:.2}.pagefind-ui__search-clear.svelte-e9gkc3{position:absolute;top:calc(3px * var(--pagefind-ui-scale));right:calc(3px * var(--pagefind-ui-scale));height:calc(58px * var(--pagefind-ui-scale));padding:0 calc(15px * var(--pagefind-ui-scale)) 0 calc(2px * var(--pagefind-ui-scale));color:var(--pagefind-ui-text);font-size:calc(14px * var(--pagefind-ui-scale));cursor:pointer;background-color:var(--pagefind-ui-background);border-radius:var(--pagefind-ui-border-radius)}.pagefind-ui__drawer.svelte-e9gkc3{gap:calc(60px * var(--pagefind-ui-scale));display:flex;flex-direction:row;flex-wrap:wrap}.pagefind-ui__results-area.svelte-e9gkc3{min-width:min(calc(400px * var(--pagefind-ui-scale)),100%);flex:1000;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__results.svelte-e9gkc3{padding:0}.pagefind-ui__message.svelte-e9gkc3{box-sizing:content-box;font-size:calc(16px * var(--pagefind-ui-scale));height:calc(24px * var(--pagefind-ui-scale));padding:calc(20px * var(--pagefind-ui-scale)) 0;display:flex;align-items:center;font-weight:700;margin-top:0}.pagefind-ui__button.svelte-e9gkc3{margin-top:calc(40px * var(--pagefind-ui-scale));border:var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);border-radius:var(--pagefind-ui-border-radius);height:calc(48px * var(--pagefind-ui-scale));padding:0 calc(12px * var(--pagefind-ui-scale));font-size:calc(16px * var(--pagefind-ui-scale));color:var(--pagefind-ui-primary);background:var(--pagefind-ui-background);width:100%;text-align:center;font-weight:700;cursor:pointer}.pagefind-ui__button.svelte-e9gkc3:hover{border-color:var(--pagefind-ui-primary);color:var(--pagefind-ui-primary);background:var(--pagefind-ui-background)} diff --git a/website/blog/pagefind/pagefind-ui.js b/website/blog/pagefind/pagefind-ui.js deleted file mode 100644 index 70603ac..0000000 --- a/website/blog/pagefind/pagefind-ui.js +++ /dev/null @@ -1,2 +0,0 @@ -(()=>{var Ds=Object.defineProperty;var Z=(l,e)=>{for(var t in e)Ds(l,t,{get:e[t],enumerable:!0})};function W(){}function ft(l){return l()}function Nl(){return Object.create(null)}function w(l){l.forEach(ft)}function gt(l){return typeof l=="function"}function z(l,e){return l!=l?e==e:l!==e||l&&typeof l=="object"||typeof l=="function"}var nt;function ne(l,e){return nt||(nt=document.createElement("a")),nt.href=e,l===nt.href}function Xl(l){return Object.keys(l).length===0}var El=typeof window<"u"?window:typeof globalThis<"u"?globalThis:global,bt=class l{constructor(e){this.options=e,this._listeners="WeakMap"in El?new WeakMap:void 0}observe(e,t){return this._listeners.set(e,t),this._getObserver().observe(e,this.options),()=>{this._listeners.delete(e),this._observer.unobserve(e)}}_getObserver(){var e;return(e=this._observer)!==null&&e!==void 0?e:this._observer=new ResizeObserver(t=>{var s;for(let a of t)l.entries.set(a.target,a),(s=this._listeners.get(a.target))===null||s===void 0||s(a)})}};bt.entries="WeakMap"in El?new WeakMap:void 0;var kl=!1;function Ts(){kl=!0}function vs(){kl=!1}function m(l,e){l.appendChild(e)}function p(l,e,t){l.insertBefore(e,t||null)}function U(l){l.parentNode&&l.parentNode.removeChild(l)}function P(l,e){for(let t=0;tl.removeEventListener(e,t,s)}function _(l,e,t){t==null?l.removeAttribute(e):l.getAttribute(e)!==t&&l.setAttribute(e,t)}function Ys(l){return Array.from(l.childNodes)}function L(l,e){e=""+e,l.data!==e&&(l.data=e)}function ht(l,e){l.value=e??""}function Y(l,e,t){l.classList[t?"add":"remove"](e)}var ct=class{constructor(e=!1){this.is_svg=!1,this.is_svg=e,this.e=this.n=null}c(e){this.h(e)}m(e,t,s=null){this.e||(this.is_svg?this.e=Hs(t.nodeName):this.e=B(t.nodeType===11?"TEMPLATE":t.nodeName),this.t=t.tagName!=="TEMPLATE"?t:t.content,this.c(e)),this.i(s)}h(e){this.e.innerHTML=e,this.n=Array.from(this.e.nodeName==="TEMPLATE"?this.e.content.childNodes:this.e.childNodes)}i(e){for(let t=0;tl.indexOf(s)===-1?e.push(s):t.push(s)),t.forEach(s=>s()),ae=e}var rt=new Set,ee;function re(){ee={r:0,c:[],p:ee}}function ge(){ee.r||w(ee.c),ee=ee.p}function S(l,e){l&&l.i&&(rt.delete(l),l.i(e))}function D(l,e,t,s){if(l&&l.o){if(rt.has(l))return;rt.add(l),ee.c.push(()=>{rt.delete(l),s&&(t&&l.d(1),s())}),l.o(e)}else s&&s()}function Sl(l,e){D(l,1,1,()=>{e.delete(l.key)})}function Vl(l,e,t,s,a,i,n,r,g,I,o,A){let C=l.length,d=i.length,c=C,u={};for(;c--;)u[l[c].key]=c;let b=[],F=new Map,f=new Map,h=[];for(c=d;c--;){let N=A(a,i,c),R=t(N),E=n.get(R);E?s&&h.push(()=>E.p(N,e)):(E=I(R,N),E.c()),F.set(R,b[c]=E),R in u&&f.set(R,Math.abs(c-u[R]))}let y=new Set,K=new Set;function M(N){S(N,1),N.m(r,o),n.set(N.key,N),o=N.first,d--}for(;C&&d;){let N=b[d-1],R=l[C-1],E=N.key,T=R.key;N===R?(o=N.first,C--,d--):F.has(T)?!n.has(E)||y.has(E)?M(N):K.has(T)?C--:f.get(E)>f.get(T)?(K.add(E),M(N)):(y.add(T),C--):(g(R,n),C--)}for(;C--;){let N=l[C];F.has(N.key)||g(N,n)}for(;d;)M(b[d-1]);return w(h),b}var Os=["allowfullscreen","allowpaymentrequest","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","hidden","inert","ismap","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected"],Zg=new Set([...Os]);function Dl(l,e,t){let s=l.$$.props[e];s!==void 0&&(l.$$.bound[s]=t,t(l.$$.ctx[s]))}function ot(l){l&&l.c()}function de(l,e,t,s){let{fragment:a,after_update:i}=l.$$;a&&a.m(e,t),s||Bt(()=>{let n=l.$$.on_mount.map(ft).filter(gt);l.$$.on_destroy?l.$$.on_destroy.push(...n):w(n),l.$$.on_mount=[]}),i.forEach(Bt)}function ce(l,e){let t=l.$$;t.fragment!==null&&(Js(t.after_update),w(t.on_destroy),t.fragment&&t.fragment.d(e),t.on_destroy=t.fragment=null,t.ctx=[])}function js(l,e){l.$$.dirty[0]===-1&&(se.push(l),ws(),l.$$.dirty.fill(0)),l.$$.dirty[e/31|0]|=1<{let c=d.length?d[0]:C;return I.ctx&&a(I.ctx[A],I.ctx[A]=c)&&(!I.skip_bound&&I.bound[A]&&I.bound[A](c),o&&js(l,A)),C}):[],I.update(),o=!0,w(I.before_update),I.fragment=s?s(I.ctx):!1,e.target){if(e.hydrate){Ts();let A=Ys(e.target);I.fragment&&I.fragment.l(A),A.forEach(U)}else I.fragment&&I.fragment.c();e.intro&&S(l.$$.fragment),de(l,e.target,e.anchor,e.customElement),vs(),Wl()}ue(g)}var Ks;typeof HTMLElement=="function"&&(Ks=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){let{on_mount:l}=this.$$;this.$$.on_disconnect=l.map(ft).filter(gt);for(let e in this.$$.slotted)this.appendChild(this.$$.slotted[e])}attributeChangedCallback(l,e,t){this[l]=t}disconnectedCallback(){w(this.$$.on_disconnect)}$destroy(){ce(this,1),this.$destroy=W}$on(l,e){if(!gt(e))return W;let t=this.$$.callbacks[l]||(this.$$.callbacks[l]=[]);return t.push(e),()=>{let s=t.indexOf(e);s!==-1&&t.splice(s,1)}}$set(l){this.$$set&&!Xl(l)&&(this.$$.skip_bound=!0,this.$$set(l),this.$$.skip_bound=!1)}});var H=class{$destroy(){ce(this,1),this.$destroy=W}$on(e,t){if(!gt(t))return W;let s=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return s.push(t),()=>{let a=s.indexOf(t);a!==-1&&s.splice(a,1)}}$set(e){this.$$set&&!Xl(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}};function V(l){let e=typeof l=="string"?l.charCodeAt(0):l;return e>=97&&e<=122||e>=65&&e<=90}function $(l){let e=typeof l=="string"?l.charCodeAt(0):l;return e>=48&&e<=57}function j(l){return V(l)||$(l)}var Tl=["art-lojban","cel-gaulish","no-bok","no-nyn","zh-guoyu","zh-hakka","zh-min","zh-min-nan","zh-xiang"];var Zt={"en-gb-oed":"en-GB-oxendict","i-ami":"ami","i-bnn":"bnn","i-default":null,"i-enochian":null,"i-hak":"hak","i-klingon":"tlh","i-lux":"lb","i-mingo":null,"i-navajo":"nv","i-pwn":"pwn","i-tao":"tao","i-tay":"tay","i-tsu":"tsu","sgn-be-fr":"sfb","sgn-be-nl":"vgt","sgn-ch-de":"sgg","art-lojban":"jbo","cel-gaulish":null,"no-bok":"nb","no-nyn":"nn","zh-guoyu":"cmn","zh-hakka":"hak","zh-min":null,"zh-min-nan":"nan","zh-xiang":"hsn"};var Ps={}.hasOwnProperty;function Ct(l,e={}){let t=vl(),s=String(l),a=s.toLowerCase(),i=0;if(l==null)throw new Error("Expected string, got `"+l+"`");if(Ps.call(Zt,a)){let r=Zt[a];return(e.normalize===void 0||e.normalize===null||e.normalize)&&typeof r=="string"?Ct(r):(t[Tl.includes(a)?"regular":"irregular"]=s,t)}for(;V(a.charCodeAt(i))&&i<9;)i++;if(i>1&&i<9){if(t.language=s.slice(0,i),i<4){let r=0;for(;a.charCodeAt(i)===45&&V(a.charCodeAt(i+1))&&V(a.charCodeAt(i+2))&&V(a.charCodeAt(i+3))&&!V(a.charCodeAt(i+4));){if(r>2)return n(i,3,"Too many extended language subtags, expected at most 3 subtags");t.extendedLanguageSubtags.push(s.slice(i+1,i+4)),i+=4,r++}}for(a.charCodeAt(i)===45&&V(a.charCodeAt(i+1))&&V(a.charCodeAt(i+2))&&V(a.charCodeAt(i+3))&&V(a.charCodeAt(i+4))&&!V(a.charCodeAt(i+5))&&(t.script=s.slice(i+1,i+5),i+=5),a.charCodeAt(i)===45&&(V(a.charCodeAt(i+1))&&V(a.charCodeAt(i+2))&&!V(a.charCodeAt(i+3))?(t.region=s.slice(i+1,i+3),i+=3):$(a.charCodeAt(i+1))&&$(a.charCodeAt(i+2))&&$(a.charCodeAt(i+3))&&!$(a.charCodeAt(i+4))&&(t.region=s.slice(i+1,i+4),i+=4));a.charCodeAt(i)===45;){let r=i+1,g=r;for(;j(a.charCodeAt(g));){if(g-r>7)return n(g,1,"Too long variant, expected at most 8 characters");g++}if(g-r>4||g-r>3&&$(a.charCodeAt(r)))t.variants.push(s.slice(r,g)),i=g;else break}for(;a.charCodeAt(i)===45&&!(a.charCodeAt(i+1)===120||!j(a.charCodeAt(i+1))||a.charCodeAt(i+2)!==45||!j(a.charCodeAt(i+3)));){let r=i+2,g=0;for(;a.charCodeAt(r)===45&&j(a.charCodeAt(r+1))&&j(a.charCodeAt(r+2));){let I=r+1;for(r=I+2,g++;j(a.charCodeAt(r));){if(r-I>7)return n(r,2,"Too long extension, expected at most 8 characters");r++}}if(!g)return n(r,4,"Empty extension, extensions must have at least 2 characters of content");t.extensions.push({singleton:s.charAt(i+1),extensions:s.slice(i+3,r).split("-")}),i=r}}else i=0;if(i===0&&a.charCodeAt(i)===120||a.charCodeAt(i)===45&&a.charCodeAt(i+1)===120){i=i?i+2:1;let r=i;for(;a.charCodeAt(r)===45&&j(a.charCodeAt(r+1));){let g=i+1;for(r=g;j(a.charCodeAt(r));){if(r-g>7)return n(r,5,"Too long private-use area, expected at most 8 characters");r++}t.privateuse.push(s.slice(i+1,r)),i=r}}if(i!==s.length)return n(i,6,"Found superfluous content after tag");return t;function n(r,g,I){return e.warning&&e.warning(I,g,r),e.forgiving?t:vl()}}function vl(){return{language:null,extendedLanguageSubtags:[],script:null,region:null,variants:[],extensions:[],privateuse:[],irregular:null,regular:null}}function Hl(l,e,t){let s=l.slice();return s[9]=e[t][0],s[10]=e[t][1],s}function qs(l){let e,t,s,a,i,n=l[0]&&Yl(l);return{c(){n&&n.c(),e=x(),t=B("div"),s=B("p"),s.textContent=`${l[3](30)}`,a=x(),i=B("p"),i.textContent=`${l[3](40)}`,_(s,"class","pagefind-ui__result-title pagefind-ui__loading svelte-j9e30"),_(i,"class","pagefind-ui__result-excerpt pagefind-ui__loading svelte-j9e30"),_(t,"class","pagefind-ui__result-inner svelte-j9e30")},m(r,g){n&&n.m(r,g),p(r,e,g),p(r,t,g),m(t,s),m(t,a),m(t,i)},p(r,g){r[0]?n||(n=Yl(r),n.c(),n.m(e.parentNode,e)):n&&(n.d(1),n=null)},d(r){n&&n.d(r),r&&U(e),r&&U(t)}}}function $s(l){let e,t,s,a,i=l[1].meta?.title+"",n,r,g,I,o=l[1].excerpt+"",A,C=l[0]&&Ml(l),d=l[2].length&&zl(l);return{c(){C&&C.c(),e=x(),t=B("div"),s=B("p"),a=B("a"),n=G(i),g=x(),I=B("p"),A=x(),d&&d.c(),_(a,"class","pagefind-ui__result-link svelte-j9e30"),_(a,"href",r=l[1].meta?.url||l[1].url),_(s,"class","pagefind-ui__result-title svelte-j9e30"),_(I,"class","pagefind-ui__result-excerpt svelte-j9e30"),_(t,"class","pagefind-ui__result-inner svelte-j9e30")},m(c,u){C&&C.m(c,u),p(c,e,u),p(c,t,u),m(t,s),m(s,a),m(a,n),m(t,g),m(t,I),I.innerHTML=o,m(t,A),d&&d.m(t,null)},p(c,u){c[0]?C?C.p(c,u):(C=Ml(c),C.c(),C.m(e.parentNode,e)):C&&(C.d(1),C=null),u&2&&i!==(i=c[1].meta?.title+"")&&L(n,i),u&2&&r!==(r=c[1].meta?.url||c[1].url)&&_(a,"href",r),u&2&&o!==(o=c[1].excerpt+"")&&(I.innerHTML=o),c[2].length?d?d.p(c,u):(d=zl(c),d.c(),d.m(t,null)):d&&(d.d(1),d=null)},d(c){C&&C.d(c),c&&U(e),c&&U(t),d&&d.d()}}}function Yl(l){let e;return{c(){e=B("div"),_(e,"class","pagefind-ui__result-thumb pagefind-ui__loading svelte-j9e30")},m(t,s){p(t,e,s)},d(t){t&&U(e)}}}function Ml(l){let e,t=l[1].meta.image&&wl(l);return{c(){e=B("div"),t&&t.c(),_(e,"class","pagefind-ui__result-thumb svelte-j9e30")},m(s,a){p(s,e,a),t&&t.m(e,null)},p(s,a){s[1].meta.image?t?t.p(s,a):(t=wl(s),t.c(),t.m(e,null)):t&&(t.d(1),t=null)},d(s){s&&U(e),t&&t.d()}}}function wl(l){let e,t,s;return{c(){e=B("img"),_(e,"class","pagefind-ui__result-image svelte-j9e30"),ne(e.src,t=l[1].meta?.image)||_(e,"src",t),_(e,"alt",s=l[1].meta?.image_alt||l[1].meta?.title)},m(a,i){p(a,e,i)},p(a,i){i&2&&!ne(e.src,t=a[1].meta?.image)&&_(e,"src",t),i&2&&s!==(s=a[1].meta?.image_alt||a[1].meta?.title)&&_(e,"alt",s)},d(a){a&&U(e)}}}function zl(l){let e,t=l[2],s=[];for(let a=0;al.toLocaleUpperCase();function ta(l,e,t){let{show_images:s=!0}=e,{process_result:a=null}=e,{result:i={data:async()=>{}}}=e,n=["title","image","image_alt","url"],r,g=[],I=(C,d)=>{if(!C||/^[a-z][a-z0-9+.-]*:/i.test(C)||/^\/\//.test(C)||C.startsWith("/"))return C;try{return new URL(C,new URL(d||"/","https://p")).pathname}catch{return C}},o=async C=>{t(1,r=await C.data()),t(1,r=a?.(r)??r),r.meta?.image&&t(1,r={...r,meta:{...r.meta,image:I(r.meta.image,r.meta.url||r.url)}}),t(2,g=Object.entries(r.meta).filter(([d])=>!n.includes(d)))},A=(C=30)=>". ".repeat(Math.floor(10+Math.random()*C));return l.$$set=C=>{"show_images"in C&&t(0,s=C.show_images),"process_result"in C&&t(4,a=C.process_result),"result"in C&&t(5,i=C.result)},l.$$.update=()=>{l.$$.dirty&32&&o(i)},[s,r,g,A,a,i]}var yt=class extends H{constructor(e){super(),O(this,e,ta,ea,z,{show_images:0,process_result:4,result:5})}},jl=yt;function Kl(l,e,t){let s=l.slice();return s[11]=e[t][0],s[12]=e[t][1],s}function Pl(l,e,t){let s=l.slice();return s[15]=e[t],s}function la(l){let e,t,s,a,i,n=l[0]&&ql(l);return{c(){n&&n.c(),e=x(),t=B("div"),s=B("p"),s.textContent=`${l[5](30)}`,a=x(),i=B("p"),i.textContent=`${l[5](40)}`,_(s,"class","pagefind-ui__result-title pagefind-ui__loading svelte-4xnkmf"),_(i,"class","pagefind-ui__result-excerpt pagefind-ui__loading svelte-4xnkmf"),_(t,"class","pagefind-ui__result-inner svelte-4xnkmf")},m(r,g){n&&n.m(r,g),p(r,e,g),p(r,t,g),m(t,s),m(t,a),m(t,i)},p(r,g){r[0]?n||(n=ql(r),n.c(),n.m(e.parentNode,e)):n&&(n.d(1),n=null)},d(r){n&&n.d(r),r&&U(e),r&&U(t)}}}function sa(l){let e,t,s,a,i=l[1].meta?.title+"",n,r,g,I,o,A=l[0]&&$l(l),C=l[4]&&ts(l),d=l[3],c=[];for(let b=0;bl.toLocaleUpperCase();function ia(l,e,t){let{show_images:s=!0}=e,{process_result:a=null}=e,{result:i={data:async()=>{}}}=e,n=["title","image","image_alt","url"],r,g=[],I=[],o=!1,A=(c,u)=>{if(c.length<=u)return c;let b=[...c].sort((F,f)=>f.locations.length-F.locations.length).slice(0,3).map(F=>F.url);return c.filter(F=>b.includes(F.url))},C=async c=>{t(1,r=await c.data()),t(1,r=a?.(r)??r),t(2,g=Object.entries(r.meta).filter(([u])=>!n.includes(u))),Array.isArray(r.sub_results)&&(t(4,o=r.sub_results?.[0]?.url===(r.meta?.url||r.url)),o?t(3,I=A(r.sub_results.slice(1),3)):t(3,I=A([...r.sub_results],3)))},d=(c=30)=>". ".repeat(Math.floor(10+Math.random()*c));return l.$$set=c=>{"show_images"in c&&t(0,s=c.show_images),"process_result"in c&&t(6,a=c.process_result),"result"in c&&t(7,i=c.result)},l.$$.update=()=>{l.$$.dirty&128&&C(i)},[s,r,g,I,o,d,a,i]}var xt=class extends H{constructor(e){super(),O(this,e,ia,aa,z,{show_images:0,process_result:6,result:7})}},ns=xt;function rs(l,e,t){let s=l.slice();return s[10]=e[t][0],s[11]=e[t][1],s[12]=e,s[13]=t,s}function gs(l,e,t){let s=l.slice();return s[14]=e[t][0],s[15]=e[t][1],s[16]=e,s[17]=t,s}function cs(l){let e,t,s=l[4]("filters_label",l[5],l[6])+"",a,i,n=Object.entries(l[1]),r=[];for(let g=0;gl.toLocaleUpperCase(),ds=l=>l.toLowerCase();function ra(l,e,t){let{available_filters:s=null}=e,{show_empty_filters:a=!0}=e,{open_filters:i=[]}=e,{translate:n=()=>""}=e,{automatic_translations:r={}}=e,{translations:g={}}=e,{selected_filters:I={}}=e,o=!1,A=!1;function C(d,c){I[`${d}:${c}`]=this.checked,t(0,I)}return l.$$set=d=>{"available_filters"in d&&t(1,s=d.available_filters),"show_empty_filters"in d&&t(2,a=d.show_empty_filters),"open_filters"in d&&t(3,i=d.open_filters),"translate"in d&&t(4,n=d.translate),"automatic_translations"in d&&t(5,r=d.automatic_translations),"translations"in d&&t(6,g=d.translations),"selected_filters"in d&&t(0,I=d.selected_filters)},l.$$.update=()=>{if(l.$$.dirty&258&&s&&!o){t(8,o=!0);let d=Object.entries(s||{});d.length===1&&Object.entries(d[0][1])?.length<=6&&t(7,A=!0)}},[I,s,a,i,n,r,g,A,o,C]}var Gt=class extends H{constructor(e){super(),O(this,e,ra,na,z,{available_filters:1,show_empty_filters:2,open_filters:3,translate:4,automatic_translations:5,translations:6,selected_filters:0})}},As=Gt;var Nt={};Z(Nt,{comments:()=>ca,default:()=>ua,direction:()=>oa,strings:()=>Ca,thanks_to:()=>ga});var ga="Jan Claasen ",ca="",oa="ltr",Ca={placeholder:"Soek",clear_search:"Opruim",load_more:"Laai nog resultate",search_label:"Soek hierdie webwerf",filters_label:"Filters",zero_results:"Geen resultate vir [SEARCH_TERM]",many_results:"[COUNT] resultate vir [SEARCH_TERM]",one_result:"[COUNT] resultate vir [SEARCH_TERM]",total_zero_results:"Geen resultate",total_one_result:"[COUNT] resultaat",total_many_results:"[COUNT] resultate",alt_search:"Geen resultate vir [SEARCH_TERM]. Toon resultate vir [DIFFERENT_TERM] in plaas daarvan",search_suggestion:"Geen resultate vir [SEARCH_TERM]. Probeer eerder een van die volgende terme:",searching:"Soek vir [SEARCH_TERM]",results_label:"Soekresultate",keyboard_navigate:"navigeer",keyboard_select:"kies",keyboard_clear:"wis",keyboard_close:"sluit",keyboard_search:"soek",error_search:"Soek het misluk",filter_selected_one:"[COUNT] gekies",filter_selected_many:"[COUNT] gekies",input_hint:"Resultate sal verskyn terwyl jy tik",loading:"Laai"},ua={thanks_to:ga,comments:ca,direction:oa,strings:Ca};var Xt={};Z(Xt,{comments:()=>da,default:()=>_a,direction:()=>Aa,strings:()=>Qa,thanks_to:()=>Ia});var Ia="Jermanuts",da="",Aa="rtl",Qa={placeholder:"\u0628\u062D\u062B",clear_search:"\u0627\u0645\u0633\u062D",load_more:"\u062D\u0645\u0651\u0650\u0644 \u0627\u0644\u0645\u0632\u064A\u062F \u0645\u0646 \u0627\u0644\u0646\u062A\u0627\u0626\u062C",search_label:"\u0627\u0628\u062D\u062B \u0641\u064A \u0647\u0630\u0627 \u0627\u0644\u0645\u0648\u0642\u0639",filters_label:"\u062A\u0635\u0641\u064A\u0627\u062A",zero_results:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]",many_results:"[COUNT] \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]",one_result:"[COUNT] \u0646\u062A\u064A\u062C\u0629 \u0644 [SEARCH_TERM]",total_zero_results:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C",total_one_result:"[COUNT] \u0646\u062A\u064A\u062C\u0629",total_many_results:"[COUNT] \u0646\u062A\u0627\u0626\u062C",alt_search:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]. \u064A\u0639\u0631\u0636 \u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0644 [DIFFERENT_TERM] \u0628\u062F\u0644\u0627\u064B \u0645\u0646 \u0630\u0644\u0643",search_suggestion:"\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0644 [SEARCH_TERM]. \u062C\u0631\u0628 \u0623\u062D\u062F \u0639\u0645\u0644\u064A\u0627\u062A \u0627\u0644\u0628\u062D\u062B \u0627\u0644\u062A\u0627\u0644\u064A\u0629:",searching:"\u064A\u0628\u062D\u062B \u0639\u0646 [SEARCH_TERM]...",results_label:"\u0646\u062A\u0627\u0626\u062C \u0627\u0644\u0628\u062D\u062B",keyboard_navigate:"\u062A\u0646\u0642\u0644",keyboard_select:"\u0627\u062E\u062A\u064A\u0627\u0631",keyboard_clear:"\u0627\u0645\u0633\u062D",keyboard_close:"\u0625\u063A\u0644\u0627\u0642",keyboard_search:"\u0628\u062D\u062B",error_search:"\u0641\u0634\u0644 \u0627\u0644\u0628\u062D\u062B",filter_selected_one:"[COUNT] \u0645\u062D\u062F\u062F",filter_selected_many:"[COUNT] \u0645\u062D\u062F\u062F",input_hint:"\u0633\u062A\u0638\u0647\u0631 \u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0643\u062A\u0627\u0628\u0629",loading:"\u062C\u0627\u0631\u064D \u0627\u0644\u062A\u062D\u0645\u064A\u0644"},_a={thanks_to:Ia,comments:da,direction:Aa,strings:Qa};var Et={};Z(Et,{comments:()=>ma,default:()=>fa,direction:()=>Fa,strings:()=>Ba,thanks_to:()=>ba});var ba="Maruf Alom ",ma="",Fa="ltr",Ba={placeholder:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",clear_search:"\u09AE\u09C1\u099B\u09C7 \u09AB\u09C7\u09B2\u09C1\u09A8",load_more:"\u0986\u09B0\u09CB \u09AB\u09B2\u09BE\u09AB\u09B2 \u09A6\u09C7\u0996\u09C1\u09A8",search_label:"\u098F\u0987 \u0993\u09AF\u09BC\u09C7\u09AC\u09B8\u09BE\u0987\u099F\u09C7 \u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",filters_label:"\u09AB\u09BF\u09B2\u09CD\u099F\u09BE\u09B0",zero_results:"[SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF",many_results:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u0997\u09BF\u09AF\u09BC\u09C7\u099B\u09C7 [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF",one_result:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u0997\u09BF\u09AF\u09BC\u09C7\u099B\u09C7 [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF",total_zero_results:"\u0995\u09CB\u09A8 \u09AB\u09B2\u09BE\u09AB\u09B2 \u09A8\u09C7\u0987",total_one_result:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2",total_many_results:"[COUNT]-\u099F\u09BF \u09AB\u09B2\u09BE\u09AB\u09B2",alt_search:"\u0995\u09CB\u09A8 \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF [SEARCH_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF. \u09AA\u09B0\u09BF\u09AC\u09B0\u09CD\u09A4\u09C7 [DIFFERENT_TERM] \u098F\u09B0 \u099C\u09A8\u09CD\u09AF \u09A6\u09C7\u0996\u09BE\u09A8\u09CB \u09B9\u099A\u09CD\u099B\u09C7",search_suggestion:"\u0995\u09CB\u09A8 \u0995\u09BF\u099B\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF [SEARCH_TERM] \u098F\u09B0 \u09AC\u09BF\u09B7\u09AF\u09BC\u09C7. \u09A8\u09BF\u09A8\u09CD\u09AE\u09C7\u09B0 \u09AC\u09BF\u09B7\u09AF\u09BC\u09AC\u09B8\u09CD\u09A4\u09C1 \u0996\u09C1\u0981\u099C\u09C7 \u09A6\u09C7\u0996\u09C1\u09A8:",searching:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u099A\u09B2\u099B\u09C7 [SEARCH_TERM]...",results_label:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8\u09C7\u09B0 \u09AB\u09B2\u09BE\u09AB\u09B2",keyboard_navigate:"\u09A8\u09C7\u09AD\u09BF\u0997\u09C7\u099F",keyboard_select:"\u09A8\u09BF\u09B0\u09CD\u09AC\u09BE\u099A\u09A8",keyboard_clear:"\u09AE\u09C1\u099B\u09C1\u09A8",keyboard_close:"\u09AC\u09A8\u09CD\u09A7",keyboard_search:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8",error_search:"\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u09AC\u09CD\u09AF\u09B0\u09CD\u09A5",filter_selected_one:"[COUNT]-\u099F\u09BF \u09A8\u09BF\u09B0\u09CD\u09AC\u09BE\u099A\u09BF\u09A4",filter_selected_many:"[COUNT]-\u099F\u09BF \u09A8\u09BF\u09B0\u09CD\u09AC\u09BE\u099A\u09BF\u09A4",input_hint:"\u099F\u09BE\u0987\u09AA \u0995\u09B0\u09BE\u09B0 \u09B8\u09BE\u09A5\u09C7 \u09B8\u09BE\u09A5\u09C7 \u09AB\u09B2\u09BE\u09AB\u09B2 \u09A6\u09C7\u0996\u09BE \u09AF\u09BE\u09AC\u09C7",loading:"\u09B2\u09CB\u09A1 \u09B9\u099A\u09CD\u099B\u09C7"},fa={thanks_to:ba,comments:ma,direction:Fa,strings:Ba};var kt={};Z(kt,{comments:()=>Ua,default:()=>ya,direction:()=>pa,strings:()=>Za,thanks_to:()=>ha});var ha="Pablo Villaverde ",Ua="",pa="ltr",Za={placeholder:"Cerca",clear_search:"Netejar",load_more:"Veure m\xE9s resultats",search_label:"Cerca en aquest lloc",filters_label:"Filtres",zero_results:"No es van trobar resultats per [SEARCH_TERM]",many_results:"[COUNT] resultats trobats per [SEARCH_TERM]",one_result:"[COUNT] resultat trobat per [SEARCH_TERM]",total_zero_results:"Sense resultats",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultats",alt_search:"No es van trobar resultats per [SEARCH_TERM]. Mostrant al seu lloc resultats per [DIFFERENT_TERM]",search_suggestion:"No es van trobar resultats per [SEARCH_TERM]. Proveu una de les cerques seg\xFCents:",searching:"Cercant [SEARCH_TERM]...",results_label:"Resultats de la cerca",keyboard_navigate:"navegar",keyboard_select:"triar",keyboard_clear:"netejar",keyboard_close:"tancar",keyboard_search:"cercar",error_search:"Error en la cerca",filter_selected_one:"[COUNT] seleccionat",filter_selected_many:"[COUNT] seleccionats",input_hint:"Els resultats apareixeran mentre escriviu",loading:"Carregant"},ya={thanks_to:ha,comments:Ua,direction:pa,strings:Za};var Lt={};Z(Lt,{comments:()=>Ga,default:()=>Ea,direction:()=>Na,strings:()=>Xa,thanks_to:()=>xa});var xa="Dalibor Hon ",Ga="",Na="ltr",Xa={placeholder:"Hledat",clear_search:"Smazat",load_more:"Na\u010D\xEDst dal\u0161\xED v\xFDsledky",search_label:"Prohledat tuto str\xE1nku",filters_label:"Filtry",zero_results:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]",many_results:"[COUNT] v\xFDsledk\u016F pro [SEARCH_TERM]",one_result:"[COUNT] v\xFDsledek pro [SEARCH_TERM]",total_zero_results:"\u017D\xE1dn\xE9 v\xFDsledky",total_one_result:"[COUNT] v\xFDsledek",total_many_results:"[COUNT] v\xFDsledk\u016F",alt_search:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]. Zobrazuj\xED se v\xFDsledky pro [DIFFERENT_TERM]",search_suggestion:"\u017D\xE1dn\xE9 v\xFDsledky pro [SEARCH_TERM]. Souvisej\xEDc\xED v\xFDsledky hled\xE1n\xED:",searching:"Hled\xE1m [SEARCH_TERM]...",results_label:"V\xFDsledky hled\xE1n\xED",keyboard_navigate:"navigovat",keyboard_select:"vybrat",keyboard_clear:"smazat",keyboard_close:"zav\u0159\xEDt",keyboard_search:"hledat",error_search:"Hled\xE1n\xED selhalo",filter_selected_one:"[COUNT] vybran\xFD",filter_selected_many:"[COUNT] vybran\xFDch",input_hint:"V\xFDsledky se zobraz\xED b\u011Bhem psan\xED",loading:"Na\u010D\xEDt\xE1n\xED"},Ea={thanks_to:xa,comments:Ga,direction:Na,strings:Xa};var Rt={};Z(Rt,{comments:()=>La,default:()=>Sa,direction:()=>Ra,strings:()=>Wa,thanks_to:()=>ka});var ka="Jonas Smedegaard ",La="",Ra="ltr",Wa={placeholder:"S\xF8g",clear_search:"Nulstil",load_more:"Indl\xE6s flere resultater",search_label:"S\xF8g p\xE5 dette website",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultater",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultater",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v et af disse s\xF8geord i stedet:",searching:"S\xF8ger efter [SEARCH_TERM]...",results_label:"S\xF8geresultater",keyboard_navigate:"naviger",keyboard_select:"v\xE6lg",keyboard_clear:"ryd",keyboard_close:"luk",keyboard_search:"s\xF8g",error_search:"S\xF8gning mislykkedes",filter_selected_one:"[COUNT] valgt",filter_selected_many:"[COUNT] valgte",input_hint:"Resultater vises mens du skriver",loading:"Indl\xE6ser"},Sa={thanks_to:ka,comments:La,direction:Ra,strings:Wa};var Wt={};Z(Wt,{comments:()=>Da,default:()=>Ha,direction:()=>Ta,strings:()=>va,thanks_to:()=>Va});var Va="Jan Claasen ",Da="",Ta="ltr",va={placeholder:"Suche",clear_search:"L\xF6schen",load_more:"Mehr Ergebnisse laden",search_label:"Suche diese Seite",filters_label:"Filter",zero_results:"Keine Ergebnisse f\xFCr [SEARCH_TERM]",many_results:"[COUNT] Ergebnisse f\xFCr [SEARCH_TERM]",one_result:"[COUNT] Ergebnis f\xFCr [SEARCH_TERM]",total_zero_results:"Keine Ergebnisse",total_one_result:"[COUNT] Ergebnis",total_many_results:"[COUNT] Ergebnisse",alt_search:"Keine Ergebnisse f\xFCr [SEARCH_TERM]. Stattdessen werden Ergebnisse f\xFCr [DIFFERENT_TERM] angezeigt",search_suggestion:"Keine Ergebnisse f\xFCr [SEARCH_TERM]. Versuchen Sie eine der folgenden Suchen:",searching:"Suche nach [SEARCH_TERM]\u202F\u2026",results_label:"Suchergebnisse",keyboard_navigate:"navigieren",keyboard_select:"ausw\xE4hlen",keyboard_clear:"l\xF6schen",keyboard_close:"schlie\xDFen",keyboard_search:"suchen",error_search:"Suche fehlgeschlagen",filter_selected_one:"[COUNT] ausgew\xE4hlt",filter_selected_many:"[COUNT] ausgew\xE4hlt",input_hint:"Ergebnisse werden w\xE4hrend der Eingabe angezeigt",loading:"Wird geladen"},Ha={thanks_to:Va,comments:Da,direction:Ta,strings:va};var St={};Z(St,{comments:()=>Ma,default:()=>Ja,direction:()=>wa,strings:()=>za,thanks_to:()=>Ya});var Ya="George Papadopoulos",Ma="",wa="ltr",za={placeholder:"\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7",clear_search:"\u039A\u03B1\u03B8\u03B1\u03C1\u03B9\u03C3\u03BC\u03CC\u03C2",load_more:"\u03A6\u03CC\u03C1\u03C4\u03C9\u03C3\u03B7 \u03C0\u03B5\u03C1\u03B9\u03C3\u03C3\u03CC\u03C4\u03B5\u03C1\u03C9\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03B5\u03C3\u03BC\u03AC\u03C4\u03C9\u03BD",search_label:"\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03C3\u03B5 \u03B1\u03C5\u03C4\u03CC\u03BD \u03C4\u03BF\u03BD \u03B9\u03C3\u03C4\u03CC\u03C4\u03BF\u03C0\u03BF",filters_label:"\u03A6\u03AF\u03BB\u03C4\u03C1\u03B1",zero_results:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]",many_results:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]",one_result:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03AD\u03BB\u03B5\u03C3\u03BC\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]",total_zero_results:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1",total_one_result:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03AD\u03BB\u03B5\u03C3\u03BC\u03B1",total_many_results:"[COUNT] \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1",alt_search:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]. \u0395\u03BC\u03C6\u03B1\u03BD\u03AF\u03B6\u03BF\u03BD\u03C4\u03B1\u03B9 \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [DIFFERENT_TERM]",search_suggestion:"\u0394\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 [SEARCH_TERM]. \u0394\u03BF\u03BA\u03B9\u03BC\u03AC\u03C3\u03C4\u03B5 \u03BC\u03AF\u03B1 \u03B1\u03C0\u03CC \u03C4\u03B9\u03C2 \u03C0\u03B1\u03C1\u03B1\u03BA\u03AC\u03C4\u03C9 \u03B1\u03BD\u03B1\u03B6\u03B7\u03C4\u03AE\u03C3\u03B5\u03B9\u03C2:",searching:"\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03B3\u03B9\u03B1 [SEARCH_TERM]...",results_label:"\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B1\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7\u03C2",keyboard_navigate:"\u03C0\u03BB\u03BF\u03AE\u03B3\u03B7\u03C3\u03B7",keyboard_select:"\u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE",keyboard_clear:"\u03BA\u03B1\u03B8\u03B1\u03C1\u03B9\u03C3\u03BC\u03CC\u03C2",keyboard_close:"\u03BA\u03BB\u03B5\u03AF\u03C3\u03B9\u03BC\u03BF",keyboard_search:"\u03B1\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7",error_search:"\u0397 \u03B1\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03B1\u03C0\u03AD\u03C4\u03C5\u03C7\u03B5",filter_selected_one:"[COUNT] \u03B5\u03C0\u03B9\u03BB\u03B5\u03B3\u03BC\u03AD\u03BD\u03BF",filter_selected_many:"[COUNT] \u03B5\u03C0\u03B9\u03BB\u03B5\u03B3\u03BC\u03AD\u03BD\u03B1",input_hint:"\u03A4\u03B1 \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B8\u03B1 \u03B5\u03BC\u03C6\u03B1\u03BD\u03AF\u03B6\u03BF\u03BD\u03C4\u03B1\u03B9 \u03BA\u03B1\u03B8\u03CE\u03C2 \u03C0\u03BB\u03B7\u03BA\u03C4\u03C1\u03BF\u03BB\u03BF\u03B3\u03B5\u03AF\u03C4\u03B5",loading:"\u03A6\u03CC\u03C1\u03C4\u03C9\u03C3\u03B7"},Ja={thanks_to:Ya,comments:Ma,direction:wa,strings:za};var Vt={};Z(Vt,{comments:()=>ja,default:()=>qa,direction:()=>Ka,strings:()=>Pa,thanks_to:()=>Oa});var Oa="Liam Bigelow ",ja="",Ka="ltr",Pa={placeholder:"Search",clear_search:"Clear",load_more:"Load more results",search_label:"Search this site",filters_label:"Filters",zero_results:"No results for [SEARCH_TERM]",many_results:"[COUNT] results for [SEARCH_TERM]",one_result:"[COUNT] result for [SEARCH_TERM]",total_zero_results:"No results",total_one_result:"[COUNT] result",total_many_results:"[COUNT] results",alt_search:"No results for [SEARCH_TERM]. Showing results for [DIFFERENT_TERM] instead",search_suggestion:"No results for [SEARCH_TERM]. Try one of the following searches:",searching:"Searching for [SEARCH_TERM]...",results_label:"Search results",keyboard_navigate:"navigate",keyboard_select:"select",keyboard_clear:"clear",keyboard_close:"close",keyboard_search:"search",error_search:"Search failed",filter_selected_one:"[COUNT] selected",filter_selected_many:"[COUNT] selected",input_hint:"Results will appear as you type",loading:"Loading"},qa={thanks_to:Oa,comments:ja,direction:Ka,strings:Pa};var Dt={};Z(Dt,{comments:()=>ei,default:()=>si,direction:()=>ti,strings:()=>li,thanks_to:()=>$a});var $a="Pablo Villaverde ",ei="",ti="ltr",li={placeholder:"Buscar",clear_search:"Limpiar",load_more:"Ver m\xE1s resultados",search_label:"Buscar en este sitio",filters_label:"Filtros",zero_results:"No se encontraron resultados para [SEARCH_TERM]",many_results:"[COUNT] resultados encontrados para [SEARCH_TERM]",one_result:"[COUNT] resultado encontrado para [SEARCH_TERM]",total_zero_results:"Sin resultados",total_one_result:"[COUNT] resultado",total_many_results:"[COUNT] resultados",alt_search:"No se encontraron resultados para [SEARCH_TERM]. Mostrando en su lugar resultados para [DIFFERENT_TERM]",search_suggestion:"No se encontraron resultados para [SEARCH_TERM]. Prueba una de las siguientes b\xFAsquedas:",searching:"Buscando [SEARCH_TERM]...",results_label:"Resultados de b\xFAsqueda",keyboard_navigate:"navegar",keyboard_select:"elegir",keyboard_clear:"limpiar",keyboard_close:"cerrar",keyboard_search:"buscar",error_search:"Error en la b\xFAsqueda",filter_selected_one:"[COUNT] seleccionado",filter_selected_many:"[COUNT] seleccionados",input_hint:"Los resultados aparecer\xE1n mientras escribe",loading:"Cargando"},si={thanks_to:$a,comments:ei,direction:ti,strings:li};var Tt={};Z(Tt,{comments:()=>ii,default:()=>gi,direction:()=>ni,strings:()=>ri,thanks_to:()=>ai});var ai="Mikel Larreategi ",ii="",ni="ltr",ri={placeholder:"Bilatu",clear_search:"Garbitu",load_more:"Kargatu emaitza gehiagi",search_label:"Bilatu",filters_label:"Iragazkiak",zero_results:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat",many_results:"[COUNT] emaitza [SEARCH_TERM] bilaketarentzat",one_result:"Emaitza bat [COUNT] [SEARCH_TERM] bilaketarentzat",total_zero_results:"Emaitzarik ez",total_one_result:"[COUNT] emaitza",total_many_results:"[COUNT] emaitza",alt_search:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat. [DIFFERENT_TERM] bilaketaren emaitzak erakusten",search_suggestion:"Ez dago emaitzarik [SEARCH_TERM] bilaketarentzat. Saiatu hauetako beste bateikin:",searching:"[SEARCH_TERM] bilatzen...",results_label:"Bilaketaren emaitzak",keyboard_navigate:"nabigatu",keyboard_select:"hautatu",keyboard_clear:"garbitu",keyboard_close:"itxi",keyboard_search:"bilatu",error_search:"Bilaketak huts egin du",filter_selected_one:"[COUNT] hautatuta",filter_selected_many:"[COUNT] hautatuta",input_hint:"Emaitzak idatzi ahala agertuko dira",loading:"Kargatzen"},gi={thanks_to:ai,comments:ii,direction:ni,strings:ri};var vt={};Z(vt,{comments:()=>oi,default:()=>Ii,direction:()=>Ci,strings:()=>ui,thanks_to:()=>ci});var ci="Ali Khaleqi Yekta ",oi="",Ci="rtl",ui={placeholder:"\u062C\u0633\u062A\u062C\u0648",clear_search:"\u067E\u0627\u06A9\u0633\u0627\u0632\u06CC",load_more:"\u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u062A\u0627\u06CC\u062C \u0628\u06CC\u0634\u062A\u0631",search_label:"\u062C\u0633\u062A\u062C\u0648 \u062F\u0631 \u0633\u0627\u06CC\u062A",filters_label:"\u0641\u06CC\u0644\u062A\u0631\u0647\u0627",zero_results:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F",many_results:"[COUNT] \u0646\u062A\u06CC\u062C\u0647 \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0634\u062F",one_result:"[COUNT] \u0646\u062A\u06CC\u062C\u0647 \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0634\u062F",total_zero_results:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u06CC\u0627\u0641\u062A \u0646\u0634\u062F",total_one_result:"[COUNT] \u0646\u062A\u06CC\u062C\u0647",total_many_results:"[COUNT] \u0646\u062A\u06CC\u062C\u0647",alt_search:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F. \u062F\u0631 \u0639\u0648\u0636 \u0646\u062A\u0627\u06CC\u062C \u0628\u0631\u0627\u06CC [DIFFERENT_TERM] \u0646\u0645\u0627\u06CC\u0634 \u062F\u0627\u062F\u0647 \u0645\u06CC\u200C\u0634\u0648\u062F",search_suggestion:"\u0646\u062A\u06CC\u062C\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC [SEARCH_TERM] \u06CC\u0627\u0641\u062A \u0646\u0634\u062F. \u06CC\u06A9\u06CC \u0627\u0632 \u062C\u0633\u062A\u062C\u0648\u0647\u0627\u06CC \u0632\u06CC\u0631 \u0631\u0627 \u0627\u0645\u062A\u062D\u0627\u0646 \u06A9\u0646\u06CC\u062F:",searching:"\u062F\u0631 \u062D\u0627\u0644 \u062C\u0633\u062A\u062C\u0648\u06CC [SEARCH_TERM]...",results_label:"\u0646\u062A\u0627\u06CC\u062C \u062C\u0633\u062A\u062C\u0648",keyboard_navigate:"\u067E\u06CC\u0645\u0627\u06CC\u0634",keyboard_select:"\u0627\u0646\u062A\u062E\u0627\u0628",keyboard_clear:"\u067E\u0627\u06A9\u0633\u0627\u0632\u06CC",keyboard_close:"\u0628\u0633\u062A\u0646",keyboard_search:"\u062C\u0633\u062A\u062C\u0648",error_search:"\u062C\u0633\u062A\u062C\u0648 \u0646\u0627\u0645\u0648\u0641\u0642 \u0628\u0648\u062F",filter_selected_one:"[COUNT] \u0627\u0646\u062A\u062E\u0627\u0628 \u0634\u062F\u0647",filter_selected_many:"[COUNT] \u0627\u0646\u062A\u062E\u0627\u0628 \u0634\u062F\u0647",input_hint:"\u0646\u062A\u0627\u06CC\u062C \u0647\u0646\u06AF\u0627\u0645 \u062A\u0627\u06CC\u067E \u0646\u0645\u0627\u06CC\u0634 \u062F\u0627\u062F\u0647 \u0645\u06CC\u200C\u0634\u0648\u0646\u062F",loading:"\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC"},Ii={thanks_to:ci,comments:oi,direction:Ci,strings:ui};var Ht={};Z(Ht,{comments:()=>Ai,default:()=>bi,direction:()=>Qi,strings:()=>_i,thanks_to:()=>di});var di="Valtteri Laitinen ",Ai="",Qi="ltr",_i={placeholder:"Haku",clear_search:"Tyhjenn\xE4",load_more:"Lataa lis\xE4\xE4 tuloksia",search_label:"Hae t\xE4lt\xE4 sivustolta",filters_label:"Suodattimet",zero_results:"Ei tuloksia haulle [SEARCH_TERM]",many_results:"[COUNT] tulosta haulle [SEARCH_TERM]",one_result:"[COUNT] tulos haulle [SEARCH_TERM]",total_zero_results:"Ei tuloksia",total_one_result:"[COUNT] tulos",total_many_results:"[COUNT] tulosta",alt_search:"Ei tuloksia haulle [SEARCH_TERM]. N\xE4ytet\xE4\xE4n tulokset sen sijaan haulle [DIFFERENT_TERM]",search_suggestion:"Ei tuloksia haulle [SEARCH_TERM]. Kokeile jotain seuraavista:",searching:"Haetaan [SEARCH_TERM]...",results_label:"Hakutulokset",keyboard_navigate:"siirry",keyboard_select:"valitse",keyboard_clear:"tyhjenn\xE4",keyboard_close:"sulje",keyboard_search:"hae",error_search:"Haku ep\xE4onnistui",filter_selected_one:"[COUNT] valittu",filter_selected_many:"[COUNT] valittu",input_hint:"Tulokset n\xE4kyv\xE4t kirjoittaessasi",loading:"Ladataan"},bi={thanks_to:di,comments:Ai,direction:Qi,strings:_i};var Yt={};Z(Yt,{comments:()=>Fi,default:()=>hi,direction:()=>Bi,strings:()=>fi,thanks_to:()=>mi});var mi="Nicolas Friedli ",Fi="",Bi="ltr",fi={placeholder:"Rechercher",clear_search:"Nettoyer",load_more:"Charger plus de r\xE9sultats",search_label:"Recherche sur ce site",filters_label:"Filtres",zero_results:"Pas de r\xE9sultat pour [SEARCH_TERM]",many_results:"[COUNT] r\xE9sultats pour [SEARCH_TERM]",one_result:"[COUNT] r\xE9sultat pour [SEARCH_TERM]",total_zero_results:"Pas de r\xE9sultat",total_one_result:"[COUNT] r\xE9sultat",total_many_results:"[COUNT] r\xE9sultats",alt_search:"Pas de r\xE9sultat pour [SEARCH_TERM]. Montre les r\xE9sultats pour [DIFFERENT_TERM] \xE0 la place",search_suggestion:"Pas de r\xE9sultat pour [SEARCH_TERM]. Essayer une des recherches suivantes:",searching:"Recherche [SEARCH_TERM]...",results_label:"R\xE9sultats de recherche",keyboard_navigate:"naviguer",keyboard_select:"choisir",keyboard_clear:"effacer",keyboard_close:"fermer",keyboard_search:"rechercher",error_search:"\xC9chec de la recherche",filter_selected_one:"[COUNT] s\xE9lectionn\xE9",filter_selected_many:"[COUNT] s\xE9lectionn\xE9s",input_hint:"Les r\xE9sultats appara\xEEtront au fur et \xE0 mesure de la saisie",loading:"Chargement"},hi={thanks_to:mi,comments:Fi,direction:Bi,strings:fi};var Mt={};Z(Mt,{comments:()=>pi,default:()=>xi,direction:()=>Zi,strings:()=>yi,thanks_to:()=>Ui});var Ui="Pablo Villaverde ",pi="",Zi="ltr",yi={placeholder:"Buscar",clear_search:"Limpar",load_more:"Ver m\xE1is resultados",search_label:"Buscar neste sitio",filters_label:"Filtros",zero_results:"Non se atoparon resultados para [SEARCH_TERM]",many_results:"[COUNT] resultados atopados para [SEARCH_TERM]",one_result:"[COUNT] resultado atopado para [SEARCH_TERM]",total_zero_results:"Sen resultados",total_one_result:"[COUNT] resultado",total_many_results:"[COUNT] resultados",alt_search:"Non se atoparon resultados para [SEARCH_TERM]. Amosando no seu lugar resultados para [DIFFERENT_TERM]",search_suggestion:"Non se atoparon resultados para [SEARCH_TERM]. Probe unha das seguintes pesquisas:",searching:"Buscando [SEARCH_TERM]...",results_label:"Resultados da busca",keyboard_navigate:"navegar",keyboard_select:"escoller",keyboard_clear:"limpar",keyboard_close:"pechar",keyboard_search:"buscar",error_search:"Erro na busca",filter_selected_one:"[COUNT] seleccionado",filter_selected_many:"[COUNT] seleccionados",input_hint:"Os resultados aparecer\xE1n mentres escribe",loading:"Cargando"},xi={thanks_to:Ui,comments:pi,direction:Zi,strings:yi};var wt={};Z(wt,{comments:()=>Ni,default:()=>ki,direction:()=>Xi,strings:()=>Ei,thanks_to:()=>Gi});var Gi="Nir Tamir ",Ni="",Xi="rtl",Ei={placeholder:"\u05D7\u05D9\u05E4\u05D5\u05E9",clear_search:"\u05E0\u05D9\u05E7\u05D5\u05D9",load_more:"\u05E2\u05D5\u05D3 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA",search_label:"\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05D0\u05EA\u05E8 \u05D6\u05D4",filters_label:"\u05DE\u05E1\u05E0\u05E0\u05D9\u05DD",zero_results:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",many_results:"\u05E0\u05DE\u05E6\u05D0\u05D5 [COUNT] \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",one_result:"\u05E0\u05DE\u05E6\u05D0\u05D4 \u05EA\u05D5\u05E6\u05D0\u05D4 \u05D0\u05D7\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]",total_zero_results:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA",total_one_result:"\u05EA\u05D5\u05E6\u05D0\u05D4 [COUNT]",total_many_results:"[COUNT] \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA",alt_search:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]. \u05DE\u05D5\u05E6\u05D2\u05D5\u05EA \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [DIFFERENT_TERM]",search_suggestion:"\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8 [SEARCH_TERM]. \u05E0\u05E1\u05D5 \u05D0\u05D7\u05D3 \u05DE\u05D4\u05D7\u05D9\u05E4\u05D5\u05E9\u05D9\u05DD \u05D4\u05D1\u05D0\u05D9\u05DD:",searching:"\u05DE\u05D7\u05E4\u05E9 \u05D0\u05EA [SEARCH_TERM]...",results_label:"\u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05D7\u05D9\u05E4\u05D5\u05E9",keyboard_navigate:"\u05E0\u05D9\u05D5\u05D5\u05D8",keyboard_select:"\u05D1\u05D7\u05D9\u05E8\u05D4",keyboard_clear:"\u05E0\u05D9\u05E7\u05D5\u05D9",keyboard_close:"\u05E1\u05D2\u05D9\u05E8\u05D4",keyboard_search:"\u05D7\u05D9\u05E4\u05D5\u05E9",error_search:"\u05D4\u05D7\u05D9\u05E4\u05D5\u05E9 \u05E0\u05DB\u05E9\u05DC",filter_selected_one:"[COUNT] \u05E0\u05D1\u05D7\u05E8",filter_selected_many:"[COUNT] \u05E0\u05D1\u05D7\u05E8\u05D5",input_hint:"\u05D4\u05EA\u05D5\u05E6\u05D0\u05D5\u05EA \u05D9\u05D5\u05E4\u05D9\u05E2\u05D5 \u05EA\u05D5\u05DA \u05DB\u05D3\u05D9 \u05D4\u05E7\u05DC\u05D3\u05D4",loading:"\u05D8\u05D5\u05E2\u05DF"},ki={thanks_to:Gi,comments:Ni,direction:Xi,strings:Ei};var zt={};Z(zt,{comments:()=>Ri,default:()=>Vi,direction:()=>Wi,strings:()=>Si,thanks_to:()=>Li});var Li="Amit Yadav ",Ri="",Wi="ltr",Si={placeholder:"\u0916\u094B\u091C\u0947\u0902",clear_search:"\u0938\u093E\u092B \u0915\u0930\u0947\u0902",load_more:"\u0914\u0930 \u0905\u0927\u093F\u0915 \u092A\u0930\u093F\u0923\u093E\u092E \u0932\u094B\u0921 \u0915\u0930\u0947\u0902",search_label:"\u0907\u0938 \u0938\u093E\u0907\u091F \u092E\u0947\u0902 \u0916\u094B\u091C\u0947\u0902",filters_label:"\u092B\u093C\u093F\u0932\u094D\u091F\u0930",zero_results:"\u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E",many_results:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u092E\u093F\u0932\u0947",one_result:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E [SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u092E\u093F\u0932\u093E",total_zero_results:"\u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902",total_one_result:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E",total_many_results:"[COUNT] \u092A\u0930\u093F\u0923\u093E\u092E",alt_search:"[SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E\u0964 \u0907\u0938\u0915\u0947 \u092C\u091C\u093E\u092F [DIFFERENT_TERM] \u0915\u0947 \u0932\u093F\u090F \u092A\u0930\u093F\u0923\u093E\u092E \u0926\u093F\u0916\u093E \u0930\u0939\u093E \u0939\u0948",search_suggestion:"[SEARCH_TERM] \u0915\u0947 \u0932\u093F\u090F \u0915\u094B\u0908 \u092A\u0930\u093F\u0923\u093E\u092E \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E\u0964 \u0928\u093F\u092E\u094D\u0928\u0932\u093F\u0916\u093F\u0924 \u0916\u094B\u091C\u094B\u0902 \u092E\u0947\u0902 \u0938\u0947 \u0915\u094B\u0908 \u090F\u0915 \u0906\u091C\u093C\u092E\u093E\u090F\u0902:",searching:"[SEARCH_TERM] \u0915\u0940 \u0916\u094B\u091C \u0915\u0940 \u091C\u093E \u0930\u0939\u0940 \u0939\u0948...",results_label:"\u0916\u094B\u091C \u092A\u0930\u093F\u0923\u093E\u092E",keyboard_navigate:"\u0928\u0947\u0935\u093F\u0917\u0947\u091F",keyboard_select:"\u091A\u0941\u0928\u0947\u0902",keyboard_clear:"\u0938\u093E\u092B\u093C \u0915\u0930\u0947\u0902",keyboard_close:"\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",keyboard_search:"\u0916\u094B\u091C\u0947\u0902",error_search:"\u0916\u094B\u091C \u0935\u093F\u092B\u0932",filter_selected_one:"[COUNT] \u091A\u092F\u0928\u093F\u0924",filter_selected_many:"[COUNT] \u091A\u092F\u0928\u093F\u0924",input_hint:"\u091F\u093E\u0907\u092A \u0915\u0930\u0924\u0947 \u0938\u092E\u092F \u092A\u0930\u093F\u0923\u093E\u092E \u0926\u093F\u0916\u093E\u0908 \u0926\u0947\u0902\u0917\u0947",loading:"\u0932\u094B\u0921 \u0939\u094B \u0930\u0939\u093E \u0939\u0948"},Vi={thanks_to:Li,comments:Ri,direction:Wi,strings:Si};var Jt={};Z(Jt,{comments:()=>Ti,default:()=>Yi,direction:()=>vi,strings:()=>Hi,thanks_to:()=>Di});var Di="Diomed ",Ti="",vi="ltr",Hi={placeholder:"Tra\u017Ei",clear_search:"O\u010Disti",load_more:"U\u010Ditaj vi\u0161e rezultata",search_label:"Pretra\u017Ei ovu stranicu",filters_label:"Filteri",zero_results:"Nema rezultata za [SEARCH_TERM]",many_results:"[COUNT] rezultata za [SEARCH_TERM]",one_result:"[COUNT] rezultat za [SEARCH_TERM]",total_zero_results:"Nema rezultata",total_one_result:"[COUNT] rezultat",total_many_results:"[COUNT] rezultata",alt_search:"Nema rezultata za [SEARCH_TERM]. Prikazujem rezultate za [DIFFERENT_TERM]",search_suggestion:"Nema rezultata za [SEARCH_TERM]. Poku\u0161aj s jednom od ovih pretraga:",searching:"Pretra\u017Eujem [SEARCH_TERM]...",results_label:"Rezultati pretrage",keyboard_navigate:"navigiraj",keyboard_select:"odaberi",keyboard_clear:"o\u010Disti",keyboard_close:"zatvori",keyboard_search:"tra\u017Ei",error_search:"Pretraga nije uspjela",filter_selected_one:"[COUNT] odabran",filter_selected_many:"[COUNT] odabranih",input_hint:"Rezultati \u0107e se pojaviti dok tipkate",loading:"U\u010Ditavanje"},Yi={thanks_to:Di,comments:Ti,direction:vi,strings:Hi};var Ot={};Z(Ot,{comments:()=>wi,default:()=>Oi,direction:()=>zi,strings:()=>Ji,thanks_to:()=>Mi});var Mi="Adam Laki ",wi="",zi="ltr",Ji={placeholder:"Keres\xE9s",clear_search:"T\xF6rl\xE9s",load_more:"Tov\xE1bbi tal\xE1latok bet\xF6lt\xE9se",search_label:"Keres\xE9s az oldalon",filters_label:"Sz\u0171r\xE9s",zero_results:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",many_results:"[COUNT] db tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",one_result:"[COUNT] db tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre",total_zero_results:"Nincs tal\xE1lat",total_one_result:"[COUNT] tal\xE1lat",total_many_results:"[COUNT] tal\xE1lat",alt_search:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre. Tal\xE1latok mutat\xE1sa ink\xE1bb a(z) [DIFFERENT_TERM] kifejez\xE9sre",search_suggestion:"Nincs tal\xE1lat a(z) [SEARCH_TERM] kifejez\xE9sre. Pr\xF3b\xE1ld meg a k\xF6vetkez\u0151 keres\xE9sek egyik\xE9t:",searching:"Keres\xE9s a(z) [SEARCH_TERM] kifejez\xE9sre...",results_label:"Keres\xE9si tal\xE1latok",keyboard_navigate:"navig\xE1l\xE1s",keyboard_select:"kiv\xE1laszt\xE1s",keyboard_clear:"t\xF6rl\xE9s",keyboard_close:"bez\xE1r\xE1s",keyboard_search:"keres\xE9s",error_search:"A keres\xE9s sikertelen",filter_selected_one:"[COUNT] kiv\xE1lasztva",filter_selected_many:"[COUNT] kiv\xE1lasztva",input_hint:"A tal\xE1latok g\xE9pel\xE9s k\xF6zben jelennek meg",loading:"Bet\xF6lt\xE9s"},Oi={thanks_to:Mi,comments:wi,direction:zi,strings:Ji};var jt={};Z(jt,{comments:()=>Ki,default:()=>$i,direction:()=>Pi,strings:()=>qi,thanks_to:()=>ji});var ji="Nixentric",Ki="",Pi="ltr",qi={placeholder:"Cari",clear_search:"Bersihkan",load_more:"Muat lebih banyak hasil",search_label:"Telusuri situs ini",filters_label:"Filter",zero_results:"[SEARCH_TERM] tidak ditemukan",many_results:"Ditemukan [COUNT] hasil untuk [SEARCH_TERM]",one_result:"Ditemukan [COUNT] hasil untuk [SEARCH_TERM]",total_zero_results:"Tidak ada hasil",total_one_result:"[COUNT] hasil",total_many_results:"[COUNT] hasil",alt_search:"[SEARCH_TERM] tidak ditemukan. Menampilkan hasil [DIFFERENT_TERM] sebagai gantinya",search_suggestion:"[SEARCH_TERM] tidak ditemukan. Coba salah satu pencarian berikut ini:",searching:"Mencari [SEARCH_TERM]...",results_label:"Hasil pencarian",keyboard_navigate:"navigasi",keyboard_select:"pilih",keyboard_clear:"bersihkan",keyboard_close:"tutup",keyboard_search:"cari",error_search:"Pencarian gagal",filter_selected_one:"[COUNT] dipilih",filter_selected_many:"[COUNT] dipilih",input_hint:"Hasil akan muncul saat Anda mengetik",loading:"Memuat"},$i={thanks_to:ji,comments:Ki,direction:Pi,strings:qi};var Kt={};Z(Kt,{comments:()=>tn,default:()=>an,direction:()=>ln,strings:()=>sn,thanks_to:()=>en});var en="Cosette Bruhns Alonso, Andrew Janco ",tn="",ln="ltr",sn={placeholder:"Cerca",clear_search:"Cancella la cronologia",load_more:"Mostra pi\xF9 risultati",search_label:"Cerca nel sito",filters_label:"Filtri di ricerca",zero_results:"Nessun risultato per [SEARCH_TERM]",many_results:"[COUNT] risultati per [SEARCH_TERM]",one_result:"[COUNT] risultato per [SEARCH_TERM]",total_zero_results:"Nessun risultato",total_one_result:"[COUNT] risultato",total_many_results:"[COUNT] risultati",alt_search:"Nessun risultato per [SEARCH_TERM]. Mostrando risultati per [DIFFERENT_TERM] come alternativa.",search_suggestion:"Nessun risultato per [SEARCH_TERM]. Prova una delle seguenti ricerche:",searching:"Cercando [SEARCH_TERM]...",results_label:"Risultati della ricerca",keyboard_navigate:"naviga",keyboard_select:"seleziona",keyboard_clear:"cancella",keyboard_close:"chiudi",keyboard_search:"cerca",error_search:"Ricerca fallita",filter_selected_one:"[COUNT] selezionato",filter_selected_many:"[COUNT] selezionati",input_hint:"I risultati appariranno durante la digitazione",loading:"Caricamento"},an={thanks_to:en,comments:tn,direction:ln,strings:sn};var Pt={};Z(Pt,{comments:()=>rn,default:()=>on,direction:()=>gn,strings:()=>cn,thanks_to:()=>nn});var nn="Tate",rn="",gn="ltr",cn={placeholder:"\u691C\u7D22",clear_search:"\u30AF\u30EA\u30A2",load_more:"\u6B21\u3092\u8AAD\u307F\u8FBC\u3080",search_label:"\u3053\u306E\u30B5\u30A4\u30C8\u3092\u691C\u7D22",filters_label:"\u30D5\u30A3\u30EB\u30BF",zero_results:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F",many_results:"[SEARCH_TERM]\u306E[COUNT]\u4EF6\u306E\u691C\u7D22\u7D50\u679C",one_result:"[SEARCH_TERM]\u306E[COUNT]\u4EF6\u306E\u691C\u7D22\u7D50\u679C",total_zero_results:"\u7D50\u679C\u306A\u3057",total_one_result:"[COUNT]\u4EF6\u306E\u7D50\u679C",total_many_results:"[COUNT]\u4EF6\u306E\u7D50\u679C",alt_search:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002[DIFFERENT_TERM]\u306E\u691C\u7D22\u7D50\u679C\u3092\u8868\u793A\u3057\u3066\u3044\u307E\u3059",search_suggestion:"[SEARCH_TERM]\u306E\u691C\u7D22\u306B\u4E00\u81F4\u3059\u308B\u60C5\u5831\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u6B21\u306E\u3044\u305A\u308C\u304B\u306E\u691C\u7D22\u3092\u8A66\u3057\u3066\u304F\u3060\u3055\u3044",searching:"[SEARCH_TERM]\u3092\u691C\u7D22\u3057\u3066\u3044\u307E\u3059",results_label:"\u691C\u7D22\u7D50\u679C",keyboard_navigate:"\u79FB\u52D5",keyboard_select:"\u9078\u629E",keyboard_clear:"\u30AF\u30EA\u30A2",keyboard_close:"\u9589\u3058\u308B",keyboard_search:"\u691C\u7D22",error_search:"\u691C\u7D22\u306B\u5931\u6557\u3057\u307E\u3057\u305F",filter_selected_one:"[COUNT]\u4EF6\u9078\u629E\u4E2D",filter_selected_many:"[COUNT]\u4EF6\u9078\u629E\u4E2D",input_hint:"\u5165\u529B\u4E2D\u306B\u691C\u7D22\u7D50\u679C\u304C\u8868\u793A\u3055\u308C\u307E\u3059",loading:"\u8AAD\u307F\u8FBC\u307F\u4E2D"},on={thanks_to:nn,comments:rn,direction:gn,strings:cn};var qt={};Z(qt,{comments:()=>un,default:()=>An,direction:()=>In,strings:()=>dn,thanks_to:()=>Cn});var Cn="Seokho Son ",un="",In="ltr",dn={placeholder:"\uAC80\uC0C9\uC5B4",clear_search:"\uBE44\uC6B0\uAE30",load_more:"\uAC80\uC0C9 \uACB0\uACFC \uB354 \uBCF4\uAE30",search_label:"\uC0AC\uC774\uD2B8 \uAC80\uC0C9",filters_label:"\uD544\uD130",zero_results:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C",many_results:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC [COUNT]\uAC74",one_result:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC [COUNT]\uAC74",total_zero_results:"\uACB0\uACFC \uC5C6\uC74C",total_one_result:"\uACB0\uACFC [COUNT]\uAC74",total_many_results:"\uACB0\uACFC [COUNT]\uAC74",alt_search:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C. [DIFFERENT_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC",search_suggestion:"[SEARCH_TERM]\uC5D0 \uB300\uD55C \uACB0\uACFC \uC5C6\uC74C. \uCD94\uCC9C \uAC80\uC0C9\uC5B4: ",searching:"[SEARCH_TERM] \uAC80\uC0C9 \uC911...",results_label:"\uAC80\uC0C9 \uACB0\uACFC",keyboard_navigate:"\uC774\uB3D9",keyboard_select:"\uC120\uD0DD",keyboard_clear:"\uBE44\uC6B0\uAE30",keyboard_close:"\uB2EB\uAE30",keyboard_search:"\uAC80\uC0C9",error_search:"\uAC80\uC0C9 \uC2E4\uD328",filter_selected_one:"[COUNT]\uAC1C \uC120\uD0DD\uB428",filter_selected_many:"[COUNT]\uAC1C \uC120\uD0DD\uB428",input_hint:"\uC785\uB825\uD558\uB294 \uB3D9\uC548 \uACB0\uACFC\uAC00 \uD45C\uC2DC\uB429\uB2C8\uB2E4",loading:"\uB85C\uB529 \uC911"},An={thanks_to:Cn,comments:un,direction:In,strings:dn};var $t={};Z($t,{comments:()=>_n,default:()=>Fn,direction:()=>bn,strings:()=>mn,thanks_to:()=>Qn});var Qn="",_n="",bn="ltr",mn={placeholder:"Rapu",clear_search:"Whakakore",load_more:"Whakauta \u0113tahi otinga k\u0113",search_label:"Rapu",filters_label:"T\u0101tari",zero_results:"Otinga kore ki [SEARCH_TERM]",many_results:"[COUNT] otinga ki [SEARCH_TERM]",one_result:"[COUNT] otinga ki [SEARCH_TERM]",total_zero_results:"K\u0101ore he otinga",total_one_result:"[COUNT] otinga",total_many_results:"[COUNT] ng\u0101 otinga",alt_search:"Otinga kore ki [SEARCH_TERM]. Otinga k\u0113 ki [DIFFERENT_TERM]",search_suggestion:"Otinga kore ki [SEARCH_TERM]. whakam\u0101tau ki ng\u0101 mea atu:",searching:"Rapu ki [SEARCH_TERM]...",results_label:"Ng\u0101 otinga rapu",keyboard_navigate:"whakatere",keyboard_select:"t\u012Bpako",keyboard_clear:"whakakore",keyboard_close:"kati",keyboard_search:"rapu",error_search:"K\u0101ore i eke te rapu",filter_selected_one:"[COUNT] kua t\u012Bpakohia",filter_selected_many:"[COUNT] kua t\u012Bpakohia",input_hint:"Ka puta ng\u0101 otinga i a koe e patopato ana",loading:"E uta ana"},Fn={thanks_to:Qn,comments:_n,direction:bn,strings:mn};var el={};Z(el,{comments:()=>fn,default:()=>pn,direction:()=>hn,strings:()=>Un,thanks_to:()=>Bn});var Bn="Harry Min Khant ",fn="",hn="ltr",Un={placeholder:"\u101B\u103E\u102C\u101B\u1014\u103A",clear_search:"\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F\u1000\u102D\u102F \u101B\u103E\u1004\u103A\u1038\u101C\u1004\u103A\u1038\u1015\u102B\u104B",load_more:"\u1014\u1031\u102C\u1000\u103A\u1011\u1015\u103A\u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038\u1000\u102D\u102F \u1010\u1004\u103A\u1015\u102B\u104B",search_label:"\u1024\u1006\u102D\u102F\u1000\u103A\u1010\u103D\u1004\u103A\u101B\u103E\u102C\u1016\u103D\u1031\u1015\u102B\u104B",filters_label:"\u1005\u1005\u103A\u1011\u102F\u1010\u103A\u1019\u103E\u102F\u1019\u103B\u102C\u1038",zero_results:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038 \u1019\u101B\u103E\u102D\u1015\u102B",many_results:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A [COUNT] \u1001\u102F",one_result:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A [COUNT]",total_zero_results:"\u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038 \u1019\u101B\u103E\u102D\u1015\u102B",total_one_result:"\u101B\u101C\u1012\u103A [COUNT] \u1001\u102F",total_many_results:"\u101B\u101C\u1012\u103A [COUNT] \u1001\u102F",alt_search:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u101B\u103E\u102D\u1015\u102B\u104B \u104E\u1004\u103A\u1038\u1021\u1005\u102C\u1038 [DIFFERENT_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038\u1000\u102D\u102F \u1015\u103C\u101E\u101E\u100A\u103A\u104B",search_suggestion:"[SEARCH_TERM] \u1021\u1010\u103D\u1000\u103A \u101B\u101C\u1012\u103A\u1019\u101B\u103E\u102D\u1015\u102B\u104B \u1021\u1031\u102C\u1000\u103A\u1015\u102B\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F\u1019\u103B\u102C\u1038\u1011\u1032\u1019\u103E \u1010\u1005\u103A\u1001\u102F\u1000\u102D\u102F \u1005\u1019\u103A\u1038\u1000\u103C\u100A\u1037\u103A\u1015\u102B:",searching:"[SEARCH_TERM] \u1000\u102D\u102F \u101B\u103E\u102C\u1016\u103D\u1031\u1014\u1031\u101E\u100A\u103A...",results_label:"\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038",keyboard_navigate:"\u101C\u1019\u103A\u1038\u100A\u103D\u103E\u1014\u103A",keyboard_select:"\u101B\u103D\u1031\u1038\u1001\u103B\u101A\u103A",keyboard_clear:"\u101B\u103E\u1004\u103A\u1038\u101C\u1004\u103A\u1038",keyboard_close:"\u1015\u102D\u1010\u103A",keyboard_search:"\u101B\u103E\u102C\u101B\u1014\u103A",error_search:"\u101B\u103E\u102C\u1016\u103D\u1031\u1019\u103E\u102F \u1019\u1021\u1031\u102C\u1004\u103A\u1019\u103C\u1004\u103A\u1015\u102B",filter_selected_one:"[COUNT] \u1001\u102F \u101B\u103D\u1031\u1038\u1001\u103B\u101A\u103A\u1011\u102C\u1038\u101E\u100A\u103A",filter_selected_many:"[COUNT] \u1001\u102F \u101B\u103D\u1031\u1038\u1001\u103B\u101A\u103A\u1011\u102C\u1038\u101E\u100A\u103A",input_hint:"\u101B\u102D\u102F\u1000\u103A\u1014\u1031\u1005\u1009\u103A \u101B\u101C\u1012\u103A\u1019\u103B\u102C\u1038 \u1015\u1031\u102B\u103A\u101C\u102C\u1015\u102B\u1019\u100A\u103A",loading:"\u1010\u1004\u103A\u1014\u1031\u101E\u100A\u103A"},pn={thanks_to:Bn,comments:fn,direction:hn,strings:Un};var tl={};Z(tl,{comments:()=>yn,default:()=>Nn,direction:()=>xn,strings:()=>Gn,thanks_to:()=>Zn});var Zn="Eirik Mikkelsen",yn="",xn="ltr",Gn={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last flere resultater",search_label:"S\xF8k p\xE5 denne siden",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultater",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultater",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v en av disse s\xF8keordene i stedet:",searching:"S\xF8ker etter [SEARCH_TERM]",results_label:"S\xF8keresultater",keyboard_navigate:"naviger",keyboard_select:"velg",keyboard_clear:"fjern",keyboard_close:"lukk",keyboard_search:"s\xF8k",error_search:"S\xF8k feilet",filter_selected_one:"[COUNT] valgt",filter_selected_many:"[COUNT] valgte",input_hint:"Resultater vises mens du skriver",loading:"Laster"},Nn={thanks_to:Zn,comments:yn,direction:xn,strings:Gn};var ll={};Z(ll,{comments:()=>En,default:()=>Rn,direction:()=>kn,strings:()=>Ln,thanks_to:()=>Xn});var Xn="Paul van Brouwershaven",En="",kn="ltr",Ln={placeholder:"Zoeken",clear_search:"Reset",load_more:"Meer resultaten laden",search_label:"Doorzoek deze site",filters_label:"Filters",zero_results:"Geen resultaten voor [SEARCH_TERM]",many_results:"[COUNT] resultaten voor [SEARCH_TERM]",one_result:"[COUNT] resultaat voor [SEARCH_TERM]",total_zero_results:"Geen resultaten",total_one_result:"[COUNT] resultaat",total_many_results:"[COUNT] resultaten",alt_search:"Geen resultaten voor [SEARCH_TERM]. In plaats daarvan worden resultaten voor [DIFFERENT_TERM] weergegeven",search_suggestion:"Geen resultaten voor [SEARCH_TERM]. Probeer een van de volgende zoekopdrachten:",searching:"Zoeken naar [SEARCH_TERM]...",results_label:"Zoekresultaten",keyboard_navigate:"navigeren",keyboard_select:"selecteren",keyboard_clear:"wissen",keyboard_close:"sluiten",keyboard_search:"zoeken",error_search:"Zoeken mislukt",filter_selected_one:"[COUNT] geselecteerd",filter_selected_many:"[COUNT] geselecteerd",input_hint:"Resultaten verschijnen terwijl u typt",loading:"Laden"},Rn={thanks_to:Xn,comments:En,direction:kn,strings:Ln};var sl={};Z(sl,{comments:()=>Sn,default:()=>Tn,direction:()=>Vn,strings:()=>Dn,thanks_to:()=>Wn});var Wn="Eirik Mikkelsen",Sn="",Vn="ltr",Dn={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last fleire resultat",search_label:"S\xF8k p\xE5 denne sida",filters_label:"Filter",zero_results:"Ingen resultat for [SEARCH_TERM]",many_results:"[COUNT] resultat for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultat",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultat",alt_search:"Ingen resultat for [SEARCH_TERM]. Viser resultat for [DIFFERENT_TERM] i staden",search_suggestion:"Ingen resultat for [SEARCH_TERM]. Pr\xF8v eitt av desse s\xF8keorda i staden:",searching:"S\xF8ker etter [SEARCH_TERM]",results_label:"S\xF8keresultat",keyboard_navigate:"naviger",keyboard_select:"vel",keyboard_clear:"fjern",keyboard_close:"lukk",keyboard_search:"s\xF8k",error_search:"S\xF8k feila",filter_selected_one:"[COUNT] vald",filter_selected_many:"[COUNT] valde",input_hint:"Resultat visast medan du skriv",loading:"Lastar"},Tn={thanks_to:Wn,comments:Sn,direction:Vn,strings:Dn};var al={};Z(al,{comments:()=>Hn,default:()=>wn,direction:()=>Yn,strings:()=>Mn,thanks_to:()=>vn});var vn="Christopher Wingate",Hn="",Yn="ltr",Mn={placeholder:"S\xF8k",clear_search:"Fjern",load_more:"Last flere resultater",search_label:"S\xF8k p\xE5 denne siden",filters_label:"Filtre",zero_results:"Ingen resultater for [SEARCH_TERM]",many_results:"[COUNT] resultater for [SEARCH_TERM]",one_result:"[COUNT] resultat for [SEARCH_TERM]",total_zero_results:"Ingen resultater",total_one_result:"[COUNT] resultat",total_many_results:"[COUNT] resultater",alt_search:"Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet",search_suggestion:"Ingen resultater for [SEARCH_TERM]. Pr\xF8v en av disse s\xF8keordene i stedet:",searching:"S\xF8ker etter [SEARCH_TERM]",results_label:"S\xF8keresultater",keyboard_navigate:"naviger",keyboard_select:"velg",keyboard_clear:"fjern",keyboard_close:"lukk",keyboard_search:"s\xF8k",error_search:"S\xF8k feilet",filter_selected_one:"[COUNT] valgt",filter_selected_many:"[COUNT] valgte",input_hint:"Resultater vises mens du skriver",loading:"Laster"},wn={thanks_to:vn,comments:Hn,direction:Yn,strings:Mn};var il={};Z(il,{comments:()=>Jn,default:()=>Kn,direction:()=>On,strings:()=>jn,thanks_to:()=>zn});var zn="",Jn="",On="ltr",jn={placeholder:"Szukaj",clear_search:"Wyczy\u015B\u0107",load_more:"Za\u0142aduj wi\u0119cej",search_label:"Przeszukaj t\u0119 stron\u0119",filters_label:"Filtry",zero_results:"Brak wynik\xF3w dla [SEARCH_TERM]",many_results:"[COUNT] wynik\xF3w dla [SEARCH_TERM]",one_result:"[COUNT] wynik dla [SEARCH_TERM]",total_zero_results:"Brak wynik\xF3w",total_one_result:"[COUNT] wynik",total_many_results:"[COUNT] wynik\xF3w",alt_search:"Brak wynik\xF3w dla [SEARCH_TERM]. Wy\u015Bwietlam wyniki dla [DIFFERENT_TERM]",search_suggestion:"Brak wynik\xF3w dla [SEARCH_TERM]. Pokrewne wyniki wyszukiwania:",searching:"Szukam [SEARCH_TERM]...",results_label:"Wyniki wyszukiwania",keyboard_navigate:"nawiguj",keyboard_select:"wybierz",keyboard_clear:"wyczy\u015B\u0107",keyboard_close:"zamknij",keyboard_search:"szukaj",error_search:"Wyszukiwanie nie powiod\u0142o si\u0119",filter_selected_one:"[COUNT] wybrany",filter_selected_many:"[COUNT] wybranych",input_hint:"Wyniki pojawi\u0105 si\u0119 podczas pisania",loading:"\u0141adowanie"},Kn={thanks_to:zn,comments:Jn,direction:On,strings:jn};var nl={};Z(nl,{comments:()=>qn,default:()=>tr,direction:()=>$n,strings:()=>er,thanks_to:()=>Pn});var Pn="Jonatah",qn="",$n="ltr",er={placeholder:"Pesquisar",clear_search:"Limpar",load_more:"Ver mais resultados",search_label:"Pesquisar",filters_label:"Filtros",zero_results:"Nenhum resultado encontrado para [SEARCH_TERM]",many_results:"[COUNT] resultados encontrados para [SEARCH_TERM]",one_result:"[COUNT] resultado encontrado para [SEARCH_TERM]",total_zero_results:"Nenhum resultado",total_one_result:"[COUNT] resultado",total_many_results:"[COUNT] resultados",alt_search:"Nenhum resultado encontrado para [SEARCH_TERM]. Exibindo resultados para [DIFFERENT_TERM]",search_suggestion:"Nenhum resultado encontrado para [SEARCH_TERM]. Tente uma das seguintes pesquisas:",searching:"Pesquisando por [SEARCH_TERM]...",results_label:"Resultados da pesquisa",keyboard_navigate:"navegar",keyboard_select:"selecionar",keyboard_clear:"limpar",keyboard_close:"fechar",keyboard_search:"pesquisar",error_search:"Falha na pesquisa",filter_selected_one:"[COUNT] selecionado",filter_selected_many:"[COUNT] selecionados",input_hint:"Os resultados aparecer\xE3o enquanto voc\xEA digita",loading:"Carregando"},tr={thanks_to:Pn,comments:qn,direction:$n,strings:er};var rl={};Z(rl,{comments:()=>sr,default:()=>nr,direction:()=>ar,strings:()=>ir,thanks_to:()=>lr});var lr="Bogdan Mateescu ",sr="",ar="ltr",ir={placeholder:"C\u0103utare",clear_search:"\u015Eterge\u0163i",load_more:"\xCEnc\u0103rca\u021Bi mai multe rezultate",search_label:"C\u0103uta\u021Bi \xEEn acest site",filters_label:"Filtre",zero_results:"Niciun rezultat pentru [SEARCH_TERM]",many_results:"[COUNT] rezultate pentru [SEARCH_TERM]",one_result:"[COUNT] rezultat pentru [SEARCH_TERM]",total_zero_results:"Niciun rezultat",total_one_result:"[COUNT] rezultat",total_many_results:"[COUNT] rezultate",alt_search:"Niciun rezultat pentru [SEARCH_TERM]. Se afi\u0219eaz\u0103 \xEEn schimb rezultatele pentru [DIFFERENT_TERM]",search_suggestion:"Niciun rezultat pentru [SEARCH_TERM]. \xCEncerca\u021Bi una dintre urm\u0103toarele c\u0103ut\u0103ri:",searching:"Se caut\u0103 dup\u0103: [SEARCH_TERM]...",results_label:"Rezultatele c\u0103ut\u0103rii",keyboard_navigate:"navigare",keyboard_select:"selectare",keyboard_clear:"\u0219tergere",keyboard_close:"\xEEnchidere",keyboard_search:"c\u0103utare",error_search:"C\u0103utarea a e\u0219uat",filter_selected_one:"[COUNT] selectat",filter_selected_many:"[COUNT] selectate",input_hint:"Rezultatele vor ap\u0103rea pe m\u0103sur\u0103 ce tasta\u021Bi",loading:"Se \xEEncarc\u0103"},nr={thanks_to:lr,comments:sr,direction:ar,strings:ir};var gl={};Z(gl,{comments:()=>gr,default:()=>Cr,direction:()=>cr,strings:()=>or,thanks_to:()=>rr});var rr="Aleksandr Gordeev",gr="",cr="ltr",or={placeholder:"\u041F\u043E\u0438\u0441\u043A",clear_search:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u043F\u043E\u043B\u0435",load_more:"\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0449\u0435",search_label:"\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u0441\u0430\u0439\u0442\u0443",filters_label:"\u0424\u0438\u043B\u044C\u0442\u0440\u044B",zero_results:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432 \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",total_zero_results:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E",total_one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442",total_many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432",alt_search:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]. \u041F\u043E\u043A\u0430\u0437\u0430\u043D\u044B \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [DIFFERENT_TERM]",search_suggestion:"\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043E\u0434\u0438\u043D \u0438\u0437 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u0432",searching:"\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0443: [SEARCH_TERM]",results_label:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043F\u043E\u0438\u0441\u043A\u0430",keyboard_navigate:"\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044F",keyboard_select:"\u0432\u044B\u0431\u0440\u0430\u0442\u044C",keyboard_clear:"\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",keyboard_close:"\u0437\u0430\u043A\u0440\u044B\u0442\u044C",keyboard_search:"\u043F\u043E\u0438\u0441\u043A",error_search:"\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u043E\u0438\u0441\u043A\u0430",filter_selected_one:"[COUNT] \u0432\u044B\u0431\u0440\u0430\u043D",filter_selected_many:"[COUNT] \u0432\u044B\u0431\u0440\u0430\u043D\u043E",input_hint:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u044F\u0432\u043B\u044F\u0442\u044C\u0441\u044F \u043F\u043E \u043C\u0435\u0440\u0435 \u0432\u0432\u043E\u0434\u0430",loading:"\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430"},Cr={thanks_to:rr,comments:gr,direction:cr,strings:or};var cl={};Z(cl,{comments:()=>Ir,default:()=>Qr,direction:()=>dr,strings:()=>Ar,thanks_to:()=>ur});var ur="Andrija Sagicc",Ir="",dr="ltr",Ar={placeholder:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430",clear_search:"\u0411\u0440\u0438\u0441\u0430\u045A\u0435",load_more:"\u041F\u0440\u0438\u043A\u0430\u0437 \u0432\u0438\u0448\u0435 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430",search_label:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u0441\u0430\u0458\u0442\u0430",filters_label:"\u0424\u0438\u043B\u0442\u0435\u0440\u0438",zero_results:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]",total_zero_results:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430",total_one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442",total_many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430",alt_search:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]. \u041F\u0440\u0438\u043A\u0430\u0437 \u0434\u043E\u0434\u0430\u0442\u043D\u0438\u043A \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [DIFFERENT_TERM]",search_suggestion:"\u041D\u0435\u043C\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u0437\u0430 [SEARCH_TERM]. \u041F\u043E\u043A\u0443\u0448\u0430\u0458\u0442\u0435 \u0441\u0430 \u043D\u0435\u043A\u043E\u043C \u043E\u0434 \u0441\u043B\u0435\u0434\u0435\u045B\u0438\u0445 \u043F\u0440\u0435\u0442\u0440\u0430\u0433\u0430:",searching:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u0442\u0435\u0440\u043C\u0438\u043D\u0430 [SEARCH_TERM]...",results_label:"\u0420\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0438 \u043F\u0440\u0435\u0442\u0440\u0430\u0433\u0435",keyboard_navigate:"\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0458\u0430",keyboard_select:"\u0438\u0437\u0430\u0431\u0435\u0440\u0438",keyboard_clear:"\u043E\u0431\u0440\u0438\u0448\u0438",keyboard_close:"\u0437\u0430\u0442\u0432\u043E\u0440\u0438",keyboard_search:"\u043F\u0440\u0435\u0442\u0440\u0430\u0433\u0430",error_search:"\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u0430",filter_selected_one:"[COUNT] \u0438\u0437\u0430\u0431\u0440\u0430\u043D",filter_selected_many:"[COUNT] \u0438\u0437\u0430\u0431\u0440\u0430\u043D\u0438\u0445",input_hint:"\u0420\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0438 \u045B\u0435 \u0441\u0435 \u043F\u043E\u0458\u0430\u0432\u0459\u0438\u0432\u0430\u0442\u0438 \u0434\u043E\u043A \u043A\u0443\u0446\u0430\u0442\u0435",loading:"\u0423\u0447\u0438\u0442\u0430\u0432\u0430\u045A\u0435"},Qr={thanks_to:ur,comments:Ir,direction:dr,strings:Ar};var ol={};Z(ol,{comments:()=>br,default:()=>Br,direction:()=>mr,strings:()=>Fr,thanks_to:()=>_r});var _r="Montazar Al-Jaber ",br="",mr="ltr",Fr={placeholder:"S\xF6k",clear_search:"Rensa",load_more:"Visa fler tr\xE4ffar",search_label:"S\xF6k p\xE5 denna sida",filters_label:"Filter",zero_results:"[SEARCH_TERM] gav inga tr\xE4ffar",many_results:"[SEARCH_TERM] gav [COUNT] tr\xE4ffar",one_result:"[SEARCH_TERM] gav [COUNT] tr\xE4ff",total_zero_results:"Inga tr\xE4ffar",total_one_result:"[COUNT] tr\xE4ff",total_many_results:"[COUNT] tr\xE4ffar",alt_search:"[SEARCH_TERM] gav inga tr\xE4ffar. Visar resultat f\xF6r [DIFFERENT_TERM] ist\xE4llet",search_suggestion:"[SEARCH_TERM] gav inga tr\xE4ffar. F\xF6rs\xF6k igen med en av f\xF6ljande s\xF6kord:",searching:"S\xF6ker efter [SEARCH_TERM]...",results_label:"S\xF6kresultat",keyboard_navigate:"navigera",keyboard_select:"v\xE4lj",keyboard_clear:"rensa",keyboard_close:"st\xE4ng",keyboard_search:"s\xF6k",error_search:"S\xF6kningen misslyckades",filter_selected_one:"[COUNT] vald",filter_selected_many:"[COUNT] valda",input_hint:"Resultat visas medan du skriver",loading:"L\xE4ser in"},Br={thanks_to:_r,comments:br,direction:mr,strings:Fr};var Cl={};Z(Cl,{comments:()=>hr,default:()=>Zr,direction:()=>Ur,strings:()=>pr,thanks_to:()=>fr});var fr="Anonymous",hr="",Ur="ltr",pr={placeholder:"Tafuta",clear_search:"Futa",load_more:"Pakia matokeo zaidi",search_label:"Tafuta tovuti hii",filters_label:"Vichujio",zero_results:"Hakuna matokeo ya [SEARCH_TERM]",many_results:"Matokeo [COUNT] ya [SEARCH_TERM]",one_result:"Tokeo [COUNT] la [SEARCH_TERM]",total_zero_results:"Hakuna matokeo",total_one_result:"Tokeo [COUNT]",total_many_results:"Matokeo [COUNT]",alt_search:"Hakuna mayokeo ya [SEARCH_TERM]. Badala yake, inaonyesha matokeo ya [DIFFERENT_TERM]",search_suggestion:"Hakuna matokeo ya [SEARCH_TERM]. Jaribu mojawapo ya utafutaji ufuatao:",searching:"Kutafuta [SEARCH_TERM]...",results_label:"Matokeo ya utafutaji",keyboard_navigate:"sogeza",keyboard_select:"chagua",keyboard_clear:"futa",keyboard_close:"funga",keyboard_search:"tafuta",error_search:"Utafutaji umeshindwa",filter_selected_one:"[COUNT] imechaguliwa",filter_selected_many:"[COUNT] zimechaguliwa",input_hint:"Matokeo yataonekana unapoandika",loading:"Inapakia"},Zr={thanks_to:fr,comments:hr,direction:Ur,strings:pr};var ul={};Z(ul,{comments:()=>xr,default:()=>Xr,direction:()=>Gr,strings:()=>Nr,thanks_to:()=>yr});var yr="",xr="",Gr="ltr",Nr={placeholder:"\u0BA4\u0BC7\u0B9F\u0BC1\u0B95",clear_search:"\u0B85\u0BB4\u0BBF\u0B95\u0BCD\u0B95\u0BC1\u0B95",load_more:"\u0BAE\u0BC7\u0BB2\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BC8\u0B95\u0BCD \u0B95\u0BBE\u0B9F\u0BCD\u0B9F\u0BC1\u0B95",search_label:"\u0B87\u0BA8\u0BCD\u0BA4 \u0BA4\u0BB3\u0BA4\u0BCD\u0BA4\u0BBF\u0BB2\u0BCD \u0BA4\u0BC7\u0B9F\u0BC1\u0B95",filters_label:"\u0BB5\u0B9F\u0BBF\u0B95\u0B9F\u0BCD\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BCD",zero_results:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8",many_results:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 [COUNT] \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD",one_result:"[SEARCH_TERM] \u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1",total_zero_results:"\u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8",total_one_result:"[COUNT] \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1",total_many_results:"[COUNT] \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD",alt_search:"[SEARCH_TERM] \u0B87\u0BA4\u0BCD\u0BA4\u0BC7\u0B9F\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8, \u0B87\u0BA8\u0BCD\u0BA4 \u0BA4\u0BC7\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B92\u0BA4\u0BCD\u0BA4 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD [DIFFERENT_TERM]",search_suggestion:"[SEARCH_TERM] \u0B87\u0BA4\u0BCD \u0BA4\u0BC7\u0B9F\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8.\u0B87\u0BA4\u0BB1\u0BCD\u0B95\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC0\u0B9F\u0BBE\u0BA9 \u0BA4\u0BC7\u0B9F\u0BB2\u0BCD\u0B95\u0BB3\u0BC8 \u0BA4\u0BC7\u0B9F\u0BC1\u0B95:",searching:"[SEARCH_TERM] \u0BA4\u0BC7\u0B9F\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0B95\u0BBF\u0BA9\u0BCD\u0BB1\u0BA4\u0BC1",results_label:"\u0BA4\u0BC7\u0B9F\u0BB2\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD",keyboard_navigate:"\u0BB5\u0BB4\u0BBF\u0BA8\u0B9F\u0BA4\u0BCD\u0BA4\u0BC1",keyboard_select:"\u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1",keyboard_clear:"\u0B85\u0BB4\u0BBF",keyboard_close:"\u0BAE\u0BC2\u0B9F\u0BC1",keyboard_search:"\u0BA4\u0BC7\u0B9F\u0BC1",error_search:"\u0BA4\u0BC7\u0B9F\u0BB2\u0BCD \u0BA4\u0BCB\u0BB2\u0BCD\u0BB5\u0BBF",filter_selected_one:"[COUNT] \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1",filter_selected_many:"[COUNT] \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA9",input_hint:"\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BA4\u0B9F\u0BCD\u0B9F\u0B9A\u0BCD\u0B9A\u0BC1 \u0B9A\u0BC6\u0BAF\u0BCD\u0BAF\u0BC1\u0BAE\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0BA4\u0BCB\u0BA9\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD",loading:"\u0B8F\u0BB1\u0BCD\u0BB1\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1"},Xr={thanks_to:yr,comments:xr,direction:Gr,strings:Nr};var Il={};Z(Il,{comments:()=>kr,default:()=>Wr,direction:()=>Lr,strings:()=>Rr,thanks_to:()=>Er});var Er="Patiphon Loetsuthakun ",kr="",Lr="ltr",Rr={placeholder:"\u0E04\u0E49\u0E19\u0E2B\u0E32",clear_search:"\u0E25\u0E49\u0E32\u0E07",load_more:"\u0E42\u0E2B\u0E25\u0E14\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E40\u0E15\u0E34\u0E21",search_label:"\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E1A\u0E19\u0E40\u0E27\u0E47\u0E1A\u0E44\u0E0B\u0E15\u0E4C",filters_label:"\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07",zero_results:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",many_results:"\u0E1E\u0E1A [COUNT] \u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",one_result:"\u0E1E\u0E1A [COUNT] \u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM]",total_zero_results:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C",total_one_result:"[COUNT] \u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C",total_many_results:"[COUNT] \u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C",alt_search:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM] \u0E41\u0E2A\u0E14\u0E07\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E08\u0E32\u0E01\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32 [DIFFERENT_TERM] \u0E41\u0E17\u0E19",search_suggestion:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A [SEARCH_TERM] \u0E25\u0E2D\u0E07\u0E04\u0E33\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E40\u0E2B\u0E25\u0E48\u0E32\u0E19\u0E35\u0E49\u0E41\u0E17\u0E19:",searching:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E04\u0E49\u0E19\u0E2B\u0E32 [SEARCH_TERM]...",results_label:"\u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32",keyboard_navigate:"\u0E19\u0E33\u0E17\u0E32\u0E07",keyboard_select:"\u0E40\u0E25\u0E37\u0E2D\u0E01",keyboard_clear:"\u0E25\u0E49\u0E32\u0E07",keyboard_close:"\u0E1B\u0E34\u0E14",keyboard_search:"\u0E04\u0E49\u0E19\u0E2B\u0E32",error_search:"\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27",filter_selected_one:"\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27 [COUNT] \u0E23\u0E32\u0E22\u0E01\u0E32\u0E23",filter_selected_many:"\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27 [COUNT] \u0E23\u0E32\u0E22\u0E01\u0E32\u0E23",input_hint:"\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C\u0E08\u0E30\u0E1B\u0E23\u0E32\u0E01\u0E0F\u0E02\u0E13\u0E30\u0E17\u0E35\u0E48\u0E04\u0E38\u0E13\u0E1E\u0E34\u0E21\u0E1E\u0E4C",loading:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14"},Wr={thanks_to:Er,comments:kr,direction:Lr,strings:Rr};var dl={};Z(dl,{comments:()=>Vr,default:()=>vr,direction:()=>Dr,strings:()=>Tr,thanks_to:()=>Sr});var Sr="Taylan \xD6zg\xFCr Bildik",Vr="",Dr="ltr",Tr={placeholder:"Ara\u015Ft\u0131r",clear_search:"Temizle",load_more:"Daha fazla sonu\xE7",search_label:"Site genelinde arama",filters_label:"Filtreler",zero_results:"[SEARCH_TERM] i\xE7in sonu\xE7 yok",many_results:"[SEARCH_TERM] i\xE7in [COUNT] sonu\xE7 bulundu",one_result:"[SEARCH_TERM] i\xE7in [COUNT] sonu\xE7 bulundu",total_zero_results:"Sonu\xE7 yok",total_one_result:"[COUNT] sonu\xE7",total_many_results:"[COUNT] sonu\xE7",alt_search:"[SEARCH_TERM] i\xE7in sonu\xE7 yok. Bunun yerine [DIFFERENT_TERM] i\xE7in sonu\xE7lar g\xF6steriliyor",search_suggestion:"[SEARCH_TERM] i\xE7in sonu\xE7 yok. Alternatif olarak a\u015Fa\u011F\u0131daki kelimelerden birini deneyebilirsiniz:",searching:"[SEARCH_TERM] ara\u015Ft\u0131r\u0131l\u0131yor...",results_label:"Arama sonu\xE7lar\u0131",keyboard_navigate:"gezin",keyboard_select:"se\xE7",keyboard_clear:"temizle",keyboard_close:"kapat",keyboard_search:"ara",error_search:"Arama ba\u015Far\u0131s\u0131z",filter_selected_one:"[COUNT] se\xE7ili",filter_selected_many:"[COUNT] se\xE7ili",input_hint:"Sonu\xE7lar siz yazarken g\xF6r\xFCnecektir",loading:"Y\xFCkleniyor"},vr={thanks_to:Sr,comments:Vr,direction:Dr,strings:Tr};var Al={};Z(Al,{comments:()=>Yr,default:()=>zr,direction:()=>Mr,strings:()=>wr,thanks_to:()=>Hr});var Hr="Vladyslav Lyshenko ",Yr="",Mr="ltr",wr={placeholder:"\u041F\u043E\u0448\u0443\u043A",clear_search:"\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u043F\u043E\u043B\u0435",load_more:"\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0449\u0435",search_label:"\u041F\u043E\u0448\u0443\u043A \u043F\u043E \u0441\u0430\u0439\u0442\u0443",filters_label:"\u0424\u0456\u043B\u044C\u0442\u0440\u0438",zero_results:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0456\u0432 \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]",one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",total_zero_results:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E",total_one_result:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442",total_many_results:"[COUNT] \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0456\u0432",alt_search:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]. \u041F\u043E\u043A\u0430\u0437\u0430\u043D\u043E \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0438 \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [DIFFERENT_TERM]",search_suggestion:"\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E \u043D\u0430 \u0437\u0430\u043F\u0438\u0442: [SEARCH_TERM]. \u0421\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043E\u0434\u0438\u043D \u0456\u0437 \u0442\u0430\u043A\u0438\u0445 \u0432\u0430\u0440\u0456\u0430\u043D\u0442\u0456\u0432",searching:"\u041F\u043E\u0448\u0443\u043A \u0437\u0430 \u0437\u0430\u043F\u0438\u0442\u043E\u043C: [SEARCH_TERM]",results_label:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0438 \u043F\u043E\u0448\u0443\u043A\u0443",keyboard_navigate:"\u043D\u0430\u0432\u0456\u0433\u0430\u0446\u0456\u044F",keyboard_select:"\u0432\u0438\u0431\u0440\u0430\u0442\u0438",keyboard_clear:"\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u0438",keyboard_close:"\u0437\u0430\u043A\u0440\u0438\u0442\u0438",keyboard_search:"\u043F\u043E\u0448\u0443\u043A",error_search:"\u041F\u043E\u043C\u0438\u043B\u043A\u0430 \u043F\u043E\u0448\u0443\u043A\u0443",filter_selected_one:"[COUNT] \u0432\u0438\u0431\u0440\u0430\u043D\u043E",filter_selected_many:"[COUNT] \u0432\u0438\u0431\u0440\u0430\u043D\u043E",input_hint:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0438 \u0437'\u044F\u0432\u043B\u044F\u0442\u0438\u043C\u0443\u0442\u044C\u0441\u044F \u043F\u0456\u0434 \u0447\u0430\u0441 \u0432\u0432\u0435\u0434\u0435\u043D\u043D\u044F",loading:"\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F"},zr={thanks_to:Hr,comments:Yr,direction:Mr,strings:wr};var Ql={};Z(Ql,{comments:()=>Or,default:()=>Pr,direction:()=>jr,strings:()=>Kr,thanks_to:()=>Jr});var Jr="Long Nhat Nguyen",Or="",jr="ltr",Kr={placeholder:"T\xECm ki\u1EBFm",clear_search:"X\xF3a",load_more:"Nhi\u1EC1u k\u1EBFt qu\u1EA3 h\u01A1n",search_label:"T\xECm ki\u1EBFm trong trang n\xE0y",filters_label:"B\u1ED9 l\u1ECDc",zero_results:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",many_results:"[COUNT] k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",one_result:"[COUNT] k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]",total_zero_results:"Kh\xF4ng c\xF3 k\u1EBFt qu\u1EA3",total_one_result:"[COUNT] k\u1EBFt qu\u1EA3",total_many_results:"[COUNT] k\u1EBFt qu\u1EA3",alt_search:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]. Ki\u1EC3m th\u1ECB k\u1EBFt qu\u1EA3 thay th\u1EBF v\u1EDBi [DIFFERENT_TERM]",search_suggestion:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3 cho [SEARCH_TERM]. Th\u1EED m\u1ED9t trong c\xE1c t\xECm ki\u1EBFm:",searching:"\u0110ang t\xECm ki\u1EBFm cho [SEARCH_TERM]...",results_label:"K\u1EBFt qu\u1EA3 t\xECm ki\u1EBFm",keyboard_navigate:"chuy\u1EC3n",keyboard_select:"ch\u1ECDn",keyboard_clear:"x\xF3a",keyboard_close:"\u0111\xF3ng",keyboard_search:"t\xECm ki\u1EBFm",error_search:"T\xECm ki\u1EBFm th\u1EA5t b\u1EA1i",filter_selected_one:"\u0110\xE3 ch\u1ECDn [COUNT]",filter_selected_many:"\u0110\xE3 ch\u1ECDn [COUNT]",input_hint:"K\u1EBFt qu\u1EA3 s\u1EBD xu\u1EA5t hi\u1EC7n khi b\u1EA1n nh\u1EADp",loading:"\u0110ang t\u1EA3i"},Pr={thanks_to:Jr,comments:Or,direction:jr,strings:Kr};var _l={};Z(_l,{comments:()=>$r,default:()=>lg,direction:()=>eg,strings:()=>tg,thanks_to:()=>qr});var qr="Amber Song",$r="",eg="ltr",tg={placeholder:"\u641C\u7D22",clear_search:"\u6E05\u9664",load_more:"\u52A0\u8F7D\u66F4\u591A\u7ED3\u679C",search_label:"\u7AD9\u5185\u641C\u7D22",filters_label:"\u7B5B\u9009",zero_results:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",many_results:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",one_result:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",total_zero_results:"\u65E0\u7ED3\u679C",total_one_result:"[COUNT] \u4E2A\u7ED3\u679C",total_many_results:"[COUNT] \u4E2A\u7ED3\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u6539\u4E3A\u663E\u793A [DIFFERENT_TERM] \u7684\u76F8\u5173\u7ED3\u679C",search_suggestion:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u8BF7\u5C1D\u8BD5\u4EE5\u4E0B\u641C\u7D22\u3002",searching:"\u6B63\u5728\u641C\u7D22 [SEARCH_TERM]...",results_label:"\u641C\u7D22\u7ED3\u679C",keyboard_navigate:"\u5BFC\u822A",keyboard_select:"\u9009\u62E9",keyboard_clear:"\u6E05\u9664",keyboard_close:"\u5173\u95ED",keyboard_search:"\u641C\u7D22",error_search:"\u641C\u7D22\u5931\u8D25",filter_selected_one:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",filter_selected_many:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",input_hint:"\u8F93\u5165\u65F6\u5C06\u663E\u793A\u7ED3\u679C",loading:"\u52A0\u8F7D\u4E2D"},lg={thanks_to:qr,comments:$r,direction:eg,strings:tg};var bl={};Z(bl,{comments:()=>ag,default:()=>rg,direction:()=>ig,strings:()=>ng,thanks_to:()=>sg});var sg="Amber Song",ag="",ig="ltr",ng={placeholder:"\u641C\u5C0B",clear_search:"\u6E05\u9664",load_more:"\u8F09\u5165\u66F4\u591A\u7D50\u679C",search_label:"\u7AD9\u5167\u641C\u5C0B",filters_label:"\u7BE9\u9078",zero_results:"\u627E\u4E0D\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",many_results:"\u627E\u5230 [COUNT] \u500B [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",one_result:"\u627E\u5230 [COUNT] \u500B [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C",total_zero_results:"\u7121\u7D50\u679C",total_one_result:"[COUNT] \u500B\u7D50\u679C",total_many_results:"[COUNT] \u500B\u7D50\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C\u3002\u6539\u70BA\u986F\u793A [DIFFERENT_TERM] \u7684\u76F8\u95DC\u7D50\u679C",search_suggestion:"\u627E\u4E0D\u5230 [SEARCH_TERM] \u7684\u76F8\u95DC\u7D50\u679C\u3002\u8ACB\u5617\u8A66\u4EE5\u4E0B\u7684\u5EFA\u8B70\u4E4B\u4E00\u3002",searching:"\u6B63\u5728\u641C\u5C0B[SEARCH_TERM]...",results_label:"\u641C\u5C0B\u7D50\u679C",keyboard_navigate:"\u5C0E\u89BD",keyboard_select:"\u9078\u64C7",keyboard_clear:"\u6E05\u9664",keyboard_close:"\u95DC\u9589",keyboard_search:"\u641C\u5C0B",error_search:"\u641C\u5C0B\u5931\u6557",filter_selected_one:"\u5DF2\u9078\u64C7 [COUNT] \u500B",filter_selected_many:"\u5DF2\u9078\u64C7 [COUNT] \u500B",input_hint:"\u8F38\u5165\u6642\u5C07\u986F\u793A\u7D50\u679C",loading:"\u8F09\u5165\u4E2D"},rg={thanks_to:sg,comments:ag,direction:ig,strings:ng};var ml={};Z(ml,{comments:()=>cg,default:()=>ug,direction:()=>og,strings:()=>Cg,thanks_to:()=>gg});var gg="Amber Song",cg="",og="ltr",Cg={placeholder:"\u641C\u7D22",clear_search:"\u6E05\u9664",load_more:"\u52A0\u8F7D\u66F4\u591A\u7ED3\u679C",search_label:"\u7AD9\u5185\u641C\u7D22",filters_label:"\u7B5B\u9009",zero_results:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",many_results:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",one_result:"\u627E\u5230 [COUNT] \u4E2A [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C",total_zero_results:"\u65E0\u7ED3\u679C",total_one_result:"[COUNT] \u4E2A\u7ED3\u679C",total_many_results:"[COUNT] \u4E2A\u7ED3\u679C",alt_search:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u6539\u4E3A\u663E\u793A [DIFFERENT_TERM] \u7684\u76F8\u5173\u7ED3\u679C",search_suggestion:"\u672A\u627E\u5230 [SEARCH_TERM] \u7684\u76F8\u5173\u7ED3\u679C\u3002\u8BF7\u5C1D\u8BD5\u4EE5\u4E0B\u641C\u7D22\u3002",searching:"\u6B63\u5728\u641C\u7D22 [SEARCH_TERM]...",results_label:"\u641C\u7D22\u7ED3\u679C",keyboard_navigate:"\u5BFC\u822A",keyboard_select:"\u9009\u62E9",keyboard_clear:"\u6E05\u9664",keyboard_close:"\u5173\u95ED",keyboard_search:"\u641C\u7D22",error_search:"\u641C\u7D22\u5931\u8D25",filter_selected_one:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",filter_selected_many:"\u5DF2\u9009\u62E9 [COUNT] \u4E2A",input_hint:"\u8F93\u5165\u65F6\u5C06\u663E\u793A\u7ED3\u679C",loading:"\u52A0\u8F7D\u4E2D"},ug={thanks_to:gg,comments:cg,direction:og,strings:Cg};var Ig=[Nt,Xt,Et,kt,Lt,Rt,Wt,St,Vt,Dt,Tt,vt,Ht,Yt,Mt,wt,zt,Jt,Ot,jt,Kt,Pt,qt,$t,el,tl,ll,sl,al,il,nl,rl,gl,cl,ol,Cl,ul,Il,dl,Al,Ql,_l,bl,ml],Qs=Ig,_s=["../../translations/af.json","../../translations/ar.json","../../translations/bn.json","../../translations/ca.json","../../translations/cs.json","../../translations/da.json","../../translations/de.json","../../translations/el.json","../../translations/en.json","../../translations/es.json","../../translations/eu.json","../../translations/fa.json","../../translations/fi.json","../../translations/fr.json","../../translations/gl.json","../../translations/he.json","../../translations/hi.json","../../translations/hr.json","../../translations/hu.json","../../translations/id.json","../../translations/it.json","../../translations/ja.json","../../translations/ko.json","../../translations/mi.json","../../translations/my.json","../../translations/nb.json","../../translations/nl.json","../../translations/nn.json","../../translations/no.json","../../translations/pl.json","../../translations/pt.json","../../translations/ro.json","../../translations/ru.json","../../translations/sr.json","../../translations/sv.json","../../translations/sw.json","../../translations/ta.json","../../translations/th.json","../../translations/tr.json","../../translations/uk.json","../../translations/vi.json","../../translations/zh-cn.json","../../translations/zh-tw.json","../../translations/zh.json"];function bs(l,e,t){let s=l.slice();return s[53]=e[t],s}function ms(l){let e,t,s;function a(n){l[38](n)}let i={show_empty_filters:l[5],open_filters:l[6],available_filters:l[18],translate:l[20],automatic_translations:l[19],translations:l[7]};return l[0]!==void 0&&(i.selected_filters=l[0]),e=new As({props:i}),ie.push(()=>Dl(e,"selected_filters",a)),{c(){ot(e.$$.fragment)},m(n,r){de(e,n,r),s=!0},p(n,r){let g={};r[0]&32&&(g.show_empty_filters=n[5]),r[0]&64&&(g.open_filters=n[6]),r[0]&262144&&(g.available_filters=n[18]),r[0]&524288&&(g.automatic_translations=n[19]),r[0]&128&&(g.translations=n[7]),!t&&r[0]&1&&(t=!0,g.selected_filters=n[0],Rl(()=>t=!1)),e.$set(g)},i(n){s||(S(e.$$.fragment,n),s=!0)},o(n){D(e.$$.fragment,n),s=!1},d(n){ce(e,n)}}}function Fs(l){let e,t,s,a,i=[Qg,Ag],n=[];function r(g,I){return g[14]?0:1}return t=r(l,[-1,-1]),s=n[t]=i[t](l),{c(){e=B("div"),s.c(),_(e,"class","pagefind-ui__results-area svelte-e9gkc3")},m(g,I){p(g,e,I),n[t].m(e,null),a=!0},p(g,I){let o=t;t=r(g,I),t===o?n[t].p(g,I):(re(),D(n[o],1,1,()=>{n[o]=null}),ge(),s=n[t],s?s.p(g,I):(s=n[t]=i[t](g),s.c()),S(s,1),s.m(e,null))},i(g){a||(S(s),a=!0)},o(g){D(s),a=!1},d(g){g&&U(e),n[t].d()}}}function Ag(l){let e,t,s,a=[],i=new Map,n,r,g;function I(u,b){return u[13].results.length===0?mg:u[13].results.length===1?bg:_g}let o=I(l,[-1,-1]),A=o(l),C=l[13].results.slice(0,l[17]),d=u=>u[53].id;for(let u=0;ul[17]&&fs(l);return{c(){e=B("p"),A.c(),t=x(),s=B("ol");for(let u=0;uu[17]?c?c.p(u,b):(c=fs(u),c.c(),c.m(r.parentNode,r)):c&&(c.d(1),c=null)},i(u){if(!g){for(let b=0;b{g[C]=null}),ge(),a=g[s],a?a.p(e,A):(a=g[s]=r[s](e),a.c()),S(a,1),a.m(i.parentNode,i))},i(o){n||(S(a),n=!0)},o(o){D(a),n=!1},d(o){o&&U(t),g[s].d(o),o&&U(i)}}}function fs(l){let e,t=l[20]("load_more",l[19],l[7])+"",s,a,i;return{c(){e=B("button"),s=G(t),_(e,"type","button"),_(e,"class","pagefind-ui__button svelte-e9gkc3")},m(n,r){p(n,e,r),m(e,s),a||(i=J(e,"click",l[22]),a=!0)},p(n,r){r[0]&524416&&t!==(t=n[20]("load_more",n[19],n[7])+"")&&L(s,t)},d(n){n&&U(e),a=!1,i()}}}function hs(l){let e,t=l[20]("searching",l[19],l[7]).replace(/\[SEARCH_TERM\]/,l[16])+"",s;return{c(){e=B("p"),s=G(t),_(e,"class","pagefind-ui__message svelte-e9gkc3")},m(a,i){p(a,e,i),m(e,s)},p(a,i){i[0]&589952&&t!==(t=a[20]("searching",a[19],a[7]).replace(/\[SEARCH_TERM\]/,a[16])+"")&&L(s,t)},d(a){a&&U(e)}}}function fg(l){let e,t,s,a,i,n,r,g=l[20]("clear_search",l[19],l[7])+"",I,o,A,C,d,c,u,b,F=l[12]&&ms(l),f=l[15]&&Fs(l);return{c(){e=B("div"),t=B("form"),s=B("input"),n=x(),r=B("button"),I=G(g),o=x(),A=B("div"),F&&F.c(),C=x(),f&&f.c(),_(s,"class","pagefind-ui__search-input svelte-e9gkc3"),_(s,"type","text"),_(s,"placeholder",a=l[20]("placeholder",l[19],l[7])),_(s,"title",i=l[20]("placeholder",l[19],l[7])),_(s,"autocapitalize","none"),_(s,"enterkeyhint","search"),s.autofocus=l[8],_(r,"class","pagefind-ui__search-clear svelte-e9gkc3"),Y(r,"pagefind-ui__suppressed",!l[9]),_(A,"class","pagefind-ui__drawer svelte-e9gkc3"),Y(A,"pagefind-ui__hidden",!l[15]),_(t,"class","pagefind-ui__form svelte-e9gkc3"),_(t,"role","search"),_(t,"aria-label",d=l[20]("search_label",l[19],l[7])),_(t,"action","javascript:void(0);"),_(e,"class","pagefind-ui svelte-e9gkc3"),Y(e,"pagefind-ui--reset",l[1])},m(h,y){p(h,e,y),m(e,t),m(t,s),ht(s,l[9]),l[35](s),m(t,n),m(t,r),m(r,I),l[36](r),m(t,o),m(t,A),F&&F.m(A,null),m(A,C),f&&f.m(A,null),c=!0,l[8]&&s.focus(),u||(b=[J(s,"focus",l[21]),J(s,"keydown",l[33]),J(s,"input",l[34]),J(r,"click",l[37]),J(t,"submit",hg)],u=!0)},p(h,y){(!c||y[0]&524416&&a!==(a=h[20]("placeholder",h[19],h[7])))&&_(s,"placeholder",a),(!c||y[0]&524416&&i!==(i=h[20]("placeholder",h[19],h[7])))&&_(s,"title",i),(!c||y[0]&256)&&(s.autofocus=h[8]),y[0]&512&&s.value!==h[9]&&ht(s,h[9]),(!c||y[0]&524416)&&g!==(g=h[20]("clear_search",h[19],h[7])+"")&&L(I,g),(!c||y[0]&512)&&Y(r,"pagefind-ui__suppressed",!h[9]),h[12]?F?(F.p(h,y),y[0]&4096&&S(F,1)):(F=ms(h),F.c(),S(F,1),F.m(A,C)):F&&(re(),D(F,1,1,()=>{F=null}),ge()),h[15]?f?(f.p(h,y),y[0]&32768&&S(f,1)):(f=Fs(h),f.c(),S(f,1),f.m(A,null)):f&&(re(),D(f,1,1,()=>{f=null}),ge()),(!c||y[0]&32768)&&Y(A,"pagefind-ui__hidden",!h[15]),(!c||y[0]&524416&&d!==(d=h[20]("search_label",h[19],h[7])))&&_(t,"aria-label",d),(!c||y[0]&2)&&Y(e,"pagefind-ui--reset",h[1])},i(h){c||(S(F),S(f),c=!0)},o(h){D(F),D(f),c=!1},d(h){h&&U(e),l[35](null),l[36](null),F&&F.d(),f&&f.d(),u=!1,w(b)}}}var hg=l=>l.preventDefault();function Ug(l,e,t){let s={},a=_s.map(Q=>Q.match(/([^\/]+)\.json$/)[1]);for(let Q=0;Qk[Q]??X[Q]??"",yl=Q=>{if(!K)return;let X=document.activeElement,k=X&&(X.tagName==="INPUT"||X.tagName==="TEXTAREA"||X.isContentEditable);Q.key==="/"&&!k&&(Q.preventDefault(),T?.focus())};Ut(()=>{let Q=document?.querySelector?.("html")?.getAttribute?.("lang")||"en",X=Ct(Q.toLocaleLowerCase());t(19,Zl=s[`${X.language}-${X.script}-${X.region}`]||s[`${X.language}-${X.region}`]||s[`${X.language}`]||s.en),K&&document.addEventListener("keydown",yl)}),pt(()=>{E?.destroy?.(),E=null,K&&document.removeEventListener("keydown",yl)});let xl=async()=>{if(!It&&(t(12,It=!0),!E)){let Q;try{Q=await import(`${i}pagefind.js`)}catch(k){console.error(k),console.error([`Pagefind couldn't be loaded from ${this.options.bundlePath}pagefind.js`,"You can configure this by passing a bundlePath option to PagefindUI"].join(` -`)),document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?console.error(`[DEBUG: Loaded from ${document.currentScript.src??"bad script location"}]`):console.error("no known script location")}o||t(24,o=I?12:30);let X={...b||{},excerptLength:o};await Q.options(X);for(let k of F){if(!k.bundlePath)throw new Error("mergeIndex requires a bundlePath parameter");let v=k.bundlePath;delete k.bundlePath,await Q.mergeIndex(v,k)}E=Q,ys()}},ys=async()=>{E&&(pl=await E.filters(),(!oe||!Object.keys(oe).length)&&t(18,oe=pl))},xs=Q=>{let X={};return Object.entries(Q).filter(([,k])=>k).forEach(([k])=>{let[v,te]=k.split(/:(.*)$/);X[v]=X[v]||[],X[v].push(te)}),X},Ce,Gs=async(Q,X)=>{if(!Q){t(15,At=!1),Ce&&clearTimeout(Ce);return}let k=xs(X),v=()=>Ns(Q,k);u>0&&Q?(Ce&&clearTimeout(Ce),Ce=setTimeout(v,u),await Gl(),E.preload(Q,{filters:k})):v(),Xs()},Gl=async()=>{for(;!E;)xl(),await new Promise(Q=>setTimeout(Q,50))},Ns=async(Q,X)=>{t(16,Ul=Q||""),typeof C=="function"&&(Q=C(Q)),t(14,dt=!0),t(15,At=!0),await Gl();let k=++hl,v={filters:X};M&&typeof M=="object"&&(v.sort=M);let te=await E.search(Q,v);hl===k&&(te.filters&&Object.keys(te.filters)?.length&&t(18,oe=te.filters),t(13,fl=te),t(14,dt=!1),t(17,Qt=n))},Xs=()=>{let Q=it.offsetWidth;Q!=ps&&t(10,T.style.paddingRight=`${Q+2}px`,T)},Es=Q=>{Q?.preventDefault(),t(17,Qt+=n)},ks=Q=>{Q.key==="Escape"&&(t(9,R=""),T.blur()),Q.key==="Enter"&&Q.preventDefault()};function Ls(){R=this.value,t(9,R),t(23,f)}function Rs(Q){ie[Q?"unshift":"push"](()=>{T=Q,t(10,T)})}function Ws(Q){ie[Q?"unshift":"push"](()=>{it=Q,t(11,it)})}let Ss=()=>{t(9,R=""),T.blur()};function Vs(Q){N=Q,t(0,N)}return l.$$set=Q=>{"base_path"in Q&&t(25,i=Q.base_path),"page_size"in Q&&t(26,n=Q.page_size),"reset_styles"in Q&&t(1,r=Q.reset_styles),"show_images"in Q&&t(2,g=Q.show_images),"show_sub_results"in Q&&t(3,I=Q.show_sub_results),"excerpt_length"in Q&&t(24,o=Q.excerpt_length),"process_result"in Q&&t(4,A=Q.process_result),"process_term"in Q&&t(27,C=Q.process_term),"show_empty_filters"in Q&&t(5,d=Q.show_empty_filters),"open_filters"in Q&&t(6,c=Q.open_filters),"debounce_timeout_ms"in Q&&t(28,u=Q.debounce_timeout_ms),"pagefind_options"in Q&&t(29,b=Q.pagefind_options),"merge_index"in Q&&t(30,F=Q.merge_index),"trigger_search_term"in Q&&t(23,f=Q.trigger_search_term),"translations"in Q&&t(7,h=Q.translations),"autofocus"in Q&&t(8,y=Q.autofocus),"focus_on_slash"in Q&&t(31,K=Q.focus_on_slash),"sort"in Q&&t(32,M=Q.sort),"selected_filters"in Q&&t(0,N=Q.selected_filters)},l.$$.update=()=>{l.$$.dirty[0]&8388608&&f&&(t(9,R=f),t(23,f="")),l.$$.dirty[0]&513&&Gs(R,N)},[N,r,g,I,A,d,c,h,y,R,T,it,It,fl,dt,At,Ul,Qt,oe,Zl,Zs,xl,Es,f,o,i,n,C,u,b,F,K,M,ks,Ls,Rs,Ws,Ss,Vs]}var Fl=class extends H{constructor(e){super(),O(this,e,Ug,fg,z,{base_path:25,page_size:26,reset_styles:1,show_images:2,show_sub_results:3,excerpt_length:24,process_result:4,process_term:27,show_empty_filters:5,open_filters:6,debounce_timeout_ms:28,pagefind_options:29,merge_index:30,trigger_search_term:23,translations:7,autofocus:8,focus_on_slash:31,sort:32,selected_filters:0},null,[-1,-1])}},Us=Fl;var Bl;try{document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&(Bl=new URL(document.currentScript.src).pathname.match(/^(.*\/)(?:pagefind-)?ui.js.*$/)[1])}catch{Bl="/pagefind/"}var ut=class{constructor(e){this._pfs=null;let t=e.element??"[data-pagefind-ui]",s=e.bundlePath??Bl,a=e.pageSize??5,i=e.resetStyles??!0,n=e.showImages??!0,r=e.showSubResults??!1,g=e.excerptLength??0,I=e.processResult??null,o=e.processTerm??null,A=e.showEmptyFilters??!0,C=e.openFilters??[],d=e.debounceTimeoutMs??300,c=e.mergeIndex??[],u=e.translations??[],b=e.autofocus??!1,F=e.focusOnSlash??!1,f=e.sort??null;delete e.element,delete e.bundlePath,delete e.pageSize,delete e.resetStyles,delete e.showImages,delete e.showSubResults,delete e.excerptLength,delete e.processResult,delete e.processTerm,delete e.showEmptyFilters,delete e.openFilters,delete e.debounceTimeoutMs,delete e.mergeIndex,delete e.translations,delete e.autofocus,delete e.focusOnSlash,delete e.sort;let h=t instanceof HTMLElement?t:document.querySelector(t);h?this._pfs=new Us({target:h,props:{base_path:s,page_size:a,reset_styles:i,show_images:n,show_sub_results:r,excerpt_length:g,process_result:I,process_term:o,show_empty_filters:A,open_filters:C,debounce_timeout_ms:d,merge_index:c,translations:u,autofocus:b,focus_on_slash:F,sort:f,pagefind_options:e}}):console.error(`Pagefind UI couldn't find the selector ${t}`)}triggerSearch(e){this._pfs.$$set({trigger_search_term:e})}triggerFilters(e){let t={};for(let[s,a]of Object.entries(e))if(Array.isArray(a))for(let i of a)t[`${s}:${i}`]=!0;else t[`${s}:${a}`]=!0;this._pfs.$$set({selected_filters:t})}destroy(){this._pfs.$destroy()}};window.PagefindUI=ut;})(); diff --git a/website/blog/pagefind/pagefind-worker.js b/website/blog/pagefind/pagefind-worker.js deleted file mode 100644 index 67e04a1..0000000 --- a/website/blog/pagefind/pagefind-worker.js +++ /dev/null @@ -1,6 +0,0 @@ -const pagefind_version="1.5.0";let wasm_bindgen=(function(exports){let script_src;if(typeof document!=='undefined'&&document.currentScript!==null){script_src=new URL("UNHANDLED",location.href).toString();}function add_synthetic_filter(ptr,filter){const ptr0=passStringToWasm0(filter,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.add_synthetic_filter(ptr,ptr0,len0);return ret>>>0;}exports.add_synthetic_filter=add_synthetic_filter;function enter_playground_mode(ptr){const ret=wasm.enter_playground_mode(ptr);return ret>>>0;}exports.enter_playground_mode=enter_playground_mode;function filters(ptr){let deferred1_0;let deferred1_1;try{const ret=wasm.filters(ptr);deferred1_0=ret[0];deferred1_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred1_0,deferred1_1,1);}}exports.filters=filters;function init_pagefind(metadata_bytes){const ptr0=passArray8ToWasm0(metadata_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.init_pagefind(ptr0,len0);return ret>>>0;}exports.init_pagefind=init_pagefind;function load_filter_chunk(ptr,chunk_bytes){const ptr0=passArray8ToWasm0(chunk_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.load_filter_chunk(ptr,ptr0,len0);return ret>>>0;}exports.load_filter_chunk=load_filter_chunk;function load_index_chunk(ptr,chunk_bytes){const ptr0=passArray8ToWasm0(chunk_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.load_index_chunk(ptr,ptr0,len0);return ret>>>0;}exports.load_index_chunk=load_index_chunk;function request_all_filter_indexes(ptr){let deferred1_0;let deferred1_1;try{const ret=wasm.request_all_filter_indexes(ptr);deferred1_0=ret[0];deferred1_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred1_0,deferred1_1,1);}}exports.request_all_filter_indexes=request_all_filter_indexes;function request_filter_indexes(ptr,filters){let deferred2_0;let deferred2_1;try{const ptr0=passStringToWasm0(filters,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.request_filter_indexes(ptr,ptr0,len0);deferred2_0=ret[0];deferred2_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred2_0,deferred2_1,1);}}exports.request_filter_indexes=request_filter_indexes;function request_indexes(ptr,query){let deferred2_0;let deferred2_1;try{const ptr0=passStringToWasm0(query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.request_indexes(ptr,ptr0,len0);deferred2_0=ret[0];deferred2_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred2_0,deferred2_1,1);}}exports.request_indexes=request_indexes;function search(ptr,query,original_query,filter,sort,exact,exact_diacritics){let deferred5_0;let deferred5_1;try{const ptr0=passStringToWasm0(query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ptr1=passStringToWasm0(original_query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len1=WASM_VECTOR_LEN;const ptr2=passStringToWasm0(filter,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len2=WASM_VECTOR_LEN;const ptr3=passStringToWasm0(sort,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len3=WASM_VECTOR_LEN;const ret=wasm.search(ptr,ptr0,len0,ptr1,len1,ptr2,len2,ptr3,len3,exact,exact_diacritics);deferred5_0=ret[0];deferred5_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred5_0,deferred5_1,1);}}exports.search=search;function set_ranking_weights(ptr,weights){const ptr0=passStringToWasm0(weights,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.set_ranking_weights(ptr,ptr0,len0);return ret>>>0;}exports.set_ranking_weights=set_ranking_weights;function __wbg_get_imports(){const import0={__proto__:null,__wbindgen_init_externref_table:function(){const table=wasm.__wbindgen_externrefs;const offset=table.grow(4);table.set(0,undefined);table.set(offset+0,undefined);table.set(offset+1,null);table.set(offset+2,true);table.set(offset+3,false);},};return{__proto__:null,"./pagefind_web_bg.js":import0,};}function getStringFromWasm0(ptr,len){ptr=ptr>>>0;return decodeText(ptr,len);}let cachedUint8ArrayMemory0=null;function getUint8ArrayMemory0(){if(cachedUint8ArrayMemory0===null||cachedUint8ArrayMemory0.byteLength===0){cachedUint8ArrayMemory0=new Uint8Array(wasm.memory.buffer);}return cachedUint8ArrayMemory0;}function passArray8ToWasm0(arg,malloc){const ptr=malloc(arg.length*1,1)>>>0;getUint8ArrayMemory0().set(arg,ptr/1);WASM_VECTOR_LEN=arg.length;return ptr;}function passStringToWasm0(arg,malloc,realloc){if(realloc===undefined){const buf=cachedTextEncoder.encode(arg);const ptr=malloc(buf.length,1)>>>0;getUint8ArrayMemory0().subarray(ptr,ptr+buf.length).set(buf);WASM_VECTOR_LEN=buf.length;return ptr;}let len=arg.length;let ptr=malloc(len,1)>>>0;const mem=getUint8ArrayMemory0();let offset=0;for(;offset0x7F)break;mem[ptr+offset]=code;}if(offset!==len){if(offset!==0){arg=arg.slice(offset);}ptr=realloc(ptr,len,len=offset+arg.length*3,1)>>>0;const view=getUint8ArrayMemory0().subarray(ptr+offset,ptr+len);const ret=cachedTextEncoder.encodeInto(arg,view);offset+=ret.written;ptr=realloc(ptr,len,offset,1)>>>0;}WASM_VECTOR_LEN=offset;return ptr;}let cachedTextDecoder=new TextDecoder('utf-8',{ignoreBOM:true,fatal:true});cachedTextDecoder.decode();function decodeText(ptr,len){return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr,ptr+len));}const cachedTextEncoder=new TextEncoder();if(!('encodeInto'in cachedTextEncoder)){cachedTextEncoder.encodeInto=function(arg,view){const buf=cachedTextEncoder.encode(arg);view.set(buf);return{read:arg.length,written:buf.length};};}let WASM_VECTOR_LEN=0;let wasmModule,wasm;function __wbg_finalize_init(instance,module){wasm=instance.exports;wasmModule=module;cachedUint8ArrayMemory0=null;wasm.__wbindgen_start();return wasm;}async function __wbg_load(module,imports){if(typeof Response==='function'&&module instanceof Response){if(typeof WebAssembly.instantiateStreaming==='function'){try{return await WebAssembly.instantiateStreaming(module,imports);}catch(e){const validResponse=module.ok&&expectedResponseType(module.type);if(validResponse&&module.headers.get('Content-Type')!=='application/wasm'){console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e);}else{throw e;}}}const bytes=await module.arrayBuffer();return await WebAssembly.instantiate(bytes,imports);}else{const instance=await WebAssembly.instantiate(module,imports);if(instance instanceof WebAssembly.Instance){return{instance,module};}else{return instance;}}function expectedResponseType(type){switch(type){case'basic':case'cors':case'default':return true;}return false;}}function initSync(module){if(wasm!==undefined)return wasm;if(module!==undefined){if(Object.getPrototypeOf(module)===Object.prototype){({module}=module)}else{console.warn('using deprecated parameters for `initSync()`; pass a single object instead')}}const imports=__wbg_get_imports();if(!(module instanceof WebAssembly.Module)){module=new WebAssembly.Module(module);}const instance=new WebAssembly.Instance(module,imports);return __wbg_finalize_init(instance,module);}async function __wbg_init(module_or_path){if(wasm!==undefined)return wasm;if(module_or_path!==undefined){if(Object.getPrototypeOf(module_or_path)===Object.prototype){({module_or_path}=module_or_path)}else{console.warn('using deprecated parameters for the initialization function; pass a single object instead')}}if(module_or_path===undefined&&script_src!==undefined){module_or_path=script_src.replace(/\.js$/,"_bg.wasm");}const imports=__wbg_get_imports();if(typeof module_or_path==='string'||(typeof Request==='function'&&module_or_path instanceof Request)||(typeof URL==='function'&&module_or_path instanceof URL)){module_or_path=fetch(module_or_path);}const{instance,module}=await __wbg_load(await module_or_path,imports);return __wbg_finalize_init(instance,module);}return Object.assign(__wbg_init,{initSync},exports);})({__proto__:null});"use strict";(()=>{var __defProp=Object.defineProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);var u8=Uint8Array;var u16=Uint16Array;var u32=Uint32Array;var fleb=new u8([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]);var fdeb=new u8([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]);var clim=new u8([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);var freb=function(eb,start){var b=new u16(31);for(var i2=0;i2<31;++i2){b[i2]=start+=1<>>1|(i&21845)<<1;x=(x&52428)>>>2|(x&13107)<<2;x=(x&61680)>>>4|(x&3855)<<4;rev[i]=((x&65280)>>>8|(x&255)<<8)>>>1;}var x;var i;var hMap=function(cd,mb,r){var s=cd.length;var i2=0;var l=new u16(mb);for(;i2>>rvb]=sv;}}}}else{co=new u16(s);for(i2=0;i2>>15-cd[i2];}}}return co;};var flt=new u8(288);for(i=0;i<144;++i)flt[i]=8;var i;for(i=144;i<256;++i)flt[i]=9;var i;for(i=256;i<280;++i)flt[i]=7;var i;for(i=280;i<288;++i)flt[i]=8;var i;var fdt=new u8(32);for(i=0;i<32;++i)fdt[i]=5;var i;var flrm=hMap(flt,9,1);var fdrm=hMap(fdt,5,1);var max=function(a){var m=a[0];for(var i2=1;i2m)m=a[i2];}return m;};var bits=function(d,p,m){var o=p/8|0;return(d[o]|d[o+1]<<8)>>(p&7)&m;};var bits16=function(d,p){var o=p/8|0;return(d[o]|d[o+1]<<8|d[o+2]<<16)>>(p&7);};var shft=function(p){return(p+7)/8|0;};var slc=function(v,s,e){if(s==null||s<0)s=0;if(e==null||e>v.length)e=v.length;var n=new(v.BYTES_PER_ELEMENT==2?u16:v.BYTES_PER_ELEMENT==4?u32:u8)(e-s);n.set(v.subarray(s,e));return n;};var ec=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"];var err=function(ind,msg,nt){var e=new Error(msg||ec[ind]);e.code=ind;if(Error.captureStackTrace)Error.captureStackTrace(e,err);if(!nt)throw e;return e;};var inflt=function(dat,buf,st){var sl=dat.length;if(!sl||st&&st.f&&!st.l)return buf||new u8(0);var noBuf=!buf||st;var noSt=!st||st.i;if(!st)st={};if(!buf)buf=new u8(sl*3);var cbuf=function(l2){var bl=buf.length;if(l2>bl){var nbuf=new u8(Math.max(bl*2,l2));nbuf.set(buf);buf=nbuf;}};var final=st.f||0,pos=st.p||0,bt=st.b||0,lm=st.l,dm=st.d,lbt=st.m,dbt=st.n;var tbts=sl*8;do{if(!lm){final=bits(dat,pos,1);var type=bits(dat,pos+1,3);pos+=3;if(!type){var s=shft(pos)+4,l=dat[s-4]|dat[s-3]<<8,t=s+l;if(t>sl){if(noSt)err(0);break;}if(noBuf)cbuf(bt+l);buf.set(dat.subarray(s,t),bt);st.b=bt+=l,st.p=pos=t*8,st.f=final;continue;}else if(type==1)lm=flrm,dm=fdrm,lbt=9,dbt=5;else if(type==2){var hLit=bits(dat,pos,31)+257,hcLen=bits(dat,pos+10,15)+4;var tl=hLit+bits(dat,pos+5,31)+1;pos+=14;var ldt=new u8(tl);var clt=new u8(19);for(var i2=0;i2>>4;if(s<16){ldt[i2++]=s;}else{var c=0,n=0;if(s==16)n=3+bits(dat,pos,3),pos+=2,c=ldt[i2-1];else if(s==17)n=3+bits(dat,pos,7),pos+=3;else if(s==18)n=11+bits(dat,pos,127),pos+=7;while(n--)ldt[i2++]=c;}}var lt=ldt.subarray(0,hLit),dt=ldt.subarray(hLit);lbt=max(lt);dbt=max(dt);lm=hMap(lt,lbt,1);dm=hMap(dt,dbt,1);}else err(1);if(pos>tbts){if(noSt)err(0);break;}}if(noBuf)cbuf(bt+131072);var lms=(1<>>4;pos+=c&15;if(pos>tbts){if(noSt)err(0);break;}if(!c)err(2);if(sym<256)buf[bt++]=sym;else if(sym==256){lpos=pos,lm=null;break;}else{var add=sym-254;if(sym>264){var i2=sym-257,b=fleb[i2];add=bits(dat,pos,(1<>>4;if(!d)err(3);pos+=d&15;var dt=fd[dsym];if(dsym>3){var b=fdeb[dsym];dt+=bits16(dat,pos)&(1<tbts){if(noSt)err(0);break;}if(noBuf)cbuf(bt+131072);var end=bt+add;for(;bt>3&1)+(flg>>4&1);zs>0;zs-=!d[st++]);return st+(flg&2);};var gzl=function(d){var l=d.length;return(d[l-4]|d[l-3]<<8|d[l-2]<<16|d[l-1]<<24)>>>0;};function gunzipSync(data,out){return inflt(data.subarray(gzs(data),-8),out||new u8(gzl(data)));}var td=typeof TextDecoder!="undefined"&&new TextDecoder();var tds=0;try{td.decode(et,{stream:true});tds=1;}catch(e){}var gz_default=gunzipSync;var calculate_excerpt_region=(word_positions,excerpt_length)=>{if(word_positions.length===0){return 0;}let words=[];for(const word of word_positions){words[word.location]=words[word.location]||0;words[word.location]+=word.balanced_score;}if(words.length<=excerpt_length){return 0;}let densest=words.slice(0,excerpt_length).reduce((partialSum,a)=>partialSum+a,0);let working_sum=densest;let densest_at=[0];for(let i2=0;i2densest){densest=working_sum;densest_at=[i2];}else if(working_sum===densest&&densest_at[densest_at.length-1]===i2-1){densest_at.push(i2);}}let midpoint=densest_at[Math.floor(densest_at.length/2)];return midpoint;};var build_excerpt=(content,start,length,locations,not_before,not_from)=>{let is_zws_delimited=content.includes("\u200B");let fragment_words=[];if(is_zws_delimited){fragment_words=content.split("\u200B");}else{fragment_words=content.split(/[\r\n\s]+/g);}let endcap=not_from??fragment_words.length;let startcap=not_before??0;if(endcap-startcapendcap){start=endcap-length;}if(start`)){continue;}fragment_words[word]=`${fragment_words[word]}`;}const excerpt=fragment_words.slice(start,start+length).join(joiner).trim();return{excerpt,plain_excerpt};};var calculate_sub_results=(fragment,desired_excerpt_length)=>{const effective_url=fragment.meta?.url||fragment.url;const anchors=fragment.anchors.filter((a)=>/h\d/i.test(a.element)&&a.text?.length&&/\S/.test(a.text)).sort((a,b)=>a.location-b.location);const results=[];let current_anchor_position=0;let current_anchor={title:fragment.meta["title"],url:effective_url,weighted_locations:[],locations:[],excerpt:"",plain_excerpt:""};const add_result=(end_range)=>{if(current_anchor.locations.length){const relative_weighted_locations=current_anchor.weighted_locations.map((l)=>{return{weight:l.weight,balanced_score:l.balanced_score,location:l.location-current_anchor_position};});const excerpt_start=calculate_excerpt_region(relative_weighted_locations,desired_excerpt_length)+current_anchor_position;const excerpt_length=end_range?Math.min(end_range-excerpt_start,desired_excerpt_length):desired_excerpt_length;const excerpts=build_excerpt(fragment.raw_content??"",excerpt_start,excerpt_length,current_anchor.locations,current_anchor_position,end_range);current_anchor.excerpt=excerpts.excerpt;current_anchor.plain_excerpt=excerpts.plain_excerpt;results.push(current_anchor);}};for(let word of fragment.weighted_locations){if(!anchors.length||word.location=anchors[0].location){next_anchor=anchors.shift();}let anchored_url=effective_url;try{const url_is_fq=/^((https?:)?\/\/)/.test(anchored_url);if(url_is_fq){let fq_url=new URL(anchored_url);fq_url.hash=next_anchor.id;anchored_url=fq_url.toString();}else{if(!/^\//.test(anchored_url)){anchored_url=`/${anchored_url}`;}let fq_url=new URL(`https://example.com${anchored_url}`);fq_url.hash=next_anchor.id;anchored_url=fq_url.toString().replace(/^https:\/\/example.com/,"");}}catch(e){console.error(`Pagefind: Couldn't process ${anchored_url} for a search result`);}current_anchor_position=next_anchor.location;current_anchor={title:next_anchor.text,url:anchored_url,anchor:next_anchor,weighted_locations:[word],locations:[word.location],excerpt:"",plain_excerpt:""};}}add_result(anchors[0]?.location);return results;};var import_meta={};var asyncSleep=async(ms=100)=>{return new Promise((r)=>setTimeout(r,ms));};var normalizeDiacritics=(str)=>{return str.normalize("NFD").replace(/\p{M}/gu,"");};var isBrowser=()=>typeof window!=="undefined"&&typeof document!=="undefined";var needsWordSegmentation=(lang)=>{if(!lang)return false;const primaryLang=lang.split("-")[0].toLowerCase();return["zh","ja","th"].includes(primaryLang);};var PagefindInstance=class{constructor(opts={}){__publicField(this,"backend");__publicField(this,"decoder");__publicField(this,"wasm");__publicField(this,"basePath");__publicField(this,"baseUrl");__publicField(this,"primary");__publicField(this,"indexWeight");__publicField(this,"excerptLength");__publicField(this,"mergeFilter");__publicField(this,"ranking");__publicField(this,"highlightParam");__publicField(this,"exactDiacritics");__publicField(this,"metaCacheTag");__publicField(this,"loaded_chunks");__publicField(this,"loaded_filters");__publicField(this,"loaded_fragments");__publicField(this,"fetchQueue",[]);__publicField(this,"activeFetches",0);__publicField(this,"maxConcurrentFetches",100);__publicField(this,"raw_ptr");__publicField(this,"initError");__publicField(this,"searchMeta");__publicField(this,"languages");__publicField(this,"loadedLanguage");__publicField(this,"includeCharacters");__publicField(this,"version");__publicField(this,"loadedVersion");this.version=pagefind_version;this.backend=wasm_bindgen;this.decoder=new TextDecoder("utf-8");this.wasm=null;let basePath=opts.basePath||"/pagefind/";let primary=opts.primary||false;if(primary&&!opts.basePath&&isBrowser()){basePath=this.initPrimaryBasePath(basePath);}if(/[^\/]$/.test(basePath)){basePath=`${basePath}/`;}if(isBrowser()&&window?.location?.origin&&basePath.startsWith(window.location.origin)){basePath=basePath.replace(window.location.origin,"");}this.basePath=basePath;this.baseUrl=opts.baseUrl||this.getDefaultBaseUrl(basePath);if(!/^(\/|https?:\/\/)/.test(this.baseUrl)){this.baseUrl=`/${this.baseUrl}`;}this.primary=primary;this.indexWeight=opts.indexWeight??1;this.excerptLength=opts.excerptLength??30;this.mergeFilter=opts.mergeFilter??{};this.ranking=opts.ranking;this.highlightParam=opts.highlightParam??null;this.exactDiacritics=opts.exactDiacritics??false;this.metaCacheTag=opts.metaCacheTag??null;this.loaded_chunks={};this.loaded_filters={};this.loaded_fragments={};this.raw_ptr=null;this.initError=null;this.searchMeta=null;this.languages=null;}throttledFetch(input){return new Promise((resolve,reject)=>{this.fetchQueue.push({resolve,reject,input});this.dequeueNextFetch();});}dequeueNextFetch(){while(this.fetchQueue.length>0&&this.activeFetchesb.page_count-a.page_count);if(topLang[0])return topLang[0];}throw new Error("Pagefind Error: No language indexes found.");}async loadMeta(index){try{let compressed_resp=await this.throttledFetch(`${this.basePath}pagefind.${index}.pf_meta`);let compressed_meta=await compressed_resp.arrayBuffer();this.searchMeta=this.decompress(new Uint8Array(compressed_meta),"Pagefind metadata");}catch(e){console.error(`Failed to load the meta index: -${e?.toString()}`);}}async loadWasm(language){try{const wasm_url=`${this.basePath}wasm.${language}.pagefind`;let compressed_resp=await this.throttledFetch(wasm_url);let compressed_wasm=await compressed_resp.arrayBuffer();const final_wasm=this.decompress(new Uint8Array(compressed_wasm),"Pagefind WebAssembly");if(!final_wasm){throw new Error("No WASM after decompression");}this.wasm=await this.backend(final_wasm);}catch(e){console.error(`Failed to load the Pagefind WASM: -${e?.toString()}`);throw new Error(`Failed to load the Pagefind WASM: -${e?.toString()}`);}}async _loadGenericChunk(url,method){try{let compressed_resp=await this.throttledFetch(url);let compressed_chunk=await compressed_resp.arrayBuffer();let chunk=this.decompress(new Uint8Array(compressed_chunk),url);let ptr=await this.getPtr();this.raw_ptr=this.backend[method](ptr,chunk);}catch(e){console.error(`Failed to load the index chunk ${url}: -${e?.toString()}`);}}async loadChunk(hash){if(!this.loaded_chunks[hash]){const url=`${this.basePath}index/${hash}.pf_index`;this.loaded_chunks[hash]=this._loadGenericChunk(url,"load_index_chunk");}return await this.loaded_chunks[hash];}async loadFilterChunk(hash){if(!this.loaded_filters[hash]){const url=`${this.basePath}filter/${hash}.pf_filter`;this.loaded_filters[hash]=this._loadGenericChunk(url,"load_filter_chunk");}return await this.loaded_filters[hash];}async _loadFragment(hash){let compressed_resp=await this.throttledFetch(`${this.basePath}fragment/${hash}.pf_fragment`);let compressed_fragment=await compressed_resp.arrayBuffer();let fragment=this.decompress(new Uint8Array(compressed_fragment),`Fragment ${hash}`);return JSON.parse(new TextDecoder().decode(fragment));}async loadFragment(hash,weighted_locations=[],search_term){if(!this.loaded_fragments[hash]){this.loaded_fragments[hash]=this._loadFragment(hash);}let fragment=await this.loaded_fragments[hash];fragment.weighted_locations=weighted_locations;fragment.locations=weighted_locations.map((l)=>l.location);if(!fragment.raw_content){fragment.raw_content=fragment.content.replace(//g,">");fragment.content=fragment.content.replace(/\u200B/g,"");}if(!fragment.raw_url){fragment.raw_url=fragment.url;}fragment.url=this.processedUrl(fragment.raw_url,search_term);const excerpt_start=calculate_excerpt_region(weighted_locations,this.excerptLength);const excerpts=build_excerpt(fragment.raw_content,excerpt_start,this.excerptLength,fragment.locations);fragment.excerpt=excerpts.excerpt;fragment.plain_excerpt=excerpts.plain_excerpt;fragment.sub_results=calculate_sub_results(fragment,this.excerptLength);return fragment;}fullUrl(raw){if(/^(https?:)?\/\//.test(raw)){return raw;}return`${this.baseUrl}/${raw}`.replace(/\/+/g,"/").replace(/^(https?:\/)/,"$1/");}processedUrl(url,search_term){const normalized=this.fullUrl(url);if(this.highlightParam===null){return normalized;}let individual_terms=search_term.split(/\s+/);try{let processed=new URL(normalized);for(const term of individual_terms){processed.searchParams.append(this.highlightParam,term);}return processed.toString();}catch(e){try{let processed=new URL(`https://example.com${normalized}`);for(const term of individual_terms){processed.searchParams.append(this.highlightParam,term);}return processed.toString().replace(/^https:\/\/example\.com/,"");}catch(e2){return normalized;}}}async getPtr(){while(this.raw_ptr===null){if(this.initError){throw this.initError;}await asyncSleep(50);}if(!this.raw_ptr){console.error("Pagefind: WASM Error (No pointer)");throw new Error("Pagefind: WASM Error (No pointer)");}return this.raw_ptr;}stringifyFilters(obj={}){return JSON.stringify(obj);}stringifySorts(obj={}){let sorts=Object.entries(obj);for(let[sort,direction]of sorts){if(sorts.length>1){console.warn(`Pagefind was provided multiple sort options in this search, but can only operate on one. Using the ${sort} sort.`);}if(direction!=="asc"&&direction!=="desc"){console.warn(`Pagefind was provided a sort with unknown direction ${direction}. Supported: [asc, desc]`);}return`${sort}:${direction}`;}return``;}async filters(){let ptr=await this.getPtr();let filters=this.backend.request_all_filter_indexes(ptr);let filter_array=JSON.parse(filters);if(Array.isArray(filter_array)){let filter_chunks=filter_array.filter((v)=>v).map((chunk)=>this.loadFilterChunk(chunk));await Promise.all([...filter_chunks]);}ptr=await this.getPtr();let results=this.backend.filters(ptr);return JSON.parse(results);}async preload(term,options={}){await this.search(term,{...options,preload:true});}async search(term,options={}){options={verbose:false,filters:{},sort:{},...options};const log=(str)=>{if(options.verbose)console.log(str);};log(`Starting search on ${this.basePath}`);let start=Date.now();let ptr=await this.getPtr();let filter_only=term===null;term=term??"";let exact_search=/^\s*".+"\s*$/.test(term);if(exact_search){log(`Running an exact search`);}let trueLanguage=null;try{trueLanguage=Intl.getCanonicalLocales(this.loadedLanguage)[0];}catch(err2){}const term_chunks=[];if(trueLanguage&&typeof Intl.Segmenter!=="undefined"){const graphemeSegmenter=new Intl.Segmenter(trueLanguage,{granularity:"grapheme"});if(needsWordSegmentation(trueLanguage)){const wordSegmenter=new Intl.Segmenter(trueLanguage,{granularity:"word"});for(const{segment:word}of wordSegmenter.segment(term)){const wordChunks=[];for(const{segment:grapheme}of graphemeSegmenter.segment(word)){if(this.includeCharacters?.includes(grapheme)){wordChunks.push(grapheme);}else if(!/^\p{Pd}|\p{Pe}|\p{Pf}|\p{Pi}|\p{Po}|\p{Ps}$/u.test(grapheme)){wordChunks.push(grapheme.toLocaleLowerCase());}}if(wordChunks.length>0){term_chunks.push(wordChunks.join(""));}}term=term_chunks.join(" ").replace(/\s{2,}/g," ").trim();}else{for(const{segment:grapheme}of graphemeSegmenter.segment(term)){if(this.includeCharacters?.includes(grapheme)){term_chunks.push(grapheme);}else if(!/^\p{Pd}|\p{Pe}|\p{Pf}|\p{Pi}|\p{Po}|\p{Ps}$/u.test(grapheme)){term_chunks.push(grapheme.toLocaleLowerCase());}}term=term_chunks.join("").replace(/\s{2,}/g," ").trim();}}else{for(const char of term){if(this.includeCharacters?.includes(char)){term_chunks.push(char);}else if(!/^\p{Pd}|\p{Pe}|\p{Pf}|\p{Pi}|\p{Po}|\p{Ps}$/u.test(char)){term_chunks.push(char.toLocaleLowerCase());}}term=term_chunks.join("").replace(/\s{2,}/g," ").trim();}const originalTerm=term;term=normalizeDiacritics(term);log(`Normalized search term to ${term}`);if(!term?.length&&!filter_only){return{results:[],unfilteredResultCount:0,filters:{},totalFilters:{},timings:{preload:Date.now()-start,search:Date.now()-start,total:Date.now()-start}};}let sort_list=this.stringifySorts(options.sort);log(`Stringified sort to ${sort_list}`);const filter_list=this.stringifyFilters(options.filters);log(`Stringified filters to ${filter_list}`);let index_resp=this.backend.request_indexes(ptr,term);let index_array=JSON.parse(index_resp);let filter_resp=this.backend.request_filter_indexes(ptr,filter_list);let filter_array=JSON.parse(filter_resp);let chunks=index_array.filter((v)=>v).map((chunk)=>this.loadChunk(chunk));let filter_chunks=filter_array.filter((v)=>v).map((chunk)=>this.loadFilterChunk(chunk));await Promise.all([...chunks,...filter_chunks]);log(`Loaded necessary chunks to run search`);if(options.preload){log(`Preload \u2014 bailing out of search operation now.`);return null;}ptr=await this.getPtr();let searchStart=Date.now();let result=this.backend.search(ptr,term,originalTerm,filter_list,sort_list,exact_search,this.exactDiacritics);log(`Got the raw search result: ${result}`);let{filtered_counts,total_counts,results,unfiltered_total,search_keywords,query_term_idfs}=JSON.parse(result);let resultsInterface=results.map((result2)=>{let weighted_locations=result2.l.map((l)=>{let loc={weight:l.w/24,balanced_score:l.s,location:l.l};if(l.v){loc.verbose={word_string:l.v.ws,length_bonus:l.v.lb};}return loc;});let locations=weighted_locations.map((l)=>l.location);let res={id:result2.p,score:result2.s*this.indexWeight,words:locations,data:async()=>await this.loadFragment(result2.p,weighted_locations,term)};if(result2.params){res.params={document_length:result2.params.dl,average_page_length:result2.params.apl,total_pages:result2.params.tp};}if(result2.scores){res.scores=result2.scores.map((r)=>{return{search_term:r.w,idf:r.idf,saturating_tf:r.b_tf,raw_tf:r.r_tf,pagefind_tf:r.p_tf,score:r.s,params:{weighted_term_frequency:r.params.w_tf,pages_containing_term:r.params.pct,length_bonus:r.params.lb}};});}if(result2.mf&&result2.mf.length>0){res.matchedMetaFields=result2.mf;}if(result2.vms&&result2.vms.length>0){res.verbose_meta_scores=result2.vms.map((s)=>({field_name:s.fn,field_weight:s.fw,matched_terms:s.mt,matched_idf:s.mi,query_total_idf:s.ti,coverage:s.cv,coverage_boost:s.cb}));}return res;});const searchTime=Date.now()-searchStart;const realTime=Date.now()-start;log(`Found ${results.length} result${results.length == 1 ? "" : "s"} for "${term}" in ${Date.now() - searchStart}ms (${Date.now() - start}ms realtime)`);let response={results:resultsInterface,unfilteredResultCount:unfiltered_total,filters:filtered_counts,totalFilters:total_counts,timings:{preload:realTime-searchTime,search:searchTime,total:realTime}};if(search_keywords){response.search_keywords=search_keywords;}if(query_term_idfs){response.query_term_idfs=query_term_idfs.map((q)=>({term:q.t,idf:q.i}));}return response;}};var Pagefind=class{constructor(options={}){__publicField(this,"primaryLanguage");__publicField(this,"searchID");__publicField(this,"primary");__publicField(this,"instances");this.primaryLanguage="unknown";this.searchID=0;this.primary=new PagefindInstance({...options,primary:true});this.instances=[this.primary];this.init(options?.language);}async options(options){await this.primary.options(options);}async enterPlaygroundMode(){await this.primary.enterPlaygroundMode();}async init(overrideLanguage){if(isBrowser()&&document?.querySelector){const langCode=document.querySelector("html")?.getAttribute("lang")||"unknown";this.primaryLanguage=langCode.toLocaleLowerCase();}if(overrideLanguage){this.primaryLanguage=overrideLanguage;}await this.primary.init(overrideLanguage?overrideLanguage:this.primaryLanguage,{load_wasm:true});}async mergeIndex(indexPath,options={}){if(this.primary.basePath.startsWith(indexPath)){console.warn(`Skipping mergeIndex ${indexPath} that appears to be the same as the primary index (${this.primary.basePath})`);return;}let newInstance=new PagefindInstance({primary:false,basePath:indexPath,...options});this.instances.push(newInstance);while(this.primary.wasm===null){await asyncSleep(50);}await newInstance.init(options.language||this.primaryLanguage,{load_wasm:false});const{language,...remainingOptions}=options;await newInstance.options(remainingOptions);}mergeFilters(filters){const merged={};for(const searchFilter of filters){for(const[filterKey,values]of Object.entries(searchFilter)){if(!merged[filterKey]){merged[filterKey]=values;continue;}else{const filter=merged[filterKey];for(const[valueKey,count]of Object.entries(values)){filter[valueKey]=(filter[valueKey]||0)+count;}}}}return merged;}async filters(){let filters=await Promise.all(this.instances.map((i2)=>i2.filters()));return this.mergeFilters(filters);}async preload(term,options={}){await Promise.all(this.instances.map((i2)=>i2.preload(term,options)));}async debouncedSearch(term,options,debounceTimeoutMs){const thisSearchID=++this.searchID;this.preload(term,options);await asyncSleep(debounceTimeoutMs);if(thisSearchID!==this.searchID){return null;}const searchResult=await this.search(term,options);if(thisSearchID!==this.searchID){return null;}return searchResult;}async search(term,options={}){let search=await Promise.all(this.instances.map((i2)=>i2.search(term,options)));const filters=this.mergeFilters(search.map((s)=>s.filters));const totalFilters=this.mergeFilters(search.map((s)=>s.totalFilters));const results=search.map((s)=>s.results).flat().sort((a,b)=>b.score-a.score);const timings=search.map((s)=>s.timings);const unfilteredResultCount=search.reduce((sum,s)=>sum+s.unfilteredResultCount,0);let response={results,unfilteredResultCount,filters,totalFilters,timings};if(search[0].search_keywords){response.search_keywords=search[0].search_keywords;}if(search[0].query_term_idfs){response.query_term_idfs=search[0].query_term_idfs;}return response;}};var dataCallbacks=new Map();var instanceDataIds=new Map();var instances=new Map();var DEFAULT_INSTANCE="default";var getInstance=(instanceId)=>{const instance=instances.get(instanceId);if(!instance){throw new Error(`Pagefind instance "${instanceId}" not initialized`);}return instance;};var registerDataCallback=(instanceId,dataId,dataFn)=>{dataCallbacks.set(dataId,{getData:dataFn});if(!instanceDataIds.has(instanceId)){instanceDataIds.set(instanceId,new Set());}instanceDataIds.get(instanceId).add(dataId);};var handleMessage=async(message)=>{const{id,method,args}=message;const instanceId=message.instanceId??DEFAULT_INSTANCE;try{switch(method){case"init":{const[options]=args;instances.set(instanceId,new Pagefind(options));return{id,result:true};}case"options":{const pagefindInstance=getInstance(instanceId);const[options]=args;await pagefindInstance.options(options);return{id,result:true};}case"enterPlaygroundMode":{const pagefindInstance=getInstance(instanceId);await pagefindInstance.enterPlaygroundMode();return{id,result:true};}case"mergeIndex":{const pagefindInstance=getInstance(instanceId);const[indexPath,options]=args;await pagefindInstance.mergeIndex(indexPath,options);return{id,result:true};}case"search":{const pagefindInstance=getInstance(instanceId);const[term,options]=args;const results=await pagefindInstance.search(term,options);if(results&&results.results){for(let i2=0;i2{const message=event.data;const response=await handleMessage(message);self.postMessage(response);});})(); \ No newline at end of file diff --git a/website/blog/pagefind/pagefind.js b/website/blog/pagefind/pagefind.js deleted file mode 100644 index a772a12..0000000 --- a/website/blog/pagefind/pagefind.js +++ /dev/null @@ -1,6 +0,0 @@ -const pagefind_version="1.5.0";let wasm_bindgen=(function(exports){let script_src;if(typeof document!=='undefined'&&document.currentScript!==null){script_src=new URL("UNHANDLED",location.href).toString();}function add_synthetic_filter(ptr,filter){const ptr0=passStringToWasm0(filter,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.add_synthetic_filter(ptr,ptr0,len0);return ret>>>0;}exports.add_synthetic_filter=add_synthetic_filter;function enter_playground_mode(ptr){const ret=wasm.enter_playground_mode(ptr);return ret>>>0;}exports.enter_playground_mode=enter_playground_mode;function filters(ptr){let deferred1_0;let deferred1_1;try{const ret=wasm.filters(ptr);deferred1_0=ret[0];deferred1_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred1_0,deferred1_1,1);}}exports.filters=filters;function init_pagefind(metadata_bytes){const ptr0=passArray8ToWasm0(metadata_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.init_pagefind(ptr0,len0);return ret>>>0;}exports.init_pagefind=init_pagefind;function load_filter_chunk(ptr,chunk_bytes){const ptr0=passArray8ToWasm0(chunk_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.load_filter_chunk(ptr,ptr0,len0);return ret>>>0;}exports.load_filter_chunk=load_filter_chunk;function load_index_chunk(ptr,chunk_bytes){const ptr0=passArray8ToWasm0(chunk_bytes,wasm.__wbindgen_malloc);const len0=WASM_VECTOR_LEN;const ret=wasm.load_index_chunk(ptr,ptr0,len0);return ret>>>0;}exports.load_index_chunk=load_index_chunk;function request_all_filter_indexes(ptr){let deferred1_0;let deferred1_1;try{const ret=wasm.request_all_filter_indexes(ptr);deferred1_0=ret[0];deferred1_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred1_0,deferred1_1,1);}}exports.request_all_filter_indexes=request_all_filter_indexes;function request_filter_indexes(ptr,filters){let deferred2_0;let deferred2_1;try{const ptr0=passStringToWasm0(filters,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.request_filter_indexes(ptr,ptr0,len0);deferred2_0=ret[0];deferred2_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred2_0,deferred2_1,1);}}exports.request_filter_indexes=request_filter_indexes;function request_indexes(ptr,query){let deferred2_0;let deferred2_1;try{const ptr0=passStringToWasm0(query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.request_indexes(ptr,ptr0,len0);deferred2_0=ret[0];deferred2_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred2_0,deferred2_1,1);}}exports.request_indexes=request_indexes;function search(ptr,query,original_query,filter,sort,exact,exact_diacritics){let deferred5_0;let deferred5_1;try{const ptr0=passStringToWasm0(query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ptr1=passStringToWasm0(original_query,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len1=WASM_VECTOR_LEN;const ptr2=passStringToWasm0(filter,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len2=WASM_VECTOR_LEN;const ptr3=passStringToWasm0(sort,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len3=WASM_VECTOR_LEN;const ret=wasm.search(ptr,ptr0,len0,ptr1,len1,ptr2,len2,ptr3,len3,exact,exact_diacritics);deferred5_0=ret[0];deferred5_1=ret[1];return getStringFromWasm0(ret[0],ret[1]);}finally{wasm.__wbindgen_free(deferred5_0,deferred5_1,1);}}exports.search=search;function set_ranking_weights(ptr,weights){const ptr0=passStringToWasm0(weights,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);const len0=WASM_VECTOR_LEN;const ret=wasm.set_ranking_weights(ptr,ptr0,len0);return ret>>>0;}exports.set_ranking_weights=set_ranking_weights;function __wbg_get_imports(){const import0={__proto__:null,__wbindgen_init_externref_table:function(){const table=wasm.__wbindgen_externrefs;const offset=table.grow(4);table.set(0,undefined);table.set(offset+0,undefined);table.set(offset+1,null);table.set(offset+2,true);table.set(offset+3,false);},};return{__proto__:null,"./pagefind_web_bg.js":import0,};}function getStringFromWasm0(ptr,len){ptr=ptr>>>0;return decodeText(ptr,len);}let cachedUint8ArrayMemory0=null;function getUint8ArrayMemory0(){if(cachedUint8ArrayMemory0===null||cachedUint8ArrayMemory0.byteLength===0){cachedUint8ArrayMemory0=new Uint8Array(wasm.memory.buffer);}return cachedUint8ArrayMemory0;}function passArray8ToWasm0(arg,malloc){const ptr=malloc(arg.length*1,1)>>>0;getUint8ArrayMemory0().set(arg,ptr/1);WASM_VECTOR_LEN=arg.length;return ptr;}function passStringToWasm0(arg,malloc,realloc){if(realloc===undefined){const buf=cachedTextEncoder.encode(arg);const ptr=malloc(buf.length,1)>>>0;getUint8ArrayMemory0().subarray(ptr,ptr+buf.length).set(buf);WASM_VECTOR_LEN=buf.length;return ptr;}let len=arg.length;let ptr=malloc(len,1)>>>0;const mem=getUint8ArrayMemory0();let offset=0;for(;offset0x7F)break;mem[ptr+offset]=code;}if(offset!==len){if(offset!==0){arg=arg.slice(offset);}ptr=realloc(ptr,len,len=offset+arg.length*3,1)>>>0;const view=getUint8ArrayMemory0().subarray(ptr+offset,ptr+len);const ret=cachedTextEncoder.encodeInto(arg,view);offset+=ret.written;ptr=realloc(ptr,len,offset,1)>>>0;}WASM_VECTOR_LEN=offset;return ptr;}let cachedTextDecoder=new TextDecoder('utf-8',{ignoreBOM:true,fatal:true});cachedTextDecoder.decode();function decodeText(ptr,len){return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr,ptr+len));}const cachedTextEncoder=new TextEncoder();if(!('encodeInto'in cachedTextEncoder)){cachedTextEncoder.encodeInto=function(arg,view){const buf=cachedTextEncoder.encode(arg);view.set(buf);return{read:arg.length,written:buf.length};};}let WASM_VECTOR_LEN=0;let wasmModule,wasm;function __wbg_finalize_init(instance,module){wasm=instance.exports;wasmModule=module;cachedUint8ArrayMemory0=null;wasm.__wbindgen_start();return wasm;}async function __wbg_load(module,imports){if(typeof Response==='function'&&module instanceof Response){if(typeof WebAssembly.instantiateStreaming==='function'){try{return await WebAssembly.instantiateStreaming(module,imports);}catch(e){const validResponse=module.ok&&expectedResponseType(module.type);if(validResponse&&module.headers.get('Content-Type')!=='application/wasm'){console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e);}else{throw e;}}}const bytes=await module.arrayBuffer();return await WebAssembly.instantiate(bytes,imports);}else{const instance=await WebAssembly.instantiate(module,imports);if(instance instanceof WebAssembly.Instance){return{instance,module};}else{return instance;}}function expectedResponseType(type){switch(type){case'basic':case'cors':case'default':return true;}return false;}}function initSync(module){if(wasm!==undefined)return wasm;if(module!==undefined){if(Object.getPrototypeOf(module)===Object.prototype){({module}=module)}else{console.warn('using deprecated parameters for `initSync()`; pass a single object instead')}}const imports=__wbg_get_imports();if(!(module instanceof WebAssembly.Module)){module=new WebAssembly.Module(module);}const instance=new WebAssembly.Instance(module,imports);return __wbg_finalize_init(instance,module);}async function __wbg_init(module_or_path){if(wasm!==undefined)return wasm;if(module_or_path!==undefined){if(Object.getPrototypeOf(module_or_path)===Object.prototype){({module_or_path}=module_or_path)}else{console.warn('using deprecated parameters for the initialization function; pass a single object instead')}}if(module_or_path===undefined&&script_src!==undefined){module_or_path=script_src.replace(/\.js$/,"_bg.wasm");}const imports=__wbg_get_imports();if(typeof module_or_path==='string'||(typeof Request==='function'&&module_or_path instanceof Request)||(typeof URL==='function'&&module_or_path instanceof URL)){module_or_path=fetch(module_or_path);}const{instance,module}=await __wbg_load(await module_or_path,imports);return __wbg_finalize_init(instance,module);}return Object.assign(__wbg_init,{initSync},exports);})({__proto__:null});var __defProp=Object.defineProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);var u8=Uint8Array;var u16=Uint16Array;var u32=Uint32Array;var fleb=new u8([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]);var fdeb=new u8([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]);var clim=new u8([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);var freb=function(eb,start){var b=new u16(31);for(var i2=0;i2<31;++i2){b[i2]=start+=1<>>1|(i&21845)<<1;x=(x&52428)>>>2|(x&13107)<<2;x=(x&61680)>>>4|(x&3855)<<4;rev[i]=((x&65280)>>>8|(x&255)<<8)>>>1;}var x;var i;var hMap=function(cd,mb,r){var s=cd.length;var i2=0;var l=new u16(mb);for(;i2>>rvb]=sv;}}}}else{co=new u16(s);for(i2=0;i2>>15-cd[i2];}}}return co;};var flt=new u8(288);for(i=0;i<144;++i)flt[i]=8;var i;for(i=144;i<256;++i)flt[i]=9;var i;for(i=256;i<280;++i)flt[i]=7;var i;for(i=280;i<288;++i)flt[i]=8;var i;var fdt=new u8(32);for(i=0;i<32;++i)fdt[i]=5;var i;var flrm=hMap(flt,9,1);var fdrm=hMap(fdt,5,1);var max=function(a){var m=a[0];for(var i2=1;i2m)m=a[i2];}return m;};var bits=function(d,p,m){var o=p/8|0;return(d[o]|d[o+1]<<8)>>(p&7)&m;};var bits16=function(d,p){var o=p/8|0;return(d[o]|d[o+1]<<8|d[o+2]<<16)>>(p&7);};var shft=function(p){return(p+7)/8|0;};var slc=function(v,s,e){if(s==null||s<0)s=0;if(e==null||e>v.length)e=v.length;var n=new(v.BYTES_PER_ELEMENT==2?u16:v.BYTES_PER_ELEMENT==4?u32:u8)(e-s);n.set(v.subarray(s,e));return n;};var ec=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"];var err=function(ind,msg,nt){var e=new Error(msg||ec[ind]);e.code=ind;if(Error.captureStackTrace)Error.captureStackTrace(e,err);if(!nt)throw e;return e;};var inflt=function(dat,buf,st){var sl=dat.length;if(!sl||st&&st.f&&!st.l)return buf||new u8(0);var noBuf=!buf||st;var noSt=!st||st.i;if(!st)st={};if(!buf)buf=new u8(sl*3);var cbuf=function(l2){var bl=buf.length;if(l2>bl){var nbuf=new u8(Math.max(bl*2,l2));nbuf.set(buf);buf=nbuf;}};var final=st.f||0,pos=st.p||0,bt=st.b||0,lm=st.l,dm=st.d,lbt=st.m,dbt=st.n;var tbts=sl*8;do{if(!lm){final=bits(dat,pos,1);var type=bits(dat,pos+1,3);pos+=3;if(!type){var s=shft(pos)+4,l=dat[s-4]|dat[s-3]<<8,t=s+l;if(t>sl){if(noSt)err(0);break;}if(noBuf)cbuf(bt+l);buf.set(dat.subarray(s,t),bt);st.b=bt+=l,st.p=pos=t*8,st.f=final;continue;}else if(type==1)lm=flrm,dm=fdrm,lbt=9,dbt=5;else if(type==2){var hLit=bits(dat,pos,31)+257,hcLen=bits(dat,pos+10,15)+4;var tl=hLit+bits(dat,pos+5,31)+1;pos+=14;var ldt=new u8(tl);var clt=new u8(19);for(var i2=0;i2>>4;if(s<16){ldt[i2++]=s;}else{var c=0,n=0;if(s==16)n=3+bits(dat,pos,3),pos+=2,c=ldt[i2-1];else if(s==17)n=3+bits(dat,pos,7),pos+=3;else if(s==18)n=11+bits(dat,pos,127),pos+=7;while(n--)ldt[i2++]=c;}}var lt=ldt.subarray(0,hLit),dt=ldt.subarray(hLit);lbt=max(lt);dbt=max(dt);lm=hMap(lt,lbt,1);dm=hMap(dt,dbt,1);}else err(1);if(pos>tbts){if(noSt)err(0);break;}}if(noBuf)cbuf(bt+131072);var lms=(1<>>4;pos+=c&15;if(pos>tbts){if(noSt)err(0);break;}if(!c)err(2);if(sym<256)buf[bt++]=sym;else if(sym==256){lpos=pos,lm=null;break;}else{var add=sym-254;if(sym>264){var i2=sym-257,b=fleb[i2];add=bits(dat,pos,(1<>>4;if(!d)err(3);pos+=d&15;var dt=fd[dsym];if(dsym>3){var b=fdeb[dsym];dt+=bits16(dat,pos)&(1<tbts){if(noSt)err(0);break;}if(noBuf)cbuf(bt+131072);var end=bt+add;for(;bt>3&1)+(flg>>4&1);zs>0;zs-=!d[st++]);return st+(flg&2);};var gzl=function(d){var l=d.length;return(d[l-4]|d[l-3]<<8|d[l-2]<<16|d[l-1]<<24)>>>0;};function gunzipSync(data,out){return inflt(data.subarray(gzs(data),-8),out||new u8(gzl(data)));}var td=typeof TextDecoder!="undefined"&&new TextDecoder();var tds=0;try{td.decode(et,{stream:true});tds=1;}catch(e){}var gz_default=gunzipSync;var calculate_excerpt_region=(word_positions,excerpt_length)=>{if(word_positions.length===0){return 0;}let words=[];for(const word of word_positions){words[word.location]=words[word.location]||0;words[word.location]+=word.balanced_score;}if(words.length<=excerpt_length){return 0;}let densest=words.slice(0,excerpt_length).reduce((partialSum,a)=>partialSum+a,0);let working_sum=densest;let densest_at=[0];for(let i2=0;i2densest){densest=working_sum;densest_at=[i2];}else if(working_sum===densest&&densest_at[densest_at.length-1]===i2-1){densest_at.push(i2);}}let midpoint=densest_at[Math.floor(densest_at.length/2)];return midpoint;};var build_excerpt=(content,start,length,locations,not_before,not_from)=>{let is_zws_delimited=content.includes("\u200B");let fragment_words=[];if(is_zws_delimited){fragment_words=content.split("\u200B");}else{fragment_words=content.split(/[\r\n\s]+/g);}let endcap=not_from??fragment_words.length;let startcap=not_before??0;if(endcap-startcapendcap){start=endcap-length;}if(start`)){continue;}fragment_words[word]=`${fragment_words[word]}`;}const excerpt=fragment_words.slice(start,start+length).join(joiner).trim();return{excerpt,plain_excerpt};};var calculate_sub_results=(fragment,desired_excerpt_length)=>{const effective_url=fragment.meta?.url||fragment.url;const anchors=fragment.anchors.filter((a)=>/h\d/i.test(a.element)&&a.text?.length&&/\S/.test(a.text)).sort((a,b)=>a.location-b.location);const results=[];let current_anchor_position=0;let current_anchor={title:fragment.meta["title"],url:effective_url,weighted_locations:[],locations:[],excerpt:"",plain_excerpt:""};const add_result=(end_range)=>{if(current_anchor.locations.length){const relative_weighted_locations=current_anchor.weighted_locations.map((l)=>{return{weight:l.weight,balanced_score:l.balanced_score,location:l.location-current_anchor_position};});const excerpt_start=calculate_excerpt_region(relative_weighted_locations,desired_excerpt_length)+current_anchor_position;const excerpt_length=end_range?Math.min(end_range-excerpt_start,desired_excerpt_length):desired_excerpt_length;const excerpts=build_excerpt(fragment.raw_content??"",excerpt_start,excerpt_length,current_anchor.locations,current_anchor_position,end_range);current_anchor.excerpt=excerpts.excerpt;current_anchor.plain_excerpt=excerpts.plain_excerpt;results.push(current_anchor);}};for(let word of fragment.weighted_locations){if(!anchors.length||word.location=anchors[0].location){next_anchor=anchors.shift();}let anchored_url=effective_url;try{const url_is_fq=/^((https?:)?\/\/)/.test(anchored_url);if(url_is_fq){let fq_url=new URL(anchored_url);fq_url.hash=next_anchor.id;anchored_url=fq_url.toString();}else{if(!/^\//.test(anchored_url)){anchored_url=`/${anchored_url}`;}let fq_url=new URL(`https://example.com${anchored_url}`);fq_url.hash=next_anchor.id;anchored_url=fq_url.toString().replace(/^https:\/\/example.com/,"");}}catch(e){console.error(`Pagefind: Couldn't process ${anchored_url} for a search result`);}current_anchor_position=next_anchor.location;current_anchor={title:next_anchor.text,url:anchored_url,anchor:next_anchor,weighted_locations:[word],locations:[word.location],excerpt:"",plain_excerpt:""};}}add_result(anchors[0]?.location);return results;};var asyncSleep=async(ms=100)=>{return new Promise((r)=>setTimeout(r,ms));};var normalizeDiacritics=(str)=>{return str.normalize("NFD").replace(/\p{M}/gu,"");};var isBrowser=()=>typeof window!=="undefined"&&typeof document!=="undefined";var needsWordSegmentation=(lang)=>{if(!lang)return false;const primaryLang=lang.split("-")[0].toLowerCase();return["zh","ja","th"].includes(primaryLang);};var PagefindInstance=class{constructor(opts={}){__publicField(this,"backend");__publicField(this,"decoder");__publicField(this,"wasm");__publicField(this,"basePath");__publicField(this,"baseUrl");__publicField(this,"primary");__publicField(this,"indexWeight");__publicField(this,"excerptLength");__publicField(this,"mergeFilter");__publicField(this,"ranking");__publicField(this,"highlightParam");__publicField(this,"exactDiacritics");__publicField(this,"metaCacheTag");__publicField(this,"loaded_chunks");__publicField(this,"loaded_filters");__publicField(this,"loaded_fragments");__publicField(this,"fetchQueue",[]);__publicField(this,"activeFetches",0);__publicField(this,"maxConcurrentFetches",100);__publicField(this,"raw_ptr");__publicField(this,"initError");__publicField(this,"searchMeta");__publicField(this,"languages");__publicField(this,"loadedLanguage");__publicField(this,"includeCharacters");__publicField(this,"version");__publicField(this,"loadedVersion");this.version=pagefind_version;this.backend=wasm_bindgen;this.decoder=new TextDecoder("utf-8");this.wasm=null;let basePath=opts.basePath||"/pagefind/";let primary=opts.primary||false;if(primary&&!opts.basePath&&isBrowser()){basePath=this.initPrimaryBasePath(basePath);}if(/[^\/]$/.test(basePath)){basePath=`${basePath}/`;}if(isBrowser()&&window?.location?.origin&&basePath.startsWith(window.location.origin)){basePath=basePath.replace(window.location.origin,"");}this.basePath=basePath;this.baseUrl=opts.baseUrl||this.getDefaultBaseUrl(basePath);if(!/^(\/|https?:\/\/)/.test(this.baseUrl)){this.baseUrl=`/${this.baseUrl}`;}this.primary=primary;this.indexWeight=opts.indexWeight??1;this.excerptLength=opts.excerptLength??30;this.mergeFilter=opts.mergeFilter??{};this.ranking=opts.ranking;this.highlightParam=opts.highlightParam??null;this.exactDiacritics=opts.exactDiacritics??false;this.metaCacheTag=opts.metaCacheTag??null;this.loaded_chunks={};this.loaded_filters={};this.loaded_fragments={};this.raw_ptr=null;this.initError=null;this.searchMeta=null;this.languages=null;}throttledFetch(input){return new Promise((resolve,reject)=>{this.fetchQueue.push({resolve,reject,input});this.dequeueNextFetch();});}dequeueNextFetch(){while(this.fetchQueue.length>0&&this.activeFetchesb.page_count-a.page_count);if(topLang[0])return topLang[0];}throw new Error("Pagefind Error: No language indexes found.");}async loadMeta(index){try{let compressed_resp=await this.throttledFetch(`${this.basePath}pagefind.${index}.pf_meta`);let compressed_meta=await compressed_resp.arrayBuffer();this.searchMeta=this.decompress(new Uint8Array(compressed_meta),"Pagefind metadata");}catch(e){console.error(`Failed to load the meta index: -${e?.toString()}`);}}async loadWasm(language){try{const wasm_url=`${this.basePath}wasm.${language}.pagefind`;let compressed_resp=await this.throttledFetch(wasm_url);let compressed_wasm=await compressed_resp.arrayBuffer();const final_wasm=this.decompress(new Uint8Array(compressed_wasm),"Pagefind WebAssembly");if(!final_wasm){throw new Error("No WASM after decompression");}this.wasm=await this.backend(final_wasm);}catch(e){console.error(`Failed to load the Pagefind WASM: -${e?.toString()}`);throw new Error(`Failed to load the Pagefind WASM: -${e?.toString()}`);}}async _loadGenericChunk(url,method){try{let compressed_resp=await this.throttledFetch(url);let compressed_chunk=await compressed_resp.arrayBuffer();let chunk=this.decompress(new Uint8Array(compressed_chunk),url);let ptr=await this.getPtr();this.raw_ptr=this.backend[method](ptr,chunk);}catch(e){console.error(`Failed to load the index chunk ${url}: -${e?.toString()}`);}}async loadChunk(hash){if(!this.loaded_chunks[hash]){const url=`${this.basePath}index/${hash}.pf_index`;this.loaded_chunks[hash]=this._loadGenericChunk(url,"load_index_chunk");}return await this.loaded_chunks[hash];}async loadFilterChunk(hash){if(!this.loaded_filters[hash]){const url=`${this.basePath}filter/${hash}.pf_filter`;this.loaded_filters[hash]=this._loadGenericChunk(url,"load_filter_chunk");}return await this.loaded_filters[hash];}async _loadFragment(hash){let compressed_resp=await this.throttledFetch(`${this.basePath}fragment/${hash}.pf_fragment`);let compressed_fragment=await compressed_resp.arrayBuffer();let fragment=this.decompress(new Uint8Array(compressed_fragment),`Fragment ${hash}`);return JSON.parse(new TextDecoder().decode(fragment));}async loadFragment(hash,weighted_locations=[],search_term){if(!this.loaded_fragments[hash]){this.loaded_fragments[hash]=this._loadFragment(hash);}let fragment=await this.loaded_fragments[hash];fragment.weighted_locations=weighted_locations;fragment.locations=weighted_locations.map((l)=>l.location);if(!fragment.raw_content){fragment.raw_content=fragment.content.replace(//g,">");fragment.content=fragment.content.replace(/\u200B/g,"");}if(!fragment.raw_url){fragment.raw_url=fragment.url;}fragment.url=this.processedUrl(fragment.raw_url,search_term);const excerpt_start=calculate_excerpt_region(weighted_locations,this.excerptLength);const excerpts=build_excerpt(fragment.raw_content,excerpt_start,this.excerptLength,fragment.locations);fragment.excerpt=excerpts.excerpt;fragment.plain_excerpt=excerpts.plain_excerpt;fragment.sub_results=calculate_sub_results(fragment,this.excerptLength);return fragment;}fullUrl(raw){if(/^(https?:)?\/\//.test(raw)){return raw;}return`${this.baseUrl}/${raw}`.replace(/\/+/g,"/").replace(/^(https?:\/)/,"$1/");}processedUrl(url,search_term){const normalized=this.fullUrl(url);if(this.highlightParam===null){return normalized;}let individual_terms=search_term.split(/\s+/);try{let processed=new URL(normalized);for(const term of individual_terms){processed.searchParams.append(this.highlightParam,term);}return processed.toString();}catch(e){try{let processed=new URL(`https://example.com${normalized}`);for(const term of individual_terms){processed.searchParams.append(this.highlightParam,term);}return processed.toString().replace(/^https:\/\/example\.com/,"");}catch(e2){return normalized;}}}async getPtr(){while(this.raw_ptr===null){if(this.initError){throw this.initError;}await asyncSleep(50);}if(!this.raw_ptr){console.error("Pagefind: WASM Error (No pointer)");throw new Error("Pagefind: WASM Error (No pointer)");}return this.raw_ptr;}stringifyFilters(obj={}){return JSON.stringify(obj);}stringifySorts(obj={}){let sorts=Object.entries(obj);for(let[sort,direction]of sorts){if(sorts.length>1){console.warn(`Pagefind was provided multiple sort options in this search, but can only operate on one. Using the ${sort} sort.`);}if(direction!=="asc"&&direction!=="desc"){console.warn(`Pagefind was provided a sort with unknown direction ${direction}. Supported: [asc, desc]`);}return`${sort}:${direction}`;}return``;}async filters(){let ptr=await this.getPtr();let filters2=this.backend.request_all_filter_indexes(ptr);let filter_array=JSON.parse(filters2);if(Array.isArray(filter_array)){let filter_chunks=filter_array.filter((v)=>v).map((chunk)=>this.loadFilterChunk(chunk));await Promise.all([...filter_chunks]);}ptr=await this.getPtr();let results=this.backend.filters(ptr);return JSON.parse(results);}async preload(term,options2={}){await this.search(term,{...options2,preload:true});}async search(term,options2={}){options2={verbose:false,filters:{},sort:{},...options2};const log=(str)=>{if(options2.verbose)console.log(str);};log(`Starting search on ${this.basePath}`);let start=Date.now();let ptr=await this.getPtr();let filter_only=term===null;term=term??"";let exact_search=/^\s*".+"\s*$/.test(term);if(exact_search){log(`Running an exact search`);}let trueLanguage=null;try{trueLanguage=Intl.getCanonicalLocales(this.loadedLanguage)[0];}catch(err2){}const term_chunks=[];if(trueLanguage&&typeof Intl.Segmenter!=="undefined"){const graphemeSegmenter=new Intl.Segmenter(trueLanguage,{granularity:"grapheme"});if(needsWordSegmentation(trueLanguage)){const wordSegmenter=new Intl.Segmenter(trueLanguage,{granularity:"word"});for(const{segment:word}of wordSegmenter.segment(term)){const wordChunks=[];for(const{segment:grapheme}of graphemeSegmenter.segment(word)){if(this.includeCharacters?.includes(grapheme)){wordChunks.push(grapheme);}else if(!/^\p{Pd}|\p{Pe}|\p{Pf}|\p{Pi}|\p{Po}|\p{Ps}$/u.test(grapheme)){wordChunks.push(grapheme.toLocaleLowerCase());}}if(wordChunks.length>0){term_chunks.push(wordChunks.join(""));}}term=term_chunks.join(" ").replace(/\s{2,}/g," ").trim();}else{for(const{segment:grapheme}of graphemeSegmenter.segment(term)){if(this.includeCharacters?.includes(grapheme)){term_chunks.push(grapheme);}else if(!/^\p{Pd}|\p{Pe}|\p{Pf}|\p{Pi}|\p{Po}|\p{Ps}$/u.test(grapheme)){term_chunks.push(grapheme.toLocaleLowerCase());}}term=term_chunks.join("").replace(/\s{2,}/g," ").trim();}}else{for(const char of term){if(this.includeCharacters?.includes(char)){term_chunks.push(char);}else if(!/^\p{Pd}|\p{Pe}|\p{Pf}|\p{Pi}|\p{Po}|\p{Ps}$/u.test(char)){term_chunks.push(char.toLocaleLowerCase());}}term=term_chunks.join("").replace(/\s{2,}/g," ").trim();}const originalTerm=term;term=normalizeDiacritics(term);log(`Normalized search term to ${term}`);if(!term?.length&&!filter_only){return{results:[],unfilteredResultCount:0,filters:{},totalFilters:{},timings:{preload:Date.now()-start,search:Date.now()-start,total:Date.now()-start}};}let sort_list=this.stringifySorts(options2.sort);log(`Stringified sort to ${sort_list}`);const filter_list=this.stringifyFilters(options2.filters);log(`Stringified filters to ${filter_list}`);let index_resp=this.backend.request_indexes(ptr,term);let index_array=JSON.parse(index_resp);let filter_resp=this.backend.request_filter_indexes(ptr,filter_list);let filter_array=JSON.parse(filter_resp);let chunks=index_array.filter((v)=>v).map((chunk)=>this.loadChunk(chunk));let filter_chunks=filter_array.filter((v)=>v).map((chunk)=>this.loadFilterChunk(chunk));await Promise.all([...chunks,...filter_chunks]);log(`Loaded necessary chunks to run search`);if(options2.preload){log(`Preload \u2014 bailing out of search operation now.`);return null;}ptr=await this.getPtr();let searchStart=Date.now();let result=this.backend.search(ptr,term,originalTerm,filter_list,sort_list,exact_search,this.exactDiacritics);log(`Got the raw search result: ${result}`);let{filtered_counts,total_counts,results,unfiltered_total,search_keywords,query_term_idfs}=JSON.parse(result);let resultsInterface=results.map((result2)=>{let weighted_locations=result2.l.map((l)=>{let loc={weight:l.w/24,balanced_score:l.s,location:l.l};if(l.v){loc.verbose={word_string:l.v.ws,length_bonus:l.v.lb};}return loc;});let locations=weighted_locations.map((l)=>l.location);let res={id:result2.p,score:result2.s*this.indexWeight,words:locations,data:async()=>await this.loadFragment(result2.p,weighted_locations,term)};if(result2.params){res.params={document_length:result2.params.dl,average_page_length:result2.params.apl,total_pages:result2.params.tp};}if(result2.scores){res.scores=result2.scores.map((r)=>{return{search_term:r.w,idf:r.idf,saturating_tf:r.b_tf,raw_tf:r.r_tf,pagefind_tf:r.p_tf,score:r.s,params:{weighted_term_frequency:r.params.w_tf,pages_containing_term:r.params.pct,length_bonus:r.params.lb}};});}if(result2.mf&&result2.mf.length>0){res.matchedMetaFields=result2.mf;}if(result2.vms&&result2.vms.length>0){res.verbose_meta_scores=result2.vms.map((s)=>({field_name:s.fn,field_weight:s.fw,matched_terms:s.mt,matched_idf:s.mi,query_total_idf:s.ti,coverage:s.cv,coverage_boost:s.cb}));}return res;});const searchTime=Date.now()-searchStart;const realTime=Date.now()-start;log(`Found ${results.length} result${results.length == 1 ? "" : "s"} for "${term}" in ${Date.now() - searchStart}ms (${Date.now() - start}ms realtime)`);let response={results:resultsInterface,unfilteredResultCount:unfiltered_total,filters:filtered_counts,totalFilters:total_counts,timings:{preload:realTime-searchTime,search:searchTime,total:realTime}};if(search_keywords){response.search_keywords=search_keywords;}if(query_term_idfs){response.query_term_idfs=query_term_idfs.map((q)=>({term:q.t,idf:q.i}));}return response;}};var Pagefind=class{constructor(options2={}){__publicField(this,"primaryLanguage");__publicField(this,"searchID");__publicField(this,"primary");__publicField(this,"instances");this.primaryLanguage="unknown";this.searchID=0;this.primary=new PagefindInstance({...options2,primary:true});this.instances=[this.primary];this.init(options2?.language);}async options(options2){await this.primary.options(options2);}async enterPlaygroundMode(){await this.primary.enterPlaygroundMode();}async init(overrideLanguage){if(isBrowser()&&document?.querySelector){const langCode=document.querySelector("html")?.getAttribute("lang")||"unknown";this.primaryLanguage=langCode.toLocaleLowerCase();}if(overrideLanguage){this.primaryLanguage=overrideLanguage;}await this.primary.init(overrideLanguage?overrideLanguage:this.primaryLanguage,{load_wasm:true});}async mergeIndex(indexPath,options2={}){if(this.primary.basePath.startsWith(indexPath)){console.warn(`Skipping mergeIndex ${indexPath} that appears to be the same as the primary index (${this.primary.basePath})`);return;}let newInstance=new PagefindInstance({primary:false,basePath:indexPath,...options2});this.instances.push(newInstance);while(this.primary.wasm===null){await asyncSleep(50);}await newInstance.init(options2.language||this.primaryLanguage,{load_wasm:false});const{language,...remainingOptions}=options2;await newInstance.options(remainingOptions);}mergeFilters(filters2){const merged={};for(const searchFilter of filters2){for(const[filterKey,values]of Object.entries(searchFilter)){if(!merged[filterKey]){merged[filterKey]=values;continue;}else{const filter=merged[filterKey];for(const[valueKey,count]of Object.entries(values)){filter[valueKey]=(filter[valueKey]||0)+count;}}}}return merged;}async filters(){let filters2=await Promise.all(this.instances.map((i2)=>i2.filters()));return this.mergeFilters(filters2);}async preload(term,options2={}){await Promise.all(this.instances.map((i2)=>i2.preload(term,options2)));}async debouncedSearch(term,options2,debounceTimeoutMs){const thisSearchID=++this.searchID;this.preload(term,options2);await asyncSleep(debounceTimeoutMs);if(thisSearchID!==this.searchID){return null;}const searchResult=await this.search(term,options2);if(thisSearchID!==this.searchID){return null;}return searchResult;}async search(term,options2={}){let search2=await Promise.all(this.instances.map((i2)=>i2.search(term,options2)));const filters2=this.mergeFilters(search2.map((s)=>s.filters));const totalFilters=this.mergeFilters(search2.map((s)=>s.totalFilters));const results=search2.map((s)=>s.results).flat().sort((a,b)=>b.score-a.score);const timings=search2.map((s)=>s.timings);const unfilteredResultCount=search2.reduce((sum,s)=>sum+s.unfilteredResultCount,0);let response={results,unfilteredResultCount,filters:filters2,totalFilters,timings};if(search2[0].search_keywords){response.search_keywords=search2[0].search_keywords;}if(search2[0].query_term_idfs){response.query_term_idfs=search2[0].query_term_idfs;}return response;}};var hasWorkerSupport=typeof window!=="undefined"&&typeof document!=="undefined"&&typeof Worker!=="undefined";var sharedWorker=null;var sharedWorkerRefCount=0;var sharedMessageHandlers=new Map();var nextInstanceId=0;var generateInstanceId=()=>`pf_${nextInstanceId++}`;function initSharedWorker(basePath){if(sharedWorker)return true;try{const workerUrl=`${basePath}pagefind-worker.js`;sharedWorker=new Worker(workerUrl);sharedWorker.addEventListener("error",(error)=>{console.warn("The Pagefind web worker encountered an error, falling back to main thread:",error);sharedWorker=null;const pending=Array.from(sharedMessageHandlers.values());sharedMessageHandlers.clear();for(const{reject}of pending){reject(new Error("Worker failed, falling back to main thread"));}});sharedWorker.addEventListener("message",(event)=>{const{id,result,error}=event.data;const pending=sharedMessageHandlers.get(id);if(pending){sharedMessageHandlers.delete(id);if(error){pending.reject(new Error(error));}else{pending.resolve(result);}}});return true;}catch(e){return false;}}function releaseSharedWorker(){sharedWorkerRefCount--;if(sharedWorkerRefCount<=0&&sharedWorker){sharedWorker.terminate();sharedWorker=null;sharedWorkerRefCount=0;const pending=Array.from(sharedMessageHandlers.values());sharedMessageHandlers.clear();for(const{reject}of pending){reject(new Error("Pagefind worker terminated"));}}}var globalMessageId=0;function sendWorkerMessage(instanceId,method,args){if(!sharedWorker){return Promise.reject(new Error("Worker not available"));}return new Promise((resolve,reject)=>{const id=`msg_${globalMessageId++}`;sharedMessageHandlers.set(id,{resolve,reject});sharedWorker.postMessage({id,instanceId,method,args});});}var PagefindWrapper=class{constructor(options2={}){__publicField(this,"instanceId");__publicField(this,"fallback",null);__publicField(this,"basePath");__publicField(this,"initOptions");__publicField(this,"cleanup");__publicField(this,"initPromise",null);__publicField(this,"initialized",false);__publicField(this,"useWorker",false);this.instanceId=generateInstanceId();this.basePath=options2.basePath||"/pagefind/";this.initOptions=options2;if(/[^\/]$/.test(this.basePath)){this.basePath=`${this.basePath}/`;}if(hasWorkerSupport&&window?.location?.origin&&this.basePath.startsWith(window.location.origin)){this.basePath=this.basePath.replace(window.location.origin,"");}this.initOptions={...this.initOptions,basePath:this.basePath};this.initCleanup();this.initPromise=this.init();}initCleanup(){if(typeof FinalizationRegistry!=="undefined"){this.cleanup=new FinalizationRegistry((dataId)=>{if(this.useWorker&&sharedWorker){try{sendWorkerMessage(this.instanceId,"releaseData",[dataId]).catch(()=>{});}catch(e){}}});}}async init(){if(hasWorkerSupport&&!this.initOptions.noWorker){const workerAvailable=initSharedWorker(this.basePath);if(workerAvailable){try{sharedWorkerRefCount++;this.useWorker=true;await Promise.race([sendWorkerMessage(this.instanceId,"init",[this.initOptions]),new Promise((_,reject)=>setTimeout(()=>reject(new Error("Worker initialization timeout")),5e3))]);this.initialized=true;}catch(error){console.warn("Failed to initialize Pagefind in the web worker, falling back to main thread:",error);sendWorkerMessage(this.instanceId,"destroy",[]).catch(()=>{});this.useWorker=false;sharedWorkerRefCount--;this.initFallback();this.initialized=true;}}else{this.initFallback();this.initialized=true;}}else{this.initFallback();this.initialized=true;}}waitForInit(){return this.initPromise??Promise.resolve();}initFallback(){if(!this.fallback){this.fallback=new Pagefind(this.initOptions);}}async sendMessage(method,args){if(!this.initialized&&method!=="init"){if(this.initPromise){await this.initPromise;}}if(this.fallback){const fn=this.fallback[method];if(typeof fn==="function"){const result=await fn.apply(this.fallback,args);if((method==="search"||method==="debouncedSearch")&&result&&args[1]&&args[1].verbose){result.search_environment="mainthread";}return result;}throw new Error(`Method ${method} not found on fallback`);}if(!this.useWorker||!sharedWorker){throw new Error("Worker not initialized");}return sendWorkerMessage(this.instanceId,method,args);}async options(options2){return this.sendMessage("options",[options2]);}async enterPlaygroundMode(){return this.sendMessage("enterPlaygroundMode",[]);}async mergeIndex(indexPath,options2={}){return this.sendMessage("mergeIndex",[indexPath,options2]);}async search(term,options2={}){const results=await this.sendMessage("search",[term,options2]);if(results&&results.results){for(const result of results.results){if(typeof result.data==="string"){const dataId=result.data;if(this.cleanup){this.cleanup.register(result,dataId);}result.data=async()=>{return this.sendMessage("getData",[dataId]);};}}}return results;}async debouncedSearch(term,options2,debounceTimeoutMs){const results=await this.sendMessage("debouncedSearch",[term,options2,debounceTimeoutMs]);if(results&&results.results){for(const result of results.results){if(typeof result.data==="string"){const dataId=result.data;if(this.cleanup){this.cleanup.register(result,dataId);}result.data=async()=>{return this.sendMessage("getData",[dataId]);};}}}return results;}async preload(term,options2={}){return this.sendMessage("preload",[term,options2]);}async filters(){return this.sendMessage("filters",[]);}async destroy(){if(this.useWorker){try{await sendWorkerMessage(this.instanceId,"destroy",[]);}catch(e){}this.useWorker=false;releaseSharedWorker();}if(this.fallback){this.fallback=null;}}};var pagefind=void 0;var initial_options=void 0;var deriveBasePath=(explicit)=>{if(explicit)return explicit;if(typeof import.meta.url!=="undefined"){return import.meta.url.match(/^(.*\/)pagefind.js.*$/)?.[1];}};var detectLanguage=()=>{if(typeof document!=="undefined"&&document?.querySelector){return(document.querySelector("html")?.getAttribute("lang")||"unknown").toLowerCase();}return"unknown";};var init_pagefind=()=>{if(!pagefind){pagefind=new PagefindWrapper({...initial_options,basePath:deriveBasePath(initial_options?.basePath),language:detectLanguage(),primary:true});}};var options=async(new_options)=>{if(pagefind){await pagefind.options(new_options);}else{initial_options=new_options;}};var init=async()=>{init_pagefind();};var destroy=async()=>{if(pagefind){await pagefind.destroy();}pagefind=void 0;initial_options=void 0;};var mergeIndex=async(indexPath,options2)=>{init_pagefind();return await pagefind.mergeIndex(indexPath,options2);};var search=async(term,options2)=>{init_pagefind();return await pagefind.search(term,options2);};var debouncedSearch=async(term,options2,debounceTimeoutMs=300)=>{init_pagefind();return await pagefind.debouncedSearch(term,options2,debounceTimeoutMs);};var preload=async(term,options2)=>{init_pagefind();return await pagefind.preload(term,options2);};var filters=async()=>{init_pagefind();return await pagefind.filters();};var createInstance=(instanceOptions)=>{const wrapper=new PagefindWrapper({...instanceOptions,basePath:deriveBasePath(instanceOptions?.basePath),language:detectLanguage(),primary:true});return{options:(opts)=>wrapper.options(opts),init:()=>wrapper.waitForInit(),destroy:()=>wrapper.destroy(),mergeIndex:(indexPath,options2)=>wrapper.mergeIndex(indexPath,options2),search:(term,options2={})=>wrapper.search(term,options2),debouncedSearch:(term,options2,debounceTimeoutMs=300)=>wrapper.debouncedSearch(term,options2,debounceTimeoutMs),preload:(term,options2={})=>wrapper.preload(term,options2),filters:()=>wrapper.filters()};};export{createInstance,debouncedSearch,destroy,filters,init,mergeIndex,options,preload,search}; \ No newline at end of file diff --git a/website/blog/pagefind/pagefind.zh-cn_b823138fb9571.pf_meta b/website/blog/pagefind/pagefind.zh-cn_b823138fb9571.pf_meta deleted file mode 100644 index 7186e2f..0000000 Binary files a/website/blog/pagefind/pagefind.zh-cn_b823138fb9571.pf_meta and /dev/null differ diff --git a/website/blog/pagefind/wasm.unknown.pagefind b/website/blog/pagefind/wasm.unknown.pagefind deleted file mode 100644 index 472c3f0..0000000 Binary files a/website/blog/pagefind/wasm.unknown.pagefind and /dev/null differ diff --git a/website/blog/posts/markdown-mermaid/index.html b/website/blog/posts/markdown-mermaid/index.html deleted file mode 100644 index a9f7f45..0000000 --- a/website/blog/posts/markdown-mermaid/index.html +++ /dev/null @@ -1,2231 +0,0 @@ - Markdown Mermaid - FutureOSS Docs - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video
    578 字
    3 分钟
    Markdown Mermaid
    2023-10-01
    Examples
    /
    - Markdown
    /
    - Blogging
    /
    - Mermaid

    Complete Guide to Markdown with Mermaid Diagrams#

    This article demonstrates how to create various complex diagrams using Mermaid in Markdown documents, including flowcharts, sequence diagrams, Gantt charts, class diagrams, and state diagrams.

    Flowchart Example#

    Flowcharts are excellent for representing processes or algorithm steps.

    graph TD - A[Start] --> B{Condition Check} - B -->|Yes| C[Process Step 1] - B -->|No| D[Process Step 2] - C --> E[Subprocess] - D --> E - subgraph E [Subprocess Details] - E1[Substep 1] --> E2[Substep 2] - E2 --> E3[Substep 3] - end - E --> F{Another Decision} - F -->|Option 1| G[Result 1] - F -->|Option 2| H[Result 2] - F -->|Option 3| I[Result 3] - G --> J[End] - H --> J - I --> J

    Sequence Diagram Example#

    Sequence diagrams show interactions between objects over time.

    sequenceDiagram - participant User - participant WebApp - participant Server - participant Database - - User->>WebApp: Submit Login Request - WebApp->>Server: Send Auth Request - Server->>Database: Query User Credentials - Database-->>Server: Return User Data - Server-->>WebApp: Return Auth Result - - alt Auth Successful - WebApp->>User: Show Welcome Page - WebApp->>Server: Request User Data - Server->>Database: Get User Preferences - Database-->>Server: Return Preferences - Server-->>WebApp: Return User Data - WebApp->>User: Load Personalized Interface - else Auth Failed - WebApp->>User: Show Error Message - WebApp->>User: Prompt Re-entry - end

    Gantt Chart Example#

    Gantt charts are perfect for displaying project schedules and timelines.

    gantt - title Website Development Project Timeline - dateFormat YYYY-MM-DD - axisFormat %m/%d - - section Design Phase - Requirements Analysis :a1, 2023-10-01, 7d - UI Design :a2, after a1, 10d - Prototype Creation :a3, after a2, 5d - - section Development Phase - Frontend Development :b1, 2023-10-20, 15d - Backend Development :b2, after a2, 18d - Database Design :b3, after a1, 12d - - section Testing Phase - Unit Testing :c1, after b1, 8d - Integration Testing :c2, after b2, 10d - User Acceptance Testing :c3, after c2, 7d - - section Deployment - Production Deployment :d1, after c3, 3d - Launch :milestone, after d1, 0d

    Class Diagram Example#

    Class diagrams show the static structure of a system, including classes, attributes, methods, and their relationships.

    classDiagram - class User { - +String username - +String password - +String email - +Boolean active - +login() - +logout() - +updateProfile() - } - - class Article { - +String title - +String content - +Date publishDate - +Boolean published - +publish() - +edit() - +delete() - } - - class Comment { - +String content - +Date commentDate - +addComment() - +deleteComment() - } - - class Category { - +String name - +String description - +addArticle() - +removeArticle() - } - - User "1" -- "*" Article : writes - User "1" -- "*" Comment : posts - Article "1" -- "*" Comment : has - Article "1" -- "*" Category : belongs to

    State Diagram Example#

    State diagrams show the sequence of states an object goes through during its life cycle.

    stateDiagram-v2 - [*] --> Draft - - Draft --> UnderReview : submit - UnderReview --> Draft : reject - UnderReview --> Approved : approve - Approved --> Published : publish - Published --> Archived : archive - Published --> Draft : retract - - state Published { - [*] --> Active - Active --> Hidden : temporarily hide - Hidden --> Active : restore - Active --> [*] - Hidden --> [*] - } - - Archived --> [*]

    Pie Chart Example#

    Pie charts are ideal for displaying proportions and percentage data.

    pie title Website Traffic Sources Analysis - "Search Engines" : 45.6 - "Direct Access" : 30.1 - "Social Media" : 15.3 - "Referral Links" : 6.4 - "Other Sources" : 2.6

    Conclusion#

    Mermaid is a powerful tool for creating various types of diagrams in Markdown documents. This article demonstrated how to use flowcharts, sequence diagrams, Gantt charts, class diagrams, state diagrams, and pie charts. These diagrams can help you express complex concepts, processes, and data structures more clearly.

    To use Mermaid, simply specify the mermaid language in a code block and describe the diagram using concise text syntax. Mermaid will automatically convert these descriptions into beautiful visual diagrams.

    Try using Mermaid diagrams in your next technical blog post or project documentation - they will make your content more professional and easier to understand!

    Markdown Mermaid
    https://oss-runtime.dev/blog/posts/markdown-mermaid/
    作者
    FutureOSS
    发布于
    2023-10-01
    许可协议
    Apache 2.0
    Markdown Tutorial
    Markdown Example
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/posts/markdown-tutorial/index.html b/website/blog/posts/markdown-tutorial/index.html deleted file mode 100644 index df18498..0000000 --- a/website/blog/posts/markdown-tutorial/index.html +++ /dev/null @@ -1,909 +0,0 @@ - Markdown Tutorial - FutureOSS Docs - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video
    1700 字
    9 分钟
    Markdown Tutorial
    2025-01-20
    Examples
    /
    - Markdown
    /
    - Blogging

    Markdown Tutorial#

    A markdown example shows how to write a markdown file. This document integrates core syntax and extensions (GMF).

      -
    • Block Elements -
        -
      • Paragraphs and Line Breaks
      • -
      • Headers
      • -
      • Blockquotes
      • -
      • Lists
      • -
      • Code Blocks
      • -
      • Horizontal Rules
      • -
      • Table
      • -
      -
    • -
    • Span Elements -
        -
      • Links
      • -
      • Emphasis
      • -
      • Code
      • -
      • Images
      • -
      • Strikethrough
      • -
      -
    • -
    • Miscellaneous -
        -
      • Automatic Links
      • -
      • Backslash Escapes
      • -
      -
    • -
    • Inline HTML
    • -

    Block Elements#

    Paragraphs and Line Breaks#

    Paragraphs#

    HTML Tag: <p>

    One or more blank lines. (A blank line is a line containing nothing but spaces or tabs is considered blank.)

    Code:

    1
    This will be
    2
    inline.
    3
    -
    4
    This is second paragraph.

    Preview:


    This will be -inline.

    This is second paragraph.


    Line Breaks#

    HTML Tag: <br />

    End a line with two or more spaces.

    Code:

    1
    This will be not
    2
    inline.

    Preview:


    This will be not
    -inline.


    Headers#

    Markdown supports two styles of headers, Setext and atx.

    Setext#

    HTML Tags: <h1>, <h2>

    “Underlined” using equal signs (=) as <h1> and dashes (-) as <h2> in any number.

    Code:

    1
    This is an H1
    2
    =============
    3
    This is an H2
    4
    -------------

    Preview:


    -

    This is an H1#

    This is an H2#


    atx#

    HTML Tags: <h1>, <h2>, <h3>, <h4>, <h5>, <h6>

    Uses 1-6 hash characters (#) at the start of the line, corresponding to <h1> - <h6>.

    Code:

    1
    # This is an H1
    2
    ## This is an H2
    3
    ###### This is an H6

    Preview:


    -

    This is an H1#

    This is an H2#

    This is an H6#

    Optionally, you may “close” atx-style headers. The closing hashes don’t need to match the number of hashes used to open the header.

    Code:

    1
    # This is an H1 #
    2
    ## This is an H2 ##
    3
    ### This is an H3 ######

    Preview:


    -

    This is an H1#

    This is an H2#

    This is an H3#


    Blockquotes#

    HTML Tag: <blockquote>

    Markdown uses email-style > characters for blockquoting. It looks best if you hard wrap the text and put a > before every line.

    Code:

    1
    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
    2
    > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
    3
    > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    4
    >
    5
    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
    6
    > id sem consectetuer libero luctus adipiscing.

    Preview:


    -

    This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, -consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. -Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

    -

    Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse -id sem consectetuer libero luctus adipiscing.

    -

    Markdown allows you to be lazy and only put the > before the first line of a hard-wrapped paragraph.

    Code:

    1
    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
    2
    consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
    3
    Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
    4
    -
    5
    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
    6
    id sem consectetuer libero luctus adipiscing.

    Preview:


    -

    This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, -consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. -Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

    -
    -

    Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse -id sem consectetuer libero luctus adipiscing.

    -

    Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by adding additional levels of >.

    Code:

    1
    > This is the first level of quoting.
    2
    >
    3
    > > This is nested blockquote.
    4
    >
    5
    > Back to the first level.

    Preview:


    -

    This is the first level of quoting.

    -
    -

    This is nested blockquote.

    -
    -

    Back to the first level.

    -

    Blockquotes can contain other Markdown elements, including headers, lists, and code blocks.

    Code:

    1
    > ## This is a header.
    2
    >
    3
    > 1. This is the first list item.
    4
    > 2. This is the second list item.
    5
    >
    6
    > Here's some example code:
    7
    >
    8
    > return shell_exec("echo $input | $markdown_script");

    Preview:


    -

    This is a header.#

    -
      -
    1. This is the first list item.
    2. -
    3. This is the second list item.
    4. -
    -

    Here’s some example code:

    -
    1
    return shell_exec("echo $input | $markdown_script");
    -

    Lists#

    Markdown supports ordered (numbered) and unordered (bulleted) lists.

    Unordered#

    HTML Tag: <ul>

    Unordered lists use asterisks (*), pluses (+), and hyphens (-).

    Code:

    1
    * Red
    2
    * Green
    3
    * Blue

    Preview:


      -
    • Red
    • -
    • Green
    • -
    • Blue
    • -

    is equivalent to:

    Code:

    1
    + Red
    2
    + Green
    3
    + Blue

    and:

    Code:

    1
    - Red
    2
    - Green
    3
    - Blue

    Ordered#

    HTML Tag: <ol>

    Ordered lists use numbers followed by periods:

    Code:

    1
    1. Bird
    2
    2. McHale
    3
    3. Parish

    Preview:


      -
    1. Bird
    2. -
    3. McHale
    4. -
    5. Parish
    6. -

    It’s possible to trigger an ordered list by accident, by writing something like this:

    Code:

    1
    1986. What a great season.

    Preview:


      -
    1. What a great season.
    2. -

    You can backslash-escape (\) the period:

    Code:

    1
    1986\. What a great season.

    Preview:


    1986. What a great season.


    Indented#

    Blockquote#

    To put a blockquote within a list item, the blockquote’s > delimiters need to be indented:

    Code:

    1
    * A list item with a blockquote:
    2
    -
    3
    > This is a blockquote
    4
    > inside a list item.

    Preview:


      -
    • -

      A list item with a blockquote:

      -
      -

      This is a blockquote -inside a list item.

      -
      -
    • -

    Code Block#

    To put a code block within a list item, the code block needs to be indented twice — 8 spaces or two tabs:

    Code:

    1
    * A list item with a code block:
    2
    -
    3
    <code goes here>

    Preview:


      -
    • -

      A list item with a code block:

      -
      1
      <code goes here>
      -
    • -

    Nested List#

    Code:

    1
    * A
    2
    * A1
    3
    * A2
    4
    * B
    5
    * C

    Preview:


      -
    • A -
        -
      • A1
      • -
      • A2
      • -
      -
    • -
    • B
    • -
    • C
    • -

    Code Blocks#

    HTML Tag: <pre>

    Indent every line of the block by at least 4 spaces or 1 tab.

    Code:

    1
    This is a normal paragraph:
    2
    -
    3
    This is a code block.

    Preview:


    This is a normal paragraph:

    1
    This is a code block.

    A code block continues until it reaches a line that is not indented (or the end of the article).

    Within a code block, ampersands (&) and angle brackets (< and >) are automatically converted into HTML entities.

    Code:

    1
    <div class="footer">
    2
    &copy; 2004 Foo Corporation
    3
    </div>

    Preview:


    1
    <div class="footer">
    2
    &copy; 2004 Foo Corporation
    3
    </div>

    Following sections Fenced Code Blocks and Syntax Highlighting are extensions, you can use the other way to write the code block.

    Fenced Code Blocks#

    Just wrap your code in ``` (as shown below) and you won’t need to indent it by four spaces.

    Code:

    1
    Here's an example:
    2
    -
    3
    ```
    4
    function test() {
    5
    console.log("notice the blank line before this function?");
    6
    }
    7
    ```

    Preview:


    Here’s an example:

    1
    function test() {
    2
    console.log("notice the blank line before this function?");
    3
    }

    Syntax Highlighting#

    In your fenced block, add an optional language identifier and we’ll run it through syntax highlighting (Support Languages).

    Code:

    1
    ```ruby
    2
    require 'redcarpet'
    3
    markdown = Redcarpet.new("Hello World!")
    4
    puts markdown.to_html
    5
    ```

    Preview:


    1
    require 'redcarpet'
    2
    markdown = Redcarpet.new("Hello World!")
    3
    puts markdown.to_html

    Horizontal Rules#

    HTML Tag: <hr /> -Places three or more hyphens (-), asterisks (*), or underscores (_) on a line by themselves. You may use spaces between the hyphens or asterisks.

    Code:

    1
    * * *
    2
    ***
    3
    *****
    4
    - - -
    5
    ---------------------------------------
    6
    ___

    Preview:









    Table#

    HTML Tag: <table>

    It’s an extension.

    Separates column by pipe (|) and header by dashes (-), and uses colon (:) for alignment.

    The outer pipes (|) and alignment are optional. There are 3 delimiters each cell at least for separating header.

    Code:

    1
    | Left | Center | Right |
    2
    |:-----|:------:|------:|
    3
    |aaa |bbb |ccc |
    4
    |ddd |eee |fff |
    5
    -
    6
    A | B
    7
    ---|---
    8
    123|456
    9
    -
    10
    -
    11
    A |B
    12
    --|--
    13
    12|45

    Preview:


    - - - - - - - - - - - - - - - - - - - -
    LeftCenterRight
    aaabbbccc
    dddeeefff
    - - - - - - - - - - - - -
    AB
    123456
    - - - - - - - - - - - - -
    AB
    1245

    Span Elements#

    Links#

    HTML Tag: <a>

    Markdown supports two style of links: inline and reference.

    Inline#

    Inline link format like this: [Link Text](URL "Title")

    Title is optional.

    Code:

    1
    This is [an example](http://example.com/ "Title") inline link.
    2
    -
    3
    [This link](http://example.net/) has no title attribute.

    Preview:


    This is an example inline link.

    This link has no title attribute.


    If you’re referring to a local resource on the same server, you can use relative paths:

    Code:

    1
    See my [About](/about/) page for details.

    Preview:


    See my About page for details.


    Reference#

    You could predefine link references. Format like this: [id]: URL "Title"

    Title is also optional. And the you refer the link, format like this: [Link Text][id]

    Code:

    1
    [id]: http://example.com/ "Optional Title Here"
    2
    This is [an example][id] reference-style link.

    Preview:


    This is an example reference-style link.


    That is:

      -
    • Square brackets containing the link identifier (not case sensitive, optionally indented from the left margin using up to three spaces);
    • -
    • followed by a colon;
    • -
    • followed by one or more spaces (or tabs);
    • -
    • followed by the URL for the link;
    • -
    • The link URL may, optionally, be surrounded by angle brackets.
    • -
    • optionally followed by a title attribute for the link, enclosed in double or single quotes, or enclosed in parentheses.
    • -

    The following three link definitions are equivalent:

    Code:

    1
    [foo]: http://example.com/ "Optional Title Here"
    2
    [foo]: http://example.com/ 'Optional Title Here'
    3
    [foo]: http://example.com/ (Optional Title Here)
    4
    [foo]: <http://example.com/> "Optional Title Here"

    Uses an empty set of square brackets, the link text itself is used as the name.

    Code:

    1
    [Google]: http://google.com/
    2
    [Google][]

    Preview:


    Google


    Emphasis#

    HTML Tags: <em>, <strong>

    Markdown treats asterisks (*) and underscores (_) as indicators of emphasis. One delimiter will be <em>; *double delimiters will be <strong>.

    Code:

    1
    *single asterisks*
    2
    -
    3
    _single underscores_
    4
    -
    5
    **double asterisks**
    6
    -
    7
    __double underscores__

    Preview:


    single asterisks

    single underscores

    double asterisks

    double underscores


    But if you surround an * or _ with spaces, it’ll be treated as a literal asterisk or underscore.

    You can backslash escape it:

    Code:

    1
    \*this text is surrounded by literal asterisks\*

    Preview:


    *this text is surrounded by literal asterisks*


    Code#

    HTML Tag: <code>

    Wraps it with backtick quotes (`).

    Code:

    1
    Use the `printf()` function.

    Preview:


    Use the printf() function.


    To include a literal backtick character within a code span, you can use multiple backticks as the opening and closing delimiters:

    Code:

    1
    ``There is a literal backtick (`) here.``

    Preview:


    There is a literal backtick (`) here.


    The backtick delimiters surrounding a code span may include spaces — one after the opening, one before the closing. This allows you to place literal backtick characters at the beginning or end of a code span:

    Code:

    1
    A single backtick in a code span: `` ` ``
    2
    -
    3
    A backtick-delimited string in a code span: `` `foo` ``

    Preview:


    A single backtick in a code span: `

    A backtick-delimited string in a code span: `foo`


    Images#

    HTML Tag: <img />

    Markdown uses an image syntax that is intended to resemble the syntax for links, allowing for two styles: inline and reference.

    Inline#

    Inline image syntax looks like this: ![Alt text](URL "Title")

    Title is optional.

    Code:

    1
    ![Alt text](/path/to/img.jpg)
    2
    -
    3
    ![Alt text](/path/to/img.jpg "Optional title")

    Preview:


    Alt text

    Alt text


    That is:

      -
    • An exclamation mark: !;
    • -
    • followed by a set of square brackets, containing the alt attribute text for the image;
    • -
    • followed by a set of parentheses, containing the URL or path to the image, and an optional title attribute enclosed in double or single quotes.
    • -

    Reference#

    Reference-style image syntax looks like this: ![Alt text][id]

    Code:

    1
    [img id]: https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp "Optional title attribute"
    2
    ![Alt text][img id]

    Preview:


    Alt text


    Strikethrough#

    HTML Tag: <del>

    It’s an extension.

    GFM adds syntax to strikethrough text.

    Code:

    1
    ~~Mistaken text.~~

    Preview:


    Mistaken text.


    Miscellaneous#

    Automatic Links#

    Markdown supports a shortcut style for creating “automatic” links for URLs and email addresses: simply surround the URL or email address with angle brackets.

    Code:

    1
    <http://example.com/>
    2
    -
    3
    <address@example.com>

    Preview:


    http://example.com/

    address@example.com


    GFM will autolink standard URLs.

    Code:

    1
    https://github.com/emn178/markdown

    Preview:


    https://github.com/emn178/markdown


    Backslash Escapes#

    Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown’s formatting syntax.

    Code:

    1
    \*literal asterisks\*

    Preview:


    *literal asterisks*


    Markdown provides backslash escapes for the following characters:

    Code:

    1
    \ backslash
    2
    ` backtick
    3
    * asterisk
    4
    _ underscore
    5
    {} curly braces
    6
    [] square brackets
    7
    () parentheses
    8
    # hash mark
    9
    + plus sign
    10
    - minus sign (hyphen)
    11
    . dot
    12
    ! exclamation mark

    Inline HTML#

    For any markup that is not covered by Markdown’s syntax, you simply use HTML itself. There’s no need to preface it or delimit it to indicate that you’re switching from Markdown to HTML; you just use the tags.

    Code:

    1
    This is a regular paragraph.
    2
    -
    3
    <table>
    4
    <tr>
    5
    <td>Foo</td>
    6
    </tr>
    7
    </table>
    8
    -
    9
    This is another regular paragraph.

    Preview:


    This is a regular paragraph.

    - - - -
    Foo

    This is another regular paragraph.


    Note that Markdown formatting syntax is not processed within block-level HTML tags.

    Unlike block-level HTML tags, Markdown syntax is processed within span-level tags.

    Code:

    1
    <span>**Work**</span>
    2
    -
    3
    <div>
    4
    **No Work**
    5
    </div>

    Preview:


    Work

    - **No Work** -
    -***
    Markdown Tutorial
    https://github.com/emn178/markdown
    作者
    emn178
    发布于
    2025-01-20
    许可协议
    Unlicensed
    Markdown Mermaid
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/posts/markdown/index.html b/website/blog/posts/markdown/index.html deleted file mode 100644 index 13263b2..0000000 --- a/website/blog/posts/markdown/index.html +++ /dev/null @@ -1,798 +0,0 @@ - Markdown Example - FutureOSS Docs - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video
    438 字
    2 分钟
    Markdown Example
    2023-10-01
    Examples
    /
    - Markdown
    /
    - Blogging

    An h1 header#

    Paragraphs are separated by a blank line.

    2nd paragraph. Italic, bold, and monospace. Itemized lists -look like:

      -
    • this one
    • -
    • that one
    • -
    • the other one
    • -

    Note that --- not considering the asterisk --- the actual text -content starts at 4-columns in.

    -

    Block quotes are -written like so.

    -

    They can span multiple paragraphs, -if you like.

    -

    Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., “it’s all -in chapters 12—14”). Three dots … will be converted to an ellipsis. -Unicode is supported. ☺

    An h2 header#

    Here’s a numbered list:

      -
    1. first item
    2. -
    3. second item
    4. -
    5. third item
    6. -

    Note again how the actual text starts at 4 columns in (4 characters -from the left side). Here’s a code sample:

    1
    # Let me re-iterate ...
    2
    for i in 1 .. 10 { do-something(i) }

    As you probably guessed, indented 4 spaces. By the way, instead of -indenting the block, you can use delimited blocks, if you like:

    1
    define foobar() {
    2
    print "Welcome to flavor country!";
    3
    }

    (which makes copying & pasting easier). You can optionally mark the -delimited block for Pandoc to syntax highlight it:

    1
    import time
    2
    # Quick, count to ten!
    3
    for i in range(10):
    4
    # (but not *too* quick)
    5
    time.sleep(0.5)
    6
    print i

    An h3 header#

    Now a nested list:

      -
    1. -

      First, get these ingredients:

      -
        -
      • carrots
      • -
      • celery
      • -
      • lentils
      • -
      -
    2. -
    3. -

      Boil some water.

      -
    4. -
    5. -

      Dump everything in the pot and follow -this algorithm:

      -
      1
      find wooden spoon
      2
      uncover pot
      3
      stir
      4
      cover pot
      5
      balance wooden spoon precariously on pot handle
      6
      wait 10 minutes
      7
      goto first step (or shut off burner when done)
      -

      Do not bump wooden spoon or it will fall.

      -
    6. -

    Notice again how text always lines up on 4-space indents (including -that last line which continues item 3 above).

    Here’s a link to a website, to a local -doc, and to a section heading in the current -doc. Here’s a footnote 1.

    Tables can look like this:

    size material color


    9 leather brown -10 hemp canvas natural -11 glass transparent

    Table: Shoes, their sizes, and what they’re made of

    (The above is the caption for the table.) Pandoc also supports -multi-line tables:


    keyword text


    red Sunsets, apples, and -other red or reddish -things.

    green Leaves, grass, frogs -and other things it’s -not easy being.


    A horizontal rule follows.


    Here’s a definition list:

    apples -: Good for making applesauce. -oranges -: Citrus! -tomatoes -: There’s no “e” in tomatoe.

    Again, text is indented 4 spaces. (Put a blank line between each -term/definition pair to spread things out more.)

    Here’s a “line block”:

    | Line one -| Line too -| Line tree

    and images can be specified like so:

    Inline math equations go in like so: ω=dϕ/dt\omega = d\phi / dtω=dϕ/dt. Display -math should get its own line and be put in in double-dollarsigns:

    I=∫ρR2dVI = \int \rho R^{2} dVI=∫ρR2dV

    And note that you can backslash-escape any punctuation characters -which you wish to be displayed literally, ex.: `foo`, *bar*, etc.

    -

    Footnotes#

    -
      -
    1. -

      Footnote text goes here. ↩

      -
    2. -
    -
    Markdown Example
    https://oss-runtime.dev/blog/posts/markdown/
    作者
    FutureOSS
    发布于
    2023-10-01
    许可协议
    Apache 2.0
    Markdown Mermaid
    Include Video in the Posts
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/posts/video/index.html b/website/blog/posts/video/index.html deleted file mode 100644 index 624744e..0000000 --- a/website/blog/posts/video/index.html +++ /dev/null @@ -1,737 +0,0 @@ - Include Video in the Posts - FutureOSS Docs - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video
    62 字
    1 分钟
    Include Video in the Posts
    2022-08-01
    Examples
    /
    - Example
    /
    - Video

    Just copy the embed code from YouTube or other platforms, and paste it in the markdown file.

    -
    1
    ---
    2
    title: Include Video in the Post
    3
    published: 2023-10-19
    4
    // ...
    5
    ---
    6
    -
    7
    <iframe width="100%" height="468" src="https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_" title="YouTube video player" frameborder="0" allowfullscreen></iframe>
    -

    YouTube#

    -

    Bilibili#

    Include Video in the Posts
    https://oss-runtime.dev/blog/posts/video/
    作者
    FutureOSS
    发布于
    2022-08-01
    许可协议
    Apache 2.0
    Markdown Example
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/projects/index.html b/website/blog/projects/index.html deleted file mode 100644 index 9101e67..0000000 --- a/website/blog/projects/index.html +++ /dev/null @@ -1,731 +0,0 @@ - 项目展示 - FutureOSS Docs - - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video

    项目展示

    我的开发项目作品集

    5
    项目总数
    3
    已完成
    1
    进行中
    15
    技术栈统计

    精选项目

    Mizuki Blog Theme

    已完成

    基于Astro框架开发的现代化博客主题,支持多语言、暗黑模式、响应式设计等功能。

    Astro TypeScript Tailwind CSS Svelte

    Personal Portfolio

    已完成

    个人作品集网站,展示项目经验和技术技能。

    React Next.js TypeScript Framer Motion

    网页应用 -(4) -

    Mizuki Blog Theme

    已完成

    基于Astro框架开发的现代化博客主题,支持多语言、暗黑模式、响应式设计等功能。

    Astro TypeScript Tailwind CSS -+1

    Personal Portfolio

    已完成

    个人作品集网站,展示项目经验和技术技能。

    React Next.js TypeScript -+1

    Data Visualization Tool

    已完成

    数据可视化工具,支持多种图表类型和交互式分析。

    Vue.js D3.js TypeScript -+1

    E-commerce Platform

    计划中

    全栈电商平台,包含用户管理、商品管理、订单处理等功能。

    Next.js Node.js PostgreSQL -+1

    移动应用 -(1) -

    Task Manager App

    进行中

    跨平台任务管理应用,支持团队协作和项目管理。

    React Native TypeScript Redux -+1

    技术栈统计

    Astro D3.js Firebase Framer Motion Next.js Node.js PostgreSQL React React Native Redux Stripe Svelte Tailwind CSS TypeScript Vue.js
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/robots.txt b/website/blog/robots.txt deleted file mode 100644 index 310b31c..0000000 --- a/website/blog/robots.txt +++ /dev/null @@ -1,4 +0,0 @@ -User-agent: * -Disallow: /_astro/ - -Sitemap: https://oss-runtime.dev/sitemap-index.xml \ No newline at end of file diff --git a/website/blog/rss.xml b/website/blog/rss.xml deleted file mode 100644 index 16c34d8..0000000 --- a/website/blog/rss.xml +++ /dev/null @@ -1,996 +0,0 @@ -FutureOSS Docs一切皆为插件的开发者工具运行时框架https://oss-runtime.dev/zh_CNMarkdown Tutorialhttps://oss-runtime.dev/blog/posts/markdown-tutorial/https://oss-runtime.dev/blog/posts/markdown-tutorial/A simple example of a Markdown blog post.Mon, 20 Jan 2025 00:00:00 GMT<h1>Markdown Tutorial</h1> -<p>A markdown example shows how to write a markdown file. This document integrates core syntax and extensions (GMF).</p> -<ul> -<li><a href="#block-elements">Block Elements</a> -<ul> -<li><a href="#paragraphs-and-line-breaks">Paragraphs and Line Breaks</a></li> -<li><a href="#headers">Headers</a></li> -<li><a href="#blockquotes">Blockquotes</a></li> -<li><a href="#lists">Lists</a></li> -<li><a href="#code-blocks">Code Blocks</a></li> -<li><a href="#horizontal-rules">Horizontal Rules</a></li> -<li><a href="#table">Table</a></li> -</ul> -</li> -<li><a href="#span-elements">Span Elements</a> -<ul> -<li><a href="#links">Links</a></li> -<li><a href="#emphasis">Emphasis</a></li> -<li><a href="#code">Code</a></li> -<li><a href="#images">Images</a></li> -<li><a href="#strikethrough">Strikethrough</a></li> -</ul> -</li> -<li><a href="#miscellaneous">Miscellaneous</a> -<ul> -<li><a href="#automatic-links">Automatic Links</a></li> -<li><a href="#backslash-escapes">Backslash Escapes</a></li> -</ul> -</li> -<li><a href="#inline-html">Inline HTML</a></li> -</ul> -<h2>Block Elements</h2> -<h3>Paragraphs and Line Breaks</h3> -<h4>Paragraphs</h4> -<p>HTML Tag: <code>&lt;p&gt;</code></p> -<p>One or more blank lines. (A blank line is a line containing nothing but <strong>spaces</strong> or <strong>tabs</strong> is considered blank.)</p> -<p>Code:</p> -<pre><code>This will be -inline. - -This is second paragraph. -</code></pre> -<p>Preview:</p> -<hr /> -<p>This will be -inline.</p> -<p>This is second paragraph.</p> -<hr /> -<h4>Line Breaks</h4> -<p>HTML Tag: <code>&lt;br /&gt;</code></p> -<p>End a line with <strong>two or more spaces</strong>.</p> -<p>Code:</p> -<pre><code>This will be not -inline. -</code></pre> -<p>Preview:</p> -<hr /> -<p>This will be not<br /> -inline.</p> -<hr /> -<h3>Headers</h3> -<p>Markdown supports two styles of headers, Setext and atx.</p> -<h4>Setext</h4> -<p>HTML Tags: <code>&lt;h1&gt;</code>, <code>&lt;h2&gt;</code></p> -<p>“Underlined” using <strong>equal signs (=)</strong> as <code>&lt;h1&gt;</code> and <strong>dashes (-)</strong> as <code>&lt;h2&gt;</code> in any number.</p> -<p>Code:</p> -<pre><code>This is an H1 -============= -This is an H2 -------------- -</code></pre> -<p>Preview:</p> -<hr /> -<h1>This is an H1</h1> -<h2>This is an H2</h2> -<hr /> -<h4>atx</h4> -<p>HTML Tags: <code>&lt;h1&gt;</code>, <code>&lt;h2&gt;</code>, <code>&lt;h3&gt;</code>, <code>&lt;h4&gt;</code>, <code>&lt;h5&gt;</code>, <code>&lt;h6&gt;</code></p> -<p>Uses 1-6 <strong>hash characters (#)</strong> at the start of the line, corresponding to <code>&lt;h1&gt;</code> - <code>&lt;h6&gt;</code>.</p> -<p>Code:</p> -<pre><code># This is an H1 -## This is an H2 -###### This is an H6 -</code></pre> -<p>Preview:</p> -<hr /> -<h1>This is an H1</h1> -<h2>This is an H2</h2> -<h6>This is an H6</h6> -<hr /> -<p>Optionally, you may “close” atx-style headers. The closing hashes <strong>don’t need to match</strong> the number of hashes used to open the header.</p> -<p>Code:</p> -<pre><code># This is an H1 # -## This is an H2 ## -### This is an H3 ###### -</code></pre> -<p>Preview:</p> -<hr /> -<h1>This is an H1</h1> -<h2>This is an H2</h2> -<h3>This is an H3</h3> -<hr /> -<h3>Blockquotes</h3> -<p>HTML Tag: <code>&lt;blockquote&gt;</code></p> -<p>Markdown uses email-style <strong>&gt;</strong> characters for blockquoting. It looks best if you hard wrap the text and put a &gt; before every line.</p> -<p>Code:</p> -<pre><code>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, -&gt; consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. -&gt; Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. -&gt; -&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse -&gt; id sem consectetuer libero luctus adipiscing. -</code></pre> -<p>Preview:</p> -<hr /> -<blockquote> -<p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, -consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. -Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p> -<p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse -id sem consectetuer libero luctus adipiscing.</p> -</blockquote> -<hr /> -<p>Markdown allows you to be lazy and only put the &gt; before the first line of a hard-wrapped paragraph.</p> -<p>Code:</p> -<pre><code>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, -consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. -Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. - -&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse -id sem consectetuer libero luctus adipiscing. -</code></pre> -<p>Preview:</p> -<hr /> -<blockquote> -<p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, -consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. -Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p> -</blockquote> -<blockquote> -<p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse -id sem consectetuer libero luctus adipiscing.</p> -</blockquote> -<hr /> -<p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by adding additional levels of &gt;.</p> -<p>Code:</p> -<pre><code>&gt; This is the first level of quoting. -&gt; -&gt; &gt; This is nested blockquote. -&gt; -&gt; Back to the first level. -</code></pre> -<p>Preview:</p> -<hr /> -<blockquote> -<p>This is the first level of quoting.</p> -<blockquote> -<p>This is nested blockquote.</p> -</blockquote> -<p>Back to the first level.</p> -</blockquote> -<hr /> -<p>Blockquotes can contain other Markdown elements, including headers, lists, and code blocks.</p> -<p>Code:</p> -<pre><code>&gt; ## This is a header. -&gt; -&gt; 1. This is the first list item. -&gt; 2. This is the second list item. -&gt; -&gt; Here's some example code: -&gt; -&gt; return shell_exec("echo $input | $markdown_script"); -</code></pre> -<p>Preview:</p> -<hr /> -<blockquote> -<h2>This is a header.</h2> -<ol> -<li>This is the first list item.</li> -<li>This is the second list item.</li> -</ol> -<p>Here's some example code:</p> -<pre><code>return shell_exec("echo $input | $markdown_script"); -</code></pre> -</blockquote> -<hr /> -<h3>Lists</h3> -<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p> -<h4>Unordered</h4> -<p>HTML Tag: <code>&lt;ul&gt;</code></p> -<p>Unordered lists use <strong>asterisks (*)</strong>, <strong>pluses (+)</strong>, and <strong>hyphens (-)</strong>.</p> -<p>Code:</p> -<pre><code>* Red -* Green -* Blue -</code></pre> -<p>Preview:</p> -<hr /> -<ul> -<li>Red</li> -<li>Green</li> -<li>Blue</li> -</ul> -<hr /> -<p>is equivalent to:</p> -<p>Code:</p> -<pre><code>+ Red -+ Green -+ Blue -</code></pre> -<p>and:</p> -<p>Code:</p> -<pre><code>- Red -- Green -- Blue -</code></pre> -<h4>Ordered</h4> -<p>HTML Tag: <code>&lt;ol&gt;</code></p> -<p>Ordered lists use numbers followed by periods:</p> -<p>Code:</p> -<pre><code>1. Bird -2. McHale -3. Parish -</code></pre> -<p>Preview:</p> -<hr /> -<ol> -<li>Bird</li> -<li>McHale</li> -<li>Parish</li> -</ol> -<hr /> -<p>It’s possible to trigger an ordered list by accident, by writing something like this:</p> -<p>Code:</p> -<pre><code>1986. What a great season. -</code></pre> -<p>Preview:</p> -<hr /> -<ol> -<li>What a great season.</li> -</ol> -<hr /> -<p>You can <strong>backslash-escape (\)</strong> the period:</p> -<p>Code:</p> -<pre><code>1986\. What a great season. -</code></pre> -<p>Preview:</p> -<hr /> -<p>1986. What a great season.</p> -<hr /> -<h4>Indented</h4> -<h5>Blockquote</h5> -<p>To put a blockquote within a list item, the blockquote’s &gt; delimiters need to be indented:</p> -<p>Code:</p> -<pre><code>* A list item with a blockquote: - - &gt; This is a blockquote - &gt; inside a list item. -</code></pre> -<p>Preview:</p> -<hr /> -<ul> -<li> -<p>A list item with a blockquote:</p> -<blockquote> -<p>This is a blockquote -inside a list item.</p> -</blockquote> -</li> -</ul> -<hr /> -<h5>Code Block</h5> -<p>To put a code block within a list item, the code block needs to be indented twice — <strong>8 spaces</strong> or <strong>two tabs</strong>:</p> -<p>Code:</p> -<pre><code>* A list item with a code block: - - &lt;code goes here&gt; -</code></pre> -<p>Preview:</p> -<hr /> -<ul> -<li> -<p>A list item with a code block:</p> -<pre><code>&lt;code goes here&gt; -</code></pre> -</li> -</ul> -<hr /> -<h5>Nested List</h5> -<p>Code:</p> -<pre><code>* A - * A1 - * A2 -* B -* C -</code></pre> -<p>Preview:</p> -<hr /> -<ul> -<li>A -<ul> -<li>A1</li> -<li>A2</li> -</ul> -</li> -<li>B</li> -<li>C</li> -</ul> -<hr /> -<h3>Code Blocks</h3> -<p>HTML Tag: <code>&lt;pre&gt;</code></p> -<p>Indent every line of the block by at least <strong>4 spaces</strong> or <strong>1 tab</strong>.</p> -<p>Code:</p> -<pre><code>This is a normal paragraph: - - This is a code block. -</code></pre> -<p>Preview:</p> -<hr /> -<p>This is a normal paragraph:</p> -<pre><code>This is a code block. -</code></pre> -<hr /> -<p>A code block continues until it reaches a line that is not indented (or the end of the article).</p> -<p>Within a code block, <strong><em>ampersands (&amp;)</em></strong> and angle <strong>brackets (&lt; and &gt;)</strong> are automatically converted into HTML entities.</p> -<p>Code:</p> -<pre><code> &lt;div class="footer"&gt; - &amp;copy; 2004 Foo Corporation - &lt;/div&gt; -</code></pre> -<p>Preview:</p> -<hr /> -<pre><code>&lt;div class="footer"&gt; - &amp;copy; 2004 Foo Corporation -&lt;/div&gt; -</code></pre> -<hr /> -<p>Following sections Fenced Code Blocks and Syntax Highlighting are extensions, you can use the other way to write the code block.</p> -<h4>Fenced Code Blocks</h4> -<p>Just wrap your code in <code>```</code> (as shown below) and you won't need to indent it by four spaces.</p> -<p>Code:</p> -<pre><code>Here's an example: - -``` -function test() { - console.log("notice the blank line before this function?"); -} -``` -</code></pre> -<p>Preview:</p> -<hr /> -<p>Here's an example:</p> -<pre><code>function test() { - console.log("notice the blank line before this function?"); -} -</code></pre> -<hr /> -<h4>Syntax Highlighting</h4> -<p>In your fenced block, add an optional language identifier and we'll run it through syntax highlighting (<a href="https://github.com/github/linguist/blob/master/lib/linguist/languages.yml">Support Languages</a>).</p> -<p>Code:</p> -<pre><code>```ruby -require 'redcarpet' -markdown = Redcarpet.new("Hello World!") -puts markdown.to_html -``` -</code></pre> -<p>Preview:</p> -<hr /> -<pre><code>require 'redcarpet' -markdown = Redcarpet.new("Hello World!") -puts markdown.to_html -</code></pre> -<hr /> -<h3>Horizontal Rules</h3> -<p>HTML Tag: <code>&lt;hr /&gt;</code> -Places <strong>three or more hyphens (-), asterisks (*), or underscores (_)</strong> on a line by themselves. You may use spaces between the hyphens or asterisks.</p> -<p>Code:</p> -<pre><code>* * * -*** -***** -- - - ---------------------------------------- -___ -</code></pre> -<p>Preview:</p> -<hr /> -<hr /> -<hr /> -<hr /> -<hr /> -<hr /> -<hr /> -<hr /> -<h3>Table</h3> -<p>HTML Tag: <code>&lt;table&gt;</code></p> -<p>It's an extension.</p> -<p>Separates column by <strong>pipe (|)</strong> and header by <strong>dashes (-)</strong>, and uses <strong>colon (:)</strong> for alignment.</p> -<p>The outer <strong>pipes (|)</strong> and alignment are optional. There are <strong>3 delimiters</strong> each cell at least for separating header.</p> -<p>Code:</p> -<pre><code>| Left | Center | Right | -|:-----|:------:|------:| -|aaa |bbb |ccc | -|ddd |eee |fff | - - A | B ----|--- -123|456 - - -A |B ---|-- -12|45 -</code></pre> -<p>Preview:</p> -<hr /> -<table> -<thead> -<tr> -<th>Left</th> -<th>Center</th> -<th>Right</th> -</tr> -</thead> -<tbody> -<tr> -<td>aaa</td> -<td>bbb</td> -<td>ccc</td> -</tr> -<tr> -<td>ddd</td> -<td>eee</td> -<td>fff</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>A</th> -<th>B</th> -</tr> -</thead> -<tbody> -<tr> -<td>123</td> -<td>456</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>A</th> -<th>B</th> -</tr> -</thead> -<tbody> -<tr> -<td>12</td> -<td>45</td> -</tr> -</tbody> -</table> -<hr /> -<h2>Span Elements</h2> -<h3>Links</h3> -<p>HTML Tag: <code>&lt;a&gt;</code></p> -<p>Markdown supports two style of links: inline and reference.</p> -<h4>Inline</h4> -<p>Inline link format like this: <code>[Link Text](URL "Title")</code></p> -<p>Title is optional.</p> -<p>Code:</p> -<pre><code>This is [an example](http://example.com/ "Title") inline link. - -[This link](http://example.net/) has no title attribute. -</code></pre> -<p>Preview:</p> -<hr /> -<p>This is <a href="http://example.com/">an example</a> inline link.</p> -<p><a href="http://example.net/">This link</a> has no title attribute.</p> -<hr /> -<p>If you’re referring to a local resource on the same server, you can use relative paths:</p> -<p>Code:</p> -<pre><code>See my [About](/about/) page for details. -</code></pre> -<p>Preview:</p> -<hr /> -<p>See my <a href="/about/">About</a> page for details.</p> -<hr /> -<h4>Reference</h4> -<p>You could predefine link references. Format like this: <code>[id]: URL "Title"</code></p> -<p>Title is also optional. And the you refer the link, format like this: <code>[Link Text][id]</code></p> -<p>Code:</p> -<pre><code>[id]: http://example.com/ "Optional Title Here" -This is [an example][id] reference-style link. -</code></pre> -<p>Preview:</p> -<hr /> -<p>This is <a href="http://example.com/">an example</a> reference-style link.</p> -<hr /> -<p>That is:</p> -<ul> -<li>Square brackets containing the link identifier (<strong>not case sensitive</strong>, optionally indented from the left margin using up to three spaces);</li> -<li>followed by a colon;</li> -<li>followed by one or more spaces (or tabs);</li> -<li>followed by the URL for the link;</li> -<li>The link URL may, optionally, be surrounded by angle brackets.</li> -<li>optionally followed by a title attribute for the link, enclosed in double or single quotes, or enclosed in parentheses.</li> -</ul> -<p>The following three link definitions are equivalent:</p> -<p>Code:</p> -<pre><code>[foo]: http://example.com/ "Optional Title Here" -[foo]: http://example.com/ 'Optional Title Here' -[foo]: http://example.com/ (Optional Title Here) -[foo]: &lt;http://example.com/&gt; "Optional Title Here" -</code></pre> -<p>Uses an empty set of square brackets, the link text itself is used as the name.</p> -<p>Code:</p> -<pre><code>[Google]: http://google.com/ -[Google][] -</code></pre> -<p>Preview:</p> -<hr /> -<p><a href="http://google.com/">Google</a></p> -<hr /> -<h3>Emphasis</h3> -<p>HTML Tags: <code>&lt;em&gt;</code>, <code>&lt;strong&gt;</code></p> -<p>Markdown treats <strong>asterisks (*)</strong> and <strong>underscores (_)</strong> as indicators of emphasis. <strong>One delimiter</strong> will be <code>&lt;em&gt;</code>; *<em>double delimiters</em> will be <code>&lt;strong&gt;</code>.</p> -<p>Code:</p> -<pre><code>*single asterisks* - -_single underscores_ - -**double asterisks** - -__double underscores__ -</code></pre> -<p>Preview:</p> -<hr /> -<p><em>single asterisks</em></p> -<p><em>single underscores</em></p> -<p><strong>double asterisks</strong></p> -<p><strong>double underscores</strong></p> -<hr /> -<p>But if you surround an * or _ with spaces, it’ll be treated as a literal asterisk or underscore.</p> -<p>You can backslash escape it:</p> -<p>Code:</p> -<pre><code>\*this text is surrounded by literal asterisks\* -</code></pre> -<p>Preview:</p> -<hr /> -<p>*this text is surrounded by literal asterisks*</p> -<hr /> -<h3>Code</h3> -<p>HTML Tag: <code>&lt;code&gt;</code></p> -<p>Wraps it with <strong>backtick quotes (`)</strong>.</p> -<p>Code:</p> -<pre><code>Use the `printf()` function. -</code></pre> -<p>Preview:</p> -<hr /> -<p>Use the <code>printf()</code> function.</p> -<hr /> -<p>To include a literal backtick character within a code span, you can use <strong>multiple backticks</strong> as the opening and closing delimiters:</p> -<p>Code:</p> -<pre><code>``There is a literal backtick (`) here.`` -</code></pre> -<p>Preview:</p> -<hr /> -<p><code>There is a literal backtick (`) here.</code></p> -<hr /> -<p>The backtick delimiters surrounding a code span may include spaces — one after the opening, one before the closing. This allows you to place literal backtick characters at the beginning or end of a code span:</p> -<p>Code:</p> -<pre><code>A single backtick in a code span: `` ` `` - -A backtick-delimited string in a code span: `` `foo` `` -</code></pre> -<p>Preview:</p> -<hr /> -<p>A single backtick in a code span: <code>`</code></p> -<p>A backtick-delimited string in a code span: <code>`foo`</code></p> -<hr /> -<h3>Images</h3> -<p>HTML Tag: <code>&lt;img /&gt;</code></p> -<p>Markdown uses an image syntax that is intended to resemble the syntax for links, allowing for two styles: inline and reference.</p> -<h4>Inline</h4> -<p>Inline image syntax looks like this: <code>![Alt text](URL "Title")</code></p> -<p>Title is optional.</p> -<p>Code:</p> -<pre><code>![Alt text](/path/to/img.jpg) - -![Alt text](/path/to/img.jpg "Optional title") -</code></pre> -<p>Preview:</p> -<hr /> -<p><img src="https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp" alt="Alt text" /></p> -<p><img src="https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp" alt="Alt text" title="Optional title" /></p> -<hr /> -<p>That is:</p> -<ul> -<li>An exclamation mark: !;</li> -<li>followed by a set of square brackets, containing the alt attribute text for the image;</li> -<li>followed by a set of parentheses, containing the URL or path to the image, and an optional title attribute enclosed in double or single quotes.</li> -</ul> -<h4>Reference</h4> -<p>Reference-style image syntax looks like this: <code>![Alt text][id]</code></p> -<p>Code:</p> -<pre><code>[img id]: https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp "Optional title attribute" -![Alt text][img id] -</code></pre> -<p>Preview:</p> -<hr /> -<p><img src="https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp" alt="Alt text" title="Optional title attribute" /></p> -<hr /> -<h3>Strikethrough</h3> -<p>HTML Tag: <code>&lt;del&gt;</code></p> -<p>It's an extension.</p> -<p>GFM adds syntax to strikethrough text.</p> -<p>Code:</p> -<pre><code>~~Mistaken text.~~ -</code></pre> -<p>Preview:</p> -<hr /> -<p><s>Mistaken text.</s></p> -<hr /> -<h2>Miscellaneous</h2> -<h3>Automatic Links</h3> -<p>Markdown supports a shortcut style for creating “automatic” links for URLs and email addresses: simply surround the URL or email address with angle brackets.</p> -<p>Code:</p> -<pre><code>&lt;http://example.com/&gt; - -&lt;address@example.com&gt; -</code></pre> -<p>Preview:</p> -<hr /> -<p><a href="http://example.com/">http://example.com/</a></p> -<p><a href="mailto:address@example.com">address@example.com</a></p> -<hr /> -<p>GFM will autolink standard URLs.</p> -<p>Code:</p> -<pre><code>https://github.com/emn178/markdown -</code></pre> -<p>Preview:</p> -<hr /> -<p>https://github.com/emn178/markdown</p> -<hr /> -<h3>Backslash Escapes</h3> -<p>Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown’s formatting syntax.</p> -<p>Code:</p> -<pre><code>\*literal asterisks\* -</code></pre> -<p>Preview:</p> -<hr /> -<p>*literal asterisks*</p> -<hr /> -<p>Markdown provides backslash escapes for the following characters:</p> -<p>Code:</p> -<pre><code>\ backslash -` backtick -* asterisk -_ underscore -{} curly braces -[] square brackets -() parentheses -# hash mark -+ plus sign -- minus sign (hyphen) -. dot -! exclamation mark -</code></pre> -<h2>Inline HTML</h2> -<p>For any markup that is not covered by Markdown’s syntax, you simply use HTML itself. There’s no need to preface it or delimit it to indicate that you’re switching from Markdown to HTML; you just use the tags.</p> -<p>Code:</p> -<pre><code>This is a regular paragraph. - -&lt;table&gt; - &lt;tr&gt; - &lt;td&gt;Foo&lt;/td&gt; - &lt;/tr&gt; -&lt;/table&gt; - -This is another regular paragraph. -</code></pre> -<p>Preview:</p> -<hr /> -<p>This is a regular paragraph.</p> -<p>&lt;table&gt; -&lt;tr&gt; -&lt;td&gt;Foo&lt;/td&gt; -&lt;/tr&gt; -&lt;/table&gt;</p> -<p>This is another regular paragraph.</p> -<hr /> -<p>Note that Markdown formatting syntax is <strong>not processed within block-level HTML tags</strong>.</p> -<p>Unlike block-level HTML tags, Markdown syntax is <strong>processed within span-level tags</strong>.</p> -<p>Code:</p> -<pre><code>&lt;span&gt;**Work**&lt;/span&gt; - -&lt;div&gt; - **No Work** -&lt;/div&gt; -</code></pre> -<p>Preview:</p> -<hr /> -<p>&lt;span&gt;<strong>Work</strong>&lt;/span&gt;</p> -<p>&lt;div&gt; -<strong>No Work</strong> -&lt;/div&gt;</p> -<hr /> -Markdown Mermaidhttps://oss-runtime.dev/blog/posts/markdown-mermaid/https://oss-runtime.dev/blog/posts/markdown-mermaid/A simple example of a Markdown blog post with Mermaid.Sun, 01 Oct 2023 00:00:00 GMT<h1>Complete Guide to Markdown with Mermaid Diagrams</h1> -<p>This article demonstrates how to create various complex diagrams using Mermaid in Markdown documents, including flowcharts, sequence diagrams, Gantt charts, class diagrams, and state diagrams.</p> -<h2>Flowchart Example</h2> -<p>Flowcharts are excellent for representing processes or algorithm steps.</p> -<pre><code>graph TD - A[Start] --&gt; B{Condition Check} - B --&gt;|Yes| C[Process Step 1] - B --&gt;|No| D[Process Step 2] - C --&gt; E[Subprocess] - D --&gt; E - subgraph E [Subprocess Details] - E1[Substep 1] --&gt; E2[Substep 2] - E2 --&gt; E3[Substep 3] - end - E --&gt; F{Another Decision} - F --&gt;|Option 1| G[Result 1] - F --&gt;|Option 2| H[Result 2] - F --&gt;|Option 3| I[Result 3] - G --&gt; J[End] - H --&gt; J - I --&gt; J -</code></pre> -<h2>Sequence Diagram Example</h2> -<p>Sequence diagrams show interactions between objects over time.</p> -<pre><code>sequenceDiagram - participant User - participant WebApp - participant Server - participant Database - - User-&gt;&gt;WebApp: Submit Login Request - WebApp-&gt;&gt;Server: Send Auth Request - Server-&gt;&gt;Database: Query User Credentials - Database--&gt;&gt;Server: Return User Data - Server--&gt;&gt;WebApp: Return Auth Result - - alt Auth Successful - WebApp-&gt;&gt;User: Show Welcome Page - WebApp-&gt;&gt;Server: Request User Data - Server-&gt;&gt;Database: Get User Preferences - Database--&gt;&gt;Server: Return Preferences - Server--&gt;&gt;WebApp: Return User Data - WebApp-&gt;&gt;User: Load Personalized Interface - else Auth Failed - WebApp-&gt;&gt;User: Show Error Message - WebApp-&gt;&gt;User: Prompt Re-entry - end -</code></pre> -<h2>Gantt Chart Example</h2> -<p>Gantt charts are perfect for displaying project schedules and timelines.</p> -<pre><code>gantt - title Website Development Project Timeline - dateFormat YYYY-MM-DD - axisFormat %m/%d - - section Design Phase - Requirements Analysis :a1, 2023-10-01, 7d - UI Design :a2, after a1, 10d - Prototype Creation :a3, after a2, 5d - - section Development Phase - Frontend Development :b1, 2023-10-20, 15d - Backend Development :b2, after a2, 18d - Database Design :b3, after a1, 12d - - section Testing Phase - Unit Testing :c1, after b1, 8d - Integration Testing :c2, after b2, 10d - User Acceptance Testing :c3, after c2, 7d - - section Deployment - Production Deployment :d1, after c3, 3d - Launch :milestone, after d1, 0d -</code></pre> -<h2>Class Diagram Example</h2> -<p>Class diagrams show the static structure of a system, including classes, attributes, methods, and their relationships.</p> -<pre><code>classDiagram - class User { - +String username - +String password - +String email - +Boolean active - +login() - +logout() - +updateProfile() - } - - class Article { - +String title - +String content - +Date publishDate - +Boolean published - +publish() - +edit() - +delete() - } - - class Comment { - +String content - +Date commentDate - +addComment() - +deleteComment() - } - - class Category { - +String name - +String description - +addArticle() - +removeArticle() - } - - User "1" -- "*" Article : writes - User "1" -- "*" Comment : posts - Article "1" -- "*" Comment : has - Article "1" -- "*" Category : belongs to -</code></pre> -<h2>State Diagram Example</h2> -<p>State diagrams show the sequence of states an object goes through during its life cycle.</p> -<pre><code>stateDiagram-v2 - [*] --&gt; Draft - - Draft --&gt; UnderReview : submit - UnderReview --&gt; Draft : reject - UnderReview --&gt; Approved : approve - Approved --&gt; Published : publish - Published --&gt; Archived : archive - Published --&gt; Draft : retract - - state Published { - [*] --&gt; Active - Active --&gt; Hidden : temporarily hide - Hidden --&gt; Active : restore - Active --&gt; [*] - Hidden --&gt; [*] - } - - Archived --&gt; [*] -</code></pre> -<h2>Pie Chart Example</h2> -<p>Pie charts are ideal for displaying proportions and percentage data.</p> -<pre><code>pie title Website Traffic Sources Analysis - "Search Engines" : 45.6 - "Direct Access" : 30.1 - "Social Media" : 15.3 - "Referral Links" : 6.4 - "Other Sources" : 2.6 -</code></pre> -<h2>Conclusion</h2> -<p>Mermaid is a powerful tool for creating various types of diagrams in Markdown documents. This article demonstrated how to use flowcharts, sequence diagrams, Gantt charts, class diagrams, state diagrams, and pie charts. These diagrams can help you express complex concepts, processes, and data structures more clearly.</p> -<p>To use Mermaid, simply specify the mermaid language in a code block and describe the diagram using concise text syntax. Mermaid will automatically convert these descriptions into beautiful visual diagrams.</p> -<p>Try using Mermaid diagrams in your next technical blog post or project documentation - they will make your content more professional and easier to understand!</p> -Markdown Examplehttps://oss-runtime.dev/blog/posts/markdown/https://oss-runtime.dev/blog/posts/markdown/A simple example of a Markdown blog post.Sun, 01 Oct 2023 00:00:00 GMT<h1>An h1 header</h1> -<p>Paragraphs are separated by a blank line.</p> -<p>2nd paragraph. <em>Italic</em>, <strong>bold</strong>, and <code>monospace</code>. Itemized lists -look like:</p> -<ul> -<li>this one</li> -<li>that one</li> -<li>the other one</li> -</ul> -<p>Note that --- not considering the asterisk --- the actual text -content starts at 4-columns in.</p> -<blockquote> -<p>Block quotes are -written like so.</p> -<p>They can span multiple paragraphs, -if you like.</p> -</blockquote> -<p>Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all -in chapters 12--14"). Three dots ... will be converted to an ellipsis. -Unicode is supported. ☺</p> -<h2>An h2 header</h2> -<p>Here's a numbered list:</p> -<ol> -<li>first item</li> -<li>second item</li> -<li>third item</li> -</ol> -<p>Note again how the actual text starts at 4 columns in (4 characters -from the left side). Here's a code sample:</p> -<pre><code># Let me re-iterate ... -for i in 1 .. 10 { do-something(i) } -</code></pre> -<p>As you probably guessed, indented 4 spaces. By the way, instead of -indenting the block, you can use delimited blocks, if you like:</p> -<pre><code>define foobar() { - print "Welcome to flavor country!"; -} -</code></pre> -<p>(which makes copying &amp; pasting easier). You can optionally mark the -delimited block for Pandoc to syntax highlight it:</p> -<pre><code>import time -# Quick, count to ten! -for i in range(10): - # (but not *too* quick) - time.sleep(0.5) - print i -</code></pre> -<h3>An h3 header</h3> -<p>Now a nested list:</p> -<ol> -<li> -<p>First, get these ingredients:</p> -<ul> -<li>carrots</li> -<li>celery</li> -<li>lentils</li> -</ul> -</li> -<li> -<p>Boil some water.</p> -</li> -<li> -<p>Dump everything in the pot and follow -this algorithm:</p> -<pre><code>find wooden spoon -uncover pot -stir -cover pot -balance wooden spoon precariously on pot handle -wait 10 minutes -goto first step (or shut off burner when done) -</code></pre> -<p>Do not bump wooden spoon or it will fall.</p> -</li> -</ol> -<p>Notice again how text always lines up on 4-space indents (including -that last line which continues item 3 above).</p> -<p>Here's a link to <a href="http://foo.bar">a website</a>, to a <a href="local-doc.html">local -doc</a>, and to a <a href="#an-h2-header">section heading in the current -doc</a>. Here's a footnote [^1].</p> -<p>[^1]: Footnote text goes here.</p> -<p>Tables can look like this:</p> -<p>size material color</p> -<hr /> -<p>9 leather brown -10 hemp canvas natural -11 glass transparent</p> -<p>Table: Shoes, their sizes, and what they're made of</p> -<p>(The above is the caption for the table.) Pandoc also supports -multi-line tables:</p> -<hr /> -<p>keyword text</p> -<hr /> -<p>red Sunsets, apples, and -other red or reddish -things.</p> -<p>green Leaves, grass, frogs -and other things it's -not easy being.</p> -<hr /> -<p>A horizontal rule follows.</p> -<hr /> -<p>Here's a definition list:</p> -<p>apples -: Good for making applesauce. -oranges -: Citrus! -tomatoes -: There's no "e" in tomatoe.</p> -<p>Again, text is indented 4 spaces. (Put a blank line between each -term/definition pair to spread things out more.)</p> -<p>Here's a "line block":</p> -<p>| Line one -| Line too -| Line tree</p> -<p>and images can be specified like so:</p> -<p>Inline math equations go in like so: $\omega = d\phi / dt$. Display -math should get its own line and be put in in double-dollarsigns:</p> -<p>$$I = \int \rho R^{2} dV$$</p> -<p>And note that you can backslash-escape any punctuation characters -which you wish to be displayed literally, ex.: `foo`, *bar*, etc.</p> -Include Video in the Postshttps://oss-runtime.dev/blog/posts/video/https://oss-runtime.dev/blog/posts/video/This post demonstrates how to include embedded video in a blog post.Mon, 01 Aug 2022 00:00:00 GMT<p>Just copy the embed code from YouTube or other platforms, and paste it in the markdown file.</p> -<pre><code>--- -title: Include Video in the Post -published: 2023-10-19 -// ... ---- - -&lt;iframe width="100%" height="468" src="https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_" title="YouTube video player" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt; -</code></pre> -<h2>YouTube</h2> -<p>&lt;iframe width="100%" height="468" src="https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen&gt;&lt;/iframe&gt;</p> -<h2>Bilibili</h2> -<p>&lt;iframe width="100%" height="468" src="//player.bilibili.com/player.html?bvid=BV1fK4y1s7Qf&amp;p=1&amp;autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" &amp;autoplay=0&gt; &lt;/iframe&gt;</p> - \ No newline at end of file diff --git a/website/blog/sakura.png b/website/blog/sakura.png deleted file mode 100644 index 1939aa1..0000000 Binary files a/website/blog/sakura.png and /dev/null differ diff --git a/website/blog/scroll-protection.js b/website/blog/scroll-protection.js deleted file mode 100644 index bc19beb..0000000 --- a/website/blog/scroll-protection.js +++ /dev/null @@ -1,350 +0,0 @@ -/** - * 强力滚动保护脚本 - * 通过劫持 window.scrollTo 和相关滚动方法来阻止意外的滚动跳转 - * 专门解决 Twikoo 评论系统的滚动问题 - */ - -(() => { - // 保存原始的滚动方法 - const originalScrollTo = window.scrollTo; - const originalScrollBy = window.scrollBy; - const originalScrollIntoView = Element.prototype.scrollIntoView; - - // 滚动保护状态 - const scrollProtection = { - enabled: false, - allowedY: null, - startTime: 0, - duration: 0, - timeout: null, - }; - - // 检测是否为TOC导航触发的滚动 - function checkIsTOCNavigation() { - // 检查调用堆栈,看是否来自TOC组件 - const stack = new Error().stack; - if (stack && (stack.includes('handleAnchorClick') || stack.includes('TOC.astro'))) { - return true; - } - - // 检查最近是否有TOC点击事件 - if (window.tocClickTimestamp && Date.now() - window.tocClickTimestamp < 1000) { - return true; - } - - // 检查是否在TOC元素上 - const activeElement = document.activeElement; - if (activeElement && activeElement.closest('#toc, .table-of-contents')) { - return true; - } - - return false; - } - - // 启动滚动保护 - function enableScrollProtection(duration = 3000, currentY = null) { - scrollProtection.enabled = true; - scrollProtection.allowedY = - currentY !== null ? currentY : window.scrollY || window.pageYOffset; - scrollProtection.startTime = Date.now(); - scrollProtection.duration = duration; - - // 清除之前的定时器 - if (scrollProtection.timeout) { - clearTimeout(scrollProtection.timeout); - } - - // 设置保护结束时间 - scrollProtection.timeout = setTimeout(() => { - scrollProtection.enabled = false; - console.log("[强力滚动保护] 保护期结束"); - }, duration); - - console.log( - `[强力滚动保护] 启动保护 ${duration}ms,允许Y位置:`, - scrollProtection.allowedY, - ); - } - - // 检查滚动是否被允许 - function isScrollAllowed(x, y) { - if (!scrollProtection.enabled) { - return true; - } - - // 检查是否是TOC或MD导航触发的滚动 - const isTOCNavigation = checkIsTOCNavigation(); - if (isTOCNavigation) { - console.log('[强力滚动保护] 检测到TOC导航,允许滚动'); - return true; - } - - // 允许小幅度的滚动调整(±50像素) - const tolerance = 50; - const allowedY = scrollProtection.allowedY; - - if (Math.abs(y - allowedY) <= tolerance) { - return true; - } - - // 如果尝试滚动到顶部(y < 100)而当前位置在更下方,阻止 - if (y < 100 && allowedY > 100) { - console.log( - "[强力滚动保护] 阻止滚动到顶部,目标Y:", - y, - "允许Y:", - allowedY, - ); - return false; - } - - return true; - } - - // 劫持 window.scrollTo - window.scrollTo = (x, y) => { - // 处理参数为对象的情况 - if (typeof x === "object") { - const options = x; - x = options.left || 0; - y = options.top || 0; - } - - if (isScrollAllowed(x, y)) { - originalScrollTo.call(window, x, y); - } else { - console.log("[强力滚动保护] 阻止 scrollTo:", x, y); - // 如果被阻止,滚动到允许的位置 - originalScrollTo.call(window, x, scrollProtection.allowedY); - } - }; - - // 劫持 window.scrollBy - window.scrollBy = (x, y) => { - const currentY = window.scrollY || window.pageYOffset; - const targetY = currentY + y; - - if (typeof x === "object") { - const options = x; - x = options.left || 0; - y = options.top || 0; - } - - if (isScrollAllowed(x, targetY)) { - originalScrollBy.call(window, x, y); - } else { - console.log("[强力滚动保护] 阻止 scrollBy:", x, y); - } - }; - - // 劫持 Element.scrollIntoView - Element.prototype.scrollIntoView = function (options) { - if (!scrollProtection.enabled) { - originalScrollIntoView.call(this, options); - return; - } - - // 在保护期内,尝试阻止 scrollIntoView - const rect = this.getBoundingClientRect(); - const currentY = window.scrollY || window.pageYOffset; - const targetY = currentY + rect.top; - - if (isScrollAllowed(0, targetY)) { - originalScrollIntoView.call(this, options); - } else { - console.log("[强力滚动保护] 阻止 scrollIntoView"); - } - }; - - // 监听 Twikoo 相关的交互事件 - document.addEventListener( - "click", - (event) => { - const target = event.target; - - // 检查是否点击了TOC导航 - if (target.closest('#toc, .table-of-contents') && target.closest('a[href^="#"]')) { - window.tocClickTimestamp = Date.now(); - console.log('[强力滚动保护] 检测到TOC导航点击'); - return; // 不启动保护,允许TOC正常工作 - } - - // 检查是否点击了 Twikoo 相关元素 - if ( - target.closest("#tcomment") || - target.matches( - ".tk-action-icon, .tk-submit, .tk-cancel, .tk-preview, .tk-owo, .tk-admin, .tk-edit, .tk-delete, .tk-reply, .tk-expand", - ) || - target.closest( - ".tk-action-icon, .tk-submit, .tk-cancel, .tk-preview, .tk-owo, .tk-admin, .tk-edit, .tk-delete, .tk-reply, .tk-expand", - ) - ) { - // 立即启动保护 - enableScrollProtection(4000); // 增加保护时间到4秒 - console.log("[强力滚动保护] 检测到 Twikoo 交互,启动保护"); - } - - // 特别检查管理面板相关操作(包括关闭操作) - if ( - target.matches( - ".tk-admin-panel, .tk-admin-overlay, .tk-modal, .tk-dialog, .tk-admin-close, .tk-close", - ) || - target.closest( - ".tk-admin-panel, .tk-admin-overlay, .tk-modal, .tk-dialog, .tk-admin-close, .tk-close", - ) || - target.classList.contains("tk-admin") || - target.closest(".tk-admin") - ) { - enableScrollProtection(6000); // 管理面板操作保护更长时间 - console.log("[强力滚动保护] 检测到 Twikoo 管理面板操作,启动长期保护"); - } - - // 检查是否点击了遮罩层(通常用于关闭模态框) - if ( - target.classList.contains("tk-overlay") || - target.classList.contains("tk-mask") || - target.matches('[class*="overlay"]') || - target.matches('[class*="mask"]') || - target.matches('[class*="backdrop"]') - ) { - // 检查是否在 Twikoo 区域内 - const tcommentEl = document.querySelector("#tcomment"); - if ( - tcommentEl && - (target.closest("#tcomment") || tcommentEl.contains(target)) - ) { - enableScrollProtection(4000); - console.log("[强力滚动保护] 检测到 Twikoo 遮罩层点击,启动保护"); - } - } - }, - true, - ); // 使用捕获阶段 - - // 监听表单提交 - document.addEventListener( - "submit", - (event) => { - if (event.target.closest("#tcomment")) { - enableScrollProtection(4000); - console.log("[强力滚动保护] 检测到 Twikoo 表单提交,启动保护"); - } - }, - true, - ); - - // 监听键盘事件(特别是 ESC 键,用于关闭管理面板) - document.addEventListener( - "keydown", - (event) => { - if (event.key === "Escape" || event.keyCode === 27) { - // 检查是否在 Twikoo 区域内有活动的管理面板 - const tcommentEl = document.querySelector("#tcomment"); - if (tcommentEl) { - // 检查是否有可见的管理面板或模态框 - const adminPanel = tcommentEl.querySelector( - ".tk-admin-panel, .tk-modal, .tk-dialog, [class*='admin'], [class*='modal']", - ); - if (adminPanel && adminPanel.offsetParent !== null) { - // 面板可见,启动保护 - enableScrollProtection(3000); - console.log( - "[强力滚动保护] 检测到 ESC 键关闭 Twikoo 管理面板,启动保护", - ); - } - } - } - }, - true, - ); - - // 监听 DOM 变化,检测管理面板的关闭 - const observer = new MutationObserver((mutations) => { - mutations.forEach((mutation) => { - if (mutation.type === "childList" || mutation.type === "attributes") { - const target = mutation.target; - - // 检查是否是 Twikoo 相关的 DOM 变化 - if (target.closest && target.closest("#tcomment")) { - // 检查是否有元素被移除或隐藏(可能是面板关闭) - if ( - mutation.removedNodes.length > 0 || - (mutation.type === "attributes" && - mutation.attributeName === "style") - ) { - enableScrollProtection(2000); - console.log( - "[强力滚动保护] 检测到 Twikoo DOM 变化(可能是面板关闭),启动保护", - ); - } - } - } - }); - }); - - // 开始监听 DOM 变化 - if (document.body) { - observer.observe(document.body, { - childList: true, - subtree: true, - attributes: true, - attributeFilter: ["style", "class"], - }); - } else { - document.addEventListener("DOMContentLoaded", () => { - observer.observe(document.body, { - childList: true, - subtree: true, - attributes: true, - attributeFilter: ["style", "class"], - }); - }); - } - - // 提供全局接口 - window.scrollProtectionManager = { - enable: enableScrollProtection, - disable: () => { - scrollProtection.enabled = false; - if (scrollProtection.timeout) { - clearTimeout(scrollProtection.timeout); - } - console.log("[强力滚动保护] 手动停止保护"); - }, - isEnabled: () => scrollProtection.enabled, - getStatus: () => ({ ...scrollProtection }), - // 新增:强制保护模式(用于调试) - forceProtect: (duration = 10000) => { - enableScrollProtection(duration); - console.log(`[强力滚动保护] 强制保护模式启动 ${duration}ms`); - }, - // 新增:获取当前滚动位置 - getCurrentScroll: () => { - return { - x: window.scrollX || window.pageXOffset, - y: window.scrollY || window.pageYOffset, - }; - }, - // 新增:检测 Twikoo 状态 - checkTwikooStatus: () => { - const tcomment = document.querySelector("#tcomment"); - if (!tcomment) return { exists: false }; - - const adminPanels = tcomment.querySelectorAll( - ".tk-admin-panel, .tk-modal, .tk-dialog, [class*='admin'], [class*='modal']", - ); - const visiblePanels = Array.from(adminPanels).filter( - (panel) => panel.offsetParent !== null, - ); - - return { - exists: true, - adminPanelsCount: adminPanels.length, - visiblePanelsCount: visiblePanels.length, - hasVisiblePanels: visiblePanels.length > 0, - }; - }, - }; - - console.log("[强力滚动保护] 初始化完成"); -})(); diff --git a/website/blog/sitemap-0.xml b/website/blog/sitemap-0.xml deleted file mode 100644 index 8535465..0000000 --- a/website/blog/sitemap-0.xml +++ /dev/null @@ -1 +0,0 @@ -https://oss-runtime.dev/blog/https://oss-runtime.dev/blog/about/https://oss-runtime.dev/blog/anime/https://oss-runtime.dev/blog/archive/https://oss-runtime.dev/blog/diary/https://oss-runtime.dev/blog/friends/https://oss-runtime.dev/blog/gallery/https://oss-runtime.dev/blog/posts/markdown-mermaid/https://oss-runtime.dev/blog/posts/markdown-tutorial/https://oss-runtime.dev/blog/posts/markdown/https://oss-runtime.dev/blog/posts/video/https://oss-runtime.dev/blog/projects/https://oss-runtime.dev/blog/skills/https://oss-runtime.dev/blog/timeline/ \ No newline at end of file diff --git a/website/blog/sitemap-index.xml b/website/blog/sitemap-index.xml deleted file mode 100644 index 120fd3f..0000000 --- a/website/blog/sitemap-index.xml +++ /dev/null @@ -1 +0,0 @@ -https://oss-runtime.dev/blog/sitemap-0.xml \ No newline at end of file diff --git a/website/blog/skills/index.html b/website/blog/skills/index.html deleted file mode 100644 index 76f9b2d..0000000 --- a/website/blog/skills/index.html +++ /dev/null @@ -1,2892 +0,0 @@ - 技能展示 - FutureOSS Docs - - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video

    技能展示

    我的技术技能和专业知识

    16
    总技能数
    1
    专家级
    6
    高级
    32
    经验

    专业技能

    J

    JavaScript

    高级

    现代JavaScript开发,包括ES6+语法、异步编程、模块化开发等。

    经验 3年 6个月
    T

    TypeScript

    高级

    类型安全的JavaScript超集,提升代码质量和开发效率。

    经验 2年 8个月
    R

    React

    高级

    构建用户界面的JavaScript库,包括Hooks、Context、状态管理等。

    经验 2年 10个月
    A

    Astro

    高级

    现代静态站点生成器,支持多框架集成和优秀的性能。

    经验 1年 2个月
    T

    Tailwind CSS

    高级

    实用优先的CSS框架,快速构建现代化用户界面。

    经验 2年
    G

    Git

    高级

    分布式版本控制系统,代码管理和团队协作必备工具。

    经验 3年
    V

    VS Code

    专家级

    轻量级但功能强大的代码编辑器,丰富的插件生态。

    经验 3年 6个月

    前端开发 -(6) -

    J

    JavaScript

    高级

    现代JavaScript开发,包括ES6+语法、异步编程、模块化开发等。

    经验 3年 6个月
    相关项目: 3
    T

    TypeScript

    高级

    类型安全的JavaScript超集,提升代码质量和开发效率。

    经验 2年 8个月
    相关项目: 3
    R

    React

    高级

    构建用户界面的JavaScript库,包括Hooks、Context、状态管理等。

    经验 2年 10个月
    相关项目: 2
    V

    Vue.js

    中级

    渐进式JavaScript框架,易学易用,适合快速开发。

    经验 1年 8个月
    相关项目: 1
    A

    Astro

    高级

    现代静态站点生成器,支持多框架集成和优秀的性能。

    经验 1年 2个月
    相关项目: 1
    T

    Tailwind CSS

    高级

    实用优先的CSS框架,快速构建现代化用户界面。

    经验 2年
    相关项目: 2

    后端开发 -(3) -

    N

    Node.js

    中级

    基于Chrome V8引擎的JavaScript运行时,用于服务端开发。

    经验 2年 3个月
    相关项目: 2
    P

    Python

    中级

    通用编程语言,适用于Web开发、数据分析、机器学习等。

    经验 1年 10个月
    E

    Express.js

    中级

    快速、极简的Node.js Web应用框架。

    经验 1年 8个月
    相关项目: 1

    数据库 -(3) -

    P

    PostgreSQL

    中级

    强大的开源关系型数据库管理系统。

    经验 1年 5个月
    相关项目: 1
    M

    MongoDB

    中级

    面向文档的NoSQL数据库,灵活的数据模型。

    经验 1年 2个月
    F

    Firebase

    中级

    Google的移动和Web应用开发平台,提供实时数据库和认证服务。

    经验 0年 10个月
    相关项目: 1

    开发工具 -(4) -

    G

    Git

    高级

    分布式版本控制系统,代码管理和团队协作必备工具。

    经验 3年
    V

    VS Code

    专家级

    轻量级但功能强大的代码编辑器,丰富的插件生态。

    经验 3年 6个月
    D

    Docker

    中级

    容器化平台,简化应用部署和环境管理。

    经验 1年
    F

    Figma

    中级

    协作式界面设计工具,用于UI/UX设计和原型制作。

    经验 1年 6个月

    技能分布

    按等级分布

    初级
    0
    中级
    9
    高级
    6
    专家级
    1

    按分类分布

    前端开发
    6
    后端开发
    3
    数据库
    3
    开发工具
    4
    其他技能
    0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/timeline/index.html b/website/blog/timeline/index.html deleted file mode 100644 index de4055a..0000000 --- a/website/blog/timeline/index.html +++ /dev/null @@ -1,1893 +0,0 @@ - 时间线 - FutureOSS Docs - - - - - - - -
    FutureOSS Docs
    主页
    归档
    -
    Gitee
    GitHub
    -
    主页
    -
    归档
    -
    Gitee
    GitHub
    -
    Mobile banner image of the blog
    Desktop banner image of the blog

    FutureOSS

    Profile Image of the Author
    FutureOSS
    一切皆为插件的开发者工具运行时框架
    欢迎来到 FutureOSS
    一切皆为插件的开发者工具运行时框架,支持插件热插拔、依赖自动解析、熔断降级、事件驱动等企业级稳定性机制。
    快速开始
    分类
    标签
    Blogging Example Markdown Mermaid Video

    时间线

    我的成长历程和重要里程碑

    8
    总计
    3
    工作经历
    1
    项目数
    4+ -
    工作经验

    当前状态

    全

    全栈开发工程师

    当前状态
    TechCorp Inc. • Senior Full Stack Developer
    -📍 北京

    负责Web应用的前后端开发,参与产品架构设计和技术选型,带领团队完成多个重要项目。

    2023年6月 - 至今 (2 年 11 个月) -
    React Node.js TypeScript PostgreSQL AWS
    R

    React开发者认证

    当前状态
    Meta (Facebook)

    通过了React官方认证考试,证明了在React开发方面的专业能力。

    2022年8月 - 至今 (3 年 9 个月) -
    Certificate
    开

    开始编程学习

    当前状态

    第一次接触编程,从HTML和CSS开始,逐步学习JavaScript和其他技术。

    2018年1月 - 至今 (8 年 5 个月) -
    HTML CSS JavaScript

    历史记录

    M

    Mizuki博客主题开源项目

    项目经历
    2024年1月 - 2024年6月
    •
    6 个月

    基于Astro框架开发的现代化博客主题,获得了社区的广泛认可和使用。

    成就荣誉

    • • GitHub获得500+ Stars
    • • 支持多语言和主题切换
    • • 完善的文档和示例
    Astro TypeScript Tailwind CSS Svelte
    🔗 GitHub Repository 🌐 Live Demo
    全

    全栈开发工程师

    TechCorp Inc. • Senior Full Stack Developer
    工作经历
    2023年6月 - 至今
    •
    2 年 11 个月
    •
    📍 北京

    负责Web应用的前后端开发,参与产品架构设计和技术选型,带领团队完成多个重要项目。

    成就荣誉

    • • 主导开发了公司核心产品的前端架构重构
    • • 优化系统性能,页面加载速度提升40%
    • • 建立了完善的代码审查和测试流程
    React Node.js TypeScript PostgreSQL AWS
    R

    React开发者认证

    Meta (Facebook)
    成就荣誉
    2022年8月 - 至今
    •
    3 年 9 个月

    通过了React官方认证考试,证明了在React开发方面的专业能力。

    🏆 Certificate
    前

    前端开发工程师

    WebTech Solutions • Frontend Developer
    工作经历
    2022年3月 - 2023年5月
    •
    1 年 4 个月
    •
    📍 上海

    专注于React生态系统开发,负责多个企业级Web应用的前端架构和开发。

    成就荣誉

    • • 开发了公司主要产品的用户界面
    • • 建立了组件库和设计系统
    • • 提升了团队的开发效率和代码质量
    React JavaScript CSS3 Webpack Jest
    黑

    黑客马拉松比赛获奖

    TechHackathon 2021
    成就荣誉
    2021年11月 - 2021年11月
    •
    1 个月
    •
    📍 上海

    在48小时内开发了一个创新的Web应用,获得了最佳技术实现奖。

    成就荣誉

    • • 获得最佳技术实现奖
    • • 团队协作完成复杂项目
    • • 在短时间内学习新技术
    React Express.js MongoDB Socket.io
    🔗 Project Demo
    软

    软件开发实习生

    StartupTech • Software Development Intern
    工作经历
    2021年7月 - 2021年9月
    •
    4 个月
    •
    📍 北京

    在大学期间的实习经历,参与了Web应用开发和数据库设计工作。

    成就荣誉

    • • 完成了用户管理系统的开发
    • • 学习了敏捷开发流程
    • • 获得了实习优秀表现奖
    JavaScript Vue.js Node.js MySQL
    计

    计算机科学与技术学士学位

    北京理工大学
    教育经历
    2018年9月 - 2022年6月
    •
    3 年 11 个月
    •
    📍 北京

    系统学习了计算机科学基础理论,包括数据结构、算法、操作系统、数据库等核心课程。

    成就荣誉

    • • GPA: 3.8/4.0
    • • 获得校级优秀学生奖学金
    • • 参与多个课程项目和实习
    Java C++ Python MySQL Linux
    开

    开始编程学习

    教育经历
    2018年1月 - 至今
    •
    8 年 5 个月

    第一次接触编程,从HTML和CSS开始,逐步学习JavaScript和其他技术。

    成就荣誉

    • • 完成了第一个个人网站
    • • 掌握了Web开发基础
    • • 培养了对编程的兴趣
    HTML CSS JavaScript

    统计信息

    按类型分组

    教育经历
    2
    工作经历
    3
    项目经历
    1
    成就荣誉
    2

    工作经验

    总工作经验 4 年 7 个月
    工作岗位数 3
    当前状态 在职
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    -© 2026 FutureOSS. All Rights Reserved. / -RSS / -Sitemap
    -Powered by -Astro & -Mizuki  Version 4.0
    \ No newline at end of file diff --git a/website/blog/translate.js b/website/blog/translate.js deleted file mode 100644 index f1bd73f..0000000 --- a/website/blog/translate.js +++ /dev/null @@ -1,9477 +0,0 @@ -/* - - 国际化,网页自动翻译。 - 作者:管雷鸣 - 开原仓库:https://github.com/xnx3/translate - */ -if (typeof translate == "object" && typeof translate.version == "string") { - throw new Error( - "translate.js 已经加载过一次了,当前是重复加载,避免你的翻译出现异常,已帮你拦截此次加载。本信息只是给你一个提示,你可以检查一下你的项目中是否出现了重复引入 translate.js ,当然,这个异常并不会影响到你的具体使用,它已经自动帮你处理拦截了这个异常,只不过提示出来是让你知道,你的代码里出现了重复引入的情况。", - ); -} -var translate = { - /** - * 当前的版本 - * 由 npm 脚本自动更新,无需手动修改 - * 格式:major.minor.patch.date - */ - // AUTO_VERSION_START - version: "3.17.17.20250808", - // AUTO_VERSION_END - /* - 当前使用的版本,默认使用v2. 可使用 setUseVersion2(); - 来设置使用v2 ,已废弃,主要是区分是否是v1版本来着,v2跟v3版本是同样的使用方式 - */ - useVersion: "v2", - /*js translate.setUseVersion2 start*/ - setUseVersion2: () => { - translate.useVersion = "v2"; - console.log( - "提示:自 v2.10 之后的版本默认就是使用V2版本(当前版本为:" + - translate.version + - "), translate.setUseVersion2() 可以不用再加这一行了。当然加了也无所谓,只是加了跟不加是完全一样的。", - ); - }, - /*js translate.setUseVersion2 end*/ - /* - * 翻译的对象,也就是 new google.translate.TranslateElement(...) - * 已废弃,v1使用的 - */ - translate: null, - - /*js translate.includedLanguages end*/ - /* - * 支持哪些语言切换,包括:de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr - * 已废弃,请使用 translate.selectLanguageTag.languages - */ - includedLanguages: "zh-CN,zh-TW,en", - /*js translate.includedLanguages end*/ - - /*js translate.resourcesUrl start*/ - /* - * 资源文件url的路径 - * 已废弃,v1使用的 - */ - resourcesUrl: "//res.zvo.cn/translate", - /*js translate.resourcesUrl end*/ - - /** - * 默认出现的选择语言的 select 选择框,可以通过这个选择切换语言。 - */ - selectLanguageTag: { - /* - v3.1 增加,将 select切换语言的选择框赋予哪个id,这里是具体的id的名字。 - 如果这个id不存在,会创建这个id的元素 - */ - documentId: "translate", - /* 是否显示 select选择语言的选择框,true显示; false不显示。默认为true */ - show: false, - /* - 支持哪些语言切换 - v1.x 版本包括:de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr - v2.x 版本根据后端翻译服务不同,支持的语言也不同。具体支持哪些,可通过 http://api.translate.zvo.cn/doc/language.json.html 获取 (如果您私有部署的,将请求域名换为您自己私有部署的域名) - */ - languages: "", - alreadyRender: false, //当前是否已渲染过了 true为是 v2.2增加 - selectOnChange: (event) => { - var language = event.target.value; - translate.changeLanguage(language); - }, - //重新绘制 select 语种下拉选择。比如进行二次开发过translate.js,手动进行了设置 translate.to ,但是手动改动后的,在select语种选择框中并不会自动进行改变,这是就需要手动重新绘制一下 select语种选择的下拉选择框 - refreshRender: () => { - // 获取元素 - const element = document.getElementById( - translate.selectLanguageTag.documentId + "SelectLanguage", - ); - - // 删除元素 - if (element) { - element.parentNode.removeChild(element); - } - - //设置为未 render 状态,允许进行 render - translate.selectLanguageTag.alreadyRender = false; - - translate.selectLanguageTag.render(); - }, - - /* - 自定义切换语言的样式渲染 v3.2.4 增加 - - */ - customUI: (languageList) => { - //select的onchange事件 - var onchange = (event) => { - translate.selectLanguageTag.selectOnChange(event); - }; - - //创建 select 标签 - var selectLanguage = document.createElement("select"); - selectLanguage.id = - translate.selectLanguageTag.documentId + "SelectLanguage"; - selectLanguage.className = - translate.selectLanguageTag.documentId + "SelectLanguage"; - var to = translate.language.getCurrent(); - for (var i = 0; i < languageList.length; i++) { - var option = document.createElement("option"); - option.setAttribute("value", languageList[i].id); - - //判断 selectLanguageTag.languages 中允许使用哪些 - - if (translate.selectLanguageTag.languages.length > 0) { - //设置了自定义显示的语言 - - //都转小写判断 - var langs_indexof = ( - "," + - translate.selectLanguageTag.languages + - "," - ).toLowerCase(); - //console.log(langs_indexof) - if ( - langs_indexof.indexOf( - "," + languageList[i].id.toLowerCase() + ",", - ) < 0 - ) { - //没发现,那不显示这个语种,调出 - continue; - } - } - - /*判断默认要选中哪个语言*/ - - if (to != null && typeof to != "undefined" && to.length > 0) { - //设置了目标语言,那就进行判断显示目标语言 - if (to == languageList[i].id) { - option.setAttribute("selected", "selected"); - } - } else { - //没设置目标语言,那默认选中当前本地的语种 - if (languageList[i].id == translate.language.getLocal()) { - option.setAttribute("selected", "selected"); - } - } - - option.appendChild(document.createTextNode(languageList[i].name)); - selectLanguage.appendChild(option); - } - //增加 onchange 事件 - if (window.addEventListener) { - // Mozilla, Netscape, Firefox - selectLanguage.addEventListener("change", onchange, false); - } else { - // IE - selectLanguage.attachEvent("onchange", onchange); - } - - //将select加入进网页显示 - document - .getElementById(translate.selectLanguageTag.documentId) - .appendChild(selectLanguage); - }, - render: () => { - //v2增加 - if (translate.selectLanguageTag.alreadyRender) { - return; - } - translate.selectLanguageTag.alreadyRender = true; - - //判断如果不显示select选择语言,直接就隐藏掉 - if (!translate.selectLanguageTag.show) { - return; - } - - //判断translate 的id是否存在,不存在就创建一个 - if ( - document.getElementById(translate.selectLanguageTag.documentId) == null - ) { - var findBody = document.getElementsByTagName("body"); - if (findBody.length == 0) { - console.log( - "body tag not find, translate.selectLanguageTag.render() is not show Select Language", - ); - return; - } - var body_trans = findBody[0]; - var div = document.createElement("div"); //创建一个script标签 - div.id = translate.selectLanguageTag.documentId; - body_trans.appendChild(div); - } else { - //存在,那么判断一下 select是否存在,要是存在就不重复创建了 - if ( - document.getElementById( - translate.selectLanguageTag.documentId + "SelectLanguage", - ) != null - ) { - //select存在了,就不重复创建了 - return; - } - } - - //从服务器加载支持的语言库 - if ( - typeof translate.request.api.language == "string" && - translate.request.api.language.length > 0 - ) { - //从接口加载语种 - translate.request.post( - translate.request.api.language, - {}, - (data) => { - if (data.result == 0) { - console.log("load language list error : " + data.info); - return; - } - //console.log(data.list); - translate.selectLanguageTag.customUI(data.list); - }, - null, - ); - } else if (typeof translate.request.api.language == "object") { - //无网络环境下,自定义显示语种 - translate.selectLanguageTag.customUI(translate.request.api.language); - } - }, - }, - - /* - * 当前本地语言 - * 已废弃,v1使用的 - */ - //localLanguage:'zh-CN', - /*js translate.localLanguage start*/ - localLanguage: "zh-CN", - /*js translate.localLanguage end*/ - - /*js translate.googleTranslateElementInit start*/ - /** - * google翻译执行的 - * 已废弃,v1使用的 - */ - googleTranslateElementInit: () => { - var selectId = ""; - if (document.getElementById("translate") != null) { - // && document.getElementById('translate').innerHTML.indexOf('translateSelectLanguage') > 0 - //已经创建过了,存在 - selectId = "translate"; - } - - translate.translate = new google.translate.TranslateElement( - { - //这参数没用,请忽略 - pageLanguage: "zh-CN", - //一共80种语言选择,这个是你需要翻译的语言,比如你只需要翻译成越南和英语,这里就只写en,vi - //includedLanguages: 'de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr', - includedLanguages: translate.selectLanguageTag.languages, - //选择语言的样式,这个是面板,还有下拉框的样式,具体的记不到了,找不到api~~ - layout: 0, - //自动显示翻译横幅,就是翻译后顶部出现的那个,有点丑,设置这个属性不起作用的话,请看文章底部的其他方法 - //autoDisplay: false, - //disableAutoTranslation:false, - //还有些其他参数,由于原插件不再维护,找不到详细api了,将就了,实在不行直接上dom操作 - }, - selectId, //触发按钮的id - ); - }, - /*js translate.googleTranslateElementInit end*/ - - /** - * 初始化,如加载js、css资源 - * 已废弃,v1使用的 - */ - /* v2.11.11.20240124 彻底注释掉,有新的init方法替代 - init:function(){ - var protocol = window.location.protocol; - if(window.location.protocol == 'file:'){ - //本地的,那就用http - protocol = 'http:'; - } - if(this.resourcesUrl.indexOf('://') == -1){ - //还没设置过,进行设置 - this.resourcesUrl = protocol + this.resourcesUrl; - } - - //this.resourcesUrl = 'file://G:/git/translate'; - - }, - */ - - /*js translate.execute_v1 start*/ - /** - * 执行翻译操作 - * 已废弃,v1使用的 - */ - execute_v1: () => { - console.log("=====ERROR======"); - console.log( - "The v1 version has been discontinued since 2022. Please use the latest V3 version and refer to: http://translate.zvo.cn/41162.html", - ); - }, - /*js translate.execute_v1 end*/ - - /*js translate.setCookie start*/ - /** - * 设置Cookie,失效时间一年。 - * @param name - * @param value - * * 已废弃,v1使用的 - */ - setCookie: (name, value) => { - var cookieString = name + "=" + escape(value); - document.cookie = cookieString; - }, - /*js translate.setCookie end*/ - - /*js translate.getCookie start*/ - //获取Cookie。若是不存再,返回空字符串 - //* 已废弃,v1使用的 - getCookie: (name) => { - var strCookie = document.cookie; - var arrCookie = strCookie.split("; "); - for (var i = 0; i < arrCookie.length; i++) { - var arr = arrCookie[i].split("="); - if (arr[0] == name) { - return unescape(arr[1]); - } - } - return ""; - }, - /*js translate.getCookie end*/ - - /*js translate.currentLanguage start*/ - /* - 获取当前页面采用的是什么语言 - 返回值如 en、zh-CN、zh-TW (如果是第一次用,没有设置过,那么返回的是 translate.localLanguage 设置的值) - 已废弃,v1使用的 - */ - currentLanguage: () => { - //translate.check(); - var cookieValue = translate.getCookie("googtrans"); - if (cookieValue.length > 0) { - return cookieValue.substr( - cookieValue.lastIndexOf("/") + 1, - cookieValue.length - 1, - ); - } - return translate.localLanguage; - }, - /*js translate.currentLanguage end*/ - - /** - * 切换语言,比如切换为英语、法语 - * @param languageName 要切换的语言语种。传入如 english - * 会自动根据传入的语言来判断使用哪种版本。比如传入 en、zh-CN 等,则会使用v1.x版本 - * 传入 chinese_simplified 、english 等,则会使用 v2.x版本 - */ - changeLanguage: (languageName) => { - //判断使用的是否是v1.x - var v1 = - ",en,de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr,"; - if (v1.indexOf("," + languageName + ",") > -1) { - //用的是v1.x - console.log( - "您使用的是v1版本的切换语种方式,v1已在2021年就以废弃,请更换为v2,参考文档: http://translate.zvo.cn/41549.html", - ); - translate.check(); - - var googtrans = "/" + translate.localLanguage + "/" + languageName; - - //先清空泛解析域名的设置 - var s = document.location.host.split("."); - if (s.length > 2) { - var fanDomain = s[s.length - 2] + "." + s[s.length - 1]; - document.cookie = - "googtrans=;expires=" + - new Date(1) + - ";domain=" + - fanDomain + - ";path=/"; - document.cookie = - "googtrans=" + googtrans + ";domain=" + fanDomain + ";path=/"; - } - - translate.setCookie("googtrans", "" + googtrans); - translate.refreshCurrentPage(); - return; - } - - //用的是v2.x或更高 - //translate.setUseVersion2(); - translate.useVersion = "v2"; - //判断是否是第一次翻译,如果是,那就不用刷新页面了。 true则是需要刷新,不是第一次翻译 - if (translate.to != null && translate.to.length > 0) { - //当前目标值有值,且目标语言跟当前语言不一致,那当前才是已经被翻译过的 - if (translate.to != translate.language.getLocal()) { - var isReload = true; //标记要刷新页面 - } - } - - translate.to = languageName; - translate.storage.set("to", languageName); //设置目标翻译语言 - - /* - 1. 先触发父级,免得当前刷新了,导致父级不执行翻译了 - */ - //检测当前是否处于iframe中,如果当前是在iframe中,有父级页面,也要触发父级进行翻译 - try { - if (window.self !== window.top) { - if ( - typeof window.parent.translate == "object" && - typeof window.parent.translate.version == "string" - ) { - //iframe页面中存在 translate,那么也控制iframe中的进行翻译 - if (window.parent.translate.language.getCurrent() != languageName) { - //如果父页面当前的语种不是需要翻译的语种,对其进行翻译 - window.parent.translate.changeLanguage(languageName); - } - } - } - } catch (e) { - //增加try,避免异常导致无法用 - console.log(e); - } - - if (isReload) { - location.reload(); //刷新页面 - } else { - //不用刷新,直接翻译 - translate.execute(); //翻译 - - //检测是否有iframe中的子页面,如果有,也对子页面下发翻译命令。这个是针对 LayuiAdmin 框架的场景适配,它的主体区域是在 iframe 中的,不能点击切换语言后,只翻译外面的大框,而iframe中的不翻译 - const iframes = document.querySelectorAll("iframe"); - for (let i = 0; i < iframes.length; i++) { - const iframe = iframes[i]; - // 获取 iframe 的 window 对象 - const iframeWindow = iframe.contentWindow; - try { - if ( - typeof iframeWindow.translate == "object" && - typeof iframeWindow.translate.version == "string" - ) { - //iframe页面中存在 translate,那么也控制iframe中的进行翻译 - if (iframeWindow.translate.to != languageName) { - iframeWindow.translate.to = languageName; - iframeWindow.translate.storage.set("to", languageName); //设置目标翻译语言 - iframeWindow.translate.execute(); - } - } - } catch (e) { - //增加try,避免异常,比如跨域,中断导致无法用 - console.log(e); - } - } - } - - //当用户代码设置里启用了 translate.listener.start() 然后用户加载页面后并没有翻译(这时listener是不启动的只是把listener.use标记为true),然后手动点击翻译按钮翻译为其他语种(这是不会刷新页面),翻译后也要跟着启动监听 - if (translate.listener.use == true && translate.listener.isStart == false) { - if (typeof translate.listener.start != "undefined") { - translate.listener.start(); - } - } - }, - - /** - * 自检提示,适用于 v1.x, 在 v2.x中已废弃 - * english - * 已废弃,v1使用的 - */ - /*js translate.check start*/ - check: () => { - if (window.location.protocol == "file:") { - console.log( - "\r\n---WARNING----\r\ntranslate.js 主动翻译组件自检异常,当前协议是file协议,翻译组件要在正常的线上http、https协议下才能正常使用翻译功能\r\n------------", - ); - } - }, - /*js translate.check end*/ - - /**************************** v2.0 */ - to: "", //翻译为的目标语言,如 english 、chinese_simplified - //用户第一次打开网页时,自动判断当前用户所在国家使用的是哪种语言,来自动进行切换为用户所在国家的语种。 - //如果使用后,第二次在用,那就优先以用户所选择的为主,这个就不管用了 - //默认是false,不使用,可设置true:使用 - //使用 setAutoDiscriminateLocalLanguage 进行设置 - autoDiscriminateLocalLanguage: false, - documents: [], //指定要翻译的元素的集合,可设置多个,如设置: document.getElementsByTagName('DIV') - /* - v2.11.5增加 - 正在进行翻译的节点,会记录到此处。 - 这里是最底的节点了,不会再有下级了。这也就是翻译的最终节点,也就是 translate.element.findNode() 发现的节点 - 也就是扫描到要进行翻译的节点,在翻译前,加入到这里,在这个节点翻译结束后,将这里面记录的节点删掉。 - - 格式如 - [ - { - node: node节点的对象 - number: 2 (当前正在翻译进行中的次数,比如一个节点有中英文混合的文本,那么中文、英文 会同时进行两次翻译,也就是最后要进行两次替换,会导致这个node产生两次改动。每次便是+1、-1) - }, - { - ...... - } - ] - - 生命周期: - - translate.execute() 执行后,会扫描要翻译的字符,扫描完成后首先会判断缓存中是否有,是否会命中缓存,如果缓存中有,那么在加入 task.add 之前就会将这个进行记录 ++ - 在浏览器缓存没有命中后,则会通过网络api请求进行翻译,此时在发起网络请求前,会进行记录 ++ - 当使用 translate.listener.start() 后,网页中动态渲染的部分会触发监听,触发监听后首先会判断这个节点是否存在于这里面正在被翻译,如果存在里面,那么忽略, 如果不存在里面,那么再进行 translate.execute(变动的节点) 进行翻译 (当然执行这个翻译后,自然也就又把它加入到此处进行记录 ++) - 【唯一的减去操作】 在task.execute() 中,翻译完成并且渲染到页面执行完成后,会触发延迟50毫秒后将这个翻译的节点从这里减去 - */ - inProgressNodes: [], - //翻译时忽略的一些东西,比如忽略某个tag、某个class等 - ignore: { - tag: ["style", "script", "link", "pre", "code"], - class: ["ignore", "translateSelectLanguage"], - id: [], - /* - 传入一个元素,判断这个元素是否是被忽略的元素。 这个会找父类,看看父类中是否包含在忽略的之中。 - return true是在忽略的之中,false不再忽略的之中 - */ - isIgnore: (ele) => { - if (ele == null || typeof ele == "undefined") { - return false; - } - - var parentNode = ele; - var maxnumber = 100; //最大循环次数,避免死循环 - while (maxnumber-- > 0) { - if (parentNode == null || typeof parentNode == "undefined") { - //没有父元素了 - return false; - } - - //判断Tag - //var tagName = parentNode.nodeName.toLowerCase(); //tag名字,小写 - var nodename = translate.element.getNodeName(parentNode).toLowerCase(); //tag名字,小写 - if (nodename.length > 0) { - //有nodename - if ( - nodename == "body" || - nodename == "html" || - nodename == "#document" - ) { - //上层元素已经是顶级元素了,那肯定就不是了 - return false; - } - if (translate.ignore.tag.indexOf(nodename) > -1) { - //发现ignore.tag 当前是处于被忽略的 tag - return true; - } - } - - //判断class name - if (parentNode.className != null) { - var classNames = parentNode.className; - if (classNames == null || typeof classNames != "string") { - continue; - } - //console.log('className:'+typeof(classNames)); - //console.log(classNames); - classNames = classNames.trim().split(" "); - for (var c_index = 0; c_index < classNames.length; c_index++) { - if ( - classNames[c_index] != null && - classNames[c_index].trim().length > 0 - ) { - //有效的class name,进行判断 - if (translate.ignore.class.indexOf(classNames[c_index]) > -1) { - //发现ignore.class 当前是处于被忽略的 class - return true; - } - } - } - } - - //判断id - if (parentNode.id != null && typeof parentNode.id != "undefined") { - //有效的class name,进行判断 - if (translate.ignore.id.indexOf(parentNode.id) > -1) { - //发现ignore.id 当前是处于被忽略的 id - return true; - } - } - - //赋予判断的元素向上一级 - parentNode = parentNode.parentNode; - } - - return false; - }, - - /* - * 忽略不被翻译的文本,这里出现的文本将不会被翻译。 - * 这个其实是借用了 自定义术语 的能力,设置了自定义术语的原字符等于翻译后的字符, 于是这个字符就不会被翻译了 - * 这里可以是多个,数组,如 ['你好','世界'] - */ - text: [], - /* - 下面的 textRegex 、 setTextRegexs 正则方式设置忽略不翻译text的能力,有 https://github.com/wangliangyu 提交贡献, 弥补 translate.ignore.text 固定设置的不足 - */ - textRegex: [], - /* - 使用方式如: - translate.ignore.setTextRegexs([/请求/g, /[\u4a01-\u4a05]+/g]); - */ - setTextRegexs: function (arr) { - if (!Array.isArray(arr)) throw new Error("参数必须为数组"); - for (let i = 0; i < arr.length; i++) { - if (!(arr[i] instanceof RegExp)) { - throw new Error("第" + i + "项不是RegExp对象"); - } - } - //this.textRegex = [...this.textRegex, ...arr]; - //改为兼容 es5 的方式,提供更多兼容 - this.textRegex = this.textRegex.concat(arr); - }, - }, - //刷新页面,你可以自定义刷新页面的方式,比如在 uniapp 打包生成 apk 时,apk中的刷新页面就不是h5的这个刷新,而是app的刷新方式,就需要自己进行重写这个刷新页面的方法了 - refreshCurrentPage: () => { - location.reload(); - }, - //自定义翻译术语 - nomenclature: { - /* - 术语表 - 一维:要转换的语种,如 english - 二维:翻译至的目标语种,如 english - 三维:要转换的字符串,如 "你好" - 结果:自定义的翻译结果,如 “Hallo” - */ - data: [], - - /* - 原始术语表,可编辑的 - 一维:要自定义目标词 - 二维:针对的是哪个语种 - 值:要翻译为什么内容 - - 其设置如 - var data = new Array(); - data['版本'] = { - english : 'banben', - korean : 'BanBen' - }; - data['国际化'] = { - english : 'guojihua', - korean : 'GuoJiHua' - }; - - 【已过时】 - */ - old_Data: [], - /* - set:function(data){ - translate.nomenclature.data = data; - }, - */ - set: (data) => { - alert( - "请将 translate.nomenclature.set 更换为 append,具体使用可参考: https://github.com/xnx3/translate ", - ); - }, - /* - 向当前术语库中追加自定义术语。如果追加的数据重复,会自动去重 - 传入参数: - from 要转换的语种 - to 翻译至的目标语种 - properties 属于配置表,格式如: - 你好=Hello - 世界=ShiJie - - */ - append: (from, to, properties) => { - if (typeof translate.nomenclature.data[from] == "undefined") { - translate.nomenclature.data[from] = []; - } - if (typeof translate.nomenclature.data[from][to] == "undefined") { - translate.nomenclature.data[from][to] = []; - } - - //将properties进行分析 - //按行拆分 - var line = properties.split("\n"); - //console.log(line) - for (var line_index = 0; line_index < line.length; line_index++) { - var item = line[line_index].trim(); - if (item.length < 1) { - //空行,忽略 - continue; - } - var kvs = item.split("="); - //console.log(kvs) - if (kvs.length != 2) { - //不是key、value构成的,忽略 - continue; - } - var key = kvs[0].trim(); - var value = kvs[1].trim(); - //console.log(key) - if (key.length == 0 || value.length == 0) { - //其中某个有空,则忽略 - continue; - } - - //加入,如果之前有加入,则会覆盖 - translate.nomenclature.data[from][to][key] = value; - //console.log(local+', '+target+', key:'+key+', value:'+value); - } - - //追加完后,对整个对象数组进行排序,key越大越在前面 - translate.nomenclature.data[from][to] = translate.util.objSort( - translate.nomenclature.data[from][to], - ); - }, - //获取当前定义的术语表 - get: () => translate.nomenclature.data, - //对传入的str字符进行替换,将其中的自定义术语提前进行替换,然后将替换后的结果返回 - //v3.11 后此方法已废弃,不再使用 - dispose: (str) => { - if (str == null || str.length == 0) { - return str; - } - //if(translate.nomenclature.data.length == 0){ - // return str; - //} - //判断当前翻译的两种语种是否有自定义术语库 - //console.log(typeof(translate.nomenclature.data[translate.language.getLocal()][translate.to])) - if ( - typeof translate.nomenclature.data[translate.language.getLocal()] == - "undefined" || - typeof translate.nomenclature.data[translate.language.getLocal()][ - translate.to - ] == "undefined" - ) { - return str; - } - //console.log(str) - for (var originalText in translate.nomenclature.data[ - translate.language.getLocal() - ][translate.to]) { - if ( - !Object.hasOwn( - translate.nomenclature.data[translate.language.getLocal()][ - translate.to - ], - originalText, - ) - ) { - continue; - } - - var translateText = - translate.nomenclature.data[translate.language.getLocal()][ - translate.to - ][originalText]; - if (typeof translateText == "function") { - //进行异常的预处理调出 - continue; - } - - var index = str.indexOf(originalText); - if (index > -1) { - //console.log('find -- '+originalText+', \t'+translateText); - if (translate.language.getLocal() == "english") { - //如果本地语种是英文,那么还要判断它的前后,避免比如要替换 is 将 display 中的is给替换,将单词给强行拆分了 - - //判断这个词前面是否符合 - var beforeChar = ""; //前面的字符 - if (index == 0) { - //前面没别的字符了,那前面合适 - } else { - //前面有别的字符,判断是什么字符,如果是英文,那么这个是不能被拆分的,要忽略 - beforeChar = str.substr(index - 1, 1); - //console.log('beforeChar:'+beforeChar+', str:'+str) - var lang = translate.language.getCharLanguage(beforeChar); - //console.log(lang); - if (lang == "english" || lang == "romance") { - //调出,不能强拆 - continue; - } - } - - //判断这个词的后面是否符合 - var afterChar = ""; //后面的字符 - if (index + originalText.length == str.length) { - //后面没别的字符了,那前面合适 - //console.log(originalText+', meile '+str) - } else { - //后面有别的字符,判断是什么字符,如果是英文,那么这个是不能被拆分的,要忽略 - afterChar = str.substr(index + originalText.length, 1); - var lang = translate.language.getCharLanguage(afterChar); - if (lang == "english" || lang == "romance") { - //跳出,不能强拆 - continue; - } - } - - str = str.replace( - new RegExp(beforeChar + originalText + afterChar, "g"), - beforeChar + translateText + afterChar, - ); - } else { - //其他情况,如汉语、汉语等语种 - str = str.replace(new RegExp(originalText, "g"), translateText); - } - } - } - - return str; - - /* - //遍历一维 - for(var originalText in translate.nomenclature.data){ - var languageResult = translate.nomenclature.data[originalText]; - if(typeof(languageResult) == 'function'){ - //进行异常的预处理调出 - continue; - } - - if(typeof(languageResult[translate.to]) == 'undefined'){ - //console.log('und'); - continue; - } - - //var hash = translate.util.hash(originalText); - - //console.log(originalText+',\t'+str); - if(str.indexOf(originalText) > -1){ - //console.log('find -- '+originalText+', \t'+languageResult[translate.to]); - str = str.replace(new RegExp(originalText,'g'),languageResult[translate.to]); - } - } - - - return str; - */ - }, - }, - - office: { - /* - 网页上翻译之后,自动导出当前页面的术语库 - - 需要先指定本地语种,会自动将本地语种进行配置术语库 - - */ - export: () => { - if (translate.language.getLocal() == translate.language.getCurrent()) { - alert("本地语种跟要翻译的语种一致,无需导出"); - return; - } - - var text = ""; - for (var uuid in translate.nodeQueue) { - if (!Object.hasOwn(translate.nodeQueue, uuid)) { - continue; - } - - var queueValue = translate.nodeQueue[uuid]; - for (var lang in translate.nodeQueue[uuid].list) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list, lang)) { - continue; - } - //console.log('------'+lang) - if (typeof lang != "string" || lang.length < 1) { - continue; - } - //if(translate.language.getLocal() == lang){ - //console.log(translate.nodeQueue[uuid].list[lang]); - for (var hash in translate.nodeQueue[uuid].list[lang]) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list[lang], hash)) { - continue; - } - //console.log(translate.nodeQueue[uuid].list[lang][hash].original); - //console.log(translate.nodeQueue[uuid].list[lang][hash].original); - text = - text + - "\n" + - translate.nodeQueue[uuid].list[lang][hash].original + - "=" + - translate.storage.get( - "hash_" + translate.language.getCurrent() + "_" + hash, - ); - } - //} - } - } - - if (text.length > 0) { - //有内容 - text = - "translate.office.append('" + - translate.language.getCurrent() + - "',`" + - text + - "\n`);"; - //console.log(text); - translate.util.loadMsgJs(); - msg.popups({ - text: '', - width: "750px", - height: "600px", - padding: "1px", - }); - document.getElementById("msgPopupsTextarea").value = text; - } else { - msg.alert("无有效内容!"); - } - }, - //显示导出面板 - showPanel: () => { - const panel = document.createElement("div"); - panel.setAttribute("id", "translate_export"); - panel.setAttribute("class", "ignore"); - - //导出按钮 - const button = document.createElement("button"); - button.onclick = () => { - translate.office.export(); - }; - button.innerHTML = "导出配置信息"; - button.setAttribute( - "style", - "margin-left: 72px; margin-top: 30px; margin-bottom: 20px; font-size: 25px; background-color: blue; padding: 15px; padding-top: 3px; padding-bottom: 3px; border-radius: 3px;", - ); - panel.appendChild(button); - - //说明文字 - const textdiv = document.createElement("div"); - textdiv.innerHTML = - '1. 首先将当前语种切换为你要翻译的语种
    2. 点击导出按钮,将翻译的配置信息导出
    3. 将导出的配置信息粘贴到代码中,即可完成
    点此进行查阅详细使用说明'; - textdiv.setAttribute("style", "font-size: 14px; padding: 12px;"); - - panel.appendChild(textdiv); - - panel.setAttribute( - "style", - "background-color: black; color: #fff; width: 320px; height: 206px; position: fixed; bottom: 50px; right: 50px;", - ); - //把元素节点添加到body元素节点中成为其子节点,放在body的现有子节点的最后 - document.body.appendChild(panel); - - translate.util.loadMsgJs(); - }, - /* - 追加离线翻译数据。如果追加的数据重复,会自动去重 - 传入参数: - from 要转换的语种 - to 翻译至的目标语种 - properties 属于配置表,格式如: - 你好=Hello - 世界=ShiJie - 这个传入参数跟 translate.nomenclature.append 的传入参数格式是一致的 - */ - append: (to, properties) => { - //console.log(properties) - //将properties进行分析 - //按行拆分 - var line = properties.split("\n"); - //console.log(line) - for (var line_index = 0; line_index < line.length; line_index++) { - var item = line[line_index].trim(); - if (item.length < 1) { - //空行,忽略 - continue; - } - var kvs = item.split("="); - //console.log(kvs) - if (kvs.length != 2) { - //不是key、value构成的,忽略 - continue; - } - var key = kvs[0]; - var value = kvs[1]; - //console.log(key) - if (key.length == 0 || value.length == 0) { - //其中某个有空,则忽略 - continue; - } - //console.log('set---'+key); - //加入 storate - translate.storage.set( - "hash_" + to + "_" + translate.util.hash(key), - value, - ); - } - }, - - //全部提取能力(整站的离线翻译数据提取) - fullExtract: { - /*js translate.office.fullExtract.set start*/ - /* - 将翻译的结果加入 - hash: 翻译前的文本的hash - originalText: 翻以前的文本,原始文本 - toLanguage: 翻译为什么语言 - translateText: 翻译结果的文本 - */ - set: async (hash, originalText, toLanguage, translateText) => { - if (typeof translate.storage.IndexedDB == "undefined") { - console.log("ERROR: translate.storage.IndexedDB not find"); - return; - } - var obj = await translate.storage.IndexedDB.get("hash_" + hash); - if (typeof obj == "undefined" && obj == null) { - obj = { - originalText: originalText, - }; - } - obj[toLanguage] = translateText; - await translate.storage.IndexedDB.set("hash_" + hash, obj); - }, - /*js translate.office.fullExtract.set end*/ - - /*js translate.office.fullExtract.export start*/ - /* - 将存储的数据导出为 txt 文件下载下来 - */ - export: async (to) => { - if (typeof translate.storage.IndexedDB == "undefined") { - console.log("ERROR: translate.storage.IndexedDB not find"); - return; - } - if (typeof to != "string") { - console.log('error : to param not find, example: "english"'); - return; - } - var text = "translate.office.append('"; - - var data = await translate.storage.IndexedDB.list("hash_*"); - for (var i in data) { - if (!Object.hasOwn(data, i)) { - continue; - } - var originalText = data[i].value.originalText - .replace(/\n/g, "\\n") - .replace(/\t/g, "\\t"); - text = - text + - "\n" + - originalText + - "=" + - data[i].value.english.replace(/\n/g, "\\n").replace(/\t/g, "\\t"); - } - text = text + "\n`);"; - - const blob = new Blob([text], { type: "text/plain" }); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = to + ".txt"; - link.click(); - URL.revokeObjectURL(url); - }, - /*js translate.office.fullExtract.export end*/ - - /* - 是否启用全部提取的能力 - true: 启用, 默认是false不启用。 - 如果设置为true,则每次通过调用翻译接口进行翻译后,都会将翻译的原文、译文、翻译为什么语种,都会单独记录一次,存入浏览器的 IndexedDB 的 translate.js 数据库 - 然后可以浏览所有页面后,把所有翻译一对一的对应翻译结果直接全部导出,用于做离线翻译配置使用。 - */ - isUse: false, - }, - }, - setAutoDiscriminateLocalLanguage: () => { - translate.autoDiscriminateLocalLanguage = true; - }, - /* - 待翻译的页面的node队列 - 一维:key:uuid,也就是execute每次执行都会创建一个翻译队列,这个是翻译队列的唯一标识。 - value: - k/v - 二维:对象形态,具体有: - key:expireTime 当前一维数组key的过期时间,到达过期时间会自动删除掉这个一维数组。如果<0则代表永不删除,常驻内存 - value:list 从DOM中自动识别出的语言文本及节点数据,按照语种进行了划分,每个语种便是其中的一项。 - 三维:针对二维的value, key:english、chinese_simplified等语种,这里的key便是对value的判断,取value中的要翻译的词是什么语种,对其进行了语种分类 value: k/v - 四维:针对三维的value, key:要翻译的词(经过语种分割的)的hash, value: node数组 - 五维:针对四维的value, 这是个对象, 其中 - original: 是三维的key的hash的原始文字, node 元素中的原始文字(可能是node元素整个内容,也可能是被分割出的某一块内容,比如中英文混合时单独提取中文) - cacheHash: 如果翻译时匹配到了自定义术语库中的词,那么翻译完后存入到缓存中时,其缓存的翻译前字符串已经不是original,而是匹配完术语库后的文本的hash了。所以这里额外多增加了这个属性。如果匹配了术语库,那这里就是要进行缓存的翻译前文本的hash,如果未使用术语库,这里就跟其key-hash 相同。 - translateText: 针对 original 的经过加工过的文字,比如经过自定义术语、以及其他处理操作后的,待进行文本翻译的文字。 - nodes: 有哪些node元素中包含了这个词,都会在这里记录 - 六维:针对五维的 nodes,将各个具体的 node 以及 其操作的 attribute 以数组形式列出 - 七维:针对六维列出的nodes数组,其中包含: - node: 具体操作的node元素 - attribute: 也就是翻译文本针对的是什么,是node本身(nodeValue),还是 node 的某个属性,比如title属性,这则是设置为 "title"。如果这里不为空,那就是针对的属性操作的。 如果这里为空或者undefined ,那就是针对node本身,也就是 nodeValue 的字符串操作的 - beforeText: node元素中进行翻译结果赋予时,额外在翻译结果的前面加上的字符串。其应用场景为,如果中英文混合场景下,避免中文跟英文挨着导致翻译为英语后,连到一块了。默认是空字符串 '' - afterText: node元素中进行翻译结果赋予时,额外在翻译结果的后面加上的字符串。其应用场景为,如果中英文混合场景下,避免中文跟英文挨着导致翻译为英语后,连到一块了。默认是空字符串 '' - - 生命周期: 当execute()执行时创建, 当execute结束(其中的所有request接收到响应并渲染完毕)时销毁(当前暂时不销毁,以方便调试) - */ - nodeQueue: {}, - //指定要翻译的元素的集合,可传入一个元素或多个元素 - //如设置一个元素,可传入如: document.getElementById('test') - //如设置多个元素,可传入如: document.getElementsByTagName('DIV') - setDocuments: (documents) => { - if (documents == null || typeof documents == "undefined") { - return; - } - - if (typeof documents.length == "undefined") { - //不是数组,是单个元素 - translate.documents[0] = documents; - } else { - //是数组,直接赋予 - translate.documents = documents; - } - //清空翻译队列,下次翻译时重新检索 - translate.nodeQueue = {}; - //console.log('set documents , clear translate.nodeQueue'); - }, - //获取当前指定翻译的元素(数组形式 [document,document,...]) - //如果用户未使用setDocuments 指定的,那么返回整个网页 - //它返回的永远是个数组形式 - getDocuments: () => { - if ( - translate.documents != null && - typeof translate.documents != "undefined" && - translate.documents.length > 0 - ) { - // setDocuments 指定的 - return translate.documents; - } - //未使用 setDocuments指定,那就是整个网页了 - //return document.all; //翻译所有的 这是 v3.5.0之前的 - //v3.5.0 之后采用 拿 html的最上层的demo,而不是 document.all 拿到可能几千个dom - var doms = []; - doms[0] = document.documentElement; - return doms; - }, - - listener: { - //当前页面打开后,是否已经执行完execute() 方法进行翻译了,只要执行完一次,这里便是true。 (多种语言的API请求完毕并已渲染html) - //isExecuteFinish:false, - //是否已经使用了 translate.listener.start() 了,如果使用了,那这里为true,多次调用 translate.listener.start() 只有第一次有效 - isStart: false, - //用户的代码里是否启用了 translate.listener.start() ,true:启用 - //当用户加载页面后,但是未启用翻译时,为了降低性能,监听是不会启动的,但是用户手动点击翻译后,也要把监听启动起来,所以就加了这个参数,来表示当前是否在代码里启用了监听,以便当触发翻译时,监听也跟着触发 - use: false, - //translate.listener.start(); //开启html页面变化的监控,对变化部分会进行自动翻译。注意,这里变化区域,是指使用 translate.setDocuments(...) 设置的区域。如果未设置,那么为监控整个网页的变化 - start: () => { - translate.listener.use = true; - translate.temp_linstenerStartInterval = setInterval(() => { - if (document.readyState == "complete") { - //dom加载完成,进行启动 - clearInterval(translate.temp_linstenerStartInterval); //停止 - - //如果不需要翻译的情况,是不需要进行监听的 - if ( - translate.language.getCurrent() == translate.language.getLocal() - ) { - if (translate.language.translateLocal) { - //本地语种也要强制翻译跟本地语种不一致的语种 - } else { - //console.log('本地语种跟目标语种一致,不进行翻译操作,无需监听。'); - return; - } - } - - //console.log('进行监听。。'); - translate.listener.addListener(); - } - - //执行完过一次,那才能使用 - //if(translate.listener.isExecuteFinish){ - /*if(translate.listener.isStart){ - //已开启了 - return; - }*/ - - //console.log('translate.temp_linstenerStartInterval Finish!'); - //} - }, 300); - }, - /* - key: nodeid node的唯一标识,格式如 HTML1_BODY1_DIV2_#text1 ,它是使用 nodeuuid.uuid(node) 获得的 - 注意,document.getElementById 获得的并不是,需要这样获得 document.getElementById('xx').childNodes[0] 因为它是要给监听dom改动那里用的,监听到的改动的是里面具体的node - value:13位时间戳 - */ - ignoreNode: [], - /* - 通过 translate.execute() 触发的翻译,来使node发生的改动,这种改动加入到 ignoreNode 的过期时间是多少。 - 单位是毫秒 - */ - translateExecuteNodeIgnoreExpireTime: 1000, - /* - 增加一个被listener忽略的节点 - 这里通常是用于被 translate.js 本身翻译更改的节点、以及像是 Layui 被翻译后触发了渲染改动了dom , 这几种场景都是翻译本身自己触发的,是不需要再被listener触发,不然就形成死循环了 - node 是哪个节点被listener扫描到改动后忽略。 - 可传入 node、也可以传入node的uuid字符串 - expireTime 过期时间,也就是执行当前方法将 node 加入后,过多长时间失效,这里是毫秒,比如传入 500 则这个node在当前时间往后的500毫秒内,如果被listener监听到改动,是直接被忽略的,不会触发任何翻译操作 - showResultText 实际显示出来的文本,翻译之后显示出来的文本。如果翻译过程中其他js改动了这个文本内容,导致未能翻译,则 analyse.set 的 resultText 会返回 空字符串设置到这里 - */ - addIgnore: (node, expireTime, showResultText) => { - let nodeid = ""; - if (typeof node == "string") { - nodeid = node; - } else { - nodeid = nodeuuid.uuid(node); - } - - translate.listener.ignoreNode[nodeid] = { - addtime: Date.now() + expireTime, - text: showResultText, - }; - - //translate.listener.renderTaskFinish(); - }, - /* - 刷新 ignoreNode 中的元素,也就是查找其中 expireTime 过期的,删掉 - */ - refreshIgnoreNode: () => { - //console.log('refresh ignore ,current: '+Object.keys(translate.listener.ignoreNode).length); - var currentTime = Date.now(); - for (const node in translate.listener.ignoreNode) { - if (translate.listener.ignoreNode[node].addtime < currentTime) { - //console.log('delete : '); - //console.log(node); - delete translate.listener.ignoreNode[node]; - } - } - //console.log('refresh ignore finish: '+Object.keys(translate.listener.ignoreNode).length); - }, - - //增加监听,开始监听。这个不要直接调用,需要使用上面的 start() 开启 - addListener: () => { - if (translate.listener.isStart == true) { - console.log( - "translate.listener.start() 已经启动了,无需再重复启动监听,增加浏览器负担", - ); - return; - } - translate.listener.isStart = true; //记录已执行过启动方法了 - - // 观察器的配置(需要观察什么变动) - translate.listener.config = { - attributes: true, - childList: true, - subtree: true, - characterData: true, - attributeOldValue: true, - characterDataOldValue: true, - }; - // 当观察到变动时执行的回调函数 - translate.listener.callback = (mutationsList, observer) => { - var documents = []; //有变动的元素 - //console.log('--------- lisetner 变动'); - // Use traditional 'for loops' for IE 11 - for (const mutation of mutationsList) { - let addNodes = []; - if (mutation.type === "childList") { - if (mutation.addedNodes.length > 0) { - //多了组件 - addNodes = mutation.addedNodes; - //documents.push.apply(documents, mutation.addedNodes); - } else if (mutation.removedNodes.length > 0) { - //console.log('remove:'); - //console.log(mutation.removedNodes); - } else { - //console.log('not find:'); - //console.log(mutation); - } - } else if (mutation.type === "attributes") { - //console.log('The ' + mutation.attributeName + ' attribute was modified.'); - } else if (mutation.type === "characterData") { - //内容改变 - addNodes = [mutation.target]; - //documents.push.apply(documents, [mutation.target]); - } - - //去重并加入 documents - for (const item of addNodes) { - //console.log(item); - - //判断是否已经加入过了,如果已经加入过了,就不重复加了 - var isFind = false; - for (var di = 0; di < documents.length; di++) { - if (documents[di].isSameNode(item)) { - isFind = true; - break; - } - } - if (isFind) { - break; - } - documents.push.apply(documents, [item]); - } - } - - //console.log(documents.length); - if (documents.length > 0) { - //有变动,需要看看是否需要翻译,延迟10毫秒执行 - - //判断是否属于在正在翻译的节点,重新组合出新的要翻译的node集合 - var translateNodes = []; - //console.log(translate.inProgressNodes.length); - for (const node of documents) { - //console.log('---type:'+node.nodeType); - - var find = false; - for (var ini = 0; ini < translate.inProgressNodes.length; ini++) { - if (translate.inProgressNodes[ini].node.isSameNode(node)) { - //有记录了,那么忽略这个node,这个node是因为翻译才导致的变动 - //console.log('发现相同'); - find = true; - break; - } - } - if (find) { - continue; - } - - //console.log(node); - const nodeid = nodeuuid.uuid(node); - if (typeof translate.listener.ignoreNode[nodeid] != "undefined") { - if ( - translate.listener.ignoreNode[nodeid].addtime > Date.now() && - typeof node.nodeValue == "string" && - node.nodeValue == translate.listener.ignoreNode[nodeid].text - ) { - //console.log('node 未过忽略期,listener扫描后忽略:'+nodeid); - continue; - } - } - - //不相同,才追加到新的 translateNodes - translateNodes.push(node); - //console.log('listener ++ '+node.nodeValue); - //console.log(node); - } - if (translateNodes.length < 1) { - return; - } - //console.log('translateNodeslength: '+translateNodes.length); - - translate.execute(translateNodes); - //setTimeout(function() { - // translate.execute(translateNodes); //指定要翻译的元素的集合,可传入一个或多个元素。如果不设置,默认翻译整个网页 - //}, 10); //这个要比 task.execute() 中的 settimeout 延迟执行删除 translate.inpr.....nodes 的时间要小,目的是前一个发生变动后,记入 inpr...nodes 然后翻译完成后节点发生变化又触发了listener,此时 inpr....nodes 还有,那么这个变化将不做处理,然后 inp.....nodes 再删除这个标记 - } - }; - // 创建一个观察器实例并传入回调函数 - translate.listener.observer = new MutationObserver( - translate.listener.callback, - ); - // 以上述配置开始观察目标节点 - var docs = translate.getDocuments(); - for (var docs_index = 0; docs_index < docs.length; docs_index++) { - var doc = docs[docs_index]; - if (doc != null) { - translate.listener.observer.observe(doc, translate.listener.config); - } - } - }, - /* - 每当执行完一次渲染任务(翻译)时会触发此。注意页面一次翻译会触发多个渲染任务。普通情况下,一次页面的翻译可能会触发两三次渲染任务。 - 另外如果页面中有ajax交互方面的信息,时,每次ajax信息刷新后,也会进行翻译,也是一次渲染任务。 - 这个是为了方便扩展使用。比如在layui中扩展,监控 select 的渲染 - */ - renderTaskFinish: (renderTask) => { - //console.log(renderTask); - }, - - /* - 翻译执行过程中,相关的监控 - */ - execute: { - /* - 每当触发执行 translate.execute() 时,当缓存中未发现,需要请求翻译API进行翻译时,在发送API请求前,触发此 - - @param uuid:translate.nodeQueue[uuid] 这里的 - @param from 来源语种,翻译前的语种 - @param to 翻译为的语种 - */ - renderStartByApi: [], - renderStartByApiRun: (uuid, from, to) => { - //console.log(translate.nodeQueue[uuid]); - for ( - var i = 0; - i < translate.listener.execute.renderStartByApi.length; - i++ - ) { - try { - translate.listener.execute.renderStartByApi[i](uuid, from, to); - } catch (e) { - console.log(e); - } - } - }, - - /* - 每当 translate.execute() 执行完毕(前提是采用API翻译的,API将翻译结果返回,并且界面上的翻译结果也已经渲染完毕)后,触发此方法。 - - @param uuid:translate.nodeQueue[uuid] 这里的 - @param from 来源语种,翻译前的语种 - @param to 翻译为的语种 - */ - renderFinishByApi: [], - renderFinishByApiRun: (uuid, from, to) => { - //console.log(translate.nodeQueue[uuid]); - for ( - var i = 0; - i < translate.listener.execute.renderFinishByApi.length; - i++ - ) { - try { - translate.listener.execute.renderFinishByApi[i](uuid, from, to); - } catch (e) { - console.log(e); - } - } - }, - }, - }, - //对翻译结果进行替换渲染的任务,将待翻译内容替换为翻译内容的过程 - renderTask: class { - constructor() { - /* - * 任务列表 - * 一维数组 [hash] = tasks; tasks 是多个task的数组集合 - * 二维数组 [task,task,...],存放多个 task,每个task是一个替换。这里的数组是同一个nodeValue的多个task替换 - * 三维数组 task['originalText'] 、 task['resultText'] 存放要替换的字符串 - task['attribute'] 存放要替换的属性,比如 a标签的title属性。 如果是直接替换node.nodeValue ,那这个没有 - */ - this.taskQueue = []; - - /* - * 要进行翻译的node元素, - * 一维数组 key:node.nodeValue 的 hash , value:node的元素数组 - * 二维数组,也就是value中包含的node集合 [node,node,...] - */ - this.nodes = []; - } - - /** - * 向替换队列中增加替换任务 - * node:要替换的字符属于那个node元素 - * originalText:待翻译的字符 - * resultText:翻译后的结果字符 - * attribute: 要替换的是哪个属性,比如 a标签的title属性,这里便是传入title。如果不是替换属性,这里不用传入,或者传入null - */ - add(node, originalText, resultText, attribute) { - var nodeAnaly = translate.element.nodeAnalyse.get(node, attribute); //node解析 - //var hash = translate.util.hash(translate.element.getTextByNode(node)); //node中内容的hash - var hash = translate.util.hash(nodeAnaly["text"]); - //console.log('--------------'+hash); - //console.log(nodeAnaly); - //console.log(node); - //console.log('originalText:'+originalText+', resultText:'+resultText+', attribute:'+attribute); - /****** 加入翻译的元素队列 */ - if (typeof this.nodes[hash] == "undefined") { - this.nodes[hash] = []; - } - this.nodes[hash].push(node); - //console.log(node) - - /****** 加入翻译的任务队列 */ - var tasks = this.taskQueue[hash]; - if (tasks == null || typeof tasks == "undefined") { - //console.log(node.nodeValue); - tasks = []; //任务列表,存放多个 task,每个task是一个替换。这里的数组是同一个nodeValue的多个task替换 - } - var task = []; - - //v2.3.3 增加 -- 开始 - //这里要进行处理,因为有时候翻译前,它前或者后是有空格的,但是翻译后会把前或者后的空格给自动弄没了,如果是这种情况,要手动补上 - if (originalText.substr(0, 1) == " ") { - //console.log('第一个字符是空格'); - if (resultText.substr(0, 1) != " ") { - //翻译结果的第一个字符不是空格,那么补上 - resultText = " " + resultText; - } - } - if (originalText.substr(originalText.length - 1, 1) === " ") { - //console.log('最后一个字符是空格'); - if (resultText.substr(0, 1) != " ") { - //翻译结果的最后一个字符不是空格,那么补上 - resultText = resultText + " "; - } - } - //v2.3.3 增加 -- 结束 - - task["originalText"] = originalText; - task["resultText"] = resultText; - task["attribute"] = attribute; - - //console.log(task); - tasks.push(task); - this.taskQueue[hash] = tasks; - /****** 加入翻译的任务队列 end */ - } - //进行替换渲染任务,对页面进行渲染替换翻译 - execute() { - //先对tasks任务队列的替换词进行排序,将同一个node的替换词有大到小排列,避免先替换了小的,大的替换时找不到 - for (var hash in this.taskQueue) { - if (!Object.hasOwn(this.taskQueue, hash)) { - continue; - } - - var tasks = this.taskQueue[hash]; - if (typeof tasks == "function") { - //进行异常的预处理调出 - continue; - } - - //进行排序,将原字符串长的放前面,避免造成有部分不翻译的情况(bug是先翻译了短的,导致长的被打断而无法进行适配) - tasks.sort((a, b) => b.originalText.length - a.originalText.length); - - this.taskQueue[hash] = tasks; - } - - //console.log('===========task========='); - //console.log(this.taskQueue); - //console.log(this.nodes); - //console.log('===========task======end==='); - - //进行翻译前,先刷新一下 dom监听的忽略node,将过期的node剔除,降低listener的压力 - translate.listener.refreshIgnoreNode(); - - //对nodeQueue进行翻译 - for (var hash in this.nodes) { - if (!Object.hasOwn(this.nodes, hash)) { - continue; - } - - var tasks = this.taskQueue[hash]; //取出当前node元素对应的替换任务 - //var tagName = this.nodes[hash][0].nodeName; //以下节点的tag name - //console.log(tasks); - for ( - var node_index = 0; - node_index < this.nodes[hash].length; - node_index++ - ) { - //对这个node元素进行替换翻译字符 - for (var task_index = 0; task_index < tasks.length; task_index++) { - var task = tasks[task_index]; - if (typeof tasks == "function") { - //进行异常的预处理调出 - continue; - } - - //翻译完毕后,再将这个翻译的目标node从 inPro....Nodes 中去掉 - var ipnode = this.nodes[hash][task_index]; - //console.log('int-----++'+ipnode.nodeValue); - setTimeout( - (ipnode) => { - //console.log('int-----'+ipnode.nodeValue); - for ( - var ini = 0; - ini < translate.inProgressNodes.length; - ini++ - ) { - if (translate.inProgressNodes[ini].node.isSameNode(ipnode)) { - //console.log('in progress --'); - //console.log(ipnode); - //有记录了,那么出现次数 +1 - translate.inProgressNodes[ini].number = - translate.inProgressNodes[ini].number - 1; - //console.log("inProgressNodes -- number: "+translate.inProgressNodes[ini].number+', text:'+ipnode.nodeValue); - if (translate.inProgressNodes[ini].number < 1) { - translate.inProgressNodes.splice(ini, 1); - //console.log("inProgressNodes -- 减去node length: "+translate.inProgressNodes.length+', text:'+ipnode.nodeValue); - } - - break; - } - } - }, - 50, - ipnode, - ); - - //渲染页面进行翻译显示 - var analyseSet = translate.element.nodeAnalyse.set( - this.nodes[hash][task_index], - task.originalText, - task.resultText, - task["attribute"], - ); - //加入 translate.listener.ignoreNode - translate.listener.addIgnore( - this.nodes[hash][task_index], - translate.listener.translateExecuteNodeIgnoreExpireTime, - analyseSet.resultText, - ); - - /* - //var tagName = translate.element.getTagNameByNode(this.nodes[hash][task_index]);//节点的tag name - //console.log(tagName) - //console.log(this.nodes[hash][task_index]) - //var tagName = this.nodes[hash][task_index].nodeName; //节点的tag name - var nodename = translate.element.getNodeName(this.nodes[hash][task_index]); - - //console.log(this.nodes[hash][task_index]+', '+task.originalText+', '+task.resultText+', tagName:'+tagName); - if(nodename == 'META'){ - if(typeof(this.nodes[hash][task_index].name) != 'undefined' && this.nodes[hash][task_index].name != null){ - //var nodeName = this.nodes[hash][task_index].name.toLowerCase(); //取meta 标签的name 属性 - - this.nodes[hash][task_index].content = this.nodes[hash][task_index].content.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText)); - } - }else if(nodename == 'IMG'){ - this.nodes[hash][task_index].alt = this.nodes[hash][task_index].alt.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText)); - }else{ - //普通的 - //console.log('task.originalText : '+task.originalText); - //console.log(translate.util.regExp.pattern(task.originalText)) - //console.log('task.resultText : '+task.resultText); - this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText)); - } - */ - } - } - } - - //console.log('---listen'); - - //监听 - 增加到翻译历史里面 nodeHistory - if ( - typeof this.taskQueue != "undefined" && - Object.keys(this.taskQueue).length > 0 - ) { - setTimeout(() => { - /** 执行完成后,保存翻译的历史node **/ - //将当前翻译完成的node进行缓存记录,以node唯一标识为key, node、以及node当前翻译之后的内容为值进行缓存。方便下一次执行 translate.execute() 时,若值未变化则不进行翻译 - for (var hash in this.nodes) { - if (!Object.hasOwn(this.nodes, hash)) { - continue; - } - - //console.log(translate.nodeQueue[uuid].list[lang][hash]) - for (var nodeindex in this.nodes[hash]) { - if (!Object.hasOwn(this.nodes[hash], nodeindex)) { - continue; - } - - //console.log(translate.nodeQueue[uuid].list[lang][hash].original); - //var nodename = translate.element.getNodeName(translate.nodeQueue[uuid].list[lang][hash].nodes[0].node); - //console.log("nodename:"+nodename); - var analyse = translate.element.nodeAnalyse.get( - this.nodes[hash][nodeindex], - ); - //analyse.text analyse.node - var nodeid = nodeuuid.uuid(analyse.node); - - if (nodeid.length == 0) { - //像是input的placeholder 暂时没考虑进去,这种就直接忽略了 - continue; - } - - //加入 - /* - if(typeof(translate.nodeHistory[nodeid]) == 'object'){ - //已经加入过了,判断它的值是否有发生过变化 - - if(translate.nodeHistory[nodeid].translateText == analyse.text){ - //值相同,就不用再加入了 - continue; - } - } - 这里就不用判断了,直接同步到最新的,因为同一个node,可能有本地缓存直接更新,这样会非常快,网络的会慢2秒,因时间导致同步不是最新的 - */ - //console.log(analyse); - //console.log('add-----'+analyse.text +', uuid:'+nodeid); - //console.log(analyse.node); - translate.nodeHistory[nodeid] = {}; - translate.nodeHistory[nodeid].node = analyse.node; - if (translate.whole.isWhole(analyse.node)) { - //这个元素使用的是整体翻译的方式,那就直接将API接口返回的翻译内容作为node最终显示的结果。 - //这样即使在翻译过程中其他js对这个元素的内容有改动了,那下次再触发翻译,还能对改动后的文本正常翻译,不至于使这个元素已被标记翻译过了,造成漏翻译。 - translate.nodeHistory[nodeid].translateText = - this.taskQueue[hash][nodeindex].resultText; - } else { - //时间差会造成漏翻译情况,见if中的注释 - translate.nodeHistory[nodeid].translateText = analyse.text; - } - } - } - //console.log(translate.nodeHistory); - - /** 执行完成后,触发用户自定义的翻译完成执行函数 **/ - translate.listener.renderTaskFinish(this); - }, 50); - } else { - //console.log(this.taskQueue); - //console.log('---this.taskQueue is null'); - } - } - }, - - /* - 当前状态,执行状态 - 0 空闲(或者执行翻译完毕) - 10 扫描要翻译的node,并读取浏览器缓存的翻译内容进行渲染显示 - 20 浏览器缓存渲染完毕,ajax通过文本翻译接口开始请求,在发起ajax请求前,状态变为20,然后再发起ajax请求 - 至于翻译完毕后进行渲染,这个就不单独记录了,因为如果页面存在不同的语种,不同的语种是按照不同的请求来的,是多个异步同时进行的过程 - */ - state: 0, - - /* - 等待翻译队列 v3.12.6 增加 - 当前是否有需要等待翻译的任务,这个目的是为了保证同一时间 translate.execute() 只有一次在执行,免得被新手前端给造成死循环,导致edge翻译给你屏蔽,用户网页还卡死 - 当执行 translate.execute() 时,会先判断状态 translate.state 是否是0空闲的状态,如果空闲,才会执行,如果不是空闲,则不会执行,而是进入到这里进行等待,等待执行完毕后 translate.state 变成0空闲之后,再来执行这里的 - - */ - waitingExecute: { - use: true, //默认是使用,自有部署场景不担心并发的场景,可以禁用,以提高用户使用体验。 - - /* - 一维数组形态,存放执行的翻译任务 - 二维对象形态,存放执行传入的 docs - */ - queue: [], - /* - 增加一个翻译任务到翻译队列中 - docs 同 translate.execute(docs) 的传入参数 - */ - add: (docs) => { - //向数组末尾追加 - translate.waitingExecute.queue.push(docs); - //开启一个定时器进行触发 - const intervalId = setInterval(() => { - if (translate.state == 0) { - //清除定时器,结束循环 - clearInterval(intervalId); - var docs = translate.waitingExecute.get(); - translate.execute(docs); - //console.log('stop waitingExecute setInterval'); - } - }, 500); - }, - /* - 从 quque 中取第一个元素,同时将其从queue中删除掉它。 - 如果取的时候 quque已经没有任何元素了,会返回 null, 但是理论上不会出现null - */ - get: () => { - //使用 shift 方法删除数组的第一个元素,并将第一个元素的值返回 - if (translate.waitingExecute.queue.length > 0) { - return translate.waitingExecute.queue.shift(); - } - console.log( - "警告, translate.waitingExecute.get 出现异常,quque已空,但还往外取。", - ); - return null; - }, - /* - 当前 translate.translateRequest[uuid] 的是否已经全部执行完毕 - 这里单纯只是对 translate.translateRequest[uuid] 的进行判断 - 这里要在 translate.json 接口触发完并渲染完毕后触发,当然接口失败时也要触发。 - - 正常情况下,是根据本地语言不同,进行分别请求翻译的,比如本地中包含中文、英文、俄语三种语种,要翻译为韩语,那么 - * 中文->韩语会请求一次api - * 英文->韩语会请求一次APi - * 俄语->韩语会请求一次APi - 也就会触发三次 - - @param uuid translate.translateRequest[uuid]中的uuid,也是 translate.nodeQueue 中的uuid - @param from 来源语种,翻译前的语种 - @param to 翻译为的语种 - */ - isAllExecuteFinish: (uuid, from, to) => { - translate.listener.execute.renderFinishByApiRun(uuid, from, to); - - //console.log('uuid:'+uuid+', from:'+from+', to:'+to); - for (var lang in translate.translateRequest[uuid]) { - if (!Object.hasOwn(translate.translateRequest[uuid], lang)) { - continue; - } - //console.log(translate.translateRequest[uuid]) - for ( - var i = 0; - i < translate.translateRequest[uuid][lang].length; - i++ - ) { - if (translate.translateRequest[uuid][lang][i].executeFinish == 0) { - //这个还没执行完,那么直接退出,不在向后执行了 - //console.log('uuid:'+uuid+' lang:'+lang+' executeFinish:0 time:'+translate.translateRequest[uuid][lang][i][addtime]); - - //这里要考虑进行时间判断 - - return; - } - } - } - - //生命周期触发事件 - translate.lifecycle.execute.renderFinish_Trigger(uuid, to); - - //都执行完了,那么设置完毕 - translate.state = 0; - translate.executeNumber++; - }, - }, - - //execute() 方法已经被执行过多少次了, 只有execute() 完全执行完,也就是界面渲染完毕后,它才会+1 - executeNumber: 0, - - lifecycle: { - execute: { - /* - 每当触发执行 translate.execute() 时,会先进行当前是否可以正常进行翻译的判定,比如 当前语种是否就已经是翻译之后的语种了是否没必要翻译了等。(这些初始判定可以理解成它的耗时小于1毫秒,几乎没有耗时) - 经过初始的判断后,发现允许被翻译,那么在向后执行之前,先触发此。 - 也就是在进行翻译之前,触发此。 - - @param uuid:translate.nodeQueue[uuid] 这里的 - @param to 翻译为的语种 - */ - start: [], - start_Trigger: (uuid, to) => { - for (var i = 0; i < translate.lifecycle.execute.start.length; i++) { - try { - translate.lifecycle.execute.start[i](uuid, to); - } catch (e) { - console.log(e); - } - } - }, - - //待整理 - start_old: [], - startRun: (uuid, from, to) => { - //console.log(translate.nodeQueue[uuid]); - for ( - var i = 0; - i < translate.listener.execute.renderStartByApi.length; - i++ - ) { - try { - translate.listener.execute.renderStartByApi[i](uuid, from, to); - } catch (e) { - console.log(e); - } - } - }, - - /* - 当扫描整个节点完成,进行翻译(1. 命中本地缓存、 2.进行网络翻译请求)之前,触发 - 待整理 - */ - scanNodesFinsh: [], - - /* - 每当触发执行 translate.execute() 时,当缓存中未发现,需要请求翻译API进行翻译时,在发送API请求前,触发此 - - @param uuid:translate.nodeQueue[uuid] 这里的 - @param from 来源语种,翻译前的语种 - @param to 翻译为的语种 - @param texts 要翻译的文本,它是一个数组形态,是要进行通过API翻译接口进行翻译的文本,格式如 ['你好','世界'] - */ - translateNetworkBefore: [], - translateNetworkBefore_Trigger: (uuid, from, to, texts) => { - for ( - var i = 0; - i < translate.lifecycle.execute.translateNetworkBefore.length; - i++ - ) { - try { - translate.lifecycle.execute.translateNetworkBefore[i]( - uuid, - from, - to, - texts, - ); - } catch (e) { - console.log(e); - } - } - }, - - /* - 当 translate.execute() 触发网络翻译请求完毕(不管成功还是失败),并将翻译结果渲染到页面完毕后,触发此。 - @param uuid translate.nodeQueue 的uuid - @param from - @param to 当前是执行的翻译为什么语种 - @param text 网络请求翻译的文本/节点/。。。待定 - */ - translateNetworkAfter: [], //已废弃 - /* - - translateNetworkAfter_Trigger:function(uuid, to){ - for(var i = 0; i < translate.lifecycle.execute.translateNetworkAfter.length; i++){ - try{ - translate.lifecycle.execute.translateNetworkAfter[i](uuid, to); - }catch(e){ - console.log(e); - } - } - }, - */ - - /* - translate.execute() 的翻译渲染完毕触发 - 这个完毕是指它当触发 translate.execute() 进行翻译后,无论是全部命中了本地缓存,还是有部分要通过翻译接口发起多个网络请求,当拿到结果(缓存中的翻译结果或多个不同的有xx语种翻译的网络请求全部完成,这个完成是包含所有成功跟失败的响应),并完成将翻译结果渲染到页面中进行显示后,触发此 - 它跟 translateNetworkFinish 的区别是, translateNetworkFinish 仅仅针对有网络请求的才会触发,而 renderFinish 是如果全部命中了浏览器本地缓存,无需发起任何网络翻译请求这种情况时,也会触发。 - @param uuid translate.nodeQueue 的uuid - @param to 当前是执行的翻译为什么语种 - */ - renderFinish: [ - (uuid, to) => { - //这里默认带着一个触发翻译为英文后,自动对英文进行元素视觉处理,追加空格的 - if (typeof translate.visual != "undefined") { - translate.visual.adjustTranslationSpacesByNodequeueUuid(uuid); - } - }, - ], - renderFinish_Trigger: (uuid, to) => { - for ( - var i = 0; - i < translate.lifecycle.execute.renderFinish.length; - i++ - ) { - try { - translate.lifecycle.execute.renderFinish[i](uuid, to); - } catch (e) { - console.log(e); - } - } - }, - }, - }, - - /*translate.execute() start */ - /* - 执行翻译操作。翻译的是 nodeQueue 中的 - docs 如果传入,那么翻译的只是传入的这个docs的。传入如 [document.getElementById('xxx'),document.getElementById('xxx'),...] - 如果不传入或者传入null,则是翻译整个网页所有能翻译的元素 - */ - execute: (docs) => { - if (translate.waitingExecute.use) { - if (translate.state != 0) { - console.log( - "当前翻译还未完结,新的翻译任务已加入等待翻译队列中,待翻译结束后便会执行当前翻译任务。", - ); - translate.waitingExecute.add(docs); - return; - } - } - - translate.state = 1; - //console.log('translate.state = 1'); - if (typeof docs != "undefined") { - //execute传入参数,只有v2版本才支持 - translate.useVersion = "v2"; - } - - if (translate.useVersion == "v1") { - //if(this.to == null || this.to == ''){ - //采用1.x版本的翻译,使用google翻译 - //translate.execute_v1(); - //return; - //v2.5.1增加 - console.log( - "提示:https://github.com/xnx3/translate 在 v2.5 版本之后,由于谷歌翻译调整,免费翻译通道不再支持,所以v1版本的翻译接口不再被支持,v1全线下架。考虑到v1已不能使用,当前已自动切换到v2版本。如果您使用中发现什么异常,请针对v2版本进行适配。", - ); - translate.useVersion = "v2"; - } - - //版本检测 - try { - translate.init(); - } catch (e) {} - - /****** 采用 2.x 版本的翻译,使用自有翻译算法 */ - - //每次执行execute,都会生成一个唯一uuid,也可以叫做队列的唯一标识,每一次执行execute都会创建一个独立的翻译执行队列 - var uuid = translate.util.uuid(); - //console.log('=====') - //console.log(translate.nodeQueue); - - /* v2.4.3 将初始化放到了 translate.element.whileNodes 中,如果uuid对应的没有,则自动创建 - - translate.nodeQueue[uuid] = new Array(); //创建 - translate.nodeQueue[uuid]['expireTime'] = Date.now() + 120*1000; //删除时间,10分钟后删除 - translate.nodeQueue[uuid]['list'] = new Array(); - */ - //console.log(translate.nodeQueue); - //console.log('=====end') - - //如果页面打开第一次使用,先判断缓存中有没有上次使用的语种,从缓存中取出 - if (translate.to == null || translate.to == "") { - var to_storage = translate.storage.get("to"); - if ( - to_storage != null && - typeof to_storage != "undefined" && - to_storage.length > 0 - ) { - translate.to = to_storage; - } - } - - //渲染select选择语言 - try { - translate.selectLanguageTag.render(); - } catch (e) { - console.log(e); - } - - //判断是否还未指定翻译的目标语言 - if ( - translate.to == null || - typeof translate.to == "undefined" || - translate.to.length == 0 - ) { - //未指定,判断如果指定了自动获取用户本国语种了,那么进行获取 - if (translate.autoDiscriminateLocalLanguage) { - translate.executeByLocalLanguage(); - } else { - //没有指定翻译目标语言、又没自动获取用户本国语种,则不翻译 - translate.state = 0; - return; - } - } - - //判断本地语种跟要翻译的目标语种是否一样,如果是一样,那就不需要进行任何翻译 - if (translate.to == translate.language.getLocal()) { - if (translate.language.translateLocal) { - //这是自定义设置的允许翻译本地语种中,跟本地语种不一致的语言进行翻译 - } else { - translate.state = 0; - return; - } - } - - /********** 翻译进行 */ - - //生命周期-触发翻译进行之前,用户自定义的钩子 - translate.lifecycle.execute.start_Trigger(uuid, translate.to); - - //先进行图片的翻译替换,毕竟图片还有加载的过程 - translate.images.execute(); - - /* - 进行翻译指定的node操作。优先级为: - 1. 这个方法已经指定的翻译 nodes - 2. setDocuments 指定的 - 3. 整个网页 - 其实2、3都是通过 getDocuments() 取,在getDocuments() 就对2、3进行了判断 - */ - var all; - if (typeof docs != "undefined" && docs != null) { - //1. 这个方法已经指定的翻译 nodes - - /* v3.12.6 注释,转到判断非null - if(docs == null){ - //要翻译的目标区域不存在 - console.log('translate.execute(...) 中传入的要翻译的目标区域不存在。'); - translate.state = 0; - return; - } - */ - - if (typeof docs.length == "undefined") { - //不是数组,是单个元素 - all = []; - all[0] = docs; - } else { - //是数组,直接赋予 - all = docs; - } - } else { - //2、3 - all = translate.getDocuments(); - } - //console.log('----要翻译的目标元素-----'); - //console.log(all) - - if (all.length > 500) { - console.log("------tip------"); - console.log( - "translate.execute( docs ) 传入的docs.length 过大,超过500,这很不正常,当前 docs.length : " + - all.length + - " ,如果你感觉真的没问题,请联系作者 http://translate.zvo.cn/43006.html 说明情况,根据你的情况进行分析。 当前只取前500个元素进行翻译", - ); - } - - //初始化 translate.element.tagAttribute ,主要针对 v3.17.10 版本的适配调整,对 translate.element.tagAttribute 的设置做了改变,做旧版本的适配 - try { - for (var te_tag in translate.element.tagAttribute) { - if (!Object.hasOwn(translate.element.tagAttribute, te_tag)) { - continue; - } - if (translate.element.tagAttribute[te_tag] instanceof Array) { - //是 v3.17.10 之前版本的设置方式,要进行对旧版本的适配 - var tArray = translate.element.tagAttribute[te_tag]; - translate.element.tagAttribute[te_tag] = { - attribute: tArray, - condition: (element) => true, - }; - } - } - } catch (e) { - console.log(e); - } - - //检索目标内的node元素 - for (var i = 0; (i < all.length) & (i < 500); i++) { - var node = all[i]; - translate.element.whileNodes(uuid, node); - } - - /***** translate.language.translateLanguagesRange 开始 *****/ - if (translate.language.translateLanguagesRange.length > 0) { - //如果大于0,则是有设置,那么只翻译有设置的语种,不在设置中的语种不会参与翻译 - for (var lang in translate.nodeQueue[uuid].list) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list, lang)) { - continue; - } - if (translate.language.translateLanguagesRange.indexOf(lang) < 0) { - //删除这个语种 - delete translate.nodeQueue[uuid].list[lang]; - } - } - } - - /***** translate.language.translateLanguagesRange 结束 *****/ - - //修复如果translate放在了页面最顶部,此时执行肯定扫描不到任何东西的,避免这种情况出现报错 - if (typeof translate.nodeQueue[uuid] == "undefined") { - translate.nodeQueue[uuid] = []; - translate.nodeQueue[uuid].list = []; - console.log("--- translate.js warn tip 警告!! ---"); - console.log( - "您使用translate.js时可能放的位置不对,不要吧 translate.js 放在网页最顶部,这样当 translate.js 进行执行,也就是 translate.execute() 执行时,因为网页是从上往下加载,它放在网页最顶部,那么它执行时网页后面的内容都还没加载出来,这个是不会获取到网页任何内容的,也就是它是不起任何作用的", - ); - } - for (var lang in translate.nodeQueue[uuid].list) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list, lang)) { - continue; - } - //console.log('lang:'+lang) - for (var hash in translate.nodeQueue[uuid].list[lang]) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list[lang], hash)) { - continue; - } - //console.log(hash) - if (typeof translate.nodeQueue[uuid].list[lang][hash] == "function") { - //v2.10增加,避免hash冒出个 Contains 出来导致for中的.length 出错 - continue; - } - if ( - typeof translate.nodeQueue[uuid].list[lang][hash].nodes == - "undefined" || - typeof translate.nodeQueue[uuid].list[lang][hash].nodes.length == - "undefined" - ) { - //v3.16.2 增加,针对深圳北理莫斯科学校龙老师提出的这里 .length 遇到了 undefined 的情况 - continue; - } - for ( - var nodeindex = - translate.nodeQueue[uuid].list[lang][hash].nodes.length - 1; - nodeindex > -1; - nodeindex-- - ) { - //console.log(translate.nodeQueue[uuid].list[lang][hash].nodes); - var analyse = translate.element.nodeAnalyse.get( - translate.nodeQueue[uuid].list[lang][hash].nodes[nodeindex].node, - ); - //analyse.text analyse.node - var nodeid = nodeuuid.uuid(analyse.node); - //translate.nodeQueue[uuid].list[lang][hash].nodes.splice(nodeindex, 1); - //console.log(nodeid+'\t'+analyse.text); - if (typeof translate.nodeHistory[nodeid] != "undefined") { - //存在,判断其内容是否发生了改变 - //console.log('比较---------'); - //console.log(translate.nodeHistory[nodeid].translateText); - //console.log(analyse.text); - if (translate.nodeHistory[nodeid].translateText == analyse.text) { - //内容未发生改变,那么不需要再翻译了,从translate.nodeQueue中删除这个node - translate.nodeQueue[uuid].list[lang][hash].nodes.splice( - nodeindex, - 1, - ); - //console.log('发现相等的node,删除 '+analyse.text+'\t'+hash); - } else { - //console.log("发现变化的node =======nodeid:"+nodeid); - //console.log(translate.nodeHistory[nodeid].translateText == analyse.text); - //console.log(translate.nodeHistory[nodeid].node); - //console.log(translate.nodeHistory[nodeid].translateText); - //console.log(analyse.text); - } - } else { - //console.log('未在 nodeHistory 中发现,新的node nodeid:'+nodeid); - //console.log(analyse.node) - } - } - if (translate.nodeQueue[uuid].list[lang][hash].nodes.length == 0) { - //如果node数组中已经没有了,那么直接把这个hash去掉 - delete translate.nodeQueue[uuid].list[lang][hash]; - } - } - if (Object.keys(translate.nodeQueue[uuid].list[lang]).length == 0) { - //如果这个语言中没有要翻译的node了,那么删除这个语言 - delete translate.nodeQueue[uuid].list[lang]; - } - } - //console.log('new queuq'); - //console.log(translate.nodeQueue[uuid]) - //translate.nodeHistory[nodeid] - - //console.log('-----待翻译:----'); - //console.log(translate.nodeQueue); - - //translateTextArray[lang][0] - var translateTextArray = {}; //要翻译的文本的数组,格式如 ["你好","欢迎"] - var translateHashArray = {}; //要翻译的文本的hash,跟上面的index是一致的,只不过上面是存要翻译的文本,这个存hash值 - - /* - 要进行第二次扫描的node - 2023.8.22 解决缓存会打散扫描到的翻译文本,导致翻译结束后找寻不到而导致不翻译的问题 - 一维 key: lang - 二维 key: hash - 三维 key: - node: 当前的node元素 - 四维 array: 当前缓存中进行翻译的文本数组: - cacheOriginal: 已缓存被替换前的文本 - cacheTranslateText: 已缓存被替换后的翻译文本 - - */ - var twoScanNodes = {}; - var cacheScanNodes = []; //同上面的 twoScanNodes,只不过 twoScanNodes 是按照lang存的,而这个不再有lang区分 - for (var lang in translate.nodeQueue[uuid]["list"]) { - //二维数组中,取语言 - if (!Object.hasOwn(translate.nodeQueue[uuid]["list"], lang)) { - continue; - } - //console.log('lang:'+lang); //lang为english这种语言标识 - if ( - lang == null || - typeof lang == "undefined" || - lang.length == 0 || - lang == "undefined" - ) { - //console.log('lang is null : '+lang); - continue; - } - - translateTextArray[lang] = []; - translateHashArray[lang] = []; - - const task = new translate.renderTask(); - //console.log(translate.nodeQueue); - - twoScanNodes[lang] = []; - //二维数组,取hash、value - for (var hash in translate.nodeQueue[uuid]["list"][lang]) { - if (!Object.hasOwn(translate.nodeQueue[uuid]["list"][lang], hash)) { - continue; - } - if ( - typeof translate.nodeQueue[uuid]["list"][lang][hash] == "function" - ) { - //跳出,增加容错。 正常情况下应该不会这样 - continue; - } - - //取原始的词,还未经过翻译的,需要进行翻译的词 - //var originalWord = translate.nodeQueue[uuid]['list'][lang][hash]['original']; - - //原始的node中的词 - var originalWord = - translate.nodeQueue[uuid]["list"][lang][hash]["original"]; - //要翻译的词 - var translateText = - translate.nodeQueue[uuid]["list"][lang][hash]["translateText"]; - //console.log(originalWord); - /* - //自定义术语后的。如果 - var nomenclatureOriginalWord = translate.nomenclature.dispose(cache); - if(nomenclatureOriginalWord != originalWord){ - has - } -*/ - //console.log(originalWord == translateText ? '1':'xin:'+translateText); - //根据hash,判断本地是否有缓存了 - var cacheHash = - originalWord == translateText - ? hash - : translate.util.hash(translateText); //如果匹配到了自定义术语库,那翻译前的hash是被改变了 - translate.nodeQueue[uuid]["list"][lang][hash]["cacheHash"] = cacheHash; //缓存的hash。 缓存时,其hash跟翻译的语言是完全对应的,缓存的hash就是翻译的语言转换来的 - var cache = translate.storage.get( - "hash_" + translate.to + "_" + cacheHash, - ); - //console.log(cacheHash+', '+cache); - - //var twoScanNodes[] = []; //要进行第二次扫描的node - if (cache != null && cache.length > 0) { - //有缓存了 - //console.log('find cache:'+cache); - //直接将缓存赋予 - //for(var index = 0; index < this.nodeQueue[lang][hash].length; index++){ - //this.nodeQueue[lang][hash][index].nodeValue = cache; - - for ( - var node_index = 0; - node_index < - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"].length; - node_index++ - ) { - //console.log(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]); - - //加入 translate.inProgressNodes - //取得这个翻译的node - var ipnode = - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["node"]; - - //判断这个node是否已经在 inProgressNodes 记录了 - var isFind = false; - for (var ini = 0; ini < translate.inProgressNodes.length; ini++) { - if (translate.inProgressNodes[ini].node.isSameNode(ipnode)) { - //有记录了,那么出现次数 +1 - translate.inProgressNodes[ini].number++; - isFind = true; - //console.log('cache - find - ++ '); - //console.log(ipnode); - } - } - //未发现,那么还要将这个node加入进去 - if (!isFind) { - //console.log('cache - find - add -- lang:'+lang+', hash:'+hash+' node_index:'+node_index); - //console.log(ipnode.nodeValue); - translate.inProgressNodes.push({ node: ipnode, number: 1 }); - } - - //console.log(translate.inProgressNodes); - //加入 translate.inProgressNodes -- 结束 - - //翻译结果的文本,包含了before 、 after 了 - var translateResultText = - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["beforeText"] + - cache + - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["afterText"]; - task.add( - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["node"], - originalWord, - translateResultText, - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["attribute"], - ); - //this.nodeQueue[lang][hash]['nodes'][node_index].nodeValue = this.nodeQueue[lang][hash]['nodes'][node_index].nodeValue.replace(new RegExp(originalWord,'g'), cache); - //console.log(translateResultText); - - //重新扫描这个node,避免这种情况: - //localstorage缓存中有几个词的缓存了,但是从缓存中使用时,把原本识别的要翻译的数据给打散了,导致翻译结果没法赋予,导致用户展示时有些句子没成功翻译的问题 -- 2023.8.22 - //console.log('继续扫描 + 1 - '+twoScanNodes.length); - var twoScanIndex = -1; //当前元素是否在 twoScan 中已经加入了,如果已经加入了,那么这里赋予当前所在的下标 - for (var i = 0; i < twoScanNodes[lang].length; i++) { - if ( - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["node"].isSameNode(twoScanNodes[lang][i]["node"]) - ) { - //if(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['node'].isSameNode(cacheScanNodes[i]['node'])){ - //如果已经加入过了,那么跳过 - twoScanIndex = i; - break; - } - } - var twoScanIndex_cache = -1; //当前元素是否在 twoScan 中已经加入了,如果已经加入了,那么这里赋予当前所在的下标 - for (var i = 0; i < cacheScanNodes.length; i++) { - //if(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['node'].isSameNode(twoScanNodes[lang][i]['node'])){ - if ( - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["node"].isSameNode(cacheScanNodes[i]["node"]) - ) { - //如果已经加入过了,那么跳过 - twoScanIndex_cache = i; - break; - } - } - - if (twoScanIndex == -1) { - //console.log(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['node']); - twoScanIndex = twoScanNodes[lang].length; - twoScanNodes[lang][twoScanIndex] = {}; - twoScanNodes[lang][twoScanIndex]["node"] = - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["node"]; - twoScanNodes[lang][twoScanIndex]["array"] = []; - } - - if (twoScanIndex_cache == -1) { - twoScanIndex_cache = cacheScanNodes.length; - cacheScanNodes[twoScanIndex_cache] = {}; - cacheScanNodes[twoScanIndex_cache]["node"] = - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["node"]; - cacheScanNodes[twoScanIndex_cache]["array"] = []; - } - - //未加入过,那么加入 - var arrayIndex = twoScanNodes[lang][twoScanIndex]["array"].length; - twoScanNodes[lang][twoScanIndex]["array"][arrayIndex] = - translateResultText; - - var arrayIndex_cache = - cacheScanNodes[twoScanIndex_cache]["array"].length; - cacheScanNodes[twoScanIndex_cache]["array"][arrayIndex_cache] = - translateResultText; - - //twoScanNodes[lang][twoScanIndex]['array'][arrayIndex] = translate.nodeQueue[uuid]['list'][lang][hash]['beforeText']+cache+translate.nodeQueue[uuid]['list'][lang][hash]['afterText']; - } - //} - - continue; //跳出,不用在传入下面的翻译接口了 - } - - /* - //取出数组 - var queueNodes = this.nodeQueue[lang][hash]; - if(queueNodes.length > 0){ - //因为在这个数组中的值都是一样的,那么只需要取出第一个就行了 - var valueStr = queueNodes[0].nodeValue; - valueStr = this.util.charReplace(valueStr); - - translateTextArray[lang].push(valueStr); - translateHashArray[lang].push(hash); - } - */ - - //加入待翻译数组 - translateTextArray[lang].push(translateText); - translateHashArray[lang].push(hash); //这里存入的依旧还是用原始hash,未使用自定义术语库前的hash,目的是不破坏 nodeQueue 的 key - } - - task.execute(); //执行渲染任务 - } - //console.log(twoScanNodes); - //console.log('cacheScanNodes:'); - //console.log(cacheScanNodes); - - if ( - typeof translate.request.api.translate != "string" || - translate.request.api.translate == null || - translate.request.api.translate.length < 1 - ) { - //用户已经设置了不掉翻译接口进行翻译 - translate.state = 0; - - //生命周期触发事件 - translate.lifecycle.execute.renderFinish_Trigger(uuid, translate.to); - translate.executeNumber++; - return; - } - - /******* 进行第二次扫描、追加入翻译队列。目的是防止缓存打散扫描的待翻译文本 ********/ - for (var lang in twoScanNodes) { - if (!Object.hasOwn(twoScanNodes, lang)) { - continue; - } - - //记录第一次扫描的数据,以便跟第二次扫描后的进行对比 - var firstScan = Object.keys(translate.nodeQueue[uuid]["list"][lang]); - var firstScan_lang_langth = firstScan.length; //第一次扫描后的数组长度 - - //console.log(twoScanNodes[lang]); - for (var i = 0; i < twoScanNodes[lang].length; i++) { - //找到这个node元素命中缓存后的翻译记录 - for (var ci = 0; ci < cacheScanNodes.length; ci++) { - if ( - twoScanNodes[lang][i].node.isSameNode(cacheScanNodes[ci]["node"]) - ) { - //如果发现,那么赋予 - twoScanNodes[lang][i].array = cacheScanNodes[ci].array; - break; - } - } - - twoScanNodes[lang][i].array.sort((a, b) => b.length - a.length); - //console.log(twoScanNodes[lang][i].array); - - var nodeAnaly = translate.element.nodeAnalyse.get( - twoScanNodes[lang][i].node, - ); - //console.log(nodeAnaly); - var text = nodeAnaly.text; - //console.log(text.indexOf(twoScanNodes[lang][i].array[0])); - - for (var ai = 0; ai < twoScanNodes[lang][i].array.length; ai++) { - if (twoScanNodes[lang][i].array[ai] < 1) { - continue; - } - text = text.replace( - new RegExp( - translate.util.regExp.pattern(twoScanNodes[lang][i].array[ai]), - "g", - ), - translate.util.regExp.resultText("\n"), - ); - } - - //console.log(text); - var textArray = text.split("\n"); - //console.log(textArray); - for (var tai = 0; tai < textArray.length; tai++) { - if (textArray[tai] < 1) { - continue; - } - //console.log(textArray[tai]); - //将新增的追加到 translate.nodeQueue 中 - translate.addNodeToQueue(uuid, nodeAnaly["node"], textArray[tai]); - } - } - - //取第二次扫描追加后的数据 - var twoScan = Object.keys(translate.nodeQueue[uuid]["list"][lang]); - var twoScan_lang_langth = twoScan.length; //第二次扫描后的数组长度 - //console.log(firstScan_lang_langth+ '=='+twoScan_lang_langth); - if (firstScan_lang_langth - twoScan_lang_langth == 0) { - //一致,没有新增,那么直接跳出,忽略 - continue; - } - - //console.log(translate.nodeQueue[uuid]['list'][lang]); - //console.log(firstScan); - for (var ti = 0; ti < twoScan.length; ti++) { - var twoHash = twoScan[ti]; - //console.log(twoHash + '-- '+firstScan.indexOf(twoHash)); - if (firstScan.indexOf(twoHash) == -1) { - //需要追加了 - var item = translate.nodeQueue[uuid]["list"][lang][twoHash]; - - var cacheHash = - item.original == item.translateText - ? twoHash - : translate.util.hash(item.translateText); //如果匹配到了自定义术语库,那翻译前的hash是被改变了 - translate.nodeQueue[uuid]["list"][lang][twoHash]["cacheHash"] = - cacheHash; //缓存的hash。 缓存时,其hash跟翻译的语言是完全对应的,缓存的hash就是翻译的语言转换来的 - - translateTextArray[lang].push(item.translateText); - translateHashArray[lang].push(twoHash); - } - } - } - /******* 进行第二次扫描、追加入翻译队列 -- 结束 ********/ - - //window.translateHashArray = translateHashArray; - - //统计出要翻译哪些语种 ,这里面的语种会调用接口进行翻译。其内格式如 english - var fanyiLangs = []; - //console.log(translateTextArray) - for (var lang in translate.nodeQueue[uuid]["list"]) { - //二维数组中取语言 - if (!Object.hasOwn(translate.nodeQueue[uuid]["list"], lang)) { - continue; - } - - if (typeof translateTextArray[lang] == "undefined") { - continue; - } - if (translateTextArray[lang].length < 1) { - continue; - } - - //如果当前语种就是需要显示的语种(也就是如果要切换的语种),那么也不会进行翻译,直接忽略 - if (lang == translate.to) { - continue; - } - fanyiLangs.push(lang); - } - - /******* 用以记录当前是否进行完第一次翻译了 *******/ - /* - if(!translate.listener.isExecuteFinish){ - translate.temp_executeFinishNumber = 0; //下面请求接口渲染,翻译执行完成的次数 - //判断是否是执行完一次了 - translate.temp_executeFinishInterval = setInterval(function(){ - if(translate.temp_executeFinishNumber == fanyiLangs.length){ - translate.listener.isExecuteFinish = true; //记录当前已执行完第一次了 - clearInterval(translate.temp_executeFinishInterval);//停止 - console.log('translate.execute() Finish!'); - //console.log(uuid); - - } - }, 50); - } - */ - - //console.log(translate.nodeQueue[uuid]['list']) - if (fanyiLangs.length == 0) { - //没有需要翻译的,直接退出 - - //生命周期触发事件 - translate.lifecycle.execute.renderFinish_Trigger(uuid, translate.to); - - translate.state = 0; - translate.executeNumber++; - return; - } - - //加入 translate.inProgressNodes -- start - for (var lang in translateHashArray) { - if (!Object.hasOwn(translateHashArray, lang)) { - continue; - } - if (typeof translateHashArray[lang] == "undefined") { - continue; - } - if (translateHashArray[lang].length < 1) { - continue; - } - for (var hai = 0; hai < translateHashArray[lang].length; hai++) { - var thhash = translateHashArray[lang][hai]; - //取得这个翻译的node - //var ipnode = translate.nodeQueue[uuid]['list'][lang][thhash].nodes[ipni].node; - //console.log('translate.nodeQueue[\''+uuid+'\'][\'list\'][\'chinese_simplified\'][\''+thhash+'\']'); - //console.log(lang); - //console.log(translate.nodeQueue[uuid]['list'][lang][thhash].nodes); - if ( - typeof translate.nodeQueue[uuid]["list"][lang][thhash].nodes == - "undefined" || - typeof translate.nodeQueue[uuid]["list"][lang][thhash].nodes.length == - "undefined" - ) { - console.log( - "translate.nodeQueue['" + - uuid + - "']['list']['" + - lang + - "']['" + - thhash + - "'].nodes.length is null ,理论上不应该存在,进行异常报出,但不影响使用,已容错。", - ); - continue; - } - - for ( - var ipni = 0; - ipni < translate.nodeQueue[uuid]["list"][lang][thhash].nodes.length; - ipni++ - ) { - //取得这个翻译的node - var ipnode = - translate.nodeQueue[uuid]["list"][lang][thhash].nodes[ipni].node; - - //判断这个node是否已经在 inProgressNodes 记录了 - var isFind = false; - for (var ini = 0; ini < translate.inProgressNodes.length; ini++) { - if (translate.inProgressNodes[ini].node.isSameNode(ipnode)) { - //有记录了,那么出现次数 +1 - //console.log('net request ++'); - //console.log(ipnode); - translate.inProgressNodes[ini].number++; - isFind = true; - } - } - //未发现,那么还要将这个node加入进去 - if (!isFind) { - //console.log('net request add'); - //console.log(ipnode); - translate.inProgressNodes.push({ node: ipnode, number: 1 }); - } - } - } - } - //加入 translate.inProgressNodes -- end - - //状态 - translate.state = 20; - - //进行掉接口翻译 - for (var lang_index in fanyiLangs) { - //一维数组,取语言 - if (!Object.hasOwn(fanyiLangs, lang_index)) { - continue; - } - var lang = fanyiLangs[lang_index]; - if (typeof lang != "string") { - continue; - } - - if ( - typeof translateTextArray[lang] == "undefined" || - translateTextArray[lang].length < 1 - ) { - console.log( - "异常,理论上不应该存在, lang:" + lang + ", translateTextArray:", - ); - console.log(translateTextArray); - console.log( - "你无需担心,这个只是个提示,它并不影响你翻译的正常进行,只是个异常提示而已,它会自动容错处理的,不会影响翻译的使用。", - ); - - translate.state = 0; - translate.executeNumber++; - return; - } - - //自定义术语 - /*var nomenclatureCache = translate.nomenclature.dispose(cache); - for(var ttr_index = 0; ttr_index { - //console.log(data); - //console.log(translateTextArray[data.from]); - if (data.result == 0) { - if ( - typeof translate.translateRequest[uuid] == "object" && - typeof translate.translateRequest[uuid][data.from] == "object" - ) { - translate.translateRequest[uuid][data.from]["result"] = 2; - translate.translateRequest[uuid][data.from].executeFinish = 1; //1是执行完毕 - translate.translateRequest[uuid][data.from].stoptime = Math.floor( - Date.now() / 1000, - ); - } else { - console.log( - "WARINNG!!! translate.translateRequest[uuid][data.from] is not object", - ); - } - - //为了兼容 v3.14以前的translate.service 版本,做了判断 - var from = ""; - if (typeof data.from != "undefined" && data.from != null) { - from = data.from; - } - var to = ""; - if (typeof data.to != "undefined" && data.to != null) { - to = data.to; - } else { - to = translate.to; - } - translate.waitingExecute.isAllExecuteFinish(uuid, from, to); - - console.log("=======ERROR START======="); - console.log(translateTextArray[data.from]); - //console.log(encodeURIComponent(JSON.stringify(translateTextArray[data.from]))); - console.log("response : " + data.info); - console.log("=======ERROR END ======="); - //translate.temp_executeFinishNumber++; //记录执行完的次数 - return; - } - - if (typeof translate.nodeQueue[uuid] == "undefined") { - console.log( - "提示:你很可能多次引入了 translate.js 所以造成了翻译本身的数据错乱,这只是个提示,它还是会给你正常翻译的,但是你最好不要重复引入太多次 translate.js ,正常情况下只需要引入一次 translate.js 就可以了。太多的话很可能会导致你页面卡顿", - ); - return; - } - - //console.log('-----待翻译3:----'); - //console.log(translate.nodeQueue); - - //console.log('response:'+uuid); - const task = new translate.renderTask(); - //遍历 translateHashArray - for (var i = 0; i < translateHashArray[data.from].length; i++) { - //翻译前的语种,如 english - var lang = data.from; - //翻译后的内容 - var text = data.text[i]; - //如果text为null,那么这个可能是一次翻译字数太多,为了保持数组长度,拼上的null - if (text == null) { - continue; - } - - // v3.0.3 添加,避免像是 JavaScript 被错误翻译为 “JavaScript的” ,然后出现了多个句子中都出现了Javascript时,会出现翻译后文本重复的问题 - // 这里就是验证一下,翻译后的文本,是否会完全包含翻以前的文本,如果包含了,那么强制将翻译后的文本赋予翻译前的原始文本(也就是不被翻译) - if ( - text - .toLowerCase() - .indexOf(translateTextArray[data.from][i].toLowerCase()) > -1 - ) { - //发现了,那么强制赋予翻以前内容 - text = translateTextArray[data.from][i]; - } - - //翻译前的hash对应下标 - var hash = translateHashArray[data.from][i]; - var cacheHash = - translate.nodeQueue[uuid]["list"][lang][hash]["cacheHash"]; - - //取原始的词,还未经过翻译的,需要进行翻译的词 - var originalWord = ""; - try { - originalWord = - translate.nodeQueue[uuid]["list"][lang][hash]["original"]; - //console.log('bef:'+translate.nodeQueue[uuid]['list'][lang][hash]['beforeText']); - } catch (e) { - console.log( - "uuid:" + - uuid + - ", originalWord:" + - originalWord + - ", lang:" + - lang + - ", hash:" + - hash + - ", text:" + - text + - ", queue:" + - translate.nodeQueue[uuid], - ); - console.log(e); - continue; - } - - //for(var index = 0; index < translate.nodeQueue[lang][hash].length; index++){ - for ( - var node_index = 0; - node_index < - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"].length; - node_index++ - ) { - //translate.nodeQueue[lang][hash]['nodes'][node_index].nodeValue = translate.nodeQueue[lang][hash]['nodes'][node_index].nodeValue.replace(new RegExp(originalWord,'g'), text); - //加入任务 - task.add( - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["node"], - originalWord, - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["beforeText"] + - text + - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["afterText"], - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][ - node_index - ]["attribute"], - ); - } - //} - /* - for(var index = 0; index < translate.nodeQueue[data.from][hash].length; index++){ - translate.nodeQueue[data.from][hash][index].nodeValue = text; - } - */ - - //将翻译结果以 key:hash value翻译结果的形式缓存 - translate.storage.set("hash_" + data.to + "_" + cacheHash, text); - //如果离线翻译启用了全部提取,那么还要存入离线翻译指定存储 - if (translate.office.fullExtract.isUse) { - translate.office.fullExtract.set( - hash, - originalWord, - data.to, - text, - ); - } - } - task.execute(); //执行渲染任务 - //translate.temp_executeFinishNumber++; //记录执行完的次数 - - translate.translateRequest[uuid][lang].result = 1; - translate.translateRequest[uuid][lang].executeFinish = 1; //1是执行完毕 - translate.translateRequest[uuid][lang].stoptime = Math.floor( - Date.now() / 1000, - ); - setTimeout(() => { - translate.waitingExecute.isAllExecuteFinish( - uuid, - data.from, - data.to, - ); - }, 10); - }, - (xhr) => { - translate.translateRequest[uuid][xhr.data.from].executeFinish = 1; //1是执行完毕 - translate.translateRequest[uuid][xhr.data.from].stoptime = Math.floor( - Date.now() / 1000, - ); - translate.translateRequest[uuid][xhr.data.from].result = 3; - translate.waitingExecute.isAllExecuteFinish( - uuid, - xhr.data.from, - translate.to, - ); - }, - ); - /*** 翻译end ***/ - } - }, - /*translate.execute() end */ - - /** - * 翻译请求记录 - * 一维:key:uuid,也就是execute每次执行都会创建一个翻译队列,这个是翻译队列的唯一标识。 这个uuid跟 nodeQueue 的uuid是一样的 - * value:对象 - * 二维: 对象,包含: - * from 存放的是要翻译的源语种,比如要讲简体中文翻译为英文,这里存放的就是 chinese_simplified - * state 是否执行完毕,0是执行中, 1是执行完毕(不管是失败还是成功) 而且执行完毕是指ajax请求获得响应,并且dom渲染完成之后才算完毕。当然如果ajax接口失败那也是直接算完毕 - * addtime 这条数据加入到本数组的时间,也就是进行ajax请求开始那一刻的时间,10位时间戳 - * stoptime 执行完毕的时间,也就是state转为2那一刻的时间 - * result 执行结果, 0 是还没执行完,等待执行完, > 0 是执行完了有结果了, - * 1 是执行成功 - * 2 是接口有响应,也是200响应,但是接口响应的结果返回了错误,也就是返回了 {result:0, info:'...'} - * 3 是接口不是200响应码 - * - */ - translateRequest: { - /* - uuid:[ - 'chinese_simplified':{ - executeFinish:0, - addtime:150001111, - stoptime:150001111, - result:0 - }, - ... - ] - */ - }, - - /* - 将已成功翻译并渲染的node节点进行缓存记录 - key: node节点的唯一标识符,通过 nodeuuid.uuid() 生成 - value: - node: node节点 - translateText: 翻译完成后,当前node节点的内容文本(是已经翻译渲染过的) - */ - nodeHistory: {}, - element: { - /* - 注意,里面全部的必须小写。 - 第一个是tag,第二个是tag的属性。比如要翻译 input 的 value 属性,那么如下: - translate.element.tagAttribute['input']=['value']; - 比如要翻译 input 的 value 、 data-value 这两个属性,那么如下: - translate.element.tagAttribute['input']=['value','data-value']; - 有几个要翻译的属性,就写上几个。 - 同样,有几个要额外翻译的tag,就加上几行。 - 详细文档参考: http://translate.zvo.cn/231504.html - - - //针对宁德时代提出的需求,需要对 标签本身进行一个判定,是否符合条件符合条件才会翻译,不符合条件则不要进行翻译 - //比如标签带有 disabled 的才会被翻译,所以要增加一个自定义入参的 function ,返回 true、false - translate.element.tagAttribute['input']={ - //要被翻译的tag的属性,这里是要翻译 input 的 value 、 data-value 这两个属性。 - //数组格式,可以一个或多个属性 - attribute:['value','data-value'], - //条件,传入一个function,返回一个布尔值。 - //只有当返回的布尔值是true时,才会对上面设置的 attribute 进行翻译,否则并不会对当前设定标签的 attribute 进行任何翻译操作。 - condition:function(element){ - // element 便是当前的元素, - // 比如这里是 translate.element.tagAttribute['input'] 那这个 element 参数便是扫描到的具体的 input 元素 - // 可以针对 element 这个当前元素本身来进行判定,来决定是否进行翻译。 - // 返回值是布尔值 true、false - // return true; //要对 attribute中设置的 ['value','data-value'] 这两个input 的属性的值进行翻译。 - // 如果不设置或传入 condition ,比如单纯这样设置: - // translate.element.tagAttribute['input']={ - // attribute:['value','data-value'] - // } - // 那么这里默认就是 return true; - // return false; //不对 attribute中设置的 ['value','data-value'] 这两个input 的属性的值进行任何操作 - return true; - } - }; - - */ - tagAttribute: {}, - - //对翻译前后的node元素的分析(翻以前)及渲染(翻译后) - nodeAnalyse: { - /* - 获取node中的要进行翻译的文本内容、以及要操作的实际node对象(这个node对象很可能是传入的node中的某个子node) - node - attribute 要获取的是某个属性的值,还是node本身的值。比如 a标签的title属性的值,则传入 title。 如果是直接获取node.nodeValue ,那这个没有 - - 返回结果是一个数组。其中: - ['text']:要进行翻译的text内容文本 - ['node']:要进行翻译的目标node - - */ - get: (node, attribute) => - translate.element.nodeAnalyse.analyse(node, "", "", attribute), - /* - 进行翻译之后的渲染显示 - 参数: - node 当前翻译的node元素 - originalText 翻译之前的内容文本 - resultText 翻译之后的内容文本 - attribute 存放要替换的属性,比如 a标签的title属性。 如果是直接替换node.nodeValue ,那这个没有 - 返回结果是一个数组,其中: - resultText: 翻译完成之后的text内容文本,注意,如果返回的是空字符串,那么则是翻译结果进行替换时,并没有成功替换,应该是翻译的过程中,这个node的值被其他js又赋予其他内容了。 - node: 进行翻译的目标node - */ - set: (node, originalText, resultText, attribute) => - translate.element.nodeAnalyse.analyse( - node, - originalText, - resultText, - attribute, - ), - /* - - 注意,这个不使用,只是服务于上面的get、set使用。具体使用用上面的get、set - - 1. 只传入 node: - 获取node中的要进行翻译的文本内容、以及要操作的实际node对象(这个node对象很可能是传入的node中的某个子node) - 返回结果是一个数组。其中: - ['text']:要进行翻译的text内容文本 - ['node']:要进行翻译的目标node - 2. 传入 node、originalText、 resultText - 则是进行翻译之后的渲染显示 - - attribute : 进行替换渲染时使用,存放要替换的属性,比如 a标签的title属性。 如果是直接替换node.nodeValue ,那这个没有 - - 返回结果是一个数组,其中: - resultText: 翻译完成之后的text内容文本。 当使用 translate.element.nodeAnalyse.set 时才会有这个参数返回。 注意,如果返回的是空字符串,那么则是翻译结果进行替换时,并没有成功替换,应该是翻译的过程中,这个node的值被其他js又赋予其他内容了。 - text : 要进行翻译的text内容文本,当使用 translate.element.nodeAnalyse.get 时才会有这个参数的返回 - node: 进行翻译的目标node - */ - analyse: (node, originalText, resultText, attribute) => { - var result = []; //返回的结果 - result["node"] = node; - result["text"] = ""; - - var nodename = translate.element.getNodeName(node); - - if ( - attribute != null && - typeof attribute == "string" && - attribute.length > 0 - ) { - //这个node有属性,替换的是node的属性,而不是nodeValue - - var nodeAttributeValue; //这个 attribute 属性的值 - if (nodename == "INPUT" && attribute.toLowerCase() == "value") { - //如果是input 的value属性,那么要直接获取,而非通过 attribute ,不然用户自己输入的通过 attribute 是获取不到的 -- catl 赵阳 提出 - - nodeAttributeValue = node.value; - } else { - nodeAttributeValue = node[attribute]; - } - result["text"] = nodeAttributeValue; - - //替换渲染 - if (typeof originalText != "undefined" && originalText.length > 0) { - if (typeof nodeAttributeValue != "undefined") { - //这种是主流框架,像是vue、element、react 都是用这种 DOM Property 的方式,更快 - var resultShowText = translate.util.textReplace( - nodeAttributeValue, - originalText, - resultText, - translate.to, - ); - if (nodename == "INPUT" && attribute.toLowerCase() == "value") { - //input 的value 对于用户输入的必须用 .value 操作 - node.value = resultShowText; - } else { - node[attribute] = resultShowText; //2025.4.26 变更为此方式 - } - if (resultShowText.indexOf(resultText) > -1) { - result["resultText"] = resultShowText; - } else { - result["resultText"] = ""; - } - } - - //这种 Html Attribute 方式 是 v3.12 版本之前一直使用的方式,速度上要慢于 上面的,为了向前兼容不至于升级出问题,后面可能会优化掉 - var htmlAttributeValue = node.getAttribute(attribute); - if ( - htmlAttributeValue != null && - typeof htmlAttributeValue != "undefined" - ) { - var resultShowText = translate.util.textReplace( - htmlAttributeValue, - originalText, - resultText, - translate.to, - ); - //这个才是在v3.9.2 后要用的,上面的留着只是为了适配以前的 - node.setAttribute(attribute, resultShowText); - if (resultShowText.indexOf(resultText) > -1) { - result["resultText"] = resultShowText; - } else { - result["resultText"] = ""; - } - } - } - return result; - } - - //正常的node ,typeof 都是 object - - //console.log(typeof(node)+node); - if (nodename == "#text") { - //如果是普通文本,判断一下上层是否是包含在textarea标签中 - if (typeof node.parentNode != "undefined") { - var parentNodename = translate.element.getNodeName(node.parentNode); - //console.log(parentNodename) - if (parentNodename == "TEXTAREA") { - //是textarea标签,那将nodename 纳入 textarea的判断中,同时将判断对象交于上级,也就是textarea标签 - nodename = "TEXTAREA"; - node = node.parentNode; - } - } - } - - //console.log(nodename) - //console.log(translate.element.getNodeName(node.parentNode)) - //console.log(node) - if (nodename == "INPUT" || nodename == "TEXTAREA") { - //console.log(node.attributes) - /* - 1. input、textarea 输入框,要对 placeholder 做翻译 - 2. input 要对 type=button 的情况进行翻译 - */ - if ( - node.attributes == null || - typeof node.attributes == "undefined" - ) { - result["text"] = ""; - return result; - } - - //input,要对 type=button、submit 的情况进行翻译 - if (nodename == "INPUT") { - if ( - typeof node.attributes.type != "undefined" && - typeof node.attributes.type.nodeValue != null && - (node.attributes.type.nodeValue.toLowerCase() == "button" || - node.attributes.type.nodeValue.toLowerCase() == "submit") - ) { - //console.log('----是 0 - ) { - //替换渲染 - if ( - typeof originalText != "undefined" && - originalText.length > 0 - ) { - var resultShowText = translate.util.textReplace( - input_value_node.nodeValue, - originalText, - resultText, - translate.to, - ); - input_value_node.nodeValue = resultShowText; //2025.4.26 变更为此方式 - if (resultShowText.indexOf(resultText) > -1) { - result["resultText"] = resultShowText; - } else { - result["resultText"] = ""; - } - } - - result["text"] = input_value_node.nodeValue; - result["node"] = input_value_node; - return result; - } - } - } - //console.log(node) - - //input textarea 的 placeholder 情况 - if (typeof node.attributes["placeholder"] != "undefined") { - //console.log(node); - //替换渲染 - if (typeof originalText != "undefined" && originalText.length > 0) { - var resultShowText = translate.util.textReplace( - node.attributes["placeholder"].nodeValue, - originalText, - resultText, - translate.to, - ); - node.attributes["placeholder"].nodeValue = resultShowText; //2025.4.26 变更为此方式 - if (resultShowText.indexOf(resultText) > -1) { - result["resultText"] = resultShowText; - } else { - result["resultText"] = ""; - } - } - - result["text"] = node.attributes["placeholder"].nodeValue; - result["node"] = node.attributes["placeholder"]; - return result; - //return node.attributes['placeholder'].nodeValue; - } - //console.log(node) - result["text"] = ""; - return result; - } - if (nodename == "META") { - //meta标签,如是关键词、描述等 - if (typeof node.name != "undefined" && node.name != null) { - var nodeAttributeName = node.name.toLowerCase(); //取meta 标签的name 属性 - var nodeAttributePropertyOri = node.getAttribute("property"); //取 property的值 - var nodeAttributeProperty = ""; - if ( - typeof nodeAttributePropertyOri != "undefined" && - nodeAttributePropertyOri != null && - nodeAttributePropertyOri.length > 0 - ) { - nodeAttributeProperty = nodeAttributePropertyOri.toLowerCase(); - } - if ( - nodeAttributeName == "keywords" || - nodeAttributeName == "description" || - nodeAttributeName == "sharetitle" || - nodeAttributeProperty == "og:title" || - nodeAttributeProperty == "og:description" || - nodeAttributeProperty == "og:site_name" || - nodeAttributeProperty == "og:novel:latest_chapter_name" - ) { - //替换渲染 - if ( - typeof originalText != "undefined" && - originalText != null && - originalText.length > 0 - ) { - var resultShowText = translate.util.textReplace( - node.content, - originalText, - resultText, - translate.to, - ); - node.content = resultShowText; //2025.4.26 变更为此方式 - if (resultShowText.indexOf(resultText) > -1) { - result["resultText"] = resultShowText; - } else { - result["resultText"] = ""; - } - } - - result["text"] = node.content; - return result; - } - } - - result["text"] = ""; - return result; - } - if (nodename == "IMG") { - if (typeof node.alt == "undefined" || node.alt == null) { - result["text"] = ""; - return result; - } - - //替换渲染 - if (typeof originalText != "undefined" && originalText.length > 0) { - var resultShowText = translate.util.textReplace( - node.alt, - originalText, - resultText, - translate.to, - ); - node.alt = resultShowText; //2025.4.26 变更为此方式 - if (resultShowText.indexOf(resultText) > -1) { - result["resultText"] = resultShowText; - } else { - result["resultText"] = ""; - } - } - result["text"] = node.alt; - return result; - } - - //其他的 - if (node.nodeValue == null || typeof node.nodeValue == "undefined") { - result["text"] = ""; - } else if (node.nodeValue.trim().length == 0) { - //避免就是单纯的空格或者换行 - result["text"] = ""; - } else { - //替换渲染 - if ( - typeof originalText != "undefined" && - originalText != null && - originalText.length > 0 - ) { - //console.log(originalText+'|'); - var resultShowText = translate.util.textReplace( - node.nodeValue, - originalText, - resultText, - translate.to, - ); - //console.log(resultShowText+'|'); - node.nodeValue = resultShowText; //2025.4.26 变更为此方式 - if (resultShowText.indexOf(resultText) > -1) { - result["resultText"] = resultShowText; - } else { - result["resultText"] = ""; - } - } - result["text"] = node.nodeValue; - } - return result; - }, - }, - //获取这个node元素的node name ,如果未发现,则返回''空字符串 - getNodeName: (node) => { - if (node == null || typeof node == "undefined") { - return ""; - } - - if (node.nodeName == null || typeof node.nodeName == "undefined") { - return ""; - } - - var nodename = node.nodeName; - if (typeof node.nodeName == "string") { - return node.nodeName; - } - if (typeof node.tagName == "string" && node.tagName.length > 0) { - return node.tagName; - } - console.log( - "warn : get nodeName is null, this node ignore translate. node : ", - ); - console.log(node); - return ""; - }, - //向下遍历node - whileNodes: (uuid, node) => { - if (node == null || typeof node == "undefined") { - return; - } - - //如果这个uuid没有,则创建 - if ( - typeof translate.nodeQueue[uuid] == "undefined" || - translate.nodeQueue[uuid] == null - ) { - translate.nodeQueue[uuid] = []; //创建 - translate.nodeQueue[uuid]["expireTime"] = Date.now() + 120 * 1000; //删除时间,10分钟后删除 - translate.nodeQueue[uuid]["list"] = []; - //console.log('创建 --- '); - //console.log(uuid) - } - - //console.log('---'+typeof(node)+', '); - //判断是否是有title属性,title属性也要翻译 - if ( - typeof node == "object" && - typeof node["title"] == "string" && - node["title"].length > 0 - ) { - //将title加入翻译队列 - //console.log('---'+node.title+'\t'+node.tagName); - //console.log(node) - //console.log('------------'); - - //判断当前元素是否在ignore忽略的tag、id、class name中 - if (!translate.ignore.isIgnore(node)) { - //不在忽略的里面,才会加入翻译 - translate.addNodeToQueue(uuid, node, node["title"], "title"); - } - } - - //v3.9.2 增加, 用户可自定义标签内 attribute 的翻译 - var nodeNameLowerCase = translate.element.getNodeName(node).toLowerCase(); - if ( - typeof translate.element.tagAttribute[nodeNameLowerCase] != "undefined" - ) { - //console.log('find:'+nodeNameLowerCase); - //console.log(translate.element.tagAttribute[nodeNameLowerCase]); - - for (var attributeName_index in translate.element.tagAttribute[ - nodeNameLowerCase - ].attribute) { - if ( - !Object.hasOwn( - translate.element.tagAttribute[nodeNameLowerCase].attribute, - attributeName_index, - ) - ) { - continue; - } - if ( - typeof translate.element.tagAttribute[nodeNameLowerCase] - .condition != "undefined" && - !translate.element.tagAttribute[nodeNameLowerCase].condition(node) - ) { - continue; - } - - var attributeName = - translate.element.tagAttribute[nodeNameLowerCase].attribute[ - attributeName_index - ]; - //console.log(attributeName); - //console.log(node.getAttribute(attributeName)); - - if ( - nodeNameLowerCase == "input" && - attributeName.toLowerCase() == "value" - ) { - //如果是input 的value属性,那么要直接获取,而非通过 attribute ,不然用户自己输入的通过 attribute 是获取不到的 - catl 赵阳 提出 - attributeValue = node.value; - DOMPropOrHTMLAttr = "DOMProperty"; - } else { - /* - * 默认是 HtmlAtrribute 也就是 HTML特性。取值有两个: - * HTMLAtrribute : HTML特性 - * DOMProperty : DOM属性 - */ - var DOMPropOrHTMLAttr = "HTMLAtrribute"; - var attributeValue = node.getAttribute(attributeName); - if ( - typeof attributeValue == "undefined" || - attributeValue == null - ) { - //vue、element、react 中的一些动态赋值,比如 element 中的 el-select 选中后赋予显示出来的文本,getAttribute 就取不到,因为是改动的 DOM属性,所以要用这种方式才能取出来 - attributeValue = node[attributeName]; - DOMPropOrHTMLAttr = "DOMProperty"; - } - if ( - typeof attributeValue == "undefined" || - attributeValue == null - ) { - //这个tag标签没有这个属性,忽略 - continue; - } - } - - //if(typeof(node.getAttribute(attributeName)) == 'undefined' && typeof(node[attributeName]) == 'undefined'){ - // //这个tag标签没有这个 attribute,忽略 - // continue - //} - //判断当前元素是否在ignore忽略的tag、id、class name中 v3.15.7 增加 - if (!translate.ignore.isIgnore(node)) { - //加入翻译 - translate.addNodeToQueue(uuid, node, attributeValue, attributeName); - } - } - } - - var childNodes = node.childNodes; - if (childNodes == null || typeof childNodes == "undefined") { - return; - } - if (childNodes.length > 0) { - for (var i = 0; i < childNodes.length; i++) { - translate.element.whileNodes(uuid, childNodes[i]); - } - } else { - //单个了 - translate.element.findNode(uuid, node); - } - }, - findNode: (uuid, node) => { - if (node == null || typeof node == "undefined") { - return; - } - if (node.parentNode == null) { - return; - } - - //console.log('-----parent') - var parentNodeName = translate.element.getNodeName(node.parentNode); - //node.parentNode.nodeName; - if (parentNodeName == "") { - return; - } - if (translate.ignore.tag.indexOf(parentNodeName.toLowerCase()) > -1) { - //忽略tag - //console.log('忽略tag:'+parentNodeName); - return; - } - - /****** 判断忽略的class ******/ - /* - 这段理论上不需要了,因为在 translate.ignore.isIgnore 判断了 - var ignoreClass = false; //是否是被忽略的class,true是 - var parentNode = node.parentNode; - while(node != parentNode && parentNode != null){ - //console.log('node:'+node+', parentNode:'+parentNode); - if(parentNode.className != null){ - if(translate.ignore.class.indexOf(parentNode.className) > -1){ - //发现ignore.class 当前是处于被忽略的 class - ignoreClass = true; - } - } - - parentNode = parentNode.parentNode; - } - if(ignoreClass){ - //console.log('ignore class : node:'+node.nodeValue); - return; - } - */ - /**** 判断忽略的class结束 ******/ - - /**** 避免中途局部翻译,在判断一下 ****/ - //判断当前元素是否在ignore忽略的tag、id、class name中 - if (translate.ignore.isIgnore(node)) { - //console.log('node包含在要忽略的元素中:'); - //console.log(node); - return; - } - - //node分析 - var nodeAnaly = translate.element.nodeAnalyse.get(node); - //console.log(nodeAnaly) - if (nodeAnaly["text"].length > 0) { - //有要翻译的目标内容,加入翻译队列 - //console.log('addNodeToQueue -- '+nodeAnaly['node']+', text:' + nodeAnaly['text']); - translate.addNodeToQueue(uuid, nodeAnaly["node"], nodeAnaly["text"]); - } - - //console.log(nodeAnaly); - /* - //console.log(node.nodeName+', type:'+node.nodeType+', '+node.nodeValue); - var nodename = translate.element.getNodeName(node); - if(nodename == 'INPUT' || nodename == 'TEXTAREA'){ - //input 输入框,要对 placeholder 做翻译 - console.log('input---'+node.attributes); - if(node.attributes == null || typeof(node.attributes) == 'undefined'){ - return; - } - - if(typeof(node.attributes['placeholder']) != 'undefined'){ - //console.log(node.attributes['placeholder'].nodeValue); - //加入要翻译的node队列 - //translate.nodeQueue[translate.hash(node.nodeValue)] = node.attributes['placeholder']; - //加入要翻译的node队列 - //translate.addNodeToQueue(translate.hash(node.attributes['placeholder'].nodeValue), node.attributes['placeholder']); - translate.addNodeToQueue(uuid, node.attributes['placeholder'], node.attributes['placeholder'].nodeValue); - } - - //console.log(node.getAttribute("placeholder")); - }else if(nodename == 'META'){ - //meta标签,如是关键词、描述等 - if(typeof(node.name) != 'undefined' && node.name != null){ - var nodeAttributeName = node.name.toLowerCase(); //取meta 标签的name 属性 - //console.log(nodeName); - if(nodeAttributeName == 'keywords' || nodeAttributeName == 'description'){ - //关键词、描述 - translate.addNodeToQueue(uuid, node, node.content); - } - } - //console.log(node.name) - }else if(nodename == 'IMG'){ - //console.log('-------'+node.alt); - translate.addNodeToQueue(uuid, node, node.alt); - }else if(node.nodeValue != null && node.nodeValue.trim().length > 0){ - - //过滤掉无效的值 - if(node.nodeValue != null && typeof(node.nodeValue) == 'string' && node.nodeValue.length > 0){ - }else{ - return; - } - - //console.log(node.nodeValue+' --- ' + translate.language.get(node.nodeValue)); - - //console.log(node.nodeName); - //console.log(node.parentNode.nodeName); - //console.log(node.nodeValue); - //加入要翻译的node队列 - translate.addNodeToQueue(uuid, node, node.nodeValue); - //translate.addNodeToQueue(translate.hash(node.nodeValue), node); - //translate.nodeQueue[translate.hash(node.nodeValue)] = node; - //translate.nodeQueue[translate.hash(node.nodeValue)] = node.nodeValue; - //node.nodeValue = node.nodeValue+'|'; - - } - */ - }, - }, - - /* - * 将发现的元素节点加入待翻译队列 - * uuid execute方法执行的唯一id - * node 当前text所在的node - * text 当前要翻译的目标文本 - * attribute 是否是元素的某个属性。比如 a标签中的title属性, a.title 再以node参数传入时是string类型的,本身并不是node类型,所以就要传入这个 attribute=title 来代表这是a标签的title属性。同样第二个参数node传入的也不能是a.title,而是传入a这个node元素 - */ - addNodeToQueue: (uuid, node, text, attribute) => { - if (node == null || text == null || text.length == 0) { - return; - } - - //console.log('find tag ignore : '+node.nodeValue+', '+node.nodeName+", "+node.nodeType+", "+node.tagName); - //console.log('addNodeToQueue into -- node:'+node+', text:'+text+', attribute:'+attribute); - var nodename = translate.element.getNodeName(node); - - //判断如果是被 注释的区域,不进行翻译 - if (nodename.toLowerCase() == "#comment") { - return; - } - //console.log('\t\t'+text); - //取要翻译字符的hash - var key = translate.util.hash(text); - /* - 如果是input 的 placeholder ,就会出现这个情况 - if(node.parentNode == null){ - console.log('node.parentNode == null'); - return; - } - */ - - //console.log(node.parentNode); - //console.log(node.parentNode.nodeName); - - //判断其内容是否是 script、style 等编程的文本,如果是,则不进行翻译,不然翻译后还会影响页面正常使用 - if (translate.util.findTag(text)) { - //console.log('find tag ignore : '+node.nodeValue+', '+node.nodeName+", "+node.nodeType+", "+node.tagName); - //console.log(node.parentNode.nodeName); - - //获取到当前文本是属于那个tag标签中的,如果是script、style 这样的标签中,那也会忽略掉它,不进行翻译 - if (node.parentNode == null) { - //没有上级了,或是没获取到上级,忽略 - return; - } - //去上级的tag name - var parentNodeName = translate.element.getNodeName(node.parentNode); - //node.parentNode.nodeName; - if (parentNodeName == "SCRIPT" || parentNodeName == "STYLE") { - //如果是script、style中发现的,那也忽略 - return; - } - } - //console.log(node.nodeValue); - - //原本传入的text会被切割为多个小块 - var textArray = []; - textArray.push(text); //先将主 text 赋予 ,后面如果对主text进行加工分割,分割后会将主text给删除掉 - //console.log(textArray); - - // 处理 ignore.regex - for (var ri = 0; ri < translate.ignore.textRegex.length; ri++) { - var regex = translate.ignore.textRegex[ri]; - for (var tai = 0; tai < textArray.length; tai++) { - var text = textArray[tai]; - var ignoreTexts = text.match(regex) || []; - translate.ignore.text = translate.ignore.text.concat(ignoreTexts); - } - } - - /**** v3.10.2.20241206 - 增加自定义忽略翻译的文本,忽略翻译的文本不会被翻译 - 当然这样会打乱翻译之后阅读的连贯性 ****/ - for (var ti = 0; ti < translate.ignore.text.length; ti++) { - if (translate.ignore.text[ti].trim().length == 0) { - continue; - } - - textArray = translate.addNodeToQueueTextAnalysis( - uuid, - node, - textArray, - attribute, - translate.ignore.text[ti], - translate.ignore.text[ti], - ); - - //console.log(textArray); - } - - /**** v3.10.2.20241206 - 自定义术语能力全面优化 - 当然这样会打乱翻译之后阅读的连贯性 ****/ - //判断是否进行了翻译,也就是有设置目标语种,并且跟当前语种不一致 - if (typeof translate.temp_nomenclature == "undefined") { - translate.temp_nomenclature = []; - } - if ( - typeof translate.temp_nomenclature[translate.language.getLocal()] == - "undefined" - ) { - nomenclatureKeyArray = []; - } - if ( - typeof translate.nomenclature.data[translate.language.getLocal()] != - "undefined" && - typeof translate.nomenclature.data[translate.language.getLocal()][ - translate.to - ] != "undefined" - ) { - var nomenclatureKeyArray; - for (var nomenclatureKey in translate.nomenclature.data[ - translate.language.getLocal() - ][translate.to]) { - if ( - !Object.hasOwn( - translate.nomenclature.data[translate.language.getLocal()][ - translate.to - ], - nomenclatureKey, - ) - ) { - continue; - } - //nomenclatureKey 便是自定义术语的原始文本,值是要替换为的文本 - //console.log(nomenclatureKey); - //自定义属于的指定的结果字符串 - var nomenclatureValue = - translate.nomenclature.data[translate.language.getLocal()][ - translate.to - ][nomenclatureKey]; - - textArray = translate.addNodeToQueueTextAnalysis( - uuid, - node, - textArray, - attribute, - nomenclatureKey, - nomenclatureValue, - ); - - if (typeof nomenclatureKeyArray != "undefined") { - nomenclatureKeyArray.push(nomenclatureKey); - } - } - - if ( - typeof translate.temp_nomenclature[translate.language.getLocal()] == - "undefined" - ) { - translate.temp_nomenclature[translate.language.getLocal()] = - nomenclatureKeyArray; - } - } - /**** v3.10.2.20241206 - 自定义术语能力全面优化 - end ****/ - - for (var tai = 0; tai < textArray.length; tai++) { - if (textArray[tai].trim().length == 0) { - continue; - } - - //判断是否出现在自定义忽略字符串 - if (translate.ignore.text.indexOf(textArray[tai].trim()) > -1) { - //console.log(textArray[tai]+' 是忽略翻译的文本,不翻译'); - continue; - } - - //判断是否出现在自定义术语的 - if ( - typeof translate.temp_nomenclature[translate.language.getLocal()] != - "undefined" - ) { - if ( - translate.temp_nomenclature[translate.language.getLocal()].indexOf( - textArray[tai].trim(), - ) > -1 - ) { - //console.log(textArray[tai]+' 是自定义术语,不翻译'); - continue; - } - } - - translate.addNodeToQueueAnalysis(uuid, node, textArray[tai], attribute); - } - - //this.nodeQueue[lang][key][this.nodeQueue[lang][key].length]=node; //往数组中追加 - }, - - /** - * 服务于上面的 addNodeToQueue ,用于区分不同type情况,进行调用此加入 translate.nodeQueue - * uuid, node, attribute 这及个参数说明见 addNodeToQueue 的参数说明,相同 - * textArray 进行处理的要翻译的文本数组。这个最开始只是一个,但是命中后分割的多了也就变成多个了 - * nomenclatureKey 替换的原始文本,也就是自定义术语的key部分 - * nomenclatureValue 替换的目标文本,也就是自定义术语的value部分 。 如果 nomenclatureKey = nomenclatureValue 则是自定义忽略翻译的文本。这个文本不被翻译 - * @return 处理过后的 textArray 如果没有命中则返回的是传入的 textArray ,命中了则是切割以及删除原本判断的text之后的 textArray - */ - addNodeToQueueTextAnalysis: ( - uuid, - node, - textArray, - attribute, - nomenclatureKey, - nomenclatureValue, - ) => { - var deleteTextArray = []; //记录要从 textArray 中删除的字符串 - - for (var tai = 0; tai < textArray.length; tai++) { - var text = textArray[tai]; - - if (text.trim() == nomenclatureValue.trim()) { - //这里是自定义术语被替换后,重新扫描时扫出来的,那么直接忽略,不做任何处理。因为自定义术语的结果就是最终结果了 - continue; - } - - //判断一下原始文本是否有出现在了这个word要翻译的字符串中 - var wordKeyIndex = text.indexOf(nomenclatureKey); - if (wordKeyIndex > -1) { - //出现了,那么需要将其立即进行更改,将自定义术语定义的结果渲染到页面中,并且将 word 要翻译的字符串中,自定义术语部分删除,只翻译除了自定义术语剩余的部分 - //console.log(text+' --> '+nomenclatureKey); - - /* - * 判断一下这个text中,出现匹配自定义术语的部分,是否是已经被替换过了,比如要将 好 替换为 你好 ,这里的好会重复替换。这里是判断这种情况 - * 其中要判断一下 key 不等于value,因为key等于value,属于是指定这个key不被翻译的情况 - */ - if (nomenclatureKey != nomenclatureValue) { - var substringStart = wordKeyIndex - nomenclatureValue.length; - if (substringStart < 0) { - substringStart = 0; - } - var substringEnd = wordKeyIndex + nomenclatureValue.length; - if (substringEnd > text.length) { - substringEnd = text.length; - } - var nomenclatureValueJudgement = text.substring( - substringStart, - substringEnd, - ); - //console.log(text+', '+nomenclatureValueJudgement); - if (nomenclatureValueJudgement.indexOf(nomenclatureValue) > -1) { - //已经替换过了,可能会重复替换,所以忽略掉 - continue; - } - } - - // 2025.4.26 优化,将不再在此处进行处理,交有 translate.util.textReplace 在页面最终渲染前处理 - // //判断当前是否是英语及变种,也就是单词之间需要有空格的,如果前后没有空格,要补充上空格 - // if(translate.language.wordBlankConnector(translate.to)){ - // if(wordKeyIndex > 0){ - // //它前面还有文本,判断它前面的文本是否是空格,如果不是,那么要补充上空格 - // var before = text.charAt(wordKeyIndex-1); - // //console.log(before); - // if(!(/\s/.test(before))){ - // //不是空白字符,补充上一个空格,用于将两个单词隔开 - // nomenclatureValue = ' '+nomenclatureValue - // } - // } - // if(wordKeyIndex + nomenclatureKey.length < text.length){ - // //它后面还有文本,判断它前面的文本是否是空格,如果不是,那么要补充上空格 - // var after = text.charAt(wordKeyIndex + nomenclatureKey.length); - // //console.log(after); - // // 2025.4.23 woodsway提出bug修复 https://gitee.com/mail_osc/translate/issues/IC34VN - // if(!(/\s/.test(after))){ - // //不是空白字符,补充上一个空格,用于将两个单词隔开 - // nomenclatureValue = nomenclatureValue+' '; - // } - // } - // } - - //如果是自定义术语的key等于value,则是属于指定的某些文本不进行翻译的情况,所以这里要单独判断一下 - //console.log(nomenclatureKey+':'+nomenclatureValue); - if (nomenclatureKey != nomenclatureValue) { - translate.element.nodeAnalyse.set( - node, - nomenclatureKey, - nomenclatureValue, - attribute, - ); - } - - //从 text 中将自定义术语的部分删掉,自定义术语的不被翻译 - var wordSplits = text.split(nomenclatureKey); - var isPushTextArray = false; - for (var index = 0; index < wordSplits.length; index++) { - //console.log(index); - var subWord = wordSplits[index]; //分割后的子字符串 - if (subWord.trim().length == 0) { - continue; - } - //console.log(subWord); - - //将其加入 textArray 中 - textArray.push(subWord); - deleteTextArray.push(text); - } - - //console.log(wordSplits); - //自定义术语适配完后就直接退出了 - //return wordSplits; - } - } - - //console.log(deleteTextArray) - //从 textArray 中删除 - if (deleteTextArray.length > 0) { - for (var di = 0; di < deleteTextArray.length; di++) { - const index = textArray.indexOf(deleteTextArray[di]); - if (index > -1) { - //console.log(textArray); - //console.log(deleteTextArray[di]); - textArray.splice(index, 1); - //console.log(textArray); - } - } - } - - //console.log(textArray); - return textArray; - }, - - /* - - 服务于上面的 addNodeToQueue ,用于区分不同type情况,进行调用此加入 translate.nodeQueue - uuid, node, attribute 这五个参数说明见 addNodeToQueue 的参数说明,相同 - - word 要实际进行翻译的文本,也就是要把它拿来进行通过后端翻译接口进行翻译的文本 - lang 当前要翻译的文本的语种,如 english - beforeText 参见 translate.nodeQueue 注释中第七维的解释 - afterText 参见 translate.nodeQueue 注释中第七维的解释 - - */ - addNodeToQueueAnalysis: (uuid, node, text, attribute) => { - //获取当前是什么语种 - //var langs = translate.language.get(text); - var textRecognition = translate.language.recognition(text); - var langs = textRecognition.languageArray; - //console.log('langs'); - //console.log(langs); - - //过滤掉要转换为的目标语种,比如要转为英语,那就将本来是英语的部分过滤掉,不用再翻译了 - if (typeof langs[translate.to] != "undefined") { - delete langs[translate.to]; - } - - var isWhole = translate.whole.isWhole(node); - //console.log('isWhole:'+isWhole+', '+text); - - if (!isWhole) { - //常规方式,进行语种分类 - - /* if(this.nodeQueue[lang] == null || typeof(this.nodeQueue[lang]) == 'undefined'){ - this.nodeQueue[lang] = new Array(); - } - //创建二维数组 - if(this.nodeQueue[lang][key] == null || typeof(this.nodeQueue[lang][key]) == 'undefined'){ - this.nodeQueue[lang][key] = new Array(); - } - */ - //console.log(langs); - - for (var lang in langs) { - if (!Object.hasOwn(langs, lang)) { - continue; - } - //创建二维数组, key为语种,如 english - /* - 放到了 translate.addNodeQueueItem 进行判断 - if(translate.nodeQueue[uuid]['list'][lang] == null || typeof(translate.nodeQueue[uuid]['list'][lang]) == 'undefined'){ - translate.nodeQueue[uuid]['list'][lang] = new Array(); - } - */ - //console.log('|'+langs[lang].length); - //遍历出该语种下有哪些词需要翻译 - for ( - var word_index = 0; - word_index < langs[lang].list.length; - word_index++ - ) { - //console.log('start:'+word_index) - //console.log(langs[lang].list[word_index]); - if ( - typeof langs[lang].list[word_index] == "undefined" || - typeof langs[lang].list[word_index]["text"] == "undefined" - ) { - //理论上应该不会,但多加个判断 - continue; - } - var word = langs[lang].list[word_index]["text"]; //要翻译的词 - var beforeText = langs[lang].list[word_index]["beforeText"]; - var afterText = langs[lang].list[word_index]["afterText"]; - - //console.log(lang+' - '+word); - translate.addNodeQueueItem( - uuid, - node, - word, - attribute, - lang, - beforeText, - afterText, - ); - - /* - var hash = translate.util.hash(word); //要翻译的词的hash - //创建三维数组, key为要通过接口翻译的文本词或句子的 hash (注意并不是node的文本,而是node拆分后的文本) - if(translate.nodeQueue[uuid]['list'][lang][hash] == null || typeof(translate.nodeQueue[uuid]['list'][lang][hash]) == 'undefined'){ - translate.nodeQueue[uuid]['list'][lang][hash] = new Array(); - - translate.nodeQueue[uuid]['list'][lang][hash]['nodes'] = new Array(); - translate.nodeQueue[uuid]['list'][lang][hash]['original'] = word; - translate.nodeQueue[uuid]['list'][lang][hash]['translateText'] = translate.nomenclature.dispose(word); //自定义术语处理 - //translate.nodeQueue[uuid]['list'][lang][hash]['beforeText'] = beforeText; - //translate.nodeQueue[uuid]['list'][lang][hash]['afterText'] = afterText; - //translate.nodeQueue[uuid]['list'][lang][hash]['attribute'] = attribute; //放入 nodes[index][attribute] 元素中 - - //其中key: nodes 是第四维数组,里面存放具体的node元素对象 - - - //console.log(translate.nodeQueue[uuid]['list'][lang][hash]); - } - - var isEquals = false; //queue中是否已经加入过这个node了(当然是同一hash同一node情况) - if(typeof(node.isSameNode) != 'undefined'){ //支持 isSameNode 方法判断对象是否相等 - for(var node_index = 0; node_index < translate.nodeQueue[uuid]['list'][lang][hash]['nodes'].length; node_index++){ - if(node.isSameNode(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['node'])){ - //相同,那就不用在存入了 - //console.log('相同,那就不用在存入了') - isEquals = true; - //console.log(node) - continue; - } - } - } - if(isEquals){ - //相同,那就不用在存入了 - continue; - } - - //往五维数组nodes中追加node元素 - var nodesIndex = translate.nodeQueue[uuid]['list'][lang][hash]['nodes'].length; - translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex] = new Array(); - translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex]['node']=node; - translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex]['attribute']=attribute; - translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex]['beforeText'] = beforeText; - translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex]['afterText'] = afterText; - - */ - - //console.log('end:'+word_index) - } - } - } else { - //直接翻译整个元素内的内容,不再做语种分类,首先删除英文,然后将出现次数最多的语种作为原本语种 - var lang = textRecognition.languageName; - //console.log(lang+' - '+text); - translate.addNodeQueueItem(uuid, node, text, attribute, lang, "", ""); - } - }, - - /* - - 服务于上面的 addNodeToQueue ,用于区分不同type情况,进行调用此加入 translate.nodeQueue - uuid, node, attribute 这五个参数说明见 addNodeToQueue 的参数说明,相同 - - word 要实际进行翻译的文本,也就是要把它拿来进行通过后端翻译接口进行翻译的文本 - lang 当前要翻译的文本的语种,如 english - beforeText 参见 translate.nodeQueue 注释中第七维的解释 - afterText 参见 translate.nodeQueue 注释中第七维的解释 - - */ - addNodeQueueItem: ( - uuid, - node, - word, - attribute, - lang, - beforeText, - afterText, - ) => { - //创建二维数组, key为语种,如 english - if ( - translate.nodeQueue[uuid]["list"][lang] == null || - typeof translate.nodeQueue[uuid]["list"][lang] == "undefined" - ) { - translate.nodeQueue[uuid]["list"][lang] = []; - } - //console.log(word) - //var word = text; //要翻译的文本 - var hash = translate.util.hash(word); //要翻译的文本的hash - - //创建三维数组, key为要通过接口翻译的文本词或句子的 hash 。这里翻译的文本也就是整个node元素的内容了,不用在做拆分了 - if ( - translate.nodeQueue[uuid]["list"][lang][hash] == null || - typeof translate.nodeQueue[uuid]["list"][lang][hash] == "undefined" - ) { - translate.nodeQueue[uuid]["list"][lang][hash] = []; - - /* - * 创建四维数组,存放具体数据 - * key: nodes 包含了这个hash的node元素的数组集合,array 多个。其中 - nodes[index]['node'] 存放当前的node元素 - nodes[index]['attribute'] 存放当前hash,也就是翻译文本针对的是什么,是node本身(nodeValue),还是 node 的某个属性,比如title属性。如果这里不为空,那就是针对的属性操作的 - * key: original 原始的要翻译的词或句子,html加载完成但还没翻译前的文本,用于支持当前页面多次语种翻译切换而无需跳转 - * beforeText、afterText:见 translate.nodeQueue 的说明 - */ - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"] = []; - translate.nodeQueue[uuid]["list"][lang][hash]["original"] = word; - //自定义术语处理在此前面已经执行过了,所以这个废弃,不需要处理自定义术语部分了 - //translate.nodeQueue[uuid]['list'][lang][hash]['translateText'] = translate.nomenclature.dispose(word); - translate.nodeQueue[uuid]["list"][lang][hash]["translateText"] = word; - //console.log(word) - - //其中key: nodes 是第四维数组,里面存放具体的node元素对象 - } - - var isEquals = false; //queue中是否已经加入过这个node了(当然是同一hash同一node情况) - if (typeof node.isSameNode != "undefined") { - //支持 isSameNode 方法判断对象是否相等 - for ( - var node_index = 0; - node_index < - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"].length; - node_index++ - ) { - if ( - node.isSameNode( - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][node_index][ - "node" - ], - ) - ) { - //相同,那就不用在存入了 - //console.log('相同,那就不用在存入了') - isEquals = true; - } - } - } - if (isEquals) { - //相同,那就不用在存入了 - return; - } - - //往五维数组nodes中追加node元素 - var nodesIndex = - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"].length; - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][nodesIndex] = []; - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][nodesIndex]["node"] = - node; - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][nodesIndex][ - "attribute" - ] = attribute; - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][nodesIndex][ - "beforeText" - ] = beforeText; - translate.nodeQueue[uuid]["list"][lang][hash]["nodes"][nodesIndex][ - "afterText" - ] = afterText; - }, - - //全部翻译,node内容全部翻译,而不是进行语种提取,直接对node本身的全部内容拿出来进行直接全部翻译 - whole: { - isEnableAll: false, //是否开启对整个html页面的整体翻译,也就是整个页面上所有存在的能被翻译的全部会采用整体翻译的方式。默认是 false不开启 - - enableAll: () => { - translate.whole.isEnableAll = true; - }, - - /* - 一下三个,也就是 class tag id 分别存储加入的值。使用参考:http://translate.zvo.cn/42563.html - */ - class: [], - tag: [], - id: [], - - //运行时出现自检并在浏览器控制台提示性文本。 - //在执行翻译,也就是 execute() 时,会调用此方法。 - executeTip: () => { - if ( - translate.whole.class.length == 0 && - translate.whole.tag.length == 0 && - translate.whole.id.length == 0 - ) { - } else { - console.log( - "您开启了 translate.whole 此次行为避开了浏览器端的文本语种自动识别,而是暴力的直接对某个元素的整个文本进行翻译,很可能会产生非常大的翻译量,请谨慎!有关每日翻译字符的说明,可参考: http://translate.zvo.cn/42557.html ", - ); - } - - if (translate.whole.tag.indexOf("html") > -1) { - console.log( - "自检发现您设置了 translate.whole.tag 其中有 html ,这个是不生效的,最大只允许设置到 body ", - ); - } - }, - - //当前元素是属于全部翻译定义的元素 - /* - 传入一个元素,判断这个元素是否是被包含的。 这个会找父类,看看父类中是否包含在其之中。 - return true是在其中,false不再其中 - */ - isWhole: (ele) => { - if (translate.whole.isEnableAll) { - return true; - } - - //如果设置了 class|tag|id 其中某个,或者 all=true ,那么就是启用,反之未启用 - if ( - translate.whole.class.length == 0 && - translate.whole.tag.length == 0 && - translate.whole.id.length == 0 && - translate.whole.isEnableAll == false - ) { - //未设置,那么直接返回false - return false; - } - if (ele == null || typeof ele == "undefined") { - return false; - } - - var parentNode = ele; - var maxnumber = 100; //最大循环次数,避免死循环 - while (maxnumber-- > 0) { - if (parentNode == null || typeof parentNode == "undefined") { - //没有父元素了 - return false; - } - - //判断Tag - //var tagName = parentNode.nodeName.toLowerCase(); //tag名字,小写 - var nodename = translate.element.getNodeName(parentNode).toLowerCase(); //tag名字,小写 - if (nodename.length > 0) { - //有nodename - if (nodename == "html" || nodename == "#document") { - //上层元素已经是顶级元素了,那肯定就不是了 - return false; - } - if (translate.whole.tag.indexOf(nodename) > -1) { - //发现ignore.tag 当前是处于被忽略的 tag - return true; - } - } - - //判断class name - if (parentNode.className != null) { - var classNames = parentNode.className; - if (classNames == null || typeof classNames != "string") { - continue; - } - //console.log('className:'+typeof(classNames)); - //console.log(classNames); - classNames = classNames.trim().split(" "); - for (var c_index = 0; c_index < classNames.length; c_index++) { - if ( - classNames[c_index] != null && - classNames[c_index].trim().length > 0 - ) { - //有效的class name,进行判断 - if (translate.whole.class.indexOf(classNames[c_index]) > -1) { - //发现ignore.class 当前是处于被忽略的 class - return true; - } - } - } - } - - //判断id - if (parentNode.id != null && typeof parentNode.id != "undefined") { - //有效的class name,进行判断 - if (translate.whole.id.indexOf(parentNode.id) > -1) { - //发现ignore.id 当前是处于被忽略的 id - return true; - } - } - - //赋予判断的元素向上一级 - parentNode = parentNode.parentElement; - } - - return false; - }, - }, - - language: { - /* - 英语的变种语种,也就是在英语26个字母的基础上加了点别的特殊字母另成的一种语言,而这些语言是没法直接通过识别字符来判断出是哪种语种的 - - 法语、意大利语、德语、葡萄牙语 - */ - englishVarietys: ["french", "italian", "deutsch", "portuguese"], - - //当前本地语种,本地语言,默认是简体中文。设置请使用 translate.language.setLocal(...)。不可直接使用,使用需用 getLocal() - local: "", - - /* - * v3.12增加, 是否会翻译本地语种,默认是false,不会翻译。 - * 比如当前设置的本地语种是简体中文, 但是网页中也有一段英文, 如果设置了translate.to 为中文,也就是要以中文显示 默认是false的情况下,整个页面是不会被任何翻译的,也就是有的那段英文也不会进行任何翻译,依旧是显示英文。 - * 如果这里设置为 true, 则英文也会被翻译,只要不是中文的,都会被翻译为要显示的语种,也就是都会被翻译为中文。 - */ - translateLocal: false, - - /* - 翻译语种范围 - 比如传入 ['chinese_simplified','chinese_traditional','english'] 则表示仅对网页中的简体中文、繁体中文、英文 进行翻译,而网页中出现的其他的像是法语、韩语则不会进行翻译 - 如果为空 [],则是翻译时,翻译网页中的所有语种 - 设置方式为: translate.language.translateLanguagesRange = ['chinese_simplified','chinese_traditional'] - */ - translateLanguagesRange: [], - //传入语种。具体可传入哪些参考: http://api.translate.zvo.cn/doc/language.json.html - setLocal: (languageName) => { - //translate.setUseVersion2(); //Set to use v2.x version - translate.useVersion = "v2"; - translate.language.local = languageName; - }, - //获取当前本地语种,本地语言,默认是简体中文。设置请使用 translate.language.setLocal(...) - getLocal: () => { - //判断是否设置了本地语种,如果没设置,自动给其设置 - if ( - translate.language.local == null || - translate.language.local.length < 1 - ) { - translate.language.autoRecognitionLocalLanguage(); - } - return translate.language.local; - }, - /* - 获取当前语种。 - 比如当前设置的本地语种是简体中文,用户并未切换其他语种,那么这个方法将返回本地当前的语种,也就是等同于 translate.language.getLocal() - 如果用户切换为英语进行浏览,那么这个方法将返回翻译的目标语种,也就是 english - */ - getCurrent: () => { - var to_storage = translate.storage.get("to"); - if ( - to_storage != null && - typeof to_storage != "undefined" && - to_storage.length > 0 - ) { - //之前有过使用,并且主动设置过目标语种 - return to_storage; - } - return translate.language.getLocal(); - }, - //如果第一次用,默认以什么语种显示。 - //比如本地当前语种是简体中文,这里设置为english,那么用户第一次使用时,会自动翻译为english进行显示。如果用户手动切换为其他语种比如韩语,那么就遵循用户手动切换的为主,显示韩语。 - setDefaultTo: (languageName) => { - var to_storage = translate.storage.get("to"); - if ( - to_storage != null && - typeof to_storage != "undefined" && - to_storage.length > 0 - ) { - //之前有过使用,并且主动设置过目标语种,那么不进行处理 - } else { - //没有设置过,进行处理 - translate.storage.set("to", languageName); - translate.to = languageName; - } - }, - /* - 清除历史翻译语种的缓存 - */ - clearCacheLanguage: () => { - if (typeof translate.language.setUrlParamControl_use != "undefined") { - if (translate.language.setUrlParamControl_use) { - console.log("使用提示:"); - console.log( - "translate.language.setUrlParamControl(...) 的作用是 可以通过URL传一个语种,来指定当前页面以什么语种显示。 参考文档: http://translate.zvo.cn/4075.html", - ); - console.log( - "translate.language.clearCacheLanguage() 是清除历史翻译语种缓存,也就是清除之前指定翻译为什么语种。 参考文档:http://translate.zvo.cn/4080.html", - ); - console.log( - "如果你执行了 translate.language.setUrlParamControl(...) 那么是要根据url传参来切换语种的,但是后面又出现了 translate.language.clearCacheLanguage() 它会阻止 translate.language.setUrlParamControl(...) 它的设置,即使有url传递翻译为什么语言,也会因为 translate.language.clearCacheLanguage() 给清除掉,使URL传参的语种不起任何作用。", - ); - } - } - translate.to = ""; - translate.storage.set("to", ""); - }, - //根据URL传参控制以何种语种显示 - //设置可以根据当前访问url的某个get参数来控制使用哪种语言显示。 - //比如当前语种是简体中文,网页url是http://translate.zvo.cn/index.html ,那么可以通过在url后面增加 language 参数指定翻译语种,来使网页内容以英文形态显示 http://translate.zvo.cn/index.html?language=english - setUrlParamControl: (paramName) => { - translate.language.setUrlParamControl_use = true; //标记已执行了 translate.language.setUrlParamControl ,仅仅只是标记,无其他作用 - if (typeof paramName == "undefined" || paramName.length < 1) { - paramName = "language"; - } - var paramValue = translate.util.getUrlParam(paramName); - if (typeof paramValue == "undefined") { - return; - } - if ( - paramValue == "" || - paramValue == "null" || - paramValue == "undefined" - ) { - return; - } - - translate.storage.set("to", paramValue); - translate.to = paramValue; - }, - /* - 获取翻译区域的原始文本,翻译前的文本。 这里会把空白符等过滤掉,只返回纯显示的文本 - 也就是获取 translate.setDocument(...) 定义的翻译区域中,翻译前,要参与翻译的文本。 - 其中像是 translate.ignore.tag 这种忽略翻译的标签,这里也不会获取的,这里只是获取实际要参与翻译的文本。 - */ - getTranslateAreaText: () => { - //v3.16.1 优化,获取本地语种,针对开源中国只对 readme 部分进行翻译的场景,将针对设置的 translate.setDocument() 区域的元素的显示文本进行判定语种 - var translateAreaText = ""; //翻译区域内当前的文本 - - /** 构建虚拟容器,将要翻译的区域放入虚拟容器,以便后续处理 **/ - var virtualContainer = document.createElement("div"); // 创建虚拟容器,处理、判断也都是针对这个虚拟容器 - if ( - translate.documents != null && - typeof translate.documents != "undefined" && - translate.documents.length > 0 - ) { - // setDocuments 指定的 - for ( - var docs_index = 0; - docs_index < translate.documents.length; - docs_index++ - ) { - var doc = translate.documents[docs_index]; - if ( - typeof doc != "undefined" && - doc != null && - typeof doc.innerText != "undefined" && - doc.innerText != null && - doc.innerText.length > 0 - ) { - virtualContainer.appendChild(doc.cloneNode(true)); - } - } - } else { - //未使用 setDocuments指定,那就是整个网页了 - //return document.all; //翻译所有的 这是 v3.5.0之前的 - //v3.5.0 之后采用 拿 html的最上层的demo,而不是 document.all 拿到可能几千个dom - if (typeof document.head != "undefined") { - virtualContainer.appendChild(document.head.cloneNode(true)); - } - if (typeof document.body != "undefined") { - virtualContainer.appendChild(document.body.cloneNode(true)); - } - } - //console.log(virtualContainer); - - /** 对虚拟容器中的元素进行处理,移除忽略的 tag (这里暂时就只是移除忽略的tag, 其他忽略的后续再加) **/ - // 遍历标签列表 - //console.log('---- remove element'); - for (var i = 0; i < translate.ignore.tag.length; i++) { - var tagName = translate.ignore.tag[i]; - var elements = virtualContainer.querySelectorAll(tagName); - // 将 NodeList 转换为数组 - var elementArray = Array.prototype.slice.call(elements); - // 遍历并移除每个匹配的元素 - for (var j = 0; j < elementArray.length; j++) { - var element = elementArray[j]; - if (element.parentNode) { - //console.log(element); - element.parentNode.removeChild(element); - } - } - } - //console.log('---- remove element end'); - - /*** 取过滤完后的文本字符 ***/ - translateAreaText = virtualContainer.innerText; - if ( - translateAreaText == null || - typeof translateAreaText == "undefined" || - translateAreaText.length < 1 - ) { - //未取到,默认赋予简体中文 - translate.language.local = "chinese_simplified"; - return; - } - // 移除所有空白字符(包括空格、制表符、换行符等) - translateAreaText = translateAreaText.replace(/\s/g, ""); - - //console.log('translateAreaText:\n'+translateAreaText); - return translateAreaText; - }, - //自动识别当前页面是什么语种 - autoRecognitionLocalLanguage: () => { - if ( - translate.language.local != null && - translate.language.local.length > 2 - ) { - //已设置过了,不需要再设置 - return translate.language.local; - } - - var translateAreaText = translate.language.getTranslateAreaText(); - - //默认赋予简体中文 - translate.language.local = "chinese_simplified"; - var recognition = translate.language.recognition(translateAreaText); - //console.log(recognition); - translate.language.local = recognition.languageName; - return translate.language.local; - /* v3.1优化 - var langs = new Array(); //上一个字符的语种是什么,当前字符向上数第一个字符。格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。 - for(var i=0; i -1){ - newLangs.splice(index,1); //移除数组中的特殊字符 - } - - if(newLangs.length > 0){ - //找到排序出现频率最多的 - translate.language.local = newLangs[0]; - }else{ - //没有,默认赋予简体中文 - translate.language.local = 'chinese_simplified'; - } - */ - }, - - /* - * 获取当前字符是什么语种。返回值是一个语言标识,有 chinese_simplified简体中文、japanese日语、korean韩语、 - * str : node.nodeValue 或 图片的 node.alt 等 - * 如果语句长,会全句翻译,以保证翻译的准确性,提高可读性。 - * 如果语句短,会自动将特殊字符、要翻译的目标语种给过滤掉,只取出具体的要翻译的目标语种文本 - * - * 返回 存放不同语言的数组,格式如 - * [ - "english":[ - {beforeText: '', afterText: '', text: 'emoambue hag'}, - ...... - ], - "japanese":[ - {beforeText: ' ', afterText: ' ', text: 'ẽ '}, - ...... - ] - ] - * - */ - get: (str) => { - //将str拆分为单个char进行判断 - - var langs = []; //当前字符串包含哪些语言的数组,其内如 english - var langStrs = []; //存放不同语言的文本,格式如 ['english'][0] = 'hello' - var upLangs = []; //上一个字符的语种是什么,当前字符向上数第一个字符。格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。 - var upLangsTwo = []; //上二个字符的语种是什么 ,当前字符向上数第二个字符。 格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。 - - //var upLangs = ''; //上一个字符的语种是什么,格式如 english - for (var i = 0; i < str.length; i++) { - var charstr = str.charAt(i); - //console.log('charstr:'+charstr) - var lang = translate.language.getCharLanguage(charstr); - if (lang == "") { - //未获取到,未发现是什么语言 - //continue; - lang = "unidentification"; - } - var result = translate.language.analyse( - lang, - langStrs, - upLangs, - upLangsTwo, - charstr, - ); - //console.log(result) - langStrs = result["langStrs"]; - //记录上几个字符 - if (typeof upLangs["language"] != "undefined") { - upLangsTwo["language"] = upLangs["language"]; - upLangsTwo["charstr"] = upLangs["charstr"]; - upLangsTwo["storage_language"] = upLangs["storage_language"]; - } - //upLangs['language'] = lang; - upLangs["language"] = result["storage_language"]; - upLangs["charstr"] = charstr; - upLangs["storage_language"] = result["storage_language"]; - //console.log(result['storage_language']) - //console.log(upLangs['language']); - langs.push(lang); - } - - //console.log(langStrs); - - //console.log(langs); - //console.log(langStrs); - - /* - //从数组中取出现频率最高的 - var newLangs = translate.util.arrayFindMaxNumber(langs); - - //移除当前翻译目标的语言。因为已经是目标预言了,不需要翻译了 - var index = newLangs.indexOf(translate.to); - if(index > -1){ - newLangs.splice(index,1); //移除 - } - - //移除特殊字符 - var index = newLangs.indexOf('specialCharacter'); - if(index > -1){ - newLangs.splice(index,1); //移除数组中的特殊字符 - } - - if(newLangs.length > 0){ - //还剩一个或多个,(如果是多个,那应该是这几个出现的频率一样,所以取频率最高的时返回了多个) - return newLangs[0]; - }else{ - //没找到,直接返回空字符串 - return ''; - } - */ - - //去除特殊符号 - //for(var i = 0; i { - /* - 如果英语跟罗曼语族(法语意大利语等多个语言)一起出现,且当前 data.languageName 认定是英语(也就是英文字符占比最大),那么要判定一下: - 如果 罗曼语族的字符数/英文的字符数 > 0.008 , 那么认为当前是罗曼语族的中的某个语种, 在对其判定出具体是罗曼语族中的哪个语种赋予最终结果。 - */ - if ( - typeof languagesSize["english"] != "undefined" && - typeof languagesSize["romance"] != "undefined" && - data.languageName == "english" - ) { - if (languagesSize["romance"] / languagesSize["english"] > 0.008) { - //排定是罗曼语族了,那么判断一下到底是 法语、西班牙语、葡萄牙语、意大利语 中的哪一种呢 - - //先判定是否有设置本地语种是罗曼语族中其中的某一个 - if ( - typeof translate.language.local != "undefined" && - translate.language.local.length > 1 - ) { - if ( - translate.language.englishVarietys.indexOf( - translate.language.local, - ) > -1 - ) { - //发现当前设置的是小语种,那么将当前识别的语种识别为 本地设置的这个小语种。 - data.languageName = translate.language.local; - } - } - - if (data.languageName == "english") { - //还是英语,那就是没有经过上面本地语种的判定,那进行罗曼语的具体语种识别 - - var romanceSentenceLanguage = - translate.language.romanceSentenceAnaly(str); - if (romanceSentenceLanguage.length == 0) { - console.log( - "语种识别异常,应该是 法语、西班牙语、葡萄牙语、意大利语 中的一种才是,除非是除了这四种语种之外的别的 罗曼语族 中的语种,当前已将 " + - str + - "识别为英语。 你可以联系我们求助 https://translate.zvo.cn/4030.html", - ); - } else { - data.languageName = romanceSentenceLanguage; - } - } - } - } - - /* - 如果发现日语、简体中文或繁体中文 一起存在,且当前 data.languageName 认定是简体或繁体中文,那么要判定一下: - 如果 日语的字符数/(简体中文+繁体中文)的字符数 > 0.1 , 那么认为当前是日语的 - */ - if ( - (typeof languagesSize["chinese_simplified"] != "undefined" || - typeof languagesSize["chinese_traditional"] != "undefined") && - typeof languagesSize["japanese"] != "undefined" && - (data.languageName == "chinese_simplified" || - data.languageName == "chinese_traditional") - ) { - var size = 0; - if (typeof languagesSize["chinese_simplified"] != "undefined") { - size = size + languagesSize["chinese_simplified"]; - } - if (typeof languagesSize["chinese_traditional"] != "undefined") { - size = size + languagesSize["chinese_traditional"]; - } - if (languagesSize["japanese"] / size > 0.1) { - data.languageName = "japanese"; - } - } - /* if(langkeys.length > 1 && langkeys.indexOf('japanese') > -1){ - langsNumber['chinese_simplified'] = 0; - langsNumber['chinese_traditional'] = 0; - } */ - - /* - 如果发现英语、简体中文或繁体中文 一起存在,且当前 data.languageName 认定是英语时,那么要判定一下: - 如果 (简体中文+繁体中文)的字符数/英语 > 0.08 , 那么认为当前是简体中文(不认为是繁体中文,因为下面还有 简体中文跟繁体中文的判定) - */ - if ( - (typeof languagesSize["chinese_simplified"] != "undefined" || - typeof languagesSize["chinese_traditional"] != "undefined") && - typeof languagesSize["english"] != "undefined" && - data.languageName == "english" - ) { - var size = 0; - if (typeof languagesSize["chinese_simplified"] != "undefined") { - size = size + languagesSize["chinese_simplified"]; - } - if (typeof languagesSize["chinese_traditional"] != "undefined") { - size = size + languagesSize["chinese_traditional"]; - } - if (size / languagesSize["english"] > 0.08) { - data.languageName = "chinese_simplified"; - } - } - - /* - 如果简体中文跟繁体中文一起出现,且当前 data.languageName 认定是简体中文(也就是简体中文字符占比最大),那么要判定一下繁体中文: - 如果 繁体中文的字符数/简体中文的字符数 > 0.08 , 那么认为当前是繁体中文的 - */ - if ( - typeof languagesSize["chinese_simplified"] != "undefined" && - typeof languagesSize["chinese_traditional"] != "undefined" && - data.languageName == "chinese_simplified" - ) { - if ( - languagesSize["chinese_traditional"] / - languagesSize["chinese_simplified"] > - 0.03 - ) { - data.languageName = "chinese_traditional"; - } - } - /* if(langkeys.indexOf('chinese_simplified') > -1 && langkeys.indexOf('chinese_traditional') > -1){ - langsNumber['chinese_simplified'] = 0; - } */ - - return data; - }, - - /* - * 识别字符串是什么语种。它是 get() 的扩展,以代替get返回更多 - * str : 要识别的字符串 - * - * 返回 存放不同语言的数组,格式如 - * - { - languageName: 'english', - languageArray:[ - english:[ - list[ - {beforeText: ' ', afterText: ' ', text: 'hello word'}, - {beforeText: ' ', afterText: ' ', text: 'who?'}, - ], - number:12 - ], - japanese:[ - ...... - ] - ] - } - languageName 是当前字符串最终判定结果是什么语种。它的识别有以下特点: - 1. 如果出现英语跟中文、罗曼语族、德语等混合的情况,也就是不纯粹英语的情况,那么会以其他语种为准,而不是识别为英语。不论英语字符出现的比例占多少。 - 2. 如果出现简体中文跟繁体中文混合的情况,那么识别为繁体中文。不论简体中文字符出现的比例占多少。 - 3. 如果出现简体中文、繁体中文、日语混合的情况,那么识别为日语。不论简体中文、繁体中文出现的比例占多少。 2025.4.19 增加 - 4. 除了以上两种规则外,如果出现了多个语种,那么会识别为出现字符数量最多的语种当做当前句子的语种。(注意是字符数,而不是语种的数组数) - languageArray 对传入字符串进行分析,识别出都有哪些语种,每个语种的字符是什么 - * - */ - recognition: (str) => { - var langs = translate.language.get(str); - //var langkeys = Object.keys(langs); - //console.log(langkeys); - var langsNumber = []; //key 语言名, value 语言字符数 - var langsNumberOriginal = []; //同上,只不过这个不会进行清空字符数 - var allNumber = 0; //总字数 - - /** 进行字数统计相关 - start **/ - for (var key in langs) { - if (!Object.hasOwn(langs, key)) { - continue; - } - if (typeof langs[key] != "object") { - continue; - } - var langStrLength = 0; - for (var ls = 0; ls < langs[key].length; ls++) { - langStrLength = langStrLength + langs[key][ls].text.length; - } - allNumber = allNumber + langStrLength; - langsNumber[key] = langStrLength; - langsNumberOriginal[key] = langStrLength; - } - /** 进行字数统计相关 - end **/ - - //从 langsNumber 中找出字数最多的来 - var maxLang = ""; //字数最多的语种 - var maxNumber = 0; - for (var lang in langsNumber) { - if (!Object.hasOwn(langsNumber, lang)) { - continue; - } - if (langsNumber[lang] > maxNumber) { - maxLang = lang; - maxNumber = langsNumber[lang]; - } - } - - //重新组合返回值的 languageArray - var languageArray = {}; - for (var lang in langs) { - if (!Object.hasOwn(langs, lang)) { - continue; - } - languageArray[lang] = {}; - languageArray[lang].number = langsNumberOriginal[lang]; - languageArray[lang].list = langs[lang]; - } - - var result = { - languageName: maxLang, - languageArray: languageArray, - }; - - //最后进行一层简单的算法处理 - return translate.language.recognitionAlgorithm( - str, - result, - langsNumber, - allNumber, - ); - }, - /* - 传入一个char,返回这个char属于什么语种,返回如 如果返回空字符串,那么表示未获取到是什么语种 - chinese_simplified 简体中文 - chinese_traditional 繁体中文 - russian 俄罗斯语 - english 英语 - romance 罗曼语族,它是 法语、西班牙语、意大利语、葡萄牙語 的集合,并不是单个语言 - specialCharacter 特殊字符,符号 - number 阿拉伯数字 - japanese 日语 - korean 韩语 - greek 希腊语 - thai 泰语 - arabic 阿拉伯语 - romanian 罗马尼亚语 - hebrew 希伯来语 - - */ - getCharLanguage: function (charstr) { - if (charstr == null || typeof charstr == "undefined") { - return ""; - } - - if (this.russian(charstr)) { - return "russian"; - } - if (this.english(charstr)) { - return "english"; - } - if (this.romance(charstr)) { - return "romance"; - } - if (this.specialCharacter(charstr)) { - return "specialCharacter"; - } - if (this.number(charstr)) { - return "number"; - } - - //中文的判断包含两种,简体跟繁体 - var chinesetype = this.chinese(charstr); - if (chinesetype == "simplified") { - return "chinese_simplified"; - } - if (chinesetype == "traditional") { - return "chinese_traditional"; - } - - if (this.japanese(charstr)) { - return "japanese"; - } - if (this.korean(charstr)) { - return "korean"; - } - if (this.greek(charstr)) { - return "greek"; - } - if (this.thai(charstr)) { - return "thai"; - } - if (this.arabic(charstr)) { - return "arabic"; - } - if (this.romanian(charstr)) { - return "romanian"; - } - if (this.hebrew(charstr)) { - return "hebrew"; - } - //未识别是什么语种 - //console.log('not find is language , char : '+charstr+', unicode: '+charstr.charCodeAt(0).toString(16)); - return ""; - }, - /* - * 对字符串进行分析,分析字符串是有哪几种语言组成。 - * language : 当前字符的语种,传入如 english - * langStrs : 操作的,如 langStrs['english'][0] = '你好' - * upLangs : 当前字符之前的上一个字符的语种是什么,当前字符向上数第一个字符。格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。 - * upLangsTwo : 当前字符之前的上二个字符的语种是什么 ,当前字符向上数第二个字符。 格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。 - * chatstr : 当前字符,如 h - */ - analyse: (language, langStrs, upLangs, upLangsTwo, charstr) => { - if (typeof langStrs[language] == "undefined") { - langStrs[language] = []; - } - var index = 0; //当前要存入的数组下标 - if (typeof upLangs["storage_language"] == "undefined") { - //第一次,那么还没存入值,index肯定为0 - //console.log('第一次,那么还没存入值,index肯定为0') - //console.log(upLangs['language']) - } else { - //console.log('analyse, charstr : '+charstr+', upLangs :'); - //console.log(upLangs); - //var isEqual = upLangs['storage_language'] == language; //上次跟当前字符是否都是同一个语种(这个字符跟这个字符前一个字符) - - /* - 英语每个单词之间都会有空格分割. 如果是英文的话,英文跟特殊字符还要单独判断一下,避免拆开,造成翻译不准,单个单词翻译的情况 - 所以如果上次的字符是英文或特殊符号,当前字符是特殊符号(逗号、句号、空格,然后直接笼统就吧特殊符号都算上吧),那么也将当次的特殊符号变为英文来进行适配 - 示例 - hello word 的 "o w" - hello word 的 " w" - hello word 的 "w " - this is a dog 的 " a " - */ - //console.log(language == 'specialCharacter'); - //如果两个字符类型不一致,但当前字符是英文或连接符时,进行判断 - /* - if(!isEqual){ - if(language == 'english' || translate.language.connector(charstr)){ - console.log('1.'+(language == 'english' || translate.language.connector(charstr))+', upLangs str:'+upLangs['charstr']); - //上一个字符是英文或连接符 - //console.log('teshu:'+translate.language.connector(upLangs['charstr'])+', str:'+upLangs['charstr']); - if(upLangs['language'] == 'english' || translate.language.connector(upLangs['charstr'])) { - console.log('2'); - //如果上二个字符不存在,那么刚开始,不再上面几种情况之中,直接不用考虑 - if(typeof(upLangsTwo['language']) != 'undefined'){ - console.log('3') - //上二个字符是空(字符串刚开始),或者是英文 - if(upLangsTwo['language'] == 'english' || translate.language.connector(upLangsTwo['charstr'])){ - //满足这三个条件,那就将这三个拼接到一起 - console.log('4/5: '+', two lang:'+upLangsTwo['language']+', str:'+upLangsTwo['charstr']) - isEqual = true; - if(language == 'specialCharacter' && upLangs['language'] == 'specialCharacter' && upLangsTwo['language'] == 'specialCharacter'){ - //如果三个都是特殊字符,或后两个是特殊字符,第一个是空(刚开始),那就归入特殊字符 - language = 'specialCharacter'; - //console.log('4') - }else{ - //不然就都归于英文中。 - //这里更改是为了让下面能将特殊字符(像是空格逗号等)也一起存入数组 - language = 'english'; - console.log(5) - } - } - } - } - } - } - */ - - /* - 不判断当前字符,而判断上个字符,是因为当前字符没法获取未知的下个字符。 - */ - //if(!isEqual){ - - //如果当前字符是连接符 - if (translate.language.connector(charstr)) { - language = upLangs["storage_language"]; - /* - //判断上个字符是否存入了待翻译字符,如要将中文翻译为英文,而上个字符是中文,待翻译,那将连接符一并加入待翻译字符中去,保持句子完整性 - //判断依据是上个字符存储至的翻译字符语种序列,不是特殊字符,而且也不是要翻译的目标语种,那肯定就是待翻译的,将连接符加入待翻译中一起进行翻译 - if(upLangs['storage_language'] != 'specialCharacter' && upLangs['storage_language'] != translate.to){ - - language = upLangs['storage_language']; - console.log('teshu:'+charstr+', 当前字符并入上个字符存储翻译语种:'+upLangs['storage_language']); - } - */ - } - //} - - //console.log('isEqual:'+isEqual); - /* - if(isEqual){ - //跟上次语言一样,那么直接拼接 - index = langStrs[language].length-1; - //但是还有别的特殊情况,v2.1针对英文翻译准确度的适配,会有特殊字符的问题 - if(typeof(upLangs['storage_language']) != 'undefined' && upLangs['storage_language'] != language){ - //如果上个字符存入的翻译队列跟当前这个要存入的队列不一个的话,那应该是特殊字符像是逗号句号等导致的,那样还要额外一个数组,不能在存入之前的数组了 - index = langStrs[language].length; - } - }else{ - //console.log('新开'); - //当前字符跟上次语言不样,那么新开一个数组 - index = langStrs[language].length; - //console.log('++, inde:'+index+',lang:'+language+', length:'+langStrs[language].length) - } - */ - - //当前要翻译的语种跟上个字符要翻译的语种一样,那么直接拼接 - if (upLangs["storage_language"] == language) { - index = langStrs[language].length - 1; - } else { - //console.log('新开'); - //当前字符跟上次语言不样,那么新开一个数组 - index = langStrs[language].length; - } - } - if (typeof langStrs[language][index] == "undefined") { - langStrs[language][index] = []; - langStrs[language][index]["beforeText"] = ""; - langStrs[language][index]["afterText"] = ""; - langStrs[language][index]["text"] = ""; - } - langStrs[language][index]["text"] = - langStrs[language][index]["text"] + charstr; - /* - 中文英文混合时,当中文+英文并没有空格间隔,翻译为英文时,会使中文翻译英文的结果跟原本的英文单词连到一块。这里就是解决这种情况 - 针对当前非英文(不需要空格分隔符,像是中文、韩语),但要翻译为英文(需要空格作为分割符号,像是法语等)时的情况进行判断 - */ - //if(translate.language.getLocal() != 'english' && translate.to == 'english'){ - //当前本地语种的语言是连续的,但翻译的目标语言不是连续的(空格间隔) - if ( - translate.language.wordBlankConnector(translate.language.getLocal()) == - false && - translate.language.wordBlankConnector(translate.to) - ) { - if ( - upLangs["storage_language"] != null && - typeof upLangs["storage_language"] != "undefined" && - upLangs["storage_language"].length > 0 - ) { - //上个字符存在 - //console.log(upLangs['storage_language']); - if (upLangs["storage_language"] != "specialCharacter") { - //上个字符不是特殊字符 (是正常语种。且不会是连接符,连接符都并入了正常语种) - - //if( upLangs['storage_language'] != 'english' && language == 'english'){ - //上个字符的语言是连续的,但当前字符的语言不是连续的(空格间隔) - if ( - translate.language.wordBlankConnector( - upLangs["storage_language"], - ) == false && - translate.language.wordBlankConnector(language) - ) { - //上个字符不是英语,当前字符是英语,这种情况要在上个字符后面追加空格,因为当前字符是英文,就不会在执行翻译操作了 - //console.log(upLangs['language']); - langStrs[upLangs["storage_language"]][ - langStrs[upLangs["storage_language"]].length - 1 - ]["afterText"] = " "; - } else if ( - upLangs["storage_language"] == "english" && - language != "english" - ) { - //上个字符是英语,当前字符不是英语,直接在当前字符前面追加空格 - langStrs[language][index]["beforeText"] = " "; - } - } - } - } - - var result = []; - result["langStrs"] = langStrs; - result["storage_language"] = language; //实际存入了哪种语种队列 - //console.log(result); - //console.log(langStrs) - //console.log(charstr); - return result; - }, - - /* - * 不同于语言,这个只是单纯的连接符。比如英文单词之间有逗号、句号、空格, 汉字之间有逗号句号书名号的。避免一行完整的句子被分割,导致翻译不准确 - * 单独拿他出来,目的是为了更好的判断计算,提高翻译的准确率 - */ - connector: (str) => { - /* - 通用的有 空格、阿拉伯数字 - 1.不间断空格\u00A0,主要用在office中,让一个单词在结尾处不会换行显示,快捷键ctrl+shift+space ; - 2.半角空格(英文符号)\u0020,代码中常用的; - 3.全角空格(中文符号)\u3000,中文文章中使用; - */ - if (/.*[\u0020\u00A0\u202F\u205F\u3000]+.*$/.test(str)) { - return true; - } - /* - U+0030 0 数字 0 - U+0031 1 数字 1 - U+0032 2 数字 2 - U+0033 3 数字 3 - U+0034 4 数字 4 - U+0035 5 数字 5 - U+0036 6 数字 6 - U+0037 7 数字 7 - U+0038 8 数字 8 - U+0039 9 数字 9 - */ - if (/.*[\u0030-\u0039]+.*$/.test(str)) { - return true; - } - - /* - 英文场景 - 英文逗号、句号 - 这里不包括() 因为这里面的基本属于补充,对语句前后并无强依赖关系 - - U+0021 ! 叹号 - U+0022 " 双引号 - U+0023 # 井号 - U+0024 $ 价钱/货币符号 - U+0025 % 百分比符号 - U+0026 & 英文“and”的简写符号 - U+0027 ' 引号 - U+002C , 逗号 - U+002D - 连字号/减号 - U+002E . 句号 - U+003A : 冒号 - U+003B ; 分号 - U+003F ? 问号 - U+0040 @ 英文“at”的简写符号 - - - */ - if ( - /.*[\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u002C\u002D\u002E\u003A\u003B\u003F\u0040]+.*$/.test( - str, - ) - ) { - return true; - } - - /* - 中文标点符号 - 名称 Unicode 符号 - 句号 3002 。 - 问号 FF1F ? - 叹号 FF01 ! - 逗号 FF0C , - 顿号 3001 、 - 分号 FF1B ; - 冒号 FF1A : - 引号 300C 「 - 300D 」 - 引号 300E 『 - 300F 』 - 引号 2018 ‘ - 2019 ’ - 引号 201C “ - 201D ” - 括号 FF08 ( - FF09 ) - 括号 3014 〔 - 3015 〕 - 括号 3010 【 - 3011 】 - 破折号 2014 — - 省略号 2026 … - 连接号 2013 – - 间隔号 FF0E . - 书名号 300A 《 - 300B 》 - 书名号 3008 〈 - 3009 〉 - 键盘123前面的那个符号 · 00b7 - */ - if ( - /.*[\u3002\uFF1F\uFF01\uFF0C\u3001\uFF1B\uFF1A\u300C\u300D\u300E\u300F\u2018\u2019\u201C\u201D\uFF08\uFF09\u3014\u3015\u3010\u3011\u2014\u2026\u2013\uFF0E\u300A\u300B\u3008\u3009\u00b7]+.*$/.test( - str, - ) - ) { - return true; - } - - //不是,返回false - return false; - }, - //语种的单词连接符是否需要空格,比如中文简体、繁体、韩文、日语都不需要空格,则返回false, 但是像是英文的单词间需要空格进行隔开,则返回true - //另外这也是区分是否使用标点符号 ,。还是 ,. 的 - //如果未匹配到,默认返回true - //language:语种,传入如 english - wordBlankConnector: (language) => { - if (language == null || typeof language == "undefined") { - return true; - } - switch (language.trim().toLowerCase()) { - case "chinese_simplified": - return false; - case "chinese_traditional": - return false; - case "korean": - return false; - case "japanese": - return false; - } - //其他情况则返回true - return true; - }, - //繁体中文的字典,判断繁体中文就是通过此判断 - chinese_traditional_dict: - "皚藹礙愛翺襖奧壩罷擺敗頒辦絆幫綁鎊謗剝飽寶報鮑輩貝鋇狽備憊繃筆畢斃閉邊編貶變辯辮鼈癟瀕濱賓擯餅撥缽鉑駁蔔補參蠶殘慚慘燦蒼艙倉滄廁側冊測層詫攙摻蟬饞讒纏鏟産闡顫場嘗長償腸廠暢鈔車徹塵陳襯撐稱懲誠騁癡遲馳恥齒熾沖蟲寵疇躊籌綢醜櫥廚鋤雛礎儲觸處傳瘡闖創錘純綽辭詞賜聰蔥囪從叢湊竄錯達帶貸擔單鄲撣膽憚誕彈當擋黨蕩檔搗島禱導盜燈鄧敵滌遞締點墊電澱釣調諜疊釘頂錠訂東動棟凍鬥犢獨讀賭鍍鍛斷緞兌隊對噸頓鈍奪鵝額訛惡餓兒爾餌貳發罰閥琺礬釩煩範販飯訪紡飛廢費紛墳奮憤糞豐楓鋒風瘋馮縫諷鳳膚輻撫輔賦複負訃婦縛該鈣蓋幹趕稈贛岡剛鋼綱崗臯鎬擱鴿閣鉻個給龔宮鞏貢鈎溝構購夠蠱顧剮關觀館慣貫廣規矽歸龜閨軌詭櫃貴劊輥滾鍋國過駭韓漢閡鶴賀橫轟鴻紅後壺護滬戶嘩華畫劃話懷壞歡環還緩換喚瘓煥渙黃謊揮輝毀賄穢會燴彙諱誨繪葷渾夥獲貨禍擊機積饑譏雞績緝極輯級擠幾薊劑濟計記際繼紀夾莢頰賈鉀價駕殲監堅箋間艱緘繭檢堿鹼揀撿簡儉減薦檻鑒踐賤見鍵艦劍餞漸濺澗漿蔣槳獎講醬膠澆驕嬌攪鉸矯僥腳餃繳絞轎較稭階節莖驚經頸靜鏡徑痙競淨糾廄舊駒舉據鋸懼劇鵑絹傑潔結誡屆緊錦僅謹進晉燼盡勁荊覺決訣絕鈞軍駿開凱顆殼課墾懇摳庫褲誇塊儈寬礦曠況虧巋窺饋潰擴闊蠟臘萊來賴藍欄攔籃闌蘭瀾讕攬覽懶纜爛濫撈勞澇樂鐳壘類淚籬離裏鯉禮麗厲勵礫曆瀝隸倆聯蓮連鐮憐漣簾斂臉鏈戀煉練糧涼兩輛諒療遼鐐獵臨鄰鱗凜賃齡鈴淩靈嶺領餾劉龍聾嚨籠壟攏隴樓婁摟簍蘆盧顱廬爐擄鹵虜魯賂祿錄陸驢呂鋁侶屢縷慮濾綠巒攣孿灤亂掄輪倫侖淪綸論蘿羅邏鑼籮騾駱絡媽瑪碼螞馬罵嗎買麥賣邁脈瞞饅蠻滿謾貓錨鉚貿麽黴沒鎂門悶們錳夢謎彌覓綿緬廟滅憫閩鳴銘謬謀畝鈉納難撓腦惱鬧餒膩攆撚釀鳥聶齧鑷鎳檸獰甯擰濘鈕紐膿濃農瘧諾歐鷗毆嘔漚盤龐國愛賠噴鵬騙飄頻貧蘋憑評潑頗撲鋪樸譜臍齊騎豈啓氣棄訖牽扡釺鉛遷簽謙錢鉗潛淺譴塹槍嗆牆薔強搶鍬橋喬僑翹竅竊欽親輕氫傾頃請慶瓊窮趨區軀驅齲顴權勸卻鵲讓饒擾繞熱韌認紉榮絨軟銳閏潤灑薩鰓賽傘喪騷掃澀殺紗篩曬閃陝贍繕傷賞燒紹賒攝懾設紳審嬸腎滲聲繩勝聖師獅濕詩屍時蝕實識駛勢釋飾視試壽獸樞輸書贖屬術樹豎數帥雙誰稅順說碩爍絲飼聳慫頌訟誦擻蘇訴肅雖綏歲孫損筍縮瑣鎖獺撻擡攤貪癱灘壇譚談歎湯燙濤縧騰謄銻題體屜條貼鐵廳聽烴銅統頭圖塗團頹蛻脫鴕馱駝橢窪襪彎灣頑萬網韋違圍爲濰維葦偉僞緯謂衛溫聞紋穩問甕撾蝸渦窩嗚鎢烏誣無蕪吳塢霧務誤錫犧襲習銑戲細蝦轄峽俠狹廈鍁鮮纖鹹賢銜閑顯險現獻縣餡羨憲線廂鑲鄉詳響項蕭銷曉嘯蠍協挾攜脅諧寫瀉謝鋅釁興洶鏽繡虛噓須許緒續軒懸選癬絢學勳詢尋馴訓訊遜壓鴉鴨啞亞訝閹煙鹽嚴顔閻豔厭硯彥諺驗鴦楊揚瘍陽癢養樣瑤搖堯遙窯謠藥爺頁業葉醫銥頤遺儀彜蟻藝億憶義詣議誼譯異繹蔭陰銀飲櫻嬰鷹應纓瑩螢營熒蠅穎喲擁傭癰踴詠湧優憂郵鈾猶遊誘輿魚漁娛與嶼語籲禦獄譽預馭鴛淵轅園員圓緣遠願約躍鑰嶽粵悅閱雲鄖勻隕運蘊醞暈韻雜災載攢暫贊贓髒鑿棗竈責擇則澤賊贈紮劄軋鍘閘詐齋債氈盞斬輾嶄棧戰綻張漲帳賬脹趙蟄轍鍺這貞針偵診鎮陣掙睜猙幀鄭證織職執紙摯擲幟質鍾終種腫衆謅軸皺晝驟豬諸誅燭矚囑貯鑄築駐專磚轉賺樁莊裝妝壯狀錐贅墜綴諄濁茲資漬蹤綜總縱鄒詛組鑽緻鐘麼為隻兇準啟闆裡靂餘鍊", - /* - 中文判断 - 返回: - simplified:简体中文 - traditional:繁体中文 - 空字符串:不是中文 - */ - chinese: function (str) { - if (/.*[\u4e00-\u9fa5]+.*$/.test(str)) { - if (this.chinese_traditional_dict.indexOf(str) > -1) { - return "traditional"; - } - return "simplified"; - } - return ""; - }, - //是否包含日语,true:包含 - japanese: (str) => { - if (/.*[\u3040-\u309F\u30A0-\u30FF]+.*$/.test(str)) { - return true; - } - return false; - }, - //是否包含韩语,true:包含 - korean: (str) => { - if (/.*[\uAC00-\uD7AF]+.*$/.test(str)) { - return true; - } - return false; - }, - //是否包含俄语 - russian: (str) => { - // 正则表达式匹配俄语大小写字母(包含 Ё/ё,排除其他语言特有的西里尔字符) - //АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЮюЯя - if (/^[А-Яа-яЁё]$/.test(str)) { - return true; - } - return false; - }, - //是否包含泰语 - thai: (str) => { - if (/^[\u0E01-\u0E59]$/.test(str)) { - return true; - } - return false; - }, - //是否包含阿拉伯语 - arabic: (str) => { - /* - 阿拉伯语基本区块(U+0600–U+06FF) - 阿拉伯语补充区块(U+0750–U+077F) - */ - return /^[\u0600-\u06FF\u0750-\u077F]$/.test(str); - }, - //是否包含 罗马尼亚语 - romanian: (str) => { - /* - U+00C0–U+00FF:Latin-1 Supplement (包含带变音符号的字母,如 Ă/ă 的部分形式) - U+0100–U+017F:Latin Extended-A (包含罗马尼亚语特有字母 Ă/ă、Â/â、Î/î 等); - U+0218–U+021B:Latin Extended-B (包含 Ș/ș 和 Ț/ț,这是罗马尼亚语标志性字母) - */ - return /^[\u00C0-\u00FF\u0100-\u017F\u0218-\u021B]$/.test(str); - }, - //是否包含希腊语 - greek: (str) => { - const greekRegex = /^[\u0391-\u03A9\u03B1-\u03C9]$/; - //判断字符有 БВДЖЗИЙЛМНОПСТУФХЦЧШЩЪЫЬЮЯЇІ - if (/^[\u0391-\u03A9\u03B1-\u03C9]$/.test(str)) { - return true; - } - return false; - }, - //希伯来语 - hebrew: (str) => /^[\u0590-\u05FF]$/.test(str), - //0-9 阿拉伯数字 - number: (str) => { - if (/.*[\u0030-\u0039]+.*$/.test(str)) { - return true; - } - return false; - }, - //是否包含英文,true:包含 - english: (str) => { - if (/.*[\u0041-\u005a]+.*$/.test(str)) { - return true; - } - if (/.*[\u0061-\u007a]+.*$/.test(str)) { - return true; - } - return false; - }, - //是否包含 罗曼语族 的特殊字符,因为 法语、西班牙语、意大利语、葡萄牙語 都属于这个语族,单纯判断特殊字符已经不能判断出到底属于哪个语种了 - romance_dict: [ - "é", - "è", - "ê", - "à", - "ç", - "œ", - "ñ", - "á", - "ó", - "ò", - "ì", - "ã", - "õ", - ], - romance: function (str) { - if (this.romance_dict.indexOf(str) > -1) { - return true; - } - return false; - }, - //对 罗曼语族 的句子进行分析,看它是属于 法语、西班牙语、意大利语、葡萄牙語 的哪个。注意这个是传入的整体的句子,不是传入的单个字符 - //返回识别的语种: french、spanish、italian、portuguese 如果都没有识别出来,则返回空字符串 - romanceSentenceAnaly: (text) => { - // 定义各语言的典型字母/符号权重 (可调整) - const langFeatures = { - french: { score: 0, chars: ["é", "è", "ê", "à", "ç", "œ"] }, - spanish: { score: 0, chars: ["ñ", "á", "ó"], pairs: ["ll"] }, - italian: { score: 0, chars: ["ò", "ì"], pairs: ["cc", "ss"] }, - portuguese: { score: 0, chars: ["ã", "õ"] }, - }; - - // 逐字扫描 + 相邻配对检测 - for (let i = 0; i < text.length; i++) { - const char = text[i].toLowerCase(); - - // 单字匹配 - Object.keys(langFeatures).forEach((lang) => { - if (langFeatures[lang].chars.includes(char)) { - langFeatures[lang].score += 1; - } - }); - - // 双字配对检测 (如 ll) - if (i < text.length - 1) { - const pair = text.slice(i, i + 2).toLowerCase(); - Object.keys(langFeatures).forEach((lang) => { - const pairs = langFeatures[lang].pairs; - if (pairs && pairs.includes(pair)) { - langFeatures[lang].score += 2; // pair权重大于单字 - } - }); - } - } - - // 结果判定 (取最高分) - let maxLang = ""; - let maxScore = -1; - - Object.keys(langFeatures).forEach((lang) => { - if (langFeatures[lang].score > maxScore) { - maxScore = langFeatures[lang].score; - maxLang = lang; - } - }); - - return maxLang || ""; - }, - /**romanceSentenceAnaly end**/ - - //是否包含特殊字符,包含,则是true - specialCharacter: (str) => { - //如:① ⑴ ⒈ - if (/.*[\u2460-\u24E9]+.*$/.test(str)) { - return true; - } - - //如:┊┌┍ ▃ ▄ ▅ - if (/.*[\u2500-\u25FF]+.*$/.test(str)) { - return true; - } - - //如:㈠ ㎎ ㎏ ㎡ - if (/.*[\u3200-\u33FF]+.*$/.test(str)) { - return true; - } - - //如:与ANSI对应的全角字符 - if (/.*[\uFF00-\uFF5E]+.*$/.test(str)) { - return true; - } - - //其它特殊符号 - if (/.*[\u2000-\u22FF]+.*$/.test(str)) { - return true; - } - - // 、><等符号 - if (/.*[\u3001-\u3036]+.*$/.test(str)) { - return true; - } - - /* - U+0020 空格 - U+0021 ! 叹号 - U+0022 " 双引号 - U+0023 # 井号 - U+0024 $ 价钱/货币符号 - U+0025 % 百分比符号 - U+0026 & 英文“and”的简写符号 - U+0027 ' 引号 - U+0028 ( 开 左圆括号 - U+0029 ) 关 右圆括号 - U+002A * 星号 - U+002B + 加号 - U+002C , 逗号 - U+002D - 连字号/减号 - U+002E . 句号 - U+002F / 左斜杠 - */ - if (/.*[\u0020-\u002F]+.*$/.test(str)) { - return true; - } - - /* - U+003A : 冒号 - U+003B ; 分号 - U+003C < 小于符号 - U+003D = 等于号 - U+003E > 大于符号 - U+003F ? 问号 - U+005B [ 开 方括号 - U+005C \ 右斜杠 - U+005D ] 关 方括号 - U+005E ^ 抑扬(重音)符号 - U+005F _ 底线 - U+0060 ` 重音符 - U+007B { 开 左花括号 - U+007C | 直线 - U+007D } 关 右花括号 - U+007E ~ 波浪纹 - */ - if ( - /.*[\u003B\u003B\u003C\u003D\u003E\u003F\u005B\u005C\u005D\u005E\u005F\u0060\u007B\u007C\u007D\u007E]+.*$/.test( - str, - ) - ) { - return true; - } - - //空白字符,\u0009\u000a + https://cloud.tencent.com/developer/article/2128593 - if ( - /.*[\u0009\u000a\u0020\u00A0\u1680\u180E\u202F\u205F\u3000\uFEFF]+.*$/.test( - str, - ) - ) { - return true; - } - if (/.*[\u2000-\u200B]+.*$/.test(str)) { - return true; - } - - /* - 这些字符主要是 罕见的拉丁字母变体 ,通常用于: - 某些非洲语言或方言; - 古文字、语音学符号; - 特殊排版或装饰性字体。 - */ - if (/.*[\u2C60-\u2C77]+.*$/.test(str)) { - return true; - } - - return false; - }, - /* - 文本翻译的替换。 - - @Deprecated 2025.4.26 最新的在 translate.util.textReplace - - text: 原始文本,翻译的某句或者某个词就在这个文本之中 - translateOriginal: 翻译的某个词或句,在翻译之前的文本 - translateResult: 翻译的某个词或句,在翻译之后的文本,翻译结果 - language: 显示的语种,这里是对应的 translateResult 这个文本的语种。 也就是最终替换之后要显示给用户的语种。比如将中文翻译为英文,这里也就是英文。 这里会根据显示的语种不同,来自主决定是否前后加空格进行分割。 另外这里传入的语种也是 translate.js 的语种标识 - - (注意,如果 translateResult 中发现 translateOriginal 的存在,将不进行任何处理,因为没必要了,还会造成死循环。直接将 text 返回) - - 使用此方法: - var text = '你世好word世界'; - var translateOriginal = '世'; - var translateResult = '世杰'; //翻译结果 - translate.language.textTranslateReplace(text, translateOriginal, translateResult, 'english'); - - */ - textTranslateReplace: ( - text, - translateOriginal, - translateResult, - language, - ) => - translate.util.textReplace( - text, - translateOriginal, - translateResult, - language, - ), - }, - //用户第一次打开网页时,自动判断当前用户所在国家使用的是哪种语言,来自动进行切换为用户所在国家的语种。 - //如果使用后,第二次在用,那就优先以用户所选择的为主 - executeByLocalLanguage: () => { - //先读用户自己浏览器的默认语言 - var browserDefaultLanguage = translate.util.browserDefaultLanguage(); - if ( - typeof browserDefaultLanguage != "undefined" && - browserDefaultLanguage.length > 0 - ) { - translate.changeLanguage(browserDefaultLanguage); - return; - } - - if ( - typeof translate.request.api.ip != "string" || - translate.request.api.ip == null || - translate.request.api.ip.length < 1 - ) { - return; - } - - //如果用户浏览器没读到默认语言,或者默认语言没有对应到translate.js支持的语种,那么在采用ip识别的方式 - translate.request.post( - translate.request.api.ip, - {}, - (data) => { - //console.log(data); - if (data.result == 0) { - console.log("==== ERROR 获取当前用户所在区域异常 ===="); - console.log(data.info); - console.log("==== ERROR END ===="); - } else { - translate.storage.set("to", data.language); //设置目标翻译语言 - translate.to = data.language; //设置目标语言 - translate.selectLanguageTag; - translate.execute(); //执行翻译 - } - }, - null, - ); - }, - - util: { - /* - 文本替换,将替换完毕的结果返回 - 自定义术语等都是通过这个来进行替换 - 2025.4.26 从 language 中 拿到这里 - - text: 原始文本,翻译的某句或者某个词就在这个文本之中 - translateOriginal: 翻译的某个词或句,在翻译之前的文本 - translateResult: 翻译的某个词或句,在翻译之后的文本,翻译结果 - language: 显示的语种,这里是对应的 translateResult 这个文本的语种。 也就是最终替换之后要显示给用户的语种。比如将中文翻译为英文,这里也就是英文。 这里会根据显示的语种不同,来自主决定是否前后加空格进行分割。 另外这里传入的语种也是 translate.js 的语种标识 - - (注意,如果 translateResult 中发现 translateOriginal 的存在,将不进行任何处理,因为没必要了,还会造成死循环。直接将 text 返回) - - 使用此方法: - var text = '你世好word世界'; - var translateOriginal = '世'; - var translateResult = '世杰'; //翻译结果 - translate.util.textReplace(text, translateOriginal, translateResult, 'english'); - - */ - textReplace: (text, translateOriginal, translateResult, language) => { - //如果要替换的源文本直接就是整个文本,那也就不用在做什么判断了,直接将 翻译的结果文本返回就好了 - if (text == translateOriginal) { - return translateResult; - } - - //当前替换后,替换结果结束位置的下标。 - //一开始还没进行替换,那么这个下标就是 0 - //比如 你好吗 中的 好 替换为 "好的" 那最后结果为 "你好的吗" ,这里是 “的” 的下标 2 - let currentReplaceEndIndex = 0; - - //while最大循环次数30次,免得出现未知异常导致死循环 - let maxWhileNumber = 30; - - //因为text中可能有多个位置要被替换,所以使用循环 - while ( - text.indexOf(translateOriginal, currentReplaceEndIndex) > -1 && - maxWhileNumber-- > 0 - ) { - //console.log('text:'+text+'\tcurrentReplaceEndIndex:'+currentReplaceEndIndex); - - //要替换的结果文本(这个文本可能前面有加空格或者后面有加空格的) - let replaceResultText = "" + translateResult; - //替换的文本 ,这里有可能会追加上某些标点符号,所以单独也列出来,而不是使用方法中传入的 translateOriginal - let replaceOriginalText = "" + translateOriginal; - - //根据不同的语种,如果有的语种需要加空格来进行区分单词,那么也要进行空格的判定 - if (translate.language.wordBlankConnector(language)) { - const originalIndex = text.indexOf( - translateOriginal, - currentReplaceEndIndex, - ); //翻译之前,翻译的单词在字符串中的起始坐标(0开始) - //console.log("originalIndex: "+originalIndex); - - //要先判断后面,不然先判断前面,加了后它的长度就又变了 - - //判断它后面是否还有文本 - if (originalIndex + 1 < text.length) { - const char = text.charAt(originalIndex + translateOriginal.length); - //console.log(char); - if (/。/.test(char)) { - replaceResultText = replaceResultText + ". "; - replaceOriginalText = translateOriginal + "。"; - } else if (/,/.test(char)) { - replaceResultText = replaceResultText + ", "; - replaceOriginalText = translateOriginal + ","; - } else if (/:/.test(char)) { - replaceResultText = replaceResultText + ": "; - replaceOriginalText = translateOriginal + ":"; - } else if ( - [" ", "\n", "\t", "]", "|", "_", "-", "/"].indexOf(char) !== -1 - ) { - // 如果后面的字符是 这些字符,那么不用添加空格隔开 - } else { - //补充上一个空格,用于将两个单词隔开。 不过 ,如果当前 replaceResultText 的最后一个字符也是空格,那就不需要再加空格了。 这里就只判断空格就好了,至于其他的换行等基本不会出现这个情况,所以不考虑 - if ( - replaceResultText.length > 0 && - replaceResultText.charAt(replaceResultText.length - 1) == " " - ) { - //replaceResultText 本身有值,且最后一个字符就是空格,就不需要再追加空格进行隔开了 - } else { - replaceResultText = replaceResultText + " "; - } - } - } - - //判断它前面是否还有文本 - if (originalIndex > 0) { - const char = text.charAt(originalIndex - 1); - //console.log(char); - - if (/。/.test(char)) { - replaceResultText = ". " + replaceResultText; - replaceOriginalText = "。" + replaceOriginalText; - } else if (/,/.test(char)) { - replaceResultText = ", " + replaceResultText; - replaceOriginalText = "," + replaceOriginalText; - } else if (/:/.test(char)) { - replaceResultText = ": " + replaceResultText; - replaceOriginalText = ":" + replaceOriginalText; - } else if ( - [" ", "\n", "\t", "[", "|", "_", "-", "/"].indexOf(char) !== -1 - ) { - // 如果前面的字符是 这些字符,那么不用添加空格隔开 - //console.log('不需要空格隔开的'); - } else { - //补充上一个空格,用于将两个单词隔开。 不过 ,如果当前 replaceResultText 的第一个字符也是空格,那就不需要再加空格了。 这里就只判断空格就好了,至于其他的换行等基本不会出现这个情况,所以不考虑 - if ( - replaceResultText.length > 0 && - replaceResultText.charAt(0) == " " - ) { - //replaceResultText 本身有值,且最后一个字符就是空格,就不需要再追加空格进行隔开了 - } else { - replaceResultText = " " + replaceResultText; - } - //console.log('before add space : '+replaceResultText); - } - } - } else { - //如果是其他语种比如英语法语翻译为中文、日文,那么标点符号也要判断的,这个因为目前这个场景还没咋遇到,就不判断了,遇到了在加。 - } - //console.log(replaceResultText) - //console.log(replaceResultText.length) - - const replaceResult = translate.util.replaceFromIndex( - text, - currentReplaceEndIndex, - replaceOriginalText, - replaceResultText, - ); - if (replaceResult.replaceEndIndex < 1) { - console.log( - "while中已经 indexOf发现了,但是实际没有替换,出现异常了!理论上这是不应该出现的。 text:" + - text + - " , translateOriginal:" + - translateOriginal, - ); - } else { - currentReplaceEndIndex = replaceResult.replaceEndIndex; - text = replaceResult.text; - } - } - - //console.log(resultText); - return text; - }, - /* - js 的 replace 能力,这个是可以指定从第几个字符开始进行replace - 1. 这里可以 replaceText 本身包含着 originalText - 2. originalText 可以出现多次 - - @param - text 要进行替换的原始文本 - index 要从 text 的哪个下标开始。 (第一个字符下标是0) - originalText 要替换的文本,被替换的文本 - replaceText 替换为的文本,将 originalText 替换为什么 - replaceFromIndex('你好吗?你也好?', 0, '你', '你是谁'); - - @return 对象 - text 替换的结果 - replaceEndIndex 当前替换后,替换结果结束位置的下标。 - 如果没进行替换,那么这个下标就是 0 - 比如 你好吗 中的 好 替换为 "好的" 那最后结果为 "你好的吗" ,这里是 “的” 的下标 2 - */ - replaceFromIndex: (text, index, originalText, replaceText) => { - const before = text.slice(0, index); - const after = text.slice(index); - const originalTextIndex = after.indexOf(originalText); - if (originalTextIndex > -1) { - const replacedAfter = after.replace(originalText, replaceText); - return { - text: before + replacedAfter, - replaceEndIndex: index + originalTextIndex + replaceText.length, - }; - } - //没有发现可替换的字符,那么就原样返回 - return { - text: before + replacedAfter, - replaceEndIndex: 0, - }; - }, - - /* 生成一个随机UUID,复制于 https://gitee.com/mail_osc/kefu.js */ - uuid: () => { - var d = new Date().getTime(); - if (window.performance && typeof window.performance.now === "function") { - d += performance.now(); //use high-precision timer if available - } - var uuid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g, (c) => { - var r = ((d + Math.random() * 16) % 16) | 0; - d = Math.floor(d / 16); - return (c == "x" ? r : (r & 0x3) | 0x8).toString(16); - }); - return uuid; - }, - - //判断字符串中是否存在tag标签。 true存在 - findTag: (str) => { - var reg = /<[^>]+>/g; - return reg.test(str); - }, - //传入一个数组,从数组中找出现频率最多的一个返回。 如果多个频率出现的次数一样,那会返回多个 - arrayFindMaxNumber: (arr) => { - // 储存每个元素出现的次数 - var numbers = {}; - - // 储存出现最多次的元素 - var maxStr = []; - - // 储存最多出现的元素次数 - var maxNum = 0; - - for (var i = 0, len = arr.length; i < len; i++) { - if (!numbers[arr[i]]) { - numbers[arr[i]] = 1; - } else { - numbers[arr[i]]++; - } - - if (numbers[arr[i]] > maxNum) { - maxNum = numbers[arr[i]]; - } - } - - for (var item in numbers) { - if (!Object.hasOwn(numbers, item)) { - continue; - } - if (numbers[item] === maxNum) { - maxStr.push(item); - } - } - - return maxStr; - }, - //对字符串进行hash化,目的取唯一值进行标识 - hash: (str) => { - if (str == null || typeof str == "undefined") { - return str; - } - var hash = 0, - i, - chr; - if (str.length === 0) { - return hash; - } - - for (i = 0; i < str.length; i++) { - chr = str.charCodeAt(i); - hash = (hash << 5) - hash + chr; - hash |= 0; // Convert to 32bit integer - } - return hash + ""; - }, - //去除一些指定字符,如换行符。 如果传入的是null,则返回空字符串 - charReplace: (str) => { - if (str == null) { - return ""; - } - str = str.trim(); - str = str.replace(/\t|\n|\v|\r|\f/g, ""); //去除换行符等 - //str = str.replace(/&/g, "%26"); //因为在提交时已经进行了url编码了 - return str; - }, - //RegExp相关 - regExp: { - // new RegExp(pattern, resultText); 中的 pattern 字符串的预处理 - pattern: (str) => { - str = str.replace(/\\/g, "\\\\"); //这个一定要放在第一个,不然会被下面的影响 - //str = str.replace(/'/g,'\\\''); - str = str.replace(/"/g, '\\\"'); - //str = str.replace(/./g,'\\\.'); - str = str.replace(/\?/g, "\\\?"); - str = str.replace(/\$/g, "\\\$"); - str = str.replace(/\(/g, "\\\("); - str = str.replace(/\)/g, "\\\)"); - str = str.replace(/\|/g, "\\\|"); - str = str.replace(/\+/g, "\\\+"); - str = str.replace(/\*/g, "\\\*"); - str = str.replace(/\[/g, "\\\["); - str = str.replace(/\]/g, "\\\]"); - str = str.replace(/\^/g, "\\\^"); - str = str.replace(/\{/g, "\\\{"); - str = str.replace(/\}/g, "\\\}"); - return str; - }, - // new RegExp(pattern, resultText); 中的 resultText 字符串的预处理 - resultText: (str) => { - //str = str.replace(/"/g,"\""); - //str = str.replace(/'/g,"\\\'"); - //str = str.replace(/"/g,"\\\""); - return str; - }, - }, - //获取URL的GET参数。若没有,返回"" - getUrlParam: (name) => { - var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); - var r = window.location.search.substr(1).match(reg); - if (r != null) return unescape(r[2]); - return ""; - }, - /** - * 同步加载JS,加载过程中会阻塞,加载完毕后继续执行后面的。 - * url: 要加载的js的url - */ - synchronizesLoadJs: (url) => { - var xmlHttp = null; - if (window.ActiveXObject) { - //IE - try { - //IE6以及以后版本中可以使用 - xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); - } catch (e) { - //IE5.5以及以后版本可以使用 - xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); - } - } else if (window.XMLHttpRequest) { - //Firefox,Opera 8.0+,Safari,Chrome - xmlHttp = new XMLHttpRequest(); - } - //采用同步加载 - xmlHttp.open("GET", url, false); - //发送同步请求,如果浏览器为Chrome或Opera,必须发布后才能运行,不然会报错 - xmlHttp.send(null); - //4代表数据发送完毕 - if (xmlHttp.readyState == 4) { - //0为访问的本地,200到300代表访问服务器成功,304代表没做修改访问的是缓存 - if ( - (xmlHttp.status >= 200 && xmlHttp.status < 300) || - xmlHttp.status == 0 || - xmlHttp.status == 304 - ) { - var myBody = document.getElementsByTagName("HTML")[0]; - var myScript = document.createElement("script"); - myScript.language = "javascript"; - myScript.type = "text/javascript"; - try { - //IE8以及以下不支持这种方式,需要通过text属性来设置 - myScript.appendChild(document.createTextNode(xmlHttp.responseText)); - } catch (ex) { - myScript.text = xmlHttp.responseText; - } - myBody.appendChild(myScript); - return true; - } - return false; - } - return false; - }, - - /*js translate.util.loadMsgJs start*/ - //加载 msg.js - loadMsgJs: () => { - if (typeof msg != "undefined") { - return; - } - translate.util.synchronizesLoadJs("https://res.zvo.cn/msg/msg.js"); - }, - /*js translate.util.loadMsgJs end*/ - /* - 对一个对象,按照对象的key的长度进行排序,越长越在前面 - */ - objSort: (obj) => { - // 获取对象数组的所有 key,并转换为普通数组 - var keys = Array.from(Object.keys(obj)); - //var keys = [].slice.call(Object.keys(obj)); //适配es5 - - // 对 key 数组进行排序 - keys.sort((a, b) => b.length - a.length); - - // 定义一个新的对象数组,用来存储排序后的结果 - var sortedObj = []; - - // 遍历排序后的 key 数组,将对应的值复制到新的对象数组中,并删除原来的对象数组中的键值对 - for (var key of keys) { - sortedObj[key] = obj[key]; - } - return sortedObj; - }, - /* - 将 2.11.3.20231232 转化为 2011003 - 转化时会去掉最后一个日期的字符 - */ - versionStringToInt: (versionString) => { - var vs = versionString.split("\."); - var result = 0; - result = Number.parseInt(vs[0]) * 1000 * 1000 + result; - result = Number.parseInt(vs[1]) * 1000 + result; - result = Number.parseInt(vs[2]) + result; - - return result; - }, - /** - * 将一个 JSONArray 数组,按照文字长度进行拆分。 - * 比如传入的 array 数组的文字长度是6200,传入的 stringLength 是2000,那么就是将 array 数组拆分为多个长度不超出2000的数组返回。 - * 如果传入了 maxSize = 5 那么会对拆分后的数组的长度进行判断,如果数组内元素超过5,那么还要进行缩短,拆分后的数组不允许超过这个数 - * 也就是拆分后的数组有两重限制,一是限制转化为文本形式的长度、再就是拆分后本身数组的大小。 - * - * 注意,这个长度是指 array.toString() 后的长度,也就是包含了 [""] 这种符号的长度 - * @param array 要被拆分的数组,其内都是String类型,传入格式如 ["你好","世界"] - * @param stringLength 要被拆分的数组转化为字符串之后的长度 - * @param maxSize 被拆分的数组最大包含多少个,数组大小最大允许多大,要小于等于这个数。 如果设置为0则是不启用这个,不对拆分后的数组进行判断。 - * @return 被拆分后的数组列表 - * @author 刘晓腾 - */ - split: (array, size, maxSize) => { - const orgsize = size; - let list = []; - // 数组长度小于size,直接进行返回 - if (JSON.stringify(array).length <= size) { - list.push(array); - } else { - // 转换成String - const arrayStr = JSON.stringify(array) - .trim() - .substring(1, JSON.stringify(array).length - 1); - - // 判断size和字符串长度的差值,如果为1或者2,就直接拆成两段 - if (JSON.stringify(array).length - size <= 2) { - size = size - 4; - // 拆两段 - const str1 = arrayStr.substring(0, arrayStr.lastIndexOf('","') + 1); - const str2 = arrayStr.substring(arrayStr.lastIndexOf('","') + 2); - list.push(JSON.parse("[" + str1 + "]")); - list.push(JSON.parse("[" + str2 + "]")); - } else { - size = size - 2; - // 拆多段 - let index = 0; - while (index - arrayStr.length < 0) { - // 按照指定大小拆一段 - let s = ""; - if (index + size - arrayStr.length >= 0) { - s = arrayStr.substring(index); - } else { - s = arrayStr.substring(index, index + size); - } - // 结尾长度默认为字符串长度 - let endIndex = s.length; - // 因为下次开始的第一个字符可能会是逗号,所以下次开始需要+1 - let startNeedAdd = 1; - // 判断最后一个字符是否为双引号 - if (s.endsWith('"')) { - // 判断倒数第二个是否为逗号 - if (s.endsWith('","')) { - // 删除两个字符 - endIndex -= 2; - } else if (!s.startsWith('"')) { - // 如果开头不是引号,需要补一个引号,这就导致会超长,所以结尾就要找指定字符的 - // 找出最后一个指定字符的位置 - const la = s.lastIndexOf('","'); - endIndex = la + 1; - } - } else if (s.endsWith('",')) { - // 判断是否为逗号,是的话删除一个字符 - endIndex -= 1; - } else { - // 都不是,那就是内容结尾 - // 找出最后一个指定字符的位置 - const la = s.lastIndexOf('","'); - endIndex = la + 1; - // 内容超长,endIndex就会变成0,这时需要手动赋值 - if (endIndex <= 0) { - // 看看是否以引号开头,如果不是,需要拼两个引号 - if (s.startsWith('"')) { - // 拼一个引号,-1 - endIndex = s.length - 1; - } else { - // 拼两个引号,-2 - endIndex = s.length - 2; - } - if (!s.endsWith('"')) { - // 开始不是逗号了,不能-1 - startNeedAdd = 0; - } - } - } - // 根据处理的结尾长度进行第二次拆分 - let s2 = ""; - if (endIndex - s.length > 0 || endIndex - 0 == 0) { - s2 = s; - endIndex = endIndex + s2.length; - } else { - s2 = s.substring(0, endIndex); - } - if (!s2.startsWith('"') && !s2.startsWith(',"')) { - // 拼一个引号 - s2 = '"' + s2; - } - if (!s2.endsWith('"')) { - // 拼一个引号 - s2 = s2 + '"'; - } - // 计算下次循环开始的长度 - index += endIndex + startNeedAdd; - // 加到list - s2 = "[" + s2 + "]"; - try { - list.push(JSON.parse(s2)); - } catch (e) { - // 遇到错误,略过一个字符 - index = index - (endIndex + startNeedAdd) + 1; - } - } - } - } - // 设置了maxSize,进行处理 - if (maxSize && maxSize > 0) { - list = translate.util._splitMaxSize(list, orgsize, maxSize); - } - return list; - }, - /** - * 针对split函数中maxSize的处理 - * private - * @param array 已拆分的二维数组 - * @param size 拆分的长度 - * @param maxSize 元素数量 - * @author 刘晓腾 - */ - _splitMaxSize: (array, size, maxSize) => { - // console.log("------ splitMaxSize run ------") - - // 返回的数据 - let list = []; - // 暂存的数组,用来存储每次遍历时超出的数据 - let tmp = []; - - // 遍历二维数组 - array.forEach((arr, index) => { - // 累加数组 - arr = tmp.concat(arr); - // 计算元素数量 - const length = arr.length; - // 数组中元素数量大于maxSize,对多余的元素进行移除 - if (length > maxSize) { - // 第一个数组,包含前N个元素 - let firstArray = arr.slice(0, maxSize); - // 第二个数组,包含剩下的元素 - let secondArray = arr.slice(maxSize); - - // 处理长度 - let len = 1; - while (JSON.stringify(firstArray).length > size) { - // 长度超过限制,进行处理 - firstArray = arr.slice(0, maxSize - len); - secondArray = arr.slice(maxSize - len); - len++; - if (len >= arr.length + 1) { - break; - } - } - - // 第一个数组记录 - list.push(firstArray); - // 第二个数组暂存 - tmp.length = 0; - tmp = secondArray; - } else { - // 没超,只处理长度 - // 处理长度 - let firstArray = arr; - let secondArray = []; - let len = 1; - while (JSON.stringify(firstArray).length > size) { - // 长度超过限制,进行处理 - firstArray = arr.slice(0, maxSize - len); - secondArray = arr.slice(maxSize - len); - len++; - if (len >= arr.length + 1) { - break; - } - } - - // 第一个数组记录 - list.push(firstArray); - // 第二个数组暂存 - tmp.length = 0; - tmp = secondArray; - } - }); - - // 临时数组中还有元素,也要进行处理 - if (tmp.length > 0) { - const tmpl = []; - tmpl.push(tmp); - // 递归处理 - const l = translate.util._splitMaxSize(tmpl, size, maxSize); - list = list.concat(l); - } - - return list; - }, - /* - 浏览器的语种标识跟translate.js的语种标识的对应 - key: 浏览器的语种标识 - value: translate.js 的语种标识 - */ - browserLanguage: { - zh: "chinese_simplified", - "zh-CN": "chinese_simplified", - "zh-TW": "chinese_traditional", - "zh-HK": "chinese_traditional", - co: "corsican", - gn: "guarani", - rw: "kinyarwanda", - ha: "hausa", - no: "norwegian", - nl: "dutch", - yo: "yoruba", - en: "english", - "en-US": "english", - kok: "gongen", - la: "latin", - ne: "nepali", - fr: "french", - cs: "czech", - haw: "hawaiian", - ka: "georgian", - ru: "russian", - fa: "persian", - bho: "bhojpuri", - hi: "hindi", - be: "belarusian", - sw: "swahili", - is: "icelandic", - yi: "yiddish", - tw: "twi", - ga: "irish", - gu: "gujarati", - km: "khmer", - sk: "slovak", - he: "hebrew", - kn: "kannada", - hu: "hungarian", - ta: "tamil", - ar: "arabic", - bn: "bengali", - az: "azerbaijani", - sm: "samoan", - af: "afrikaans", - id: "indonesian", - da: "danish", - sn: "shona", - bm: "bambara", - lt: "lithuanian", - vi: "vietnamese", - mt: "maltese", - tk: "turkmen", - as: "assamese", - ca: "catalan", - si: "singapore", - ceb: "cebuano", - gd: "scottish-gaelic", - sa: "sanskrit", - pl: "polish", - gl: "galician", - lv: "latvian", - uk: "ukrainian", - tt: "tatar", - cy: "welsh", - ja: "japanese", - fil: "filipino", - ay: "aymara", - lo: "lao", - te: "telugu", - ro: "romanian", - ht: "haitian_creole", - doi: "dogrid", - sv: "swedish", - mai: "maithili", - th: "thai", - hy: "armenian", - my: "burmese", - ps: "pashto", - hmn: "hmong", - dv: "dhivehi", - lb: "luxembourgish", - sd: "sindhi", - ku: "kurdish", - tr: "turkish", - mk: "macedonian", - bg: "bulgarian", - ms: "malay", - lg: "luganda", - mr: "marathi", - et: "estonian", - ml: "malayalam", - de: "deutsch", - sl: "slovene", - ur: "urdu", - pt: "portuguese", - ig: "igbo", - ckb: "kurdish_sorani", - om: "oromo", - el: "greek", - es: "spanish", - fy: "frisian", - so: "somali", - am: "amharic", - ny: "nyanja", - pa: "punjabi", - eu: "basque", - it: "italian", - sq: "albanian", - ko: "korean", - tg: "tajik", - fi: "finnish", - ky: "kyrgyz", - ee: "ewe", - hr: "croatian", - kri: "creole", - qu: "quechua", - bs: "bosnian", - mi: "maori", - }, - /* - 获取浏览器中设置的默认使用语言 - 返回的是 translate.js 的语言唯一标识 - 如果返回的是空字符串,则是没有匹配到(可能是没有获取到本地语言,也可能是本地语言跟translate.js 翻译通道没有对应上) - */ - browserDefaultLanguage: () => { - var language = navigator.language || navigator.userLanguage; - if (typeof language == "string" && language.length > 0) { - var tLang = translate.util.browserLanguage[language]; - if (typeof tLang == "undefined") { - //没有在里面 - console.log( - "browser default language : " + - language + - ", translate.js current translate channel not support this language ", - ); - } else { - return tLang; - } - } - - //将其转化为 translate.js 的语言id,比如简体中文是 chinese_simplified 、 英语是 english - return ""; - }, - /* - 对输入的文本 text 进行判断,判断它里面是否有url存在。如果有url存在,对其进行截取,将url跟非url进行截取处理。 - 比如传入 “这个示例:https://www.ungm.org/Public/Notice/261001,其他得示例是 http://api.translate.zvo.cn 我呢” - 那么返回的截取结果为: - { - "https://www.ungm.org/Public/Notice/261001":"1", - "http://api.translate.zvo.cn":"1", - ",其他得示例是 ":"0", - "这个示例:":"0" - " 我呢":"0" - } - 其中的key 为截取的文本,value 的值是1或0, 1代表当前key的文本是网址,0则不是网址 - */ - urlSplitByText: (text) => { - // 匹配 http/https 的 URL 正则表达式(包含常见 URL 符号,排除中文等非 ASCII 字符) - const urlRegex = - /(https?:\/\/[\w\-._~:/?#[\]@!$&'()*+;=%]+(?=[\s\u4e00-\u9fa5,。;,!?]|$))/gi; - - // 使用正则表达式分割文本,保留URL - const parts = text.split(urlRegex); - - // 结果对象 - const result = {}; - - // 添加非URL部分,并标记为 0 - for (let i = 0; i < parts.length; i++) { - if (i % 2 === 0) { - // 非URL部分 - if (parts[i] !== "") { - result[parts[i]] = "0"; - } - } else { - // URL部分 - result[parts[i]] = "1"; - } - } - - return result; - }, - - /*js translate.util.getElementPosition start*/ - /* - 计算一个元素在浏览器中的坐标系,其绝对定位、以及实际显示出来所占用的区域,宽、高 - */ - getElementPosition: (node) => { - // 获取元素的边界矩形信息(相对于视口) - const rect = node.getBoundingClientRect(); - - // 获取当前页面的滚动位置(兼容不同浏览器) - const scrollX = window.scrollX || document.documentElement.scrollLeft; - const scrollY = window.scrollY || document.documentElement.scrollTop; - - // 计算元素在文档中的起始坐标 - const startX = rect.left + scrollX; - const startY = rect.top + scrollY; - - // 计算元素的宽度和高度 - const width = rect.right - rect.left; - const height = rect.bottom - rect.top; - - // 计算元素在文档中的结束坐标 - const endX = startX + width; - const endY = startY + height; - - // 返回包含所有信息的对象(使用ES5兼容语法) - return { - startX: startX, - startY: startY, - endX: endX, - endY: endY, - width: width, - height: height, - }; - }, - /*js translate.util.getElementPosition end*/ - }, - //机器翻译采用哪种翻译服务 - service: { - /* - name填写的值,参考 translate.service.use 的注释 - */ - name: "translate.service", - - /*js translate.service.use start*/ - /* - 其实就是设置 translate.service.name - 可以设置为: - - translate.service 自行部署的translate.service 翻译API服务,部署参考: https://translate.zvo.cn/391129.html - client.edge 使用无服务器的翻译,有edge浏览器接口提供翻译服务 - siliconflow 使用指点云提供的服务器、硅基流动提供的AI算力进行大模型翻译 - giteeAI 使用 giteeAI , 亚洲、美洲、欧洲 网络节点覆盖 - - */ - use: (serviceName) => { - if ( - typeof translate.enterprise != "undefined" && - translate.enterprise.isUse == true - ) { - console.log( - "您已启用了企业级翻译通道 translate.enterprise.use(); (文档:https://translate.zvo.cn/4087.html) , 所以您设置的 translate.service.use('" + - serviceName + - "'); (文档:https://translate.zvo.cn/4081.html) 将失效不起作用,有企业级翻译通道全部接管。", - ); - return; - } - //console.log('--'+serviceName); - if (typeof serviceName == "string") { - translate.service.name = serviceName; - if (serviceName != "translate.service") { - //增加元素整体翻译能力 - translate.whole.enableAll(); - - if (serviceName.toLowerCase() == "giteeai") { - //设定翻译接口为GiteeAI的 - translate.request.api.host = [ - "https://giteeai.zvo.cn/", - "https://deutsch.enterprise.api.translate.zvo.cn:1000/", - "https://api.translate.zvo.cn:1000/", - ]; - return; - } - if (serviceName.toLowerCase() == "siliconflow") { - //设定翻译接口为硅基流动的 - translate.request.api.host = [ - "https://siliconflow.zvo.cn/", - "https://america.api.translate.zvo.cn:1414/", - "https://deutsch.enterprise.api.translate.zvo.cn:1414/", - ]; - return; - } - } - } - }, - /*js translate.service.use end*/ - - /*js translate.service.edge start*/ - //客户端方式的edge提供机器翻译服务 - edge: { - api: { - //edge浏览器的翻译功能 - auth: "https://edge.microsoft.com/translate/auth", //auth授权拉取 - translate: - "https://api.cognitive.microsofttranslator.com/translate?from={from}&to={to}&api-version=3.0&includeSentenceLength=true", //翻译接口 - }, - - language: { - json: [ - { id: "ukrainian", name: "Україна", serviceId: "uk" }, - { id: "norwegian", name: "Norge", serviceId: "no" }, - { id: "welsh", name: "Iaith Weleg", serviceId: "cy" }, - { id: "dutch", name: "nederlands", serviceId: "nl" }, - { id: "japanese", name: "日本語", serviceId: "ja" }, - { id: "filipino", name: "Pilipino", serviceId: "fil" }, - { id: "english", name: "English", serviceId: "en" }, - { id: "lao", name: "ກະຣຸນາ", serviceId: "lo" }, - { id: "telugu", name: "తెలుగుName", serviceId: "te" }, - { id: "romanian", name: "Română", serviceId: "ro" }, - { id: "nepali", name: "नेपालीName", serviceId: "ne" }, - { id: "french", name: "Français", serviceId: "fr" }, - { id: "haitian_creole", name: "Kreyòl ayisyen", serviceId: "ht" }, - { id: "czech", name: "český", serviceId: "cs" }, - { id: "swedish", name: "Svenska", serviceId: "sv" }, - { id: "russian", name: "Русский язык", serviceId: "ru" }, - { id: "malagasy", name: "Malagasy", serviceId: "mg" }, - { id: "burmese", name: "ဗာရမ်", serviceId: "my" }, - { id: "pashto", name: "پښتوName", serviceId: "ps" }, - { id: "thai", name: "คนไทย", serviceId: "th" }, - { id: "armenian", name: "Արմենյան", serviceId: "hy" }, - { id: "chinese_simplified", name: "简体中文", serviceId: "zh-CHS" }, - { id: "persian", name: "Persian", serviceId: "fa" }, - { id: "chinese_traditional", name: "繁體中文", serviceId: "zh-CHT" }, - { id: "kurdish", name: "Kurdî", serviceId: "ku" }, - { id: "turkish", name: "Türkçe", serviceId: "tr" }, - { id: "hindi", name: "हिन्दी", serviceId: "hi" }, - { id: "bulgarian", name: "български", serviceId: "bg" }, - { id: "malay", name: "Malay", serviceId: "ms" }, - { id: "swahili", name: "Kiswahili", serviceId: "sw" }, - { id: "oriya", name: "ଓଡିଆ", serviceId: "or" }, - { id: "icelandic", name: "ÍslandName", serviceId: "is" }, - { id: "irish", name: "Íris", serviceId: "ga" }, - { id: "khmer", name: "ភាសា​ខ្មែរName", serviceId: "km" }, - { id: "gujarati", name: "ગુજરાતી", serviceId: "gu" }, - { id: "slovak", name: "Slovenská", serviceId: "sk" }, - { id: "kannada", name: "ಕನ್ನಡ್Name", serviceId: "kn" }, - { id: "hebrew", name: "היברית", serviceId: "he" }, - { id: "hungarian", name: "magyar", serviceId: "hu" }, - { id: "marathi", name: "मराठीName", serviceId: "mr" }, - { id: "tamil", name: "தாமில்", serviceId: "ta" }, - { id: "estonian", name: "eesti keel", serviceId: "et" }, - { id: "malayalam", name: "മലമാലം", serviceId: "ml" }, - { id: "inuktitut", name: "ᐃᓄᒃᑎᑐᑦ", serviceId: "iu" }, - { id: "arabic", name: "بالعربية", serviceId: "ar" }, - { id: "deutsch", name: "Deutsch", serviceId: "de" }, - { id: "slovene", name: "slovenščina", serviceId: "sl" }, - { id: "bengali", name: "বেঙ্গালী", serviceId: "bn" }, - { id: "urdu", name: "اوردو", serviceId: "ur" }, - { id: "azerbaijani", name: "azerbaijani", serviceId: "az" }, - { id: "portuguese", name: "português", serviceId: "pt" }, - { id: "samoan", name: "lifiava", serviceId: "sm" }, - { id: "afrikaans", name: "afrikaans", serviceId: "af" }, - { id: "tongan", name: "汤加语", serviceId: "to" }, - { id: "greek", name: "ελληνικά", serviceId: "el" }, - { id: "indonesian", name: "IndonesiaName", serviceId: "id" }, - { id: "spanish", name: "Español", serviceId: "es" }, - { id: "danish", name: "dansk", serviceId: "da" }, - { id: "amharic", name: "amharic", serviceId: "am" }, - { id: "punjabi", name: "ਪੰਜਾਬੀName", serviceId: "pa" }, - { id: "albanian", name: "albanian", serviceId: "sq" }, - { id: "lithuanian", name: "Lietuva", serviceId: "lt" }, - { id: "italian", name: "italiano", serviceId: "it" }, - { id: "vietnamese", name: "Tiếng Việt", serviceId: "vi" }, - { id: "korean", name: "한국어", serviceId: "ko" }, - { id: "maltese", name: "Malti", serviceId: "mt" }, - { id: "finnish", name: "suomi", serviceId: "fi" }, - { id: "catalan", name: "català", serviceId: "ca" }, - { id: "croatian", name: "hrvatski", serviceId: "hr" }, - { id: "bosnian", name: "bosnian", serviceId: "bs-Latn" }, - { id: "polish", name: "Polski", serviceId: "pl" }, - { id: "latvian", name: "latviešu", serviceId: "lv" }, - { id: "maori", name: "Maori", serviceId: "mi" }, - ], - /* - 获取map形式的语言列表 - key为 translate.service 的 name - value为serviceId - - */ - getMap: () => { - if (typeof translate.service.edge.language.map == "undefined") { - translate.service.edge.language.map = []; - for ( - var i = 0; - i < translate.service.edge.language.json.length; - i++ - ) { - var item = translate.service.edge.language.json[i]; - translate.service.edge.language.map[item.id] = item.serviceId; - } - } - return translate.service.edge.language.map; - }, - }, - /** - * edge 进行翻译。 这个传入参数跟 translate.request.post 是一样的 - * @param path 请求的path(path,传入的是translate.request.api.translate 这种的,需要使用 getUrl 来组合真正请求的url ) - * @param data 请求的参数数据 - * @param func 请求完成的回调,传入如 function(data){ console.log(data); } - */ - translate: (path, data, func, abnormalFunc) => { - var textArray = JSON.parse(decodeURIComponent(data.text)); - const translateTextArray = translate.util.split(textArray, 40000, 900); - - translate.request.send( - translate.service.edge.api.auth, - {}, - {}, - (auth) => { - var appendXhrData = { - from: data.from + "", - to: data.to, - text: data.text, - }; - var from = data.from; - if (from != "auto") { - if (from == "romance") { - //这里额外加了一个罗曼语族(romance)会自动认为是法语(fr) - from = "fr"; - } else { - from = translate.service.edge.language.getMap()[data.from]; - } - } - - var to = translate.service.edge.language.getMap()[data.to]; - var transUrl = translate.service.edge.api.translate - .replace("{from}", from) - .replace("{to}", to); - - //如果翻译量大,要拆分成多次翻译请求 - for (var tai = 0; tai < translateTextArray.length; tai++) { - var json = []; - for (var i = 0; i < translateTextArray[tai].length; i++) { - json.push({ Text: translateTextArray[tai][i] }); - } - - translate.request.send( - transUrl, - JSON.stringify(json), - appendXhrData, - (result) => { - var d = {}; - d.info = "SUCCESS"; - d.result = 1; - d.from = data.from; - d.to = data.to; - d.text = []; - for (var t = 0; t < result.length; t++) { - d.text.push(result[t].translations[0].text); - } - - //判断当前翻译是否又被拆分过,比如一次超过5万字符的话就要拆分成多次请求了 - if (translateTextArray.length > 1) { - //这一次翻译呗拆分了多次请求,那么要进行补全数组,使数组个数能一致 - - /* - - 注意这里根据数组的长度来判断当前属于第几个数组, - 有几率会是拆分的数组,其中有两组的长度是一样的, - 这样的话是有问题的,只不过几率很小,就先这样了 - 但终归还是留了个坑 -- 记录 - - */ - - var currentIndex = -1; //当前翻译请求属于被拆分的第几个的数组下标,从0开始的 - for (var cri = 0; cri < translateTextArray.length; cri++) { - if (translateTextArray[cri].length - d.text.length == 0) { - currentIndex = cri; - break; - } - } - - //进行对前后进行补齐数组 - if (currentIndex < 0) { - console.log("------ERROR--------"); - console.log( - "翻译内容过多,进行拆分,但拆分判断出现异常,currentIndex:-1 请联系 http://translate.zvo.cn/43006.html 说明", - ); - } - //前插入空数组填充 - for ( - var addbeforei = 0; - addbeforei < currentIndex; - addbeforei++ - ) { - var beforeItemArrayLength = - translateTextArray[addbeforei].length; - //console.log('beforeItemArrayLength:'+beforeItemArrayLength); - for (var bi = 0; bi < beforeItemArrayLength; bi++) { - d.text.unshift(null); - } - } - //后插入空数组填充 - for ( - var addafteri = translateTextArray.length - 1; - addafteri > currentIndex; - addafteri-- - ) { - var afterItemArrayLength = - translateTextArray[addafteri].length; - for (var bi = 0; bi < afterItemArrayLength; bi++) { - d.text.push(null); - } - } - } - - func(d); - }, - "post", - true, - { - Authorization: "Bearer " + auth, - "Content-Type": "application/json", - }, - abnormalFunc, - true, - ); - } - //console.log('translateResultArray') - //console.log(translateResultArray); - }, - "get", - true, - { "content-type": "application/x-www-form-urlencoded" }, - (xhr) => { - console.log("---------error--------"); - console.log( - "edge translate service error, http code : " + - xhr.status + - ", response text : " + - xhr.responseText, - ); - }, - true, - ); - }, - }, - /*js translate.service.edge end*/ - }, - //request请求来源于 https://github.com/xnx3/request - request: { - //相关API接口方面 - api: { - /** - * 翻译接口请求的域名主机 host - * 格式注意前面要带上协议如 https:// 域名后要加 / - * v2.8.2 增加数组形态,如 ['https://api.translate.zvo.cn/','xxxxx'] - */ - //host:'https://api.translate.zvo.cn/', - host: [ - "https://api.translate.zvo.cn/", - "https://america.api.translate.zvo.cn/", - ], - //host的备用接口,格式同host,可以填写多个,只不过这里是数组格式。只有当主 host 无法连通时,才会采用备host来提供访问。如果为空也就是 [] 则是不采用备方案。 - //backupHost:['',''], - language: "language.json", //获取支持的语种列表接口 - translate: "translate.json", //翻译接口 - ip: "ip.json", //根据用户当前ip获取其所在地的语种 - connectTest: "connectTest.json", //用于 translate.js 多节点翻译自动检测网络连通情况 - init: "init.json", //获取最新版本号,跟当前版本进行比对,用于提醒版本升级等使用 - }, - /* - 追加参数, v3.15.9.20250527 增加 - 所有通过 translate.request.send 进行网络请求的,都会追加上这个参数 - 默认是空,没有任何追加参数。 - - 设置方式: https://translate.zvo.cn/471711.html - translate.request.appendParams = { - key1:'key1', - key2:'key2' - } - */ - appendParams: {}, - /* - 追加header头的参数, v3.15.13 增加 - 所有通过 translate.request.send 进行网络请求的,都会追加上这个参数 - 默认是空,没有任何追加参数。 - - 设置方式: https://translate.zvo.cn/471711.html - translate.request.appendHeaders = { - key1:'key1', - Aauthorization:'Bearer xxxxxxxxxx' - } - */ - appendHeaders: {}, - /* - 请求后端接口的响应。无论是否成功,都会触发此处。 - 另外当 xhr.readyState==4 的状态时才会触发。 - 此处会在接口请求响应后、且在translate.js处理前就会触发 - @param xhr XMLHttpRequest 接口请求 - - */ - response: (xhr) => { - //console.log('response------'); - //console.log(xhr); - }, - - /* - 速度检测控制中心, 检测主备翻译接口的响应速度进行排列,真正请求时,按照排列的顺序进行请求 - v2.8.2增加 - - storage存储方面 - storage存储的key 存的什么 - speedDetectionControl_hostQueue hostQueue - speedDetectionControl_hostQueueIndex 当前要使用的是 hostQueue 中的数组下标。如果没有,这里默认视为0 - speedDetectionControl_lasttime 最后一次执行速度检测的时间戳,13位时间戳 - - - - */ - speedDetectionControl: { - /* - - 进行 connect主节点缩减的时间,单位是毫秒. - 这个是进行 translate.request.speedDetectionControl.checkResponseSpeed() 节点测速时,translate.request.api.host 第一个元素是默认的主节点。 - 主节点在实际测速完后,会减去一定的时间,以便让用户大部分时间可以使用主节点,而不必走分节点。 - 例如主节点实际响应速度 3500 毫秒,那么会减去这里设置的2000毫秒,记为 1500 毫秒 - 当然如果是小于这里设置的2000毫秒,那么会记为0毫秒。 - 这样再跟其他分节点的响应时间进行对比,主节点只要不是响应超时,就会有更大的几率被选中为实际使用的翻译的节点 - - 这里的单位是毫秒。 - v2.10.2.20231225 增加 - */ - hostMasterNodeCutTime: 2000, - - /* - 翻译的队列,这是根据网络相应的速度排列的,0下标为请求最快,1次之... - 其格式为: - [ - { - "host":"xxxxxxxx", - "time":123 //这里的单位是毫秒 - }, - { - "host":"xxxxxxxx", - "time":123 //这里的单位是毫秒 - } - ] - */ - hostQueue: [], - hostQueueIndex: -1, //当前使用的 hostQueue的数组下标, -1表示还未初始化赋予值,不可直接使用,通过 getHostQueueIndex() 使用 - disableTime: 1000000, //不可用的时间,storage中存储的 speedDetectionControl_hostQueue 其中 time 这里,如果值是 这个,便是代表这个host处于不可用状态 - - /* - 设置当前使用的翻译通道 host - 适用于 进行中时,中途切临时换翻译通道。 - */ - setCurrentHost: (host) => { - translate.storage.set("speedDetectionControl_hostQueue", ""); - translate.request.api.host = host; - translate.request.speedDetectionControl.checkHostQueue = []; - translate.request.speedDetectionControl.checkResponseSpeed_Storage( - host, - 0, - ); - }, - - //获取 host queue 队列 - getHostQueue: () => { - if (translate.request.speedDetectionControl.hostQueue.length == 0) { - //还没有,先从本地存储中取,看之前是否已经设置过了 - // 只有经过真正的网络测速后,才会加入 storage 的 hostQueue - var storage_hostQueue = translate.storage.get( - "speedDetectionControl_hostQueue", - ); - if ( - storage_hostQueue == null || - typeof storage_hostQueue == "undefined" || - storage_hostQueue == "" - ) { - //本地存储中没有,也就是之前没设置过,是第一次用,那么直接讲 translate.request.api.host 赋予之 - //translate.request.api.host - - if (typeof translate.request.api.host == "string") { - //单个,那么赋予数组形式 - //translate.request.speedDetectionControl.hostQueue = [{"host":translate.request.api.host, time:0 }]; - translate.request.api.host = ["" + translate.request.api.host]; - } - - //数组形态,多个,v2.8.2 增加多个,根据优先级返回 - translate.request.speedDetectionControl.hostQueue = []; - for (var i = 0; i < translate.request.api.host.length; i++) { - var h = translate.request.api.host[i]; - //console.log(h); - translate.request.speedDetectionControl.hostQueue[i] = { - host: h, - time: 0, - }; - } - //console.log(translate.request.speedDetectionControl.hostQueue); - } else { - //storage中有,那么赋予 - translate.request.speedDetectionControl.hostQueue = - JSON.parse(storage_hostQueue); - //console.log(storage_hostQueue); - //console.log(translate.request.speedDetectionControl.hostQueue[0].time); - } - - //console.log(translate.request.speedDetectionControl.hostQueue) - - /* - 当页面第一次打开初始化这个时才会进行测速,另外测速也是要判断时间的,五分钟一次 - 进行测速 - */ - var lasttime = translate.storage.get( - "speedDetectionControl_lasttime", - ); - if (lasttime == null || typeof lasttime == "undefined") { - lasttime = 0; - } - var updateTime = 60000; //1分钟检测一次 - if (new Date().getTime() - lasttime > updateTime) { - translate.request.speedDetectionControl.checkResponseSpeed(); - } - } - - return translate.request.speedDetectionControl.hostQueue; - }, - - /* - 服务于 checkResponseSpeed 用于将测试结果存入 storage - time: 当前接口请求的耗时,单位是毫秒。如果是 1000000 那么表示这个接口不可用 - */ - checkResponseSpeed_Storage: (host, time) => { - translate.request.speedDetectionControl.checkHostQueue.push({ - host: host, - time: time, - }); - //按照time进行排序 - translate.request.speedDetectionControl.checkHostQueue.sort( - (a, b) => a.time - b.time, - ); - - //存储到 storage 持久化 - translate.storage.set( - "speedDetectionControl_hostQueue", - JSON.stringify( - translate.request.speedDetectionControl.checkHostQueue, - ), - ); - translate.storage.set( - "speedDetectionControl_lasttime", - new Date().getTime(), - ); - - translate.request.speedDetectionControl.hostQueue = - translate.request.speedDetectionControl.checkHostQueue; - }, - - //测试响应速度 - checkResponseSpeed: () => { - var headers = { - "content-type": "application/x-www-form-urlencoded", - }; - - if ( - typeof translate.request.api.connectTest != "string" || - translate.request.api.connectTest == null || - translate.request.api.connectTest.length < 1 - ) { - return; - } - - translate.request.speedDetectionControl.checkHostQueue = []; //用于实际存储 - translate.request.speedDetectionControl.checkHostQueueMap = []; //只是map,通过key取值,无其他作用 - - if (typeof translate.request.api.host == "string") { - //单个,那么赋予数组形式 - translate.request.api.host = ["" + translate.request.api.host]; - } - - for (var i = 0; i < translate.request.api.host.length; i++) { - var host = translate.request.api.host[i]; - // 获取当前时间的时间戳 - translate.request.speedDetectionControl.checkHostQueueMap[host] = { - start: new Date().getTime(), - }; - - try { - translate.request.send( - host + translate.request.api.connectTest, - { host: host }, - { host: host }, - (data) => { - var host = data.info; - var map = - translate.request.speedDetectionControl.checkHostQueueMap[ - host - ]; - var time = new Date().getTime() - map.start; - - if (translate.request.api.host[0] == host) { - //console.log('如果是第一个,那么是主的,默认允许缩减2000毫秒,也就是优先使用主的'); - time = - time - - translate.request.speedDetectionControl - .hostMasterNodeCutTime; - if (time < 0) { - time = 0; - } - } - - translate.request.speedDetectionControl.checkResponseSpeed_Storage( - host, - time, - ); - /* - translate.request.speedDetectionControl.checkHostQueue.push({"host":host, "time":time }); - //按照time进行排序 - translate.request.speedDetectionControl.checkHostQueue.sort((a, b) => a.time - b.time); - - //存储到 storage 持久化 - translate.storage.set('speedDetectionControl_hostQueue',JSON.stringify(translate.request.speedDetectionControl.checkHostQueue)); - translate.storage.set('speedDetectionControl_lasttime', new Date().getTime()); - - translate.request.speedDetectionControl.hostQueue = translate.request.speedDetectionControl.checkHostQueue; - //console.log(translate.request.speedDetectionControl.hostQueue); - */ - }, - "post", - true, - headers, - (data) => { - //translate.request.speedDetectionControl.checkResponseSpeed_Storage(host, time); - var hostUrl = data.requestURL.replace( - translate.request.api.connectTest, - "", - ); - translate.request.speedDetectionControl.checkResponseSpeed_Storage( - hostUrl, - translate.request.speedDetectionControl.disableTime, - ); - }, - false, - ); - } catch (e) { - //console.log('e0000'); - console.log(e); - //time = 300000; //无法连接的,那么赋予 300 秒吧 - } - } - }, - - //获取当前使用的host的数组下标 - getHostQueueIndex: () => { - if (translate.request.speedDetectionControl.hostQueueIndex < 0) { - //页面当前第一次使用,赋予值 - //先从 storage 中取 - var storage_index = translate.storage.get( - "speedDetectionControl_hostQueueIndex", - ); - if (typeof storage_index == "undefined" || storage_index == null) { - //存储中不存在,当前用户(浏览器)第一次使用,默认赋予0 - translate.request.speedDetectionControl.hostQueueIndex = 0; - translate.storage.set("speedDetectionControl_hostQueueIndex", 0); - } else { - translate.request.speedDetectionControl.hostQueueIndex = - storage_index; - } - } - return translate.request.speedDetectionControl.hostQueueIndex; - }, - - //获取当前要使用的host - getHost: () => { - var queue = translate.request.speedDetectionControl.getHostQueue(); - //console.log(queue); - var queueIndex = - translate.request.speedDetectionControl.getHostQueueIndex(); - if (queue.length > queueIndex) { - //正常,没有超出越界 - } else { - //异常,下标越界了!,固定返回最后一个 - console.log("异常,下标越界了!index:" + queueIndex); - queueIndex = queue.length - 1; - } - //console.log(queueIndex); - return queue[queueIndex].host; - }, - }, - //生成post请求的url - getUrl: (path) => { - var currentHost = translate.request.speedDetectionControl.getHost(); - var url = currentHost + path + "?v=" + translate.version; - //console.log('url: '+url); - return url; - }, - /** - * post请求 - * @param path 请求的path(path,传入的是translate.request.api.translate 这种的,需要使用 getUrl 来组合真正请求的url ) - * @param data 请求的参数数据,传入如 - * { - * from: "chinese_simplified", - * text: "%5B%22%E4%BD%A0%E5%A5%BD%EF%BC%8C%E6%88%91", - * to: "chinese_traditional - * } - * - * @param func 请求完成的回调,传入如 function(data){ console.log(data); } - * @param abnormalFunc 响应异常所执行的方法,响应码不是200就会执行这个方法 ,传入如 function(xhr){} 另外这里的 xhr 会额外有个参数 xhr.requestURL 返回当前请求失败的url - */ - post: function (path, data, func, abnormalFunc) { - var headers = { - "content-type": "application/x-www-form-urlencoded", - }; - if (typeof data == "undefined") { - return; - } - - //企业级翻译自动检测 - if (typeof translate.enterprise != "undefined") { - translate.enterprise.automaticAdaptationService(); - } - - // ------- edge start -------- - var url = translate.request.getUrl(path); - //if(url.indexOf('edge') > -1 && path == translate.request.api.translate){ - if (translate.service.name == "client.edge") { - if (path == translate.request.api.translate) { - translate.service.edge.translate(path, data, func, abnormalFunc); - return; - } - if (path == translate.request.api.language) { - var d = {}; - d.info = "SUCCESS"; - d.result = 1; - d.list = translate.service.edge.language.json; - func(d); - return; - } - - //return; - } - // ------- edge end -------- - - this.send( - path, - data, - data, - func, - "post", - true, - headers, - abnormalFunc, - true, - ); - }, - /** - * 发送请求 - * url 请求的url或者path(path,传入的是translate.request.api.translate 这种的,需要使用 getUrl 来组合真正请求的url ) - * data 请求的数据,如 {"author":"管雷鸣",'site':'www.guanleiming.com'} - * appendXhrData 附加到 xhr.data 中的对象数据,传入比如 {"from":"english","to":"japanese"} ,他会直接赋予 xhr.data - * func 请求完成的回调,传入如 function(data){} - * method 请求方式,可传入 post、get - * isAsynchronize 是否是异步请求, 传入 true 是异步请求,传入false 是同步请求。 如果传入false,则本方法返回xhr - * headers 设置请求的header,传入如 {'content-type':'application/x-www-form-urlencoded'}; - * abnormalFunc 响应异常所执行的方法,响应码不是200就会执行这个方法 ,传入如 function(xhr){} 另外这里的 xhr 会额外有个参数 xhr.requestURL 返回当前请求失败的url - * showErrorLog 是否控制台打印出来错误日志,true打印, false 不打印 - */ - send: ( - url, - data, - appendXhrData, - func, - method, - isAsynchronize, - headers, - abnormalFunc, - showErrorLog, - ) => { - //post提交的参数 - var params = ""; - - if (data == null || typeof data == "undefined") { - data = {}; - } - - if (typeof data == "string") { - params = data; //payload 方式 , edge 的方式 - } else { - //表单提交方式 - - //加入浏览器默认语种 v3.6.1 增加,以便更好的进行自动切换语种 - data.browserDefaultLanguage = translate.util.browserDefaultLanguage(); - - //追加附加参数 - for (var apindex in translate.request.appendParams) { - if (!Object.hasOwn(translate.request.appendParams, apindex)) { - continue; - } - data[apindex] = translate.request.appendParams[apindex]; - } - - if (typeof translate.enterprise != "undefined") { - //加入key - if ( - typeof translate.enterprise.key != "undefined" && - typeof translate.enterprise.key == "string" && - translate.enterprise.key.length > 0 - ) { - data.key = translate.enterprise.key; - } - } - - //组合参数 - for (var index in data) { - if (!Object.hasOwn(data, index)) { - continue; - } - if (params.length > 0) { - params = params + "&"; - } - params = params + index + "=" + data[index]; - } - } - - if (url.indexOf("https://") == 0 || url.indexOf("http://") == 0) { - //采用的url绝对路径 - } else { - //相对路径,拼接上host - url = translate.request.getUrl(url); - } - - var xhr = null; - try { - xhr = new XMLHttpRequest(); - } catch (e) { - xhr = new ActiveXObject("Microsoft.XMLHTTP"); - } - xhr.data = appendXhrData; - //2.调用open方法(true----异步) - xhr.open(method, url, isAsynchronize); - //设置headers - if (headers != null) { - for (var index in headers) { - if (!Object.hasOwn(headers, index)) { - continue; - } - xhr.setRequestHeader(index, headers[index]); - } - } - - //追加附加参数 - for (var ahindex in translate.request.appendHeaders) { - if (!Object.hasOwn(translate.request.appendHeaders, ahindex)) { - continue; - } - xhr.setRequestHeader(ahindex, translate.request.appendHeaders[ahindex]); - } - - if (translate.service.name == "translate.service") { - xhr.setRequestHeader("currentpage", window.location.href + ""); - } - xhr.send(params); - //4.请求状态改变事件 - xhr.onreadystatechange = () => { - if (xhr.readyState == 4) { - translate.request.response(xhr); //自定义响应的拦截 - - if (xhr.status == 200) { - //请求正常,响应码 200 - var json = null; - if ( - typeof xhr.responseText == "undefined" || - xhr.responseText == null - ) { - //相应内容为空 - } else { - //响应内容有值 - if ( - xhr.responseText.indexOf("{") > -1 && - xhr.responseText.indexOf("}") > -1 - ) { - //应该是json格式 - try { - json = JSON.parse(xhr.responseText); - } catch (e) { - console.log(e); - } - } - } - - if (json == null) { - func(xhr.responseText); - } else { - func(json); - } - } else { - if (showErrorLog) { - if (url.indexOf(translate.request.api.connectTest) > -1) { - //测试链接速度的不在报错里面 - } else { - //判断是否是v2版本的翻译,如果是 translate.service 模式并且没有使用企业级翻译,参会提示 - //2024.3月底开始,翻译使用量增加的太快,开源的翻译服务器有点扛不住经常出故障,所以直接把这个提示加到这里 - if (translate.service.name == "translate.service") { - console.log( - "----- translate.js 提示 -----\n翻译服务响应异常,解决这种情况可以有两种方案:\n【方案一】:使用采用最新版本 3.16.0及更高版本,js引用文件为 https://cdn.staticfile.net/translate.js/3.16.0/translate.js 并且使用 client.edge 模式 (增加一行设置代码就好,可参考 https://translate.zvo.cn/4081.html ),这样就不会再出现这种情况了,而且这个方案也是完全免费的。 \n【方案二】:采用企业级稳定翻译通道 ,但是这个相比于 方案一 来说,是有一定的收费的,大概一年600,这个就是专门为了高速及高稳定准备的,而相比于这个方案二,方案一则是全免费的。 因为方案二我们是部署了两个集群,而每个集群又下分了数个网络节点,包含中国大陆、香港、美国、欧洲、 等多个州,充分保障稳定、高效,同样也产生了不少成本,所以才需要付费。更多信息说明可以参考: http://translate.zvo.cn/4087.html \n【方案三】:私有部署你自己的翻译通道,并且启用内存级翻译缓存,毫秒级响应,但是需要依赖一台1核2G服务器,是最推荐的方式。具体参考:https://translate.zvo.cn/391129.html\n-------------", - ); - } - - //console.log(xhr); - console.log( - "------- translate.js service api response error --------", - ); - console.log(" http code : " + xhr.status); - console.log(" response : " + xhr.response); - console.log(" request url : " + url); - console.log(" request data : " + JSON.stringify(data)); - console.log(" request method : " + method); - console.log( - "---------------------- end ----------------------", - ); - } - } - xhr.requestURL = url; - if (abnormalFunc != null) { - abnormalFunc(xhr); - } - } - } - }; - return xhr; - }, - /* - - 手动进行翻译操作。参数说明: - texts: 可传入要翻译的文本、以及文本数组。 比如要一次翻译多个句子,那就可以传入数组的方式 - function: 翻译完毕后的处理函数。传入如 function(data){ console.log(data); } - 注意,返回的data.result 为 1,则是翻译成功。 为0则是出错,可通过data.info 得到错误原因。 更详细说明参考: http://api.zvo.cn/translate/service/20230807/translate.json.html - - 使用案例一: - translate.request.translateText('你好,我是翻译的内容', function(data){ - //打印翻译结果 - console.log(data); - }); - - 使用案例二: - var texts = ['我是翻译的第一句','我是翻译的第二句','我是翻译的第三句']; - translate.request.translateText(texts, function(data){ - //打印翻译结果 - console.log(data); - }); - - 使用案例三: - var obj = { - from:'chinese_simplified', - to:'english', - texts: ['我是翻译的第一句','我是翻译的第二句','我是翻译的第三句'] - } - translate.request.translateText(obj, function(data){ - //打印翻译结果 - console.log(data); - }); - */ - translateText: (obj, func) => { - var texts = []; - var from = translate.language.getLocal(); - var to = translate.language.getCurrent(); - - if (typeof obj == "string") { - //案例一的场景,传入单个字符串 - texts[0] = obj; - } else { - //不是字符串了,而是对象了,判断是案例二还是案例三 - - var type = Object.prototype.toString.call(obj); - //console.log(type); - if (type == "[object Array]") { - //案例二 - texts = obj; - } else if (type == "[object Object]") { - //案例三 - if (typeof obj.texts == "undefined") { - console.log( - "translate.request.translateText 传入的值类型异常,因为你没有传入 obj.texts 要翻译的具体文本! 请查阅文档: https://translate.zvo.cn/4077.html", - ); - } - if (typeof obj.texts == "string") { - //单个字符串 - texts = [obj.texts]; - } else { - //多个字符串,数组形态 - texts = obj.texts; - } - if (typeof obj.from == "string" && obj.from.length > 0) { - from = obj.from; - } - if (typeof obj.to == "string" && obj.to.length > 0) { - to = obj.to; - } - } else { - console.log( - "translate.request.translateText 传入的值类型错误,请查阅文档: https://translate.zvo.cn/4077.html", - ); - return; - } - } - //console.log(obj); - //返回的翻译结果,下标跟 obj.texts 一一对应的 - var translateResultArray = []; - - // 筛选需要翻译的文本及其原始索引 - var apiTranslateText = []; - var apiTranslateArray = {}; - for (var i = 0; i < texts.length; i++) { - //判断是否在浏览器缓存中出现了 - var hash = translate.util.hash(texts[i]); - var cache = translate.storage.get("hash_" + to + "_" + hash); - //console.log(hash+'\t'+texts[i]+'\t'+cache); - if (cache != null && cache.length > 0) { - //缓存中发现了这个得结果,那这个就不需要再进行翻译了 - translateResultArray[i] = cache; - } else { - translateResultArray[i] = ""; - apiTranslateText.push(texts[i]); - apiTranslateArray[hash] = i; - } - } - if (apiTranslateText.length == 0) { - //没有需要进行通过网络API翻译的任务了,全部命中缓存,那么直接返回 - var data = { - from: from, - to: to, - text: translateResultArray, - result: 1, - }; - //console.log(data); - func(data); - return; - } - - //还有需要进行通过API接口进行翻译的文本,需要调用翻译接口 - if ( - typeof translate.request.api.translate != "string" || - translate.request.api.translate == null || - translate.request.api.translate.length < 1 - ) { - //用户已经设置了不掉翻译接口进行翻译 - return; - } - - var url = translate.request.api.translate; - var data = { - from: from, - to: to, - text: encodeURIComponent(JSON.stringify(apiTranslateText)), - }; - //console.log(apiTranslateText); - translate.request.post( - url, - data, - (resultData) => { - //console.log(resultData); - //console.log(data); - if (resultData.result == 0) { - console.log("=======ERROR START======="); - console.log("from : " + resultData.from); - console.log("to : " + resultData.to); - console.log("translate text array : " + texts); - console.log("response : " + resultData.info); - console.log("=======ERROR END ======="); - //return; - } - - for (var i = 0; i < resultData.text.length; i++) { - //将翻译结果以 key:hash value翻译结果的形式缓存 - var hash = translate.util.hash(apiTranslateText[i]); - translate.storage.set( - "hash_" + to + "_" + hash, - resultData.text[i], - ); - //如果离线翻译启用了全部提取,那么还要存入离线翻译指定存储 - if (translate.office.fullExtract.isUse) { - translate.office.fullExtract.set( - hash, - apiTranslateText[i], - data.to, - resultData.text[i], - ); - } - - //进行组合数据到 translateResultArray - translateResultArray[apiTranslateArray[hash]] = resultData.text[i]; - } - resultData.text = translateResultArray; - - func(resultData); - }, - null, - ); - }, - listener: { - minIntervalTime: 800, // 两次触发的最小间隔时间,单位是毫秒,这里默认是800毫秒。最小填写时间为 200毫秒 - lasttime: 0, // 最后一次触发执行 translate.execute() 的时间,进行执行的那一刻,而不是执行完。13位时间戳 - /* - 设置要在未来的某一时刻执行,单位是毫秒,13位时间戳。 - 执行时如果当前时间大于这个数,则执行,并且将这个数置为0。 - 会有一个循环执行函数每间隔200毫秒触发一次 - */ - executetime: 0, - /* - 进行翻译时,延迟翻译执行的时间 - 当ajax请求结束后,延迟这里设置的时间,然后自动触发 translate.execute() 执行 - */ - delayExecuteTime: 200, - /* - 满足ajax出发条件,设置要执行翻译。 - 注意,设置这个后并不是立马就会执行,而是加入了一个执行队列,避免1秒请求了10次会触发10次执行的情况 - */ - addExecute: () => { - var currentTime = Date.now(); - if (translate.request.listener.lasttime == 0) { - //是第一次,lasttime还没设置过,那么直接设置执行时间为当前时间 - translate.request.listener.executetime = currentTime; - translate.request.listener.lasttime = 1; - } else { - //不是第一次了 - - if (translate.request.listener.executetime > 1) { - //当前有执行队列等待,不用再加入执行等待了 - //console.log('已在执行队列,不用再加入了 '+currentTime); - } else { - //执行队列中还没有,可以加入执行命令 - - if ( - currentTime < - translate.request.listener.lasttime + - translate.request.listener.minIntervalTime - ) { - //如果当前时间小于最后一次执行时间+间隔时间,那么就是上次才刚刚执行过,这次执行的太快了,那么赋予未来执行翻译的时间为最后一次时间+间隔时间 - translate.request.listener.executetime = - translate.request.listener.lasttime + - translate.request.listener.minIntervalTime; - //console.log('addexecute - < 如果当前时间小于最后一次执行时间+间隔时间,那么就是上次才刚刚执行过,这次执行的太快了,那么赋予未来执行翻译的时间为最后一次时间+间隔时间'); - } else { - translate.request.listener.executetime = currentTime; - //console.log('addexecute -- OK '); - } - } - } - }, - /* - 自定义是否会被触发的方法判断 - url 当前ajax请求的url,注意是这个url请求完毕获取到200相应的内容时才会触发此方法 - 返回值 return true; 默认是不管什么url,全部返回true,表示会触发翻译自动执行 translate.execute; ,如果你不想让某个url触发翻译,那么你可以自行在这个方法中用代码进行判断,然后返回false,那么这个url将不会自动触发翻译操作。 - */ - trigger: (url) => true, - - /*js translate.request.listener.start start*/ - /* - 启动根据ajax请求来自动触发执行翻译,避免有时候有的框架存在漏翻译的情况。 - 这个只需要执行一次即可,如果执行多次,只有第一次会生效 - */ - start: () => { - //确保这个方法只会触发一次,不会过多触发 - if (typeof translate.request.listener.isStart != "undefined") { - return; - } - translate.request.listener.isStart = true; - - //增加一个没100毫秒检查一次执行任务的线程 - setInterval(() => { - var currentTime = Date.now(); - if ( - translate.request.listener.executetime > 1 && - currentTime > - translate.request.listener.executetime + - translate.request.listener.delayExecuteTime - ) { - translate.request.listener.executetime = 0; - translate.request.listener.lasttime = currentTime; - try { - //console.log('执行翻译 --'+currentTime); - translate.execute(); - } catch (e) { - console.log(e); - } - } - }, 100); - if (typeof PerformanceObserver == "undefined") { - console.log( - "因浏览器版本较低, translate.request.listener.start() 中 PerformanceObserver 对象不存在,浏览器不支持,所以 translate.request.listener.start() 未生效。", - ); - return; - } - - const observer = new PerformanceObserver((list) => { - var translateExecute = false; //是否需要执行翻译 true 要执行 - for (var e = 0; e < list.getEntries().length; e++) { - var entry = list.getEntries()[e]; - - if ( - entry.initiatorType === "fetch" || - entry.initiatorType === "xmlhttprequest" - ) { - var url = entry.name; - //console.log(url); - //判断url是否是当前translate.js本身使用的 - if (typeof translate.request.api.host == "string") { - translate.request.api.host = [translate.request.api.host]; - } - var ignoreUrl = false; // 是否是忽略的url true是 - - //translate.service 模式判断 - for (var i = 0; i < translate.request.api.host.length; i++) { - if (url.indexOf(translate.request.api.host[i]) > -1) { - //是,那么直接忽略 - ignoreUrl = true; - break; - } - } - //client.edge 判断 translate.service.edge可能会被精简translate.js定制时给直接干掉,所以提前加个判断 - if ( - typeof translate.service.edge != "undefined" && - url.indexOf(translate.service.edge.api.auth) > -1 - ) { - ignoreUrl = true; - } - if (url.indexOf(".microsofttranslator.com/translate") > -1) { - ignoreUrl = true; - } - - if (ignoreUrl) { - //console.log('忽略:'+url); - continue; - } - if (translate.request.listener.trigger()) { - //正常,会触发翻译,也是默认的 - } else { - //不触发翻译,跳过 - continue; - } - - translateExecute = true; - break; - } - } - if (translateExecute) { - //console.log('translate.request.listener.addExecute() -- '+Date.now()); - translate.request.listener.addExecute(); - } - }); - - //v3.15.14.20250617 增加 - // 优先使用 entryTypes 兼容 ES5 的写法 - - var supportedTypes = PerformanceObserver.supportedEntryTypes; - if (supportedTypes) { - var hasResource = false; - for (var i = 0; i < supportedTypes.length; i++) { - if (supportedTypes[i] === "resource") { - hasResource = true; - break; - } - } - if (hasResource) { - try { - observer.observe({ entryTypes: ["resource"] }); - return; - } catch (e) { - console.log( - "PerformanceObserver entryTypes 失败,尝试 type 参数", - ); - } - } - } - - // 回退到 type 参数 - try { - observer.observe({ type: "resource", buffered: true }); - console.log("使用 PerformanceObserver type"); - } catch (e) { - console.log( - "当前浏览器不支持 PerformanceObserver 的任何参数, translate.request.listener.start() 未启动", - ); - } - }, - /*js translate.request.listener.start end*/ - }, - }, - //存储,本地缓存 - storage: { - /*js translate.storage.IndexedDB start*/ - //对浏览器的 IndexedDB 操作 - IndexedDB: { - db: null, - // 初始化数据库 - initDB: function () { - return new Promise((resolve, reject) => { - const DB_NAME = "translate.js"; - const STORE_NAME = "kvStore"; - const DB_VERSION = 1; - - const request = indexedDB.open(DB_NAME, DB_VERSION); - - request.onupgradeneeded = (event) => { - const upgradedDb = event.target.result; - if (!upgradedDb.objectStoreNames.contains(STORE_NAME)) { - upgradedDb.createObjectStore(STORE_NAME, { keyPath: "key" }); - } - }; - - request.onsuccess = (event) => { - this.db = event.target.result; - resolve(); - }; - - request.onerror = (event) => { - reject("IndexedDB 打开失败"); - }; - }); - }, - /* - 存储键值对 - 使用方式: - await translate.storage.indexedDB.set("user_001", { name: "Alice" }); - */ - set: async function (key, value) { - if (!this.db) await this.initDB(); - - return new Promise((resolve, reject) => { - const tx = this.db.transaction("kvStore", "readwrite"); - const store = tx.objectStore("kvStore"); - const item = { key, value }; - const request = store.put(item); - - request.onsuccess = () => resolve(); - request.onerror = () => reject("写入失败"); - }); - }, - /* - 获取键对应的值 - 使用方式: - var user = await translate.storage.indexedDB.get("user_001"); - */ - get: async function (key) { - if (!this.db) await this.initDB(); - - return new Promise((resolve, reject) => { - const tx = this.db.transaction("kvStore", "readonly"); - const store = tx.objectStore("kvStore"); - const request = store.get(key); - - request.onsuccess = () => { - const result = request.result; - resolve(result ? result.value : undefined); - }; - - request.onerror = () => reject("读取失败"); - }); - }, - /* - 列出针对key进行模糊匹配的所有键值对 - 使用方式: - const users = await translate.storage.indexedDB.list("*us*r*"); - 其中传入的key可以模糊搜索,其中的 * 标识另个或多个 - */ - list: async function (key = "") { - if (!this.db) await this.initDB(); - - return new Promise((resolve, reject) => { - const tx = this.db.transaction("kvStore", "readonly"); - const store = tx.objectStore("kvStore"); - const request = store.openCursor(); - const results = []; - - // 将通配符 pattern 转换为正则表达式 - const regexStr = "^" + key.replace(/\*/g, ".*") + "$"; - const regex = new RegExp(regexStr); - - request.onsuccess = (event) => { - const cursor = event.target.result; - if (cursor) { - if (regex.test(cursor.key)) { - results.push({ key: cursor.key, value: cursor.value.value }); - } - cursor.continue(); - } else { - resolve(results); - } - }; - - request.onerror = () => reject("游标读取失败"); - }); - }, - }, - /*js translate.storage.IndexedDB end*/ - - set: (key, value) => { - localStorage.setItem(key, value); - }, - get: (key) => localStorage.getItem(key), - }, - //针对图片进行相关的语种图片替换 - images: { - /* 要替换的图片队列,数组形态,其中某个数组的: - key:"/uploads/allimg/160721/2-160H11URA25-lp.jpg"; //旧图片,也就是原网站本身的图片。也可以绝对路径,会自动匹配 img src 的值,匹配时会进行完全匹配 - value:"https://xxx.com/abc_{language}.jpg" //新图片,要被替换为的新图片。新图片路径需要为绝对路径,能直接访问到的。其中 {language} 会自动替换为当前要显示的语种。比如你要将你中文网站翻译为繁体中文,那这里会自动替换为:https://xxx.com/abc_chinese_traditional.jpg 有关{language}的取值,可查阅 http://api.translate.zvo.cn/doc/language.json.html 其中的语言标识id便是 - */ - queues: [], - - /* - 向图片替换队列中追加要替换的图片 - 传入格式如: - - translate.images.add({ - "/uploads/a.jpg":"https://www.zvo.cn/a_{language}.jpg", - "/uploads/b.jpg":"https://www.zvo.cn/b_{language}.jpg", - }); - - 参数说明: - key //旧图片,也就是原网站本身的图片。也可以绝对路径,会自动匹配 img src 的值,匹配时会进行完全匹配 - value //新图片,要被替换为的新图片。新图片路径需要为绝对路径,能直接访问到的。其中 {language} 会自动替换为当前要显示的语种。比如你要将你中文网站翻译为繁体中文,那这里会自动替换为:https://xxx.com/abc_chinese_traditional.jpg 有关{language}的取值,可查阅 http://api.translate.zvo.cn/doc/language.json.html 其中的语言标识id便是 - */ - add: (queueArray) => { - /* - translate.images.queues[translate.images.queues.length] = { - old:oldImage, - new:newImage - } - */ - for (var key in queueArray) { - if (!Object.hasOwn(queueArray, key)) { - continue; - } - translate.images.queues[key] = queueArray[key]; - } - }, - //执行图片替换操作,将原本的图片替换为跟翻译语种一样的图片 - execute: () => { - //console.log(translate.images.queues); - if (Object.keys(translate.images.queues).length < 1) { - //如果没有,那么直接取消图片的替换扫描 - return; - } - - /*** 寻找img标签中的图片 ***/ - var imgs = document.getElementsByTagName("img"); - for (var i = 0; i < imgs.length; i++) { - var img = imgs[i]; - if ( - typeof img.src == "undefined" || - img.src == null || - img.src.length == 0 - ) { - continue; - } - var imgSrc = img.getAttribute("src"); //这样获取到的才是src原始的值,不然 img.src 是拿到一个绝对路径 - - for (var key in translate.images.queues) { - var oldImage = key; //原本的图片src - var newImage = translate.images.queues[key]; //新的图片src,要替换为的 - //console.log('queue : '+oldImage + ' , img.src: '+imgSrc); - if (oldImage == imgSrc) { - //console.log('发现匹配图片:'+imgSrc); - /* - //判断当前元素是否在ignore忽略的tag、id、class name中 - if(translate.ignore.isIgnore(node)){ - console.log('node包含在要忽略的元素中:'); - console.log(node); - continue; - } - */ - - //没在忽略元素里,可以替换 - newImage = newImage.replace(/{language}/g, translate.to); - img.src = newImage; - } - } - } - - /********** 还要替换style中的背景图 */ - // 获取当前网页中所有的元素 - var elems = document.getElementsByTagName("*"); - // 遍历每个元素,检查它们是否有背景图 - for (var i = 0; i < elems.length; i++) { - var elem = elems[i]; - // 获取元素的计算后样式 - var style = window.getComputedStyle(elem, null); - // 获取元素的背景图URL - var bg = style.backgroundImage; - // 如果背景图不为空,打印出来 - if (bg != "none") { - //console.log(bg); - var old_img = translate.images.gainCssBackgroundUrl(bg); - //console.log("old_img:"+old_img); - if (typeof translate.images.queues[old_img] != "undefined") { - //存在 - var newImage = translate.images.queues[old_img]; - newImage = newImage.replace(/{language}/g, translate.to); - //更换翻译指定图像 - elem.style.backgroundImage = 'url("' + newImage + '")'; - } else { - //console.log('发现图像'+old_img+', 但未做语种适配'); - } - } - } - }, - //取css中的背景图,传入 url("https://xxx.com/a.jpg") 返回里面单纯的url - gainCssBackgroundUrl: (str) => { - // 使用indexOf方法,找到第一个双引号的位置 - var start = str.indexOf('"'); - // 使用lastIndexOf方法,找到最后一个双引号的位置 - var end = str.lastIndexOf('"'); - // 如果找到了双引号,使用substring方法,截取中间的内容 - if (start != -1 && end != -1) { - var url = str.substring(start + 1, end); // +1是为了去掉双引号本身 - //console.log(url); // https://e-assets.gitee.com/gitee-community-web/_next/static/media/mini_app.2e6b6d93.jpg!/quality/100 - return url; - } - return str; - }, - }, - /*js translate.reset start*/ - //对翻译结果进行复原。比如当前网页是简体中文的,被翻译为了英文,执行此方法即可复原为网页本身简体中文的状态,而无需在通过刷新页面来实现 - reset: () => { - var currentLanguage = translate.language.getCurrent(); //获取当前翻译至的语种 - - var lastUuid = ""; //最后一次的uuid - for (var queue in translate.nodeQueue) { - if (!Object.hasOwn(translate.nodeQueue, queue)) { - continue; - } - lastUuid = queue; - } - //console.log(queue); - - if (lastUuid == "") { - console.log( - "提示,你当前还未执行过翻译,所以你无需执行 translate.reset(); 进行还原。", - ); - return; - } - - for (var lang in translate.nodeQueue[lastUuid].list) { - if (!Object.hasOwn(translate.nodeQueue[lastUuid].list, lang)) { - continue; - } - //console.log(lang); - - for (var hash in translate.nodeQueue[lastUuid].list[lang]) { - if (!Object.hasOwn(translate.nodeQueue[lastUuid].list[lang], hash)) { - continue; - } - var item = translate.nodeQueue[lastUuid].list[lang][hash]; - //console.log(item); - for (var index in item.nodes) { - if (!Object.hasOwn(item.nodes, index)) { - continue; - } - //console.log(item.nodes[index]); - //item.nodes[index].node.nodeValue = item.original; - var currentShow = translate.storage.get( - "hash_" + currentLanguage + "_" + hash, - ); //当前显示出来的文字,也就是已经翻译后的文字 - //console.log('hash_'+lang+'_'+hash+' -- '+currentShow); - if (typeof currentShow == "undefined") { - continue; - } - if (currentShow == null) { - continue; - } - if (currentShow.length == 0) { - continue; - } - /* - if(item.beforeText.length > 0 || item.afterText.length > 0){ - console.log('----'+currentShow); - console.log(item); - } - - if(item.beforeText.length > 0){ - currentShow = currentShow.substring(currentShow.lastIndexOf(item.beforeText)+1, currentShow.length); - } - if(item.afterText.length > 0){ - currentShow = currentShow.substring(0, currentShow.lastIndexOf(item.afterText)); - } - if(item.beforeText.length > 0 || item.afterText.length > 0){ - console.log(currentShow); - } -*/ - // v3.16.5 针对gitee 的 readme 接入优化 - if (typeof item.nodes[index].node == "undefined") { - continue; - } - - var attribute = - typeof item.nodes[index].node.attribute == "undefined" - ? null - : item.nodes[index].node.attribute; - var analyse = translate.element.nodeAnalyse.analyse( - item.nodes[index].node, - "", - "", - attribute, - ); - translate.element.nodeAnalyse.analyse( - item.nodes[index].node, - analyse.text, - item.original, - attribute, - ); - } - } - } - - //清除设置storage中的翻译至的语种 - translate.storage.set("to", ""); - translate.to = null; - //重新渲染select - translate.selectLanguageTag.render(); - }, - /*js translate.reset end*/ - - /*js translate.selectionTranslate start*/ - /* - 划词翻译,鼠标在网页中选中一段文字,会自动出现对应翻译后的文本 - 有网友 https://gitee.com/huangguishen 提供。 - 详细使用说明参见:http://translate.zvo.cn/41557.html - */ - selectionTranslate: { - selectionX: 0, - selectionY: 0, - callTranslate: (event) => { - const curSelection = window.getSelection(); - //相等认为没有划词 - if (curSelection.anchorOffset == curSelection.focusOffset) return; - const translateText = window.getSelection().toString(); - - //还有需要进行通过API接口进行翻译的文本,需要调用翻译接口 - if ( - typeof translate.request.api.translate != "string" || - translate.request.api.translate == null || - translate.request.api.translate.length < 1 - ) { - //用户已经设置了不掉翻译接口进行翻译 - console.log("已设置了不使用 translate 翻译接口,翻译请求被阻止"); - return; - } - - //简单Copy原有代码了 - var url = translate.request.api.translate; - var data = { - from: translate.language.getLocal(), - to: translate.to, - text: encodeURIComponent(JSON.stringify([translateText])), - }; - translate.request.post( - url, - data, - (data) => { - if (data.result == 0) return; - const curTooltipEle = document.querySelector("#translateTooltip"); - curTooltipEle.innerText = data.text[0]; - curTooltipEle.style.top = selectionY + 20 + "px"; - curTooltipEle.style.left = selectionX + 50 + "px"; - curTooltipEle.style.display = ""; - }, - null, - ); - }, - start: () => { - //新建一个tooltip元素节点用于显示翻译 - const tooltipEle = document.createElement("span"); - tooltipEle.innerText = ""; - tooltipEle.setAttribute("id", "translateTooltip"); - tooltipEle.setAttribute( - "style", - "background-color:black;color:#fff;text-align:center;border-radius:6px;padding:5px;position:absolute;z-index:999;top:150%;left:50%; ", - ); - //把元素节点添加到body元素节点中成为其子节点,放在body的现有子节点的最后 - document.body.appendChild(tooltipEle); - //监听鼠标按下事件,点击起始点位置作为显示翻译的位置点 - document.addEventListener( - "mousedown", - (event) => { - selectionX = event.pageX; - selectionY = event.pageY; - }, - false, - ); - //监听鼠标弹起事件,便于判断是否处于划词 - document.addEventListener( - "mouseup", - translate.selectionTranslate.callTranslate, - false, - ); - //监听鼠标点击事件,隐藏tooltip,此处可优化 - document.addEventListener( - "click", - (event) => { - document.querySelector("#translateTooltip").style.display = "none"; - }, - false, - ); - }, - }, - /*js translate.selectionTranslate end*/ - - /*js translate.enterprise start*/ - /* - 企业级翻译服务 - 注意,这个企业级翻译中的不在开源免费之中,企业级翻译服务追求的是高稳定,这个是收费的!详情可参考:http://translate.zvo.cn/43262.html - - */ - enterprise: { - //默认不启用企业级,除非设置了 translate.enterprise.use() 这里才会变成true - isUse: false, - use: () => { - translate.enterprise.isUse = true; //设置为使用企业级翻译服务 - - //主节点额外权重降低,更追求响应速度 - translate.request.speedDetectionControl.hostMasterNodeCutTime = 300; - translate.request.api.host = [ - "https://america-enterprise-api-translate.zvo.cn/", - "https://beijing.enterprise.api.translate.zvo.cn/", - "https://deutsch.enterprise.api.translate.zvo.cn/", - "https://america.api.translate.zvo.cn:666/", - "https://api.translate.zvo.cn:666/", - "https://api.translate.zvo.cn:888/", - ]; - - if (translate.service.name == "client.edge") { - translate.service.name = "translate.service"; - console.log( - "您已启用了企业级翻译通道 translate.enterprise.use(); (文档:https://translate.zvo.cn/4087.html) , 所以您设置的 translate.service.use('client.edge'); (文档:https://translate.zvo.cn/4081.html) 将失效不起作用,有企业级翻译通道全部接管。", - ); - return; - } - }, - /* - 自动适配翻译服务通道,如果当前所有网络节点均不可用,会自动切换到 edge.client 进行使用 - 这个会在 post请求 执行前开始时进行触发 - */ - automaticAdaptationService: () => { - if (!translate.enterprise.isUse) { - return; - } - var hosts = translate.request.speedDetectionControl.getHostQueue(); - //console.log(hosts); - if (hosts.length > 0) { - if ( - hosts[0].time + 1 > - translate.request.speedDetectionControl.disableTime - ) { - //所有节点都处于不可用状态,自动切换到 client.edge 模式 - translate.service.name = "client.edge"; - } - } - }, - /* 企业级翻译通道的key, v3.12.3.20250107 增加,针对打包成APP的场景 */ - key: "", - }, - /*js translate.enterprise end*/ - - /* - 如果使用的是 translate.service 翻译通道,那么翻译后的语种会自动以小写的方式进行显示。 - 如果你不想将翻译后的文本全部以小写显示,而是首字母大写,那么可以通过此方法设置一下 - v3.8.0.20240828 增加 - 目前感觉应该用不到,所以先忽略 - */ - /* - notConvertLowerCase:function(){ - - }, - */ - - /*js translate.init start*/ - /* - 初始化,如版本检测、初始数据加载等。 v2.11.11.20240124 增加 - 会自动在 translate.js 加载后的 200毫秒后 执行,进行初始化。同时也是节点测速 - */ - init: () => { - if (typeof translate.init_execute != "undefined") { - return; - } - translate.init_execute = "已进行"; - - if ( - typeof translate.request.api.init != "string" || - translate.request.api.init == null || - translate.request.api.init.length < 1 - ) { - return; - } - try { - translate.request.send( - translate.request.api.init, - {}, - {}, - (data) => { - if (data.result == 0) { - console.log("translate.js init 初始化异常:" + data.info); - return; - } - if (data.result == 1) { - //服务端返回的最新版本 - var newVersion = translate.util.versionStringToInt(data.version); - //当前translate.js的版本 - var currentVersion = translate.util.versionStringToInt( - translate.version.replace("v", ""), - ); - - if (newVersion > currentVersion) { - console.log( - "Tip : translate.js find new version : " + data.version, - ); - } - } - }, - "post", - true, - null, - (data) => { - //console.log('eeerrr'); - }, - false, - ); - } catch (e) {} - }, - /*js translate.init end*/ - - /*js translate.progress start*/ - /* - 翻译执行的进展相关 - 比如,浏览器本地缓存没有,需要走API接口的文本所在的元素区域,出现 记载中的动画蒙版,给用户以友好的使用提示 - */ - progress: { - style: ` - /* CSS部分 */ - /* 灰色水平加载动画 */ - .translate_api_in_progress { - position: relative; - overflow: hidden; /* 隐藏超出部分的动画 */ - } - - /* 蒙版层 */ - .translate_api_in_progress::after { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, 1); /* 半透明白色遮罩 */ - z-index: 2; - } - - /* 水平加载条动画 */ - .translate_api_in_progress::before { - content: ''; - position: absolute; - top: 50%; - left: 0; - width: 100%; - height:100%; /* 细线高度 */ - background: linear-gradient( - 90deg, - transparent 0%, - #e8e8e8 25%, /* 浅灰色 */ - #d0d0d0 50%, /* 中灰色 */ - #e8e8e8 75%, /* 浅灰色 */ - transparent 100% - ); - background-size: 200% 100%; - animation: translate_api_in_progress_horizontal-loader 3.5s linear infinite; - z-index: 3; - transform: translateY(-50%); - } - - @keyframes translate_api_in_progress_horizontal-loader { - 0% { - background-position: 200% 0; - } - 100% { - background-position: -200% 0; - } - } - `, - - /* - 通过文本翻译API进行的 - */ - api: { - isTip: true, //是否显示ui的提示,true显示,false不显示 - setUITip: (tip) => { - translate.progress.api.isTip = tip; - }, - //移除子元素(无限级别)中的所有 class name 的loading 遮罩 - //level 层级,数字,比如第一次调用,传入1, 第一次里面产生的第二次调用,这里就是2 - removeChildClass: (node, level) => { - //判断是否有子元素,判断其两级子元素,是否有加了loading遮罩了 - var childNodes = node.childNodes; - if (childNodes == null || typeof childNodes == "undefined") { - } else if (childNodes.length > 0) { - for (var i = 0; i < childNodes.length; i++) { - translate.progress.api.removeChildClass(childNodes[i], level + 1); - } - } - - if (level == 1) { - //第一次调用,是不删除本身的class name - return; - } - if (typeof node == "undefined") { - return; - } - if (typeof node.className != "string") { - return; - } - if (node.className.indexOf("translate_api_in_progress") < -1) { - return; - } - node.className = node.className.replace( - /translate_api_in_progress/g, - "", - ); - }, - startUITip: () => { - // 创建一个 style 元素 - const style = document.createElement("style"); - // 设置 style 元素的文本内容为要添加的 CSS 规则 - style.textContent = translate.progress.style; - // 将 style 元素插入到 head 元素中 - document.head.appendChild(style); - - if (translate.progress.api.isTip) { - translate.listener.execute.renderStartByApi.push((uuid, from, to) => { - for (var hash in translate.nodeQueue[uuid].list[from]) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list[from], hash)) { - continue; - } - for (var nodeindex in translate.nodeQueue[uuid].list[from][hash] - .nodes) { - if ( - !Object.hasOwn( - translate.nodeQueue[uuid].list[from][hash].nodes, - nodeindex, - ) - ) { - continue; - } - var node = - translate.nodeQueue[uuid].list[from][hash].nodes[nodeindex] - .node; - - if ( - typeof node == "undefined" || - typeof node.parentNode == "undefined" - ) { - continue; - } - var nodeParent = node.parentNode; - if (nodeParent == null) { - continue; - } - /* 这里先不考虑多隐藏的问题,只要符合的都隐藏,宁愿吧一些不需要隐藏的也会跟着一起隐藏 - if(nodeParent.childNodes.length != 1){ - //这个文本节点所在的元素里,不止有这一个文本元素,还有别的文本元素 - continue; - } - */ - - //判断其在上一层的父级是否已经加了,如果父级加了,那作为子集就不需要在加了,免得出现两个重合的 loading 遮罩 - var nodeParentParent = node.parentNode; - if ( - nodeParentParent != null && - typeof nodeParentParent.className != "undefined" && - nodeParentParent.className != null && - nodeParent.className.indexOf("translate_api_in_progress") > -1 - ) { - //父有了,那么子就不需要再加了 - continue; - } - //判断是否有子元素,判断其两级子元素,是否有加了loading遮罩了 - translate.progress.api.removeChildClass(nodeParent, 1); - - if ( - typeof nodeParent.className == "undefined" || - nodeParent.className == null || - nodeParent.className == "" - ) { - nodeParent.className = " translate_api_in_progress"; - } else { - //这个元素本身有class了,那就追加 - if ( - nodeParent.className.indexOf("translate_api_in_progress") > - -1 - ) { - continue; - } - nodeParent.className = - nodeParent.className + " translate_api_in_progress"; - } - } - } - }); - translate.listener.execute.renderFinishByApi.push( - (uuid, from, to) => { - for (var hash in translate.nodeQueue[uuid].list[from]) { - if ( - !Object.hasOwn(translate.nodeQueue[uuid].list[from], hash) - ) { - continue; - } - - for (var nodeindex in translate.nodeQueue[uuid].list[from][hash] - .nodes) { - if ( - !Object.hasOwn( - translate.nodeQueue[uuid].list[from][hash].nodes, - nodeindex, - ) - ) { - continue; - } - - var node = - translate.nodeQueue[uuid].list[from][hash].nodes[nodeindex] - .node; - var nodeParent = node.parentNode; - if (nodeParent == null) { - continue; - } - - /* - 注释这个,因为可能是给这个元素动态追加删除导致其子元素不是11 - if(nodeParent.childNodes.length != 1){ - continue; - } - */ - - var parentClassName = nodeParent.className; - if ( - typeof parentClassName == "undefined" || - parentClassName == null || - parentClassName == "" - ) { - continue; - } - if ( - parentClassName.indexOf("translate_api_in_progress") < -1 - ) { - continue; - } - - nodeParent.className = parentClassName.replace( - /translate_api_in_progress/g, - "", - ); - //nodeParent.className = parentClassName.replace(/loading/g, ''); - } - } - }, - ); - } - }, - }, - }, - /*js translate.progress end*/ - - /*js dispose start*/ - /* - 对js对象内的值进行翻译,可以是JS定义的 对象、数组、甚至是单个具体的值 - */ - js: { - /* - jsString 传入的js对象的字符串格式 - targetLanguage 翻译为的目标语言 - successFunction 执行成功后触发,传入格式 function(obj){ console.log(obj); } 其中 obj 是翻译之后的结果 - failureFunction 执行失败后触发,传入格式 function(failureInfo){ console.log(failureInfo); } 其中 failureInfo 是失败原因 - - 示例: - - var str = ` - { - "hello":"你好", - "word":"单词", - "你是谁": [ - "世界", - "大海" - ] - } - ` - translate.js.transString(str,'english',function(obj){ console.log(obj); }, function(failureInfo){ console.log(failureInfo); }); - - */ - transString: ( - jsString, - targetLanguage, - successFunction, - failureFunction, - ) => { - let jsObject; - try { - jsObject = JSON.parse(jsString); - } catch (e) { - failureFunction(e); - return; - } - translate.js.transObject( - jsObject, - targetLanguage, - successFunction, - failureFunction, - ); - }, - - /* - jsObject 传入的js对象,支持对象、数组等 - targetLanguage 翻译为的目标语言 - successFunction 执行成功后触发,传入格式 function(obj){ console.log(obj); } 其中 obj 是翻译之后的结果 - failureFunction 执行失败后触发,传入格式 function(failureInfo){ console.log(failureInfo); } 其中 failureInfo 是失败原因 - - 示例: - - var obj = { - "hello":"你好", - "word":"单词", - "世界":["世界","大海"] - }; - translate.js.transObject(obj,'english',function(obj){ console.log(obj); }, function(failureInfo){ console.log(failureInfo); }); - - */ - transObject: ( - jsObject, - targetLanguage, - successFunction, - failureFunction, - ) => { - const kvs = translate.js.find(jsObject); - //console.log(JSON.stringify(kvs, null, 2)); - - /**** 第二步,将文本值进行翻译 ***/ - //先将其 kvs 的key 取出来 - var texts = []; - for (const key in kvs) { - texts.push(key); - } - - var obj = { - from: "auto", - to: targetLanguage, - texts: texts, - }; - translate.request.translateText(obj, (data) => { - //打印翻译结果 - //console.log(data); - if (typeof data.result == "undefined" || data.result == 0) { - failureFunction("network connect failure"); - return; - } - if (data.result == 0) { - failureFunction(data.info); - return; - } - - /**** 第三步,将翻译结果赋予 jsObject ***/ - const translatedTexts = data.text; // 获取翻译结果数组 - if (translatedTexts && translatedTexts.length === texts.length) { - texts.forEach((originalText, index) => { - const translatedText = translatedTexts[index]; // 根据索引获取翻译结果 - const paths = kvs[originalText]; // 获取该文本的路径数组 - if (paths && paths.length > 0) { - paths.forEach((path) => { - translate.js.setValueByPath(jsObject, path, translatedText); // 更新 jsObject - }); - } - }); - } else { - console.error("翻译结果长度不匹配或为空"); - } - successFunction(jsObject); - //console.log("翻译后的 jsObject:", jsObject); - }); - }, - setValueByPath: (obj, path, value) => { - const parts = path.replace(/\[(\d+)\]/g, ".$1").split("."); - let current = obj; - for (let i = 0; i < parts.length - 1; i++) { - current = current[parts[i]]; - } - current[parts[parts.length - 1]] = value; - }, - /* - 对js对象进行翻译 - obj: 可以是JS定义的 对象、数组、甚至是单个具体的值 - - var obj = { - "hello":"你好", - "word":"单词", - "世界":["世界","大海"] - }; - translate.js.find(obj); - - */ - find: (obj, parentKey = "") => { - const kvs = {}; - if (typeof obj === "object" && obj !== null) { - if (Array.isArray(obj)) { - obj.forEach((item, index) => { - const currentKey = parentKey - ? `${parentKey}[${index}]` - : `[${index}]`; - const subKvs = translate.js.find(item, currentKey); - for (const [text, paths] of Object.entries(subKvs)) { - if (!kvs[text]) { - kvs[text] = []; - } - kvs[text] = kvs[text].concat(paths); - } - }); - } else { - for (const key in obj) { - const currentKey = parentKey ? `${parentKey}.${key}` : key; - if (typeof obj[key] === "object" && obj[key] !== null) { - const subKvs = translate.js.find(obj[key], currentKey); - for (const [text, paths] of Object.entries(subKvs)) { - if (!kvs[text]) { - kvs[text] = []; - } - kvs[text] = kvs[text].concat(paths); - } - } else if (typeof obj[key] === "string") { - if (typeof kvs[obj[key]] === "undefined") { - kvs[obj[key]] = []; - } - kvs[obj[key]].push(currentKey); - } - } - } - } else if (typeof obj === "string") { - if (typeof kvs[obj] === "undefined") { - kvs[obj] = []; - } - kvs[obj].push(parentKey); - } - return kvs; - }, - }, - /*js dispose end*/ - - /*js translate.network start*/ - /* - 网络请求数据拦截并翻译 - 当用户触发ajax请求时,它可以针对ajax请求中的某个参数,进行获取,并进行翻译,将翻译后的文本赋予这个参数,然后再放开请求。 - - 使用场景如: - 搜索场景,原本是中文的页面,翻译为英文后,给美国人使用,美国人使用时,进行搜索,输入的是英文,然后点击搜索按钮,发起搜索。 - 然后此会拦截网络请求,将请求中用户输入的搜索文本的内容提取出来,识别它输入的是中文还是英文,如果不是本地的语种中文,那就将其翻译为中文,然后再赋予此请求的这个参数中,然后再放开这次请求。 - 这样请求真正到达服务端接口时,服务端接受到的搜索的文本内容实际就是翻译后的中文文本,而不是用户输入的英文文本。 - - 何时自动进行翻译: - 1. 当前用户没有进行切换语言 - 2. 切换语言了,但是输入的文本的语言是不需要进行翻译的, 输入的文本本身就是本地的语言 - 这两种情况那就不需要拦截翻译 - - - */ - network: { - // 原始方法保存 - originalOpen: XMLHttpRequest.prototype.open, - originalSend: XMLHttpRequest.prototype.send, - setRequestHeaderOriginal: XMLHttpRequest.prototype.setRequestHeader, - - // 规则配置 - rules: [ - { - url: /https:\/\/www\.guanleiming\.com\/a\/b\/.html/, - methods: ["GET", "POST"], - params: ["a", "b1"], - }, - ], - //根据 当前请求的url 跟 method 来判断当前请求是否符合规则, - //如果符合,则返回符合的 rule 规则,也就是 translate.network.rules 中配置的某个。 - //如果没有找到符合的,则返回 null - getRuleMatch: (url, method) => { - for (let i = 0; i < translate.network.rules.length; i++) { - const rule = translate.network.rules[i]; - - // 检查 URL 是否匹配 - if (typeof rule.url == "undefined" && rule.url == "") { - console.log("WARINNG : translate.network.rule find url is null:"); - console.log(rule); - continue; - } - //console.log(rule); - const isUrlMatch = rule.url.test(url); - if (!isUrlMatch) { - continue; - } - - // 检查方法是否匹配(忽略大小写) - const isMethodMatch = rule.methods.includes(method.toUpperCase()); - if (!isMethodMatch) { - continue; - } - - return rule; - } - - return null; - }, - use: () => { - // 应用Hook - XMLHttpRequest.prototype.open = function (...args) { - return translate.network.hookOpen.apply(this, args); - }; - - XMLHttpRequest.prototype.send = function (...args) { - return translate.network.hookSend.apply(this, args); - }; - - // 劫持 setRequestHeader 方法 - XMLHttpRequest.prototype.setRequestHeader = function (...args) { - return translate.network.setRequestHeader.apply(this, args); - }; - - translate.network.fetch.use(); - }, - // 私有工具方法 - _translateText(text) { - if ( - translate.language.getLocal() == translate.language.getCurrent() || - (typeof text == "string" && - text.length > 0 && - translate.language.recognition(text).languageName == - translate.language.getLocal()) - ) { - /* - 1. 没有进行切换语言 - 2. 切换语言了,但是输入的文本的语言是不需要进行翻译的, 输入的文本本身就是本地的语言 - - 这两种情况那就不需要拦截翻译 - */ - - return new Promise((resolve, reject) => { - const obj = { - from: "auto", - to: translate.language.getLocal(), - text: [text], - }; - - resolve(obj); - }); - } - //有进行切换了,那进行翻译,将其他语种翻译为当前的本地语种 - return new Promise((resolve, reject) => { - const obj = { - from: "auto", - to: translate.language.getLocal(), - texts: [text], - }; - - //console.log('翻译请求:', obj); - translate.request.translateText(obj, (data) => { - if (data.result === 1) { - resolve(data); - } else { - reject(data); - } - }); - }); - }, - //劫持 setRequestHeader - setRequestHeader: function (header, value) { - if (this._requestContext) { - this._requestContext.headers = this._requestContext.headers || {}; - this._requestContext.headers[header] = value; - } - - return translate.network.setRequestHeaderOriginal.call( - this, - header, - value, - ); - }, - // 请求处理工具 - RequestHandler: { - async handleGet(url, rule) { - //console.log(url); - //console.log(rule); - if ( - typeof rule.params == "undefined" && - typeof rule.params.length == "undefined" && - rule.params.length < 1 - ) { - console.log("WARINNG: rule not find params , rule : "); - console.log(rule); - rule.params = []; - } - - try { - const urlObj = new URL(url, window.location.origin); - const params = urlObj.searchParams; - //console.log(rule.params); - - //for (const paramName in rule.params) { - for (var p = 0; p < rule.params.length; p++) { - var paramName = rule.params[p]; - //console.log(paramName); - if (params.has(paramName)) { - const original = params.get(paramName); - const translateResultData = - await translate.network._translateText(original); - - if (typeof translateResultData == "undefined") { - console.log("WARINNG: translateResultData is undefined"); - } else if (typeof translateResultData.result == "undefined") { - console.log("WARINNG: translateResultData.result is undefined"); - } else if (translateResultData.result != 1) { - console.log( - "WARINNG: translateResultData.result failure : " + - translateResultData.info, - ); - } else { - params.set( - paramName, - decodeURIComponent(translateResultData.text[0]), - ); - } - } - } - - return urlObj.toString(); - } catch (e) { - console.warn("GET处理失败:", e); - return url; - } - }, - - async handleForm(body, rule) { - try { - const params = new URLSearchParams(body); - const modified = { ...params }; - - for (const paramName of rule.params) { - if (params.has(paramName)) { - const original = params.get(paramName); - const translated = - await translate.network._translateText(original); - modified[paramName] = translated; - } - } - - return new URLSearchParams(modified).toString(); - } catch (e) { - console.warn("表单处理失败:", e); - return body; - } - }, - - async handleJson(body, rule) { - try { - const json = JSON.parse(body); - const modified = { ...json }; - - for (const paramName of rule.params) { - if (Object.hasOwn(modified, paramName)) { - const original = modified[paramName]; - modified[paramName] = - await translate.network._translateText(original); - } - } - - return JSON.stringify(modified); - } catch (e) { - console.warn("JSON处理失败:", e); - return body; - } - }, - }, - - // 请求上下文管理 - _requestContext: null, - - // Hook open 方法 - hookOpen(method, url, async, user, password) { - const matchedRule = null; - this._requestContext = { - method: method.toUpperCase(), - originalUrl: url, - async: async, - user: user, - password: password, - matchedRule: translate.network.getRuleMatch(url, method), - }; - - return translate.network.originalOpen.call( - this, - method, - url, - async, - user, - password, - ); - }, - - // Hook send 方法 - hookSend(body) { - const ctx = this._requestContext; - if (!ctx || !ctx.matchedRule) { - return translate.network.originalSend.call(this, body); - } - - const processRequest = async () => { - let modifiedBody = body; - const method = ctx.method; - - try { - // 处理GET请求 - //if (method === 'GET') { - const newUrl = await translate.network.RequestHandler.handleGet( - ctx.originalUrl, - ctx.matchedRule, - ); - translate.network.originalOpen.call( - this, - method, - newUrl, - ctx.async, - ctx.user, - ctx.password, - ); - //} - - // 恢复请求头 - if (ctx.headers) { - for (const header in ctx.headers) { - translate.network.setRequestHeaderOriginal.call( - this, - header, - ctx.headers[header], - ); - } - } - - // 处理POST请求 - if (method === "POST") { - if ( - typeof body != "undefined" && - body != null && - body.length < 2000 - ) { - var isJsonBody = false; //是否是json格式的数据,是否json已经处理了, true 是 - if ( - body.trim().indexOf("[") == 0 || - body.trim().indexOf("{") == 0 - ) { - //可能是json - try { - modifiedBody = - await translate.network.RequestHandler.handleJson( - body, - ctx.matchedRule, - ); - isJsonBody = true; - } catch (je) { - isJsonBody = false; - } - } - if (!isJsonBody) { - try { - modifiedBody = - await translate.network.RequestHandler.handleForm( - body, - ctx.matchedRule, - ); - } catch (je) {} - } - } - } - } catch (e) { - console.warn("请求处理异常:", e); - } - - translate.network.originalSend.call(this, modifiedBody); - }; - - // 异步处理 - if (ctx.async !== false) { - processRequest.call(this); - } else { - console.warn("同步请求不支持翻译拦截"); - translate.network.originalSend.call(this, body); - } - }, - //fetch请求 - fetch: { - originalFetch: window.fetch, - - // 保存原始 fetch 方法 - use: function () { - window.fetch = (...args) => this.hookFetch.apply(this, args); - }, - - // 拦截 fetch 请求 - hookFetch: async function (input, init) { - const request = new Request(input, init); - const url = request.url; - const method = request.method; - - // 获取匹配规则 - const rule = translate.network.getRuleMatch(url, method); - if (!rule) { - return this.originalFetch.call(window, request); - } - - // 初始化请求上下文 - const ctx = { - method, - url, - headers: {}, - rule, - isModified: false, - }; - - // 保存请求头 - request.headers.forEach((value, key) => { - ctx.headers[key] = value; - }); - - this._requestContext = ctx; - - try { - const newUrl = await translate.network.RequestHandler.handleGet( - url, - rule, - ); - // 处理 GET 请求 - if (method === "GET") { - const newRequest = new Request(newUrl, { - method, - headers: new Headers(ctx.headers), - mode: request.mode, - credentials: request.credentials, - cache: request.cache, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - }); - return this.originalFetch.call(window, newRequest); - } - - // 处理 POST 请求 - if (method === "POST") { - let body = null; - if (request.body) { - body = await request.clone().text(); - } - - const contentType = request.headers.get("Content-Type"); - let modifiedBody = body; - - if ( - typeof body != "undefined" && - body != null && - body.length < 2000 - ) { - var isJsonBody = false; //是否是json格式的数据,是否json已经处理了, true 是 - if ( - body.trim().indexOf("[") == 0 || - body.trim().indexOf("{") == 0 - ) { - //可能是json - try { - modifiedBody = - await translate.network.RequestHandler.handleJson( - body, - rule, - ); - isJsonBody = true; - } catch (je) { - isJsonBody = false; - } - } - if (!isJsonBody) { - try { - modifiedBody = - await translate.network.RequestHandler.handleForm( - body, - rule, - ); - } catch (je) {} - } - } - - const newRequest = new Request(newUrl, { - method, - headers: new Headers(ctx.headers), - body: modifiedBody, - mode: request.mode, - credentials: request.credentials, - cache: request.cache, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - }); - - return this.originalFetch.call(window, newRequest); - } - - // 其他方法直接返回原始请求 - return this.originalFetch.call(window, request); - } catch (e) { - console.warn("fetch 请求处理异常:", e); - return this.originalFetch.call(window, request); - } - }, - // 请求上下文管理 - _requestContext: null, - }, - }, - - /*js translate.network end*/ - - /*js translate.visual start*/ - /* - 人眼所看到的纯视觉层的处理 - */ - visual: { - /** - * 获取一组节点的视觉矩形信息 - * @param {Node[]} nodes - 节点数组,格式如 - * [node1,node2,node3] - * @returns {Object[]} - 矩形信息数组,与输入节点一一对应 - */ - getRects: (nodes) => - nodes.map((node) => { - if (!node) return null; - - let rect; - if (node.nodeType === Node.TEXT_NODE) { - const range = document.createRange(); - range.selectNodeContents(node); - const rects = range.getClientRects(); - //console.log(rect); - rect = rects.length > 0 ? rects[0] : null; - } else if (node.nodeType === Node.ELEMENT_NODE) { - rect = node.getBoundingClientRect(); - } - - return rect - ? { - node, - left: rect.left, - top: rect.top, - right: rect.right, - bottom: rect.bottom, - width: rect.width, - height: rect.height, - } - : null; - }), - /* - 对一组坐标进行排序 - 按开始坐标从左到右、从上到下排序 - @param rects translate.visual.getRects获取到的坐标数据 - */ - coordinateSort: (rects) => { - // 按从左到右、从上到下排序 - const sortedRects = rects - .filter((rect) => rect !== null) - .sort((a, b) => { - if (Math.abs(a.top - b.top) < 5) { - // 同一行 - return a.left - b.left; - } - return a.top - b.top; - }); - return sortedRects; - }, - /** - * 查找左右紧邻的矩形对 - * @param rects translate.visual.getRects获取到的坐标数据 - * @returns {Array<{before: Object, after: Object}>} - 左右紧邻的矩形对数组 - */ - afterAdjacent: (rects) => { - var sortedRects = translate.visual.coordinateSort(rects); - - const adjacentPairs = []; - const lineGroups = translate.visual.groupRectsByLine(sortedRects); - - // 检查每行中的所有紧邻元素对 - lineGroups.forEach((line) => { - for (let i = 0; i < line.length; i++) { - for (let j = i + 1; j < line.length; j++) { - const prev = line[i]; - const next = line[j]; - - // 如果后续元素与当前元素不紧邻,则后续其他元素也不可能紧邻 - if (!translate.visual.areHorizontallyAdjacent(prev, next)) { - break; - } - - adjacentPairs.push({ before: prev, after: next }); - } - } - }); - - return adjacentPairs; - }, - /** - * 按行分组矩形 - * @param rects - 排序后的矩形数组 @param rects translate.visual.coordinateSort 获取到的坐标数据 - * @returns {Object[][]} - 按行分组的矩形 - */ - groupRectsByLine: (rects) => { - const lineGroups = []; - let currentLine = []; - - rects.forEach((rect) => { - if (currentLine.length === 0) { - currentLine.push(rect); - } else { - const lastRect = currentLine[currentLine.length - 1]; - // 如果在同一行,则添加到当前行 - if (Math.abs(rect.top - lastRect.top) < 5) { - currentLine.push(rect); - } else { - // 否则开始新的一行 - lineGroups.push(currentLine); - currentLine = [rect]; - } - } - }); - - // 添加最后一行 - if (currentLine.length > 0) { - lineGroups.push(currentLine); - } - - return lineGroups; - }, - /** - * 判断两个矩形是否水平紧邻 - * @param {Object} rect1 - 第一个矩形 - * @param {Object} rect2 - 第二个矩形 - * @returns {boolean} - 是否水平紧邻 - */ - areHorizontallyAdjacent: (rect1, rect2) => { - // 检查垂直方向是否有重叠(在同一行) - const verticalOverlap = - Math.min(rect1.bottom, rect2.bottom) - Math.max(rect1.top, rect2.top); - - // 检查水平间距是否在阈值范围内 - const horizontalGap = rect2.left - rect1.right; - - return verticalOverlap > 0 && Math.abs(horizontalGap) < 1; // 允许1px误差 - }, - /** - * 找到需要在节点文本末尾添加空格的节点 - * @param {Array<{before: Object, after: Object}>} adjacentPairs - 左右紧邻的矩形对数组 - * @returns {Node[]} - 需要添加空格的节点数组 - */ - afterAddSpace: (adjacentPairs) => { - const nodesToAddSpace = []; - - adjacentPairs.forEach((pair) => { - const { before, after } = pair; - const beforeNode = before.node; - const afterNode = after.node; - - // 获取计算样式 - const beforeStyle = window.getComputedStyle( - beforeNode.nodeType === Node.TEXT_NODE - ? beforeNode.parentElement - : beforeNode, - ); - - const afterStyle = window.getComputedStyle( - afterNode.nodeType === Node.TEXT_NODE - ? afterNode.parentElement - : afterNode, - ); - - // 检查间距是否由CSS属性引起 - const hasRightSpacing = - Number.parseFloat(beforeStyle.marginRight) > 0 || - Number.parseFloat(beforeStyle.paddingRight) > 0; - - const hasLeftSpacing = - Number.parseFloat(afterStyle.marginLeft) > 0 || - Number.parseFloat(afterStyle.paddingLeft) > 0; - - // 如果没有明确的间距,且后一个节点的开始非空白符,则需要添加空格 - if (!hasRightSpacing && !hasLeftSpacing) { - //判断 before 节点的最后一个字符是否是空白符 - if ( - typeof beforeNode.textContent == "string" && - typeof afterNode.textContent == "string" - ) { - if (/\s$/.test(beforeNode.textContent)) { - //before 最后一个字符是空格,则不需要追加空格符了 - } else if (/^\s/.test(afterNode.textContent)) { - //after 节点的开始第一个字符是空白符,那么也不需要追加空格符了 - } else { - //这里就需要对 beforeNode 追加空格了 - nodesToAddSpace.push(beforeNode); - } - } - } - }); - - return nodesToAddSpace; - }, - /** - * 主函数:处理翻译后的空格调整 - * @param {Node[]} nodes - 节点数组 - */ - adjustTranslationSpaces: (nodes) => { - //先判断当前要显示的语种,是否需要用空格进行间隔单词,如果本身不需要空格间隔,像是中文,那就根本不需要去计算视觉距离 - if (!translate.language.wordBlankConnector(translate.to)) { - return; - } - - //var startTime = Date.now(); - // 1. 获取节点视觉矩形 - const rects = translate.visual.getRects(nodes); - //console.log('rects:'); - //console.log(rects); - - // 2. 查找左右紧邻的矩形对 - const adjacentPairs = translate.visual.afterAdjacent(rects); - //console.log('adjacentPairs:'); - //console.log(adjacentPairs); - - // 3. 确定需要添加空格的节点 - const nodesToAddSpace = translate.visual.afterAddSpace(adjacentPairs); - //console.log('nodesToAddSpace:'); - //console.log(nodesToAddSpace); - - // 4. 添加非断行空格 - nodesToAddSpace.forEach((node) => { - // 确保只修改文本内容,不影响HTML结构 - if (node.nodeType === Node.TEXT_NODE) { - node.textContent = node.textContent + "\u00A0"; - } else if (node.nodeType === Node.ELEMENT_NODE) { - // 如果是元素节点,修改其最后一个子节点(假设是文本节点) - const lastChild = node.lastChild; - if (lastChild && lastChild.nodeType === Node.TEXT_NODE) { - lastChild.textContent = lastChild.textContent + "\u00A0"; - } - } - }); - //var endTime = Date.now(); - //console.log('visual recognition time: '+(endTime-startTime)+'ms'); - }, - /* - 通过 translate.nodeQueue[uuid] 中的uuid,来传入这个 translate.nodeQueue[uuid] 中所包含涉及到的所有node (除特殊字符外 ,也就是 translate.nodeQueue[uuid].list 下 特殊字符那一类是不会使用的) - */ - adjustTranslationSpacesByNodequeueUuid: (uuid) => { - var nodes = []; - for (var from in translate.nodeQueue[uuid].list) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list, from)) { - continue; - } - if (from.length < 1) { - continue; - } - for (var hash in translate.nodeQueue[uuid].list[from]) { - if (!Object.hasOwn(translate.nodeQueue[uuid].list[from], hash)) { - continue; - } - for (var nodeindex in translate.nodeQueue[uuid].list[from][hash] - .nodes) { - if ( - !Object.hasOwn( - translate.nodeQueue[uuid].list[from][hash].nodes, - nodeindex, - ) - ) { - continue; - } - var node = - translate.nodeQueue[uuid].list[from][hash].nodes[nodeindex].node; - nodes.push(node); - } - } - } - translate.visual.adjustTranslationSpaces(nodes); - }, - /* - 通过 translate.nodeQueue 中最后一次执行的 uuid,来获取这个 translate.nodeQueue[uuid] 中所包含涉及到的所有node (除特殊字符外 ,也就是 translate.nodeQueue[uuid].list 下 特殊字符那一类是不会使用的) - */ - adjustTranslationSpacesByLastNodequeueUuid: (uuid) => { - var uuid = ""; - for (var uuid_index in translate.nodeQueue) { - uuid = uuid_index; - break; - } - if (typeof uuid == "string" && uuid.length > 1) { - translate.visual.adjustTranslationSpacesByNodequeueUuid(uuid); - } - }, - }, - /*js translate.visual end*/ -}; -/* - 将页面中的所有node节点,生成其在当前页面的唯一标识字符串uuid - 开源仓库: https://github.com/xnx3/nodeuuid.js - 原理: 当前节点的nodeName + 当前节点在父节点下,属于第几个 tagName ,然后追个向父级进行取,将node本身+父级+父父级+.... 拼接在一起 - 注意,如果动态添加一个节点到第一个,那么其他节点就会挤下去导致节点标记异常 -*/ -var nodeuuid = { - index: (node) => { - var parent = node.parentElement; - if (parent == null) { - return ""; - } - - var childs; - if (typeof node.tagName == "undefined") { - //console.log('undefi'); - childs = parent.childNodes; - //console.log(Array.prototype.indexOf.call(childs, node)); - } else { - // 使用querySelectorAll()方法获取所有与node元素相同标签名的子节点 - //childs = parent.querySelectorAll(node.tagName); - - // 不使用querySelectorAll,手动遍历子节点来找到相同标签名的子节点 - childs = []; - var allChilds = parent.childNodes; - for (var i = 0; i < allChilds.length; i++) { - if (allChilds[i].tagName === node.tagName) { - childs.push(allChilds[i]); - } - } - } - var index = Array.prototype.indexOf.call(childs, node); - //console.log('--------'+node.tagName); - return node.nodeName + "" + (index + 1); - }, - uuid: (node) => { - var uuid = ""; - var n = node; - while (n != null) { - var id = nodeuuid.index(n); - //console.log(id); - if (id != "") { - if (uuid != "") { - uuid = "_" + uuid; - } - uuid = id + uuid; - } - //console.log(uuid) - n = n.parentElement; - } - return uuid; - }, -}; - -/*js copyright-notice start*/ -console.log( - "------ translate.js ------\nTwo lines of js html automatic translation, page without change, no language configuration file, no API Key, SEO friendly! Open warehouse : https://github.com/xnx3/translate \n两行js实现html全自动翻译。 无需改动页面、无语言配置文件、无API Key、对SEO友好!完全开源,代码仓库:https://gitee.com/mail_osc/translate", -); -/*js copyright-notice end*/ - -/*js amd-cmd-commonjs start*/ -/*兼容 AMD、CMD、CommonJS 规范 - start*/ -/** - * 兼容 AMD、CMD、CommonJS 规范 - * node 环境使用:`npm i i18n-jsautotranslate` 安装包 - */ -((root, factory) => { - if (typeof define === "function" && define.amd) { - define([], () => factory()); - } else if (typeof module === "object" && module.exports) { - module.exports = factory(); - } else { - root["translate"] = factory(); - } -})(this, () => translate); -/*兼容 AMD、CMD、CommonJS 规范 - end*/ -/*js amd-cmd-commonjs end*/ diff --git a/website/css/architecture.css b/website/css/architecture.css deleted file mode 100644 index ca13478..0000000 --- a/website/css/architecture.css +++ /dev/null @@ -1,110 +0,0 @@ -/* ===== 架构图 ===== */ -#architecture { - padding: 120px 0; - position: relative; - z-index: 1; -} - -.arch-diagram { - max-width: 900px; - margin: 0 auto; -} - -.arch-layer { - border-radius: 16px; - padding: 24px; - border: 1px solid var(--border); -} - -.arch-core { - background: rgba(6, 182, 212, 0.05); - border-color: rgba(6, 182, 212, 0.2); -} - -.arch-label { - text-align: center; - font-size: 18px; - font-weight: 700; - margin-bottom: 16px; - color: var(--cyan-light); -} - -.arch-modules { - display: flex; - flex-wrap: wrap; - gap: 12px; - justify-content: center; -} - -.arch-module { - padding: 10px 20px; - background: rgba(6, 182, 212, 0.1); - border: 1px solid rgba(6, 182, 212, 0.2); - border-radius: 8px; - font-size: 14px; - font-weight: 500; -} - -.arch-connector { - height: 40px; - width: 2px; - background: linear-gradient(to bottom, var(--cyan), var(--blue)); - margin: 0 auto; - position: relative; -} - -.arch-connector::before, -.arch-connector::after { - content: ''; - position: absolute; - left: 50%; - transform: translateX(-50%); - width: 12px; - height: 12px; - border-radius: 50%; - background: var(--cyan); -} - -.arch-connector::before { top: -6px; } -.arch-connector::after { bottom: -6px; } - -.arch-plugins { - background: var(--bg-glass); -} - -.arch-plugin-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 16px; -} - -.arch-plugin { - background: rgba(255, 255, 255, 0.02); - border: 1px solid var(--border); - border-radius: 12px; - padding: 20px; - text-align: center; - transition: all 0.3s; -} - -.arch-plugin:hover { - border-color: var(--border-hover); - transform: translateY(-4px); -} - -.arch-plugin-title { - font-weight: 700; - font-size: 15px; - margin-bottom: 12px; - color: var(--cyan-light); -} - -.arch-plugin-items { - font-size: 13px; - color: var(--text-muted); - margin-bottom: 4px; -} - -@media (max-width: 768px) { - .arch-plugin-grid { grid-template-columns: repeat(2, 1fr); } -} diff --git a/website/css/code-examples.css b/website/css/code-examples.css deleted file mode 100644 index 1d2b4a7..0000000 --- a/website/css/code-examples.css +++ /dev/null @@ -1,63 +0,0 @@ -/* ===== 代码示例 ===== */ -#examples { - padding: 120px 0; - background: var(--bg-secondary); - position: relative; - z-index: 1; -} - -.examples-grid { - max-width: 1000px; - margin: 0 auto; - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 24px; -} - -.example-card:first-child { - grid-column: span 2; -} - -.example-card { - background: rgba(10, 15, 30, 0.9); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 16px; - overflow: hidden; -} - -.example-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 14px 20px; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); -} - -.example-title { - font-size: 14px; - font-weight: 600; - color: var(--text-secondary); -} - -.example-lang { - padding: 4px 10px; - border-radius: 4px; - background: rgba(6, 182, 212, 0.1); - color: var(--cyan); - font-size: 12px; - font-weight: 600; -} - -.example-code { - padding: 20px; - font-family: 'JetBrains Mono', monospace; - font-size: 13px; - line-height: 1.8; - color: var(--text-secondary); - overflow-x: auto; -} - -@media (max-width: 768px) { - .examples-grid { grid-template-columns: 1fr; } - .example-card:first-child { grid-column: span 1; } -} diff --git a/website/css/community.css b/website/css/community.css deleted file mode 100644 index a943d75..0000000 --- a/website/css/community.css +++ /dev/null @@ -1,46 +0,0 @@ -/* ===== 社区区域 ===== */ -#community { - padding: 120px 0; - background: var(--bg-secondary); - position: relative; - z-index: 1; -} - -.community-content { - max-width: 900px; - margin: 0 auto; - text-align: center; -} - -.community-links { - display: flex; - justify-content: center; - gap: 24px; - flex-wrap: wrap; -} - -.community-card { - display: flex; - align-items: center; - gap: 12px; - padding: 20px 32px; - background: var(--bg-glass); - border: 1px solid var(--border); - border-radius: 12px; - color: var(--text); - text-decoration: none; - font-weight: 600; - transition: all 0.3s; -} - -.community-card:hover { - border-color: var(--border-hover); - transform: translateY(-4px); - box-shadow: 0 12px 30px rgba(6, 182, 212, 0.1); -} - -.community-card svg { - width: 24px; - height: 24px; - color: var(--cyan); -} diff --git a/website/css/dock.css b/website/css/dock.css deleted file mode 100644 index 8032b22..0000000 --- a/website/css/dock.css +++ /dev/null @@ -1,195 +0,0 @@ -/* ===== Dock 侧边栏 - 苹果液态玻璃 ===== */ -#dock { - position: fixed; - right: 20px; - top: 50%; - transform: translateY(-50%); - z-index: 1000; - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - padding: 14px 10px; - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.18) 0%, - rgba(255, 255, 255, 0.08) 100% - ); - backdrop-filter: blur(50px) saturate(200%); - -webkit-backdrop-filter: blur(50px) saturate(200%); - border: 1px solid rgba(255, 255, 255, 0.25); - border-radius: 22px; - box-shadow: - 0 12px 40px rgba(0, 0, 0, 0.15), - 0 4px 12px rgba(0, 0, 0, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.6), - inset 0 -1px 0 rgba(255, 255, 255, 0.15); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -#dock:hover { - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.22) 0%, - rgba(255, 255, 255, 0.12) 100% - ); - border-color: rgba(255, 255, 255, 0.35); - box-shadow: - 0 16px 48px rgba(0, 0, 0, 0.18), - 0 6px 16px rgba(0, 0, 0, 0.12), - inset 0 1px 0 rgba(255, 255, 255, 0.7), - inset 0 -1px 0 rgba(255, 255, 255, 0.2); -} - -.dock-item { - display: flex; - align-items: center; - justify-content: center; - width: 38px; - height: 38px; - border-radius: 12px; - color: var(--text-secondary); - text-decoration: none; - transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); - position: relative; -} - -.dock-item:hover, .dock-item.active { - color: #fff; - /* 苹果风格高光滑 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.3) 0%, - rgba(255, 255, 255, 0.15) 100% - ); - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border: 1px solid rgba(255, 255, 255, 0.4); - transform: scale(1.2); - box-shadow: - 0 6px 16px rgba(0, 0, 0, 0.15), - 0 2px 6px rgba(0, 0, 0, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.8), - inset 0 -1px 0 rgba(255, 255, 255, 0.2); -} - -.dock-item svg { - width: 18px; - height: 18px; -} - -.dock-separator { - width: 20px; - height: 1px; - background: var(--border); - margin: 4px 0; -} - -/* 用户头像样式 */ -.dock-user-avatar { - position: relative; - cursor: pointer; - flex-direction: column; - gap: 4px; -} - -.dock-user-avatar svg { - color: var(--cyan); -} - -.dock-user-avatar:hover { - color: var(--cyan-light); - background: rgba(6, 182, 212, 0.15); - transform: scale(1.15); -} - -/* 称号徽章 */ -.user-title-badge { - position: absolute; - bottom: -18px; - left: 50%; - transform: translateX(-50%); - font-size: 9px; - font-weight: 600; - padding: 1px 4px; - border-radius: 4px; - background: linear-gradient(135deg, #f59e0b, #f97316); - color: #fff; - white-space: nowrap; - max-width: 80px; - overflow: hidden; - text-overflow: ellipsis; - box-shadow: 0 2px 4px rgba(245, 158, 11, 0.3); - pointer-events: none; -} - -/* 用户菜单按钮样式 */ -.dock-user-menu-btn { - position: relative; - cursor: pointer; -} - -.dock-user-menu-btn svg { - color: var(--text-secondary); -} - -.dock-user-menu-btn:hover { - color: var(--cyan-light); - background: rgba(6, 182, 212, 0.15); - transform: scale(1.15); -} - -/* Tooltip */ -.dock-item::before { - content: attr(data-tooltip); - position: absolute; - right: calc(100% + 10px); - top: 50%; - transform: translateY(-50%) scale(0.9); - padding: 4px 8px; - border-radius: 4px; - background: #1f2937; - border: 1px solid var(--border); - color: #fff; - font-size: 11px; - font-weight: 500; - white-space: nowrap; - opacity: 0; - pointer-events: none; - transition: all 0.2s ease; -} - -.dock-item:hover::before { - opacity: 1; - transform: translateY(-50%) scale(1); -} - -/* 响应式 */ -@media (max-width: 768px) { - #dock { - right: auto; - left: 50%; - top: auto; - bottom: 12px; - transform: translateX(-50%); - flex-direction: row; - gap: 4px; - padding: 8px 12px; - } - .dock-separator { - width: 1px; - height: 20px; - margin: 0 4px; - } - .dock-item::before { - right: auto; - top: auto; - bottom: calc(100% + 8px); - left: 50%; - transform: translateX(-50%) scale(0.9); - } - .dock-item:hover::before { - transform: translateX(-50%) scale(1); - } -} diff --git a/website/css/docs.css b/website/css/docs.css deleted file mode 100644 index b1dad02..0000000 --- a/website/css/docs.css +++ /dev/null @@ -1,531 +0,0 @@ -/* ===== 文档页面 ===== */ -.page-docs { - position: fixed; - inset: 0; - display: flex; - flex-direction: column; - background: var(--bg); - overflow: hidden; -} - -/* 顶部栏 - 苹果液态玻璃 */ -.docs-header { - height: 56px; - flex-shrink: 0; - display: flex; - align-items: center; - gap: 16px; - padding: 0 24px; - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(3, 7, 18, 0.75) 0%, - rgba(3, 7, 18, 0.6) 100% - ); - backdrop-filter: blur(50px) saturate(200%); - -webkit-backdrop-filter: blur(50px) saturate(200%); - border-bottom: 1px solid rgba(255, 255, 255, 0.12); - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); - z-index: 100; -} - -/* 汉堡菜单按钮 - 苹果风格 */ -.docs-hamburger { - display: none; - width: 40px; - height: 40px; - border: none; - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.08) 0%, - rgba(255, 255, 255, 0.03) 100% - ); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.1); - cursor: pointer; - position: relative; - transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); - flex-shrink: 0; - box-shadow: - 0 2px 8px rgba(0, 0, 0, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.docs-hamburger:hover { - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.12) 0%, - rgba(255, 255, 255, 0.06) 100% - ); - border-color: rgba(255, 255, 255, 0.2); - box-shadow: - 0 4px 12px rgba(0, 0, 0, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.5); -} - -.docs-hamburger-line { - position: absolute; - left: 50%; - width: 20px; - height: 2px; - background: var(--text-secondary); - border-radius: 1px; - transform: translateX(-50%); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -.docs-hamburger-line:nth-child(1) { top: 14px; } -.docs-hamburger-line:nth-child(2) { top: 19px; } -.docs-hamburger-line:nth-child(3) { top: 24px; } - -/* 汉堡菜单激活状态 - 变为 X */ -.docs-hamburger.is-active .docs-hamburger-line:nth-child(1) { - top: 19px; - transform: translateX(-50%) rotate(45deg); -} - -.docs-hamburger.is-active .docs-hamburger-line:nth-child(2) { - opacity: 0; - transform: translateX(-50%) scaleX(0); -} - -.docs-hamburger.is-active .docs-hamburger-line:nth-child(3) { - top: 19px; - transform: translateX(-50%) rotate(-45deg); -} - -.docs-header-title { - display: flex; - align-items: center; - gap: 8px; - font-size: 16px; - font-weight: 700; - color: #fff; -} - -.docs-header-title svg { - color: var(--cyan); -} - -.docs-header-breadcrumb { - flex: 1; - font-size: 14px; - color: var(--text-muted); -} - -.docs-header-actions { - display: flex; - align-items: center; - gap: 12px; -} - -.docs-wiki-link { - display: flex; - align-items: center; - gap: 6px; - padding: 6px 14px; - border: 1px solid var(--border); - border-radius: 8px; - background: transparent; - color: var(--text-secondary); - font-size: 13px; - text-decoration: none; - transition: all 0.2s; -} - -.docs-wiki-link:hover { - border-color: var(--border-hover); - color: var(--cyan-light); - background: rgba(6, 182, 212, 0.05); -} - -/* 布局 */ -.docs-layout { - flex: 1; - display: flex; - overflow: hidden; -} - -/* 左侧导航 - 苹果液态玻璃 */ -.docs-sidebar { - width: 260px; - flex-shrink: 0; - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(2, 5, 16, 0.65) 0%, - rgba(2, 5, 16, 0.5) 100% - ); - backdrop-filter: blur(40px) saturate(180%); - -webkit-backdrop-filter: blur(40px) saturate(180%); - border-right: 1px solid rgba(255, 255, 255, 0.1); - overflow-y: auto; - padding: 20px 0; - transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -/* 移动端遮罩层 */ -.docs-sidebar-overlay { - display: none; -} - -/* 液态玻璃效果 - 通用类 */ -.liquid-glass { - background: rgba(255, 255, 255, 0.02); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid rgba(255, 255, 255, 0.05); -} - -.liquid-glass-strong { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border: 1px solid rgba(255, 255, 255, 0.08); -} - -.docs-nav-section { - margin-bottom: 24px; -} - -.docs-nav-section-title { - padding: 8px 24px; - font-size: 11px; - font-weight: 600; - text-transform: uppercase; - color: var(--text-muted); - letter-spacing: 1px; -} - -.docs-nav-item { - display: block; - padding: 8px 24px 8px 32px; - color: var(--text-secondary); - text-decoration: none; - font-size: 14px; - border-left: 3px solid transparent; - transition: all 0.15s; -} - -.docs-nav-item:hover { - background: rgba(255, 255, 255, 0.03); - color: #fff; -} - -.docs-nav-item.active { - border-left-color: var(--cyan); - color: var(--cyan-light); - background: rgba(6, 182, 212, 0.05); -} - -.docs-nav-item .nav-path { - display: block; - font-size: 11px; - color: var(--text-muted); - margin-top: 2px; - font-family: 'JetBrains Mono', monospace; -} - -/* 左下角固定按钮 - 苹果液态玻璃 */ -.docs-wiki-btn { - position: fixed; - bottom: 24px; - left: 24px; - display: flex; - align-items: center; - gap: 8px; - padding: 12px 20px; - /* 苹果液态玻璃按钮 */ - background: linear-gradient( - 135deg, - rgba(6, 182, 212, 0.8) 0%, - rgba(59, 130, 246, 0.7) 100% - ); - backdrop-filter: blur(20px) saturate(180%); - -webkit-backdrop-filter: blur(20px) saturate(180%); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 16px; - color: #fff; - font-size: 14px; - font-weight: 600; - text-decoration: none; - z-index: 200; - box-shadow: - 0 8px 24px rgba(6, 182, 212, 0.3), - 0 2px 8px rgba(0, 0, 0, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.4); - transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); -} - -.docs-wiki-btn:hover { - transform: translateY(-2px) scale(1.05); - background: linear-gradient( - 135deg, - rgba(6, 182, 212, 0.9) 0%, - rgba(59, 130, 246, 0.8) 100% - ); - box-shadow: - 0 12px 32px rgba(6, 182, 212, 0.4), - 0 4px 12px rgba(0, 0, 0, 0.25), - inset 0 1px 0 rgba(255, 255, 255, 0.6); -} - -.docs-wiki-btn svg { - width: 16px; - height: 16px; -} - -/* 右侧内容区 */ -.docs-content-wrapper { - flex: 1; - overflow-y: auto; -} - -.docs-content { - max-width: 860px; - margin: 0 auto; - padding: 40px 48px 100px; -} - -.docs-content h1 { - font-size: 32px; - font-weight: 800; - color: #fff; - margin-bottom: 8px; - margin-top: 0; -} - -.docs-content h2 { - font-size: 22px; - font-weight: 700; - color: #fff; - margin-top: 32px; - margin-bottom: 12px; - padding-bottom: 8px; - border-bottom: 1px solid var(--border); -} - -.docs-content h3 { - font-size: 18px; - font-weight: 600; - color: var(--cyan-light); - margin-top: 24px; - margin-bottom: 8px; -} - -.docs-content p { - font-size: 15px; - color: var(--text-secondary); - line-height: 1.8; - margin-bottom: 12px; -} - -.docs-content strong { color: #fff; } - -.docs-content code { - font-family: 'JetBrains Mono', monospace; - font-size: 13px; - background: rgba(6, 182, 212, 0.1); - padding: 2px 8px; - border-radius: 4px; - color: var(--cyan-light); -} - -.docs-content pre { - margin: 16px 0; - padding: 16px 20px; - background: rgba(10, 15, 30, 0.8); - border: 1px solid var(--border); - border-radius: 10px; - overflow-x: auto; -} - -.docs-content pre code { - background: transparent; - padding: 0; - color: #e5e7eb; - font-size: 13px; - line-height: 1.7; -} - -.docs-content blockquote { - margin: 16px 0; - padding: 12px 20px; - border-left: 4px solid var(--cyan); - background: rgba(6, 182, 212, 0.05); - border-radius: 0 8px 8px 0; -} - -.docs-content blockquote p { margin-bottom: 0; } - -.docs-content ul, .docs-content ol { - margin: 12px 0; - padding-left: 24px; - color: var(--text-secondary); -} - -.docs-content li { - margin-bottom: 6px; - font-size: 15px; - line-height: 1.6; -} - -.docs-content hr { - border: none; - height: 1px; - background: var(--border); - margin: 24px 0; -} - -.docs-content table { - width: 100%; - border-collapse: collapse; - margin: 16px 0; - font-size: 14px; -} - -.docs-content th { - padding: 10px 16px; - text-align: left; - background: rgba(6, 182, 212, 0.05); - border-bottom: 2px solid rgba(6, 182, 212, 0.2); - color: #fff; - font-weight: 600; -} - -.docs-content td { - padding: 10px 16px; - border-bottom: 1px solid var(--border); - color: var(--text-secondary); -} - -@media (max-width: 768px) { - /* 显示汉堡菜单按钮 */ - .docs-hamburger { - display: block; - } - - /* 隐藏桌面端面包屑 */ - .docs-header-breadcrumb { - display: none; - } - - /* 侧边栏变为滑出式 - 苹果液态玻璃 */ - .docs-sidebar { - position: fixed; - top: 56px; - left: 0; - bottom: 0; - width: 280px; - z-index: 200; - transform: translateX(-100%); - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(2, 5, 16, 0.85) 0%, - rgba(2, 5, 16, 0.75) 100% - ); - backdrop-filter: blur(60px) saturate(220%); - -webkit-backdrop-filter: blur(60px) saturate(220%); - border-right: 1px solid rgba(255, 255, 255, 0.15); - box-shadow: - 10px 0 40px rgba(0, 0, 0, 0.3), - 0 0 1px rgba(255, 255, 255, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.1); - } - - /* 侧边栏激活状态 */ - .docs-sidebar.is-open { - transform: translateX(0); - } - - /* 遮罩层 */ - .docs-sidebar-overlay { - display: block; - position: fixed; - inset: 0; - top: 56px; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.6); - backdrop-filter: blur(4px); - -webkit-backdrop-filter: blur(4px); - z-index: 150; - opacity: 0; - pointer-events: none; - transition: opacity 0.3s ease; - } - - .docs-sidebar-overlay.is-visible { - opacity: 1; - pointer-events: auto; - } - - .docs-content { padding: 24px 20px 100px; } - .docs-wiki-btn span { display: none; } - - /* 移动端顶部栏 */ - .docs-header { - padding: 0 16px; - height: 56px; - } - .docs-header-title { - font-size: 14px; - } - .docs-header-breadcrumb { - font-size: 12px; - } - - /* 移动端内容区 */ - .docs-content h1 { - font-size: 24px; - } - .docs-content h2 { - font-size: 18px; - } - .docs-content h3 { - font-size: 16px; - } - .docs-content p, - .docs-content li { - font-size: 14px; - } - .docs-content pre { - padding: 12px 16px; - font-size: 12px; - } - .docs-content table { - font-size: 13px; - overflow-x: auto; - display: block; - } - - /* 底部固定按钮只显示图标 */ - .docs-wiki-btn { - bottom: 16px; - left: 16px; - padding: 12px; - border-radius: 50%; - width: 48px; - height: 48px; - justify-content: center; - } -} - -@media (max-width: 480px) { - .docs-content { - padding: 20px 16px 100px; - } - .docs-content h1 { - font-size: 22px; - } - .docs-content h2 { - font-size: 17px; - } - .docs-content pre { - font-size: 11px; - } -} diff --git a/website/css/features.css b/website/css/features.css deleted file mode 100644 index d39f41a..0000000 --- a/website/css/features.css +++ /dev/null @@ -1,98 +0,0 @@ -/* ===== 特性区域 ===== */ -#features { - padding: 120px 0; - position: relative; - z-index: 1; -} - -.features-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 24px; -} - -.feature-card { - background: var(--bg-glass); - border: 1px solid var(--border); - border-radius: 20px; - padding: 32px; - transition: all 0.4s ease; - position: relative; - overflow: hidden; -} - -.feature-card::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(135deg, rgba(6, 182, 212, 0.05), transparent); - opacity: 0; - transition: opacity 0.4s; -} - -.feature-card:hover { - border-color: var(--border-hover); - transform: translateY(-8px); - box-shadow: 0 20px 40px rgba(6, 182, 212, 0.1); -} - -.feature-card:hover::before { opacity: 1; } - -.feature-icon { - width: 56px; - height: 56px; - border-radius: 14px; - background: linear-gradient(135deg, var(--cyan), var(--blue)); - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 20px; - transition: transform 0.3s; -} - -.feature-card:hover .feature-icon { - transform: scale(1.1); -} - -.feature-icon svg { - width: 28px; - height: 28px; - color: #fff; -} - -.feature-card h3 { - font-size: 20px; - font-weight: 700; - margin-bottom: 12px; -} - -.feature-card p { - font-size: 15px; - color: var(--text-secondary); - line-height: 1.7; - margin-bottom: 20px; -} - -.feature-tags { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.feature-tags span { - padding: 4px 12px; - border-radius: 6px; - background: rgba(6, 182, 212, 0.08); - border: 1px solid rgba(6, 182, 212, 0.15); - color: var(--cyan-light); - font-size: 12px; - font-weight: 500; -} - -@media (max-width: 1024px) { - .features-grid { grid-template-columns: repeat(2, 1fr); } -} - -@media (max-width: 640px) { - .features-grid { grid-template-columns: 1fr; } -} diff --git a/website/css/footer.css b/website/css/footer.css deleted file mode 100644 index 973e25d..0000000 --- a/website/css/footer.css +++ /dev/null @@ -1,79 +0,0 @@ -/* ===== Footer ===== */ -#footer { - padding: 80px 0 40px; - border-top: 1px solid var(--border); - position: relative; - z-index: 1; -} - -.footer-container { - max-width: 1200px; - margin: 0 auto; - padding: 0 24px; - display: grid; - grid-template-columns: 1fr 2fr; - gap: 64px; - margin-bottom: 64px; -} - -.footer-brand p { - color: var(--text-muted); - font-size: 14px; - margin-top: 12px; -} - -.footer-logo { - display: flex; - align-items: center; - gap: 10px; - font-weight: 700; - font-size: 18px; -} - -.footer-links { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 32px; -} - -.footer-col h4 { - font-size: 14px; - font-weight: 600; - color: var(--text); - margin-bottom: 16px; -} - -.footer-col a { - display: block; - color: var(--text-muted); - text-decoration: none; - font-size: 14px; - margin-bottom: 10px; - transition: color 0.2s; -} - -.footer-col a:hover { color: var(--cyan); } - -.footer-bottom { - text-align: center; - padding-top: 32px; - border-top: 1px solid var(--border); - max-width: 1200px; - margin: 0 auto; - padding-left: 24px; - padding-right: 24px; -} - -.footer-bottom p { - color: var(--text-muted); - font-size: 13px; -} - -@media (max-width: 768px) { - .footer-container { grid-template-columns: 1fr; gap: 40px; } - .footer-links { grid-template-columns: repeat(2, 1fr); } -} - -@media (max-width: 480px) { - .footer-links { grid-template-columns: 1fr; } -} diff --git a/website/css/hero.css b/website/css/hero.css deleted file mode 100644 index 1e44e07..0000000 --- a/website/css/hero.css +++ /dev/null @@ -1,420 +0,0 @@ -/* ===== Hero 区域 ===== */ -#hero { - min-height: 100vh; - display: flex; - align-items: center; - position: relative; - z-index: 1; - padding-top: 64px; -} - -.hero-container { - max-width: 1400px; - margin: 0 auto; - padding: 60px 24px; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 80px; - align-items: center; -} - -.badge { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 8px 20px; - border-radius: 999px; - background: rgba(6, 182, 212, 0.1); - border: 1px solid rgba(6, 182, 212, 0.2); - margin-bottom: 32px; - font-size: 14px; - color: rgba(34, 211, 238, 0.9); -} - -.badge-dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: var(--cyan); - animation: pulse 2s ease-in-out infinite; -} - -@keyframes pulse { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.4; } -} - -.hero-title { - font-size: clamp(48px, 8vw, 80px); - font-weight: 900; - line-height: 0.95; - margin-bottom: 24px; -} - -.title-line { display: block; } - -.hero-subtitle { - font-size: clamp(20px, 3vw, 28px); - color: var(--text-secondary); - font-weight: 300; - margin-bottom: 12px; -} - -.hero-desc { - font-size: 16px; - color: var(--text-muted); - max-width: 520px; - margin-bottom: 48px; - line-height: 1.8; -} - -.hero-actions { - display: flex; - flex-wrap: wrap; - gap: 16px; - margin-bottom: 64px; -} - -.hero-stats { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 24px; -} - -.stat { text-align: left; } - -.stat-num { - display: block; - font-size: 28px; - font-weight: 800; - color: #fff; - margin-bottom: 4px; -} - -.stat-num .stat-suffix { - font-size: 20px; - color: var(--text-secondary); -} - -.stat-label { - font-size: 13px; - color: var(--text-muted); -} - -/* 右侧代码区域 */ -.hero-visual { - position: relative; - display: flex; - align-items: center; - justify-content: center; -} - -.orbit { - position: absolute; - border-radius: 50%; - border: 1px solid rgba(6, 182, 212, 0.1); -} - -.orbit-1 { - inset: 15%; - animation: spin 40s linear infinite; -} - -.orbit-2 { - inset: 25%; - animation: spin 30s linear infinite reverse; -} - -@keyframes spin { - to { transform: rotate(360deg); } -} - -.orbit-dot { - position: absolute; - top: -6px; - left: 50%; - transform: translateX(-50%); - width: 12px; - height: 12px; - border-radius: 50%; - background: var(--cyan); - box-shadow: 0 0 20px rgba(6, 182, 212, 0.5); -} - -.orbit-dot-lg { - width: 16px; - height: 16px; - background: var(--blue); - box-shadow: 0 0 24px rgba(59, 130, 246, 0.5); -} - -/* 涟漪动画区域 */ -.ripple-container { - position: relative; - width: 320px; - height: 320px; - display: flex; - align-items: center; - justify-content: center; -} - -.ripple { - position: absolute; - border-radius: 50%; - border: 2px solid rgba(6, 182, 212, 0.3); - animation: ripple-expand 3s ease-out infinite; -} - -.ripple-1 { animation-delay: 0s; } -.ripple-2 { animation-delay: 0.6s; } -.ripple-3 { animation-delay: 1.2s; } -.ripple-4 { animation-delay: 1.8s; } -.ripple-5 { animation-delay: 2.4s; } - -@keyframes ripple-expand { - 0% { - width: 40px; - height: 40px; - opacity: 1; - border-width: 3px; - border-color: rgba(6, 182, 212, 0.6); - } - 50% { - opacity: 0.5; - border-width: 2px; - border-color: rgba(6, 182, 212, 0.3); - } - 100% { - width: 320px; - height: 320px; - opacity: 0; - border-width: 1px; - border-color: rgba(6, 182, 212, 0); - } -} - -/* ===== 3D 交互立方体 ===== */ -.cube-scene { - position: relative; - width: 200px; - height: 200px; - perspective: 800px; - z-index: 1; -} - -.cube { - width: 100%; - height: 100%; - position: relative; - transform-style: preserve-3d; - cursor: pointer; -} - -.cube-face { - position: absolute; - width: 200px; - height: 200px; - background: #ffffff; - border: 2px solid rgba(6, 182, 212, 0.6); - box-shadow: - inset 0 0 30px rgba(0, 0, 0, 0.03), - 0 0 15px rgba(6, 182, 212, 0.3), - 0 0 30px rgba(6, 182, 212, 0.15); - user-select: none; -} - -/* 立方体六个面 */ -.cube-face-front { transform: rotateY(0deg) translateZ(100px); } -.cube-face-back { transform: rotateY(180deg) translateZ(100px); } -.cube-face-right { transform: rotateY(90deg) translateZ(100px); } -.cube-face-left { transform: rotateY(-90deg) translateZ(100px); } -.cube-face-top { transform: rotateX(90deg) translateZ(100px); } -.cube-face-bottom { transform: rotateX(-90deg) translateZ(100px); } - -/* 特性对话框 */ -.cube-tooltip { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%) scale(0.8); - background: rgba(3, 7, 18, 0.95); - border: 1px solid rgba(6, 182, 212, 0.4); - border-radius: 12px; - padding: 16px 24px; - min-width: 220px; - max-width: 280px; - text-align: center; - opacity: 0; - pointer-events: none; - transition: opacity 0.3s ease, transform 0.3s ease; - z-index: 10; - backdrop-filter: blur(10px); - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 20px rgba(6, 182, 212, 0.15); -} - -.cube-tooltip.is-visible { - opacity: 1; - transform: translate(-50%, -50%) scale(1); -} - -.cube-tooltip-icon { - font-size: 28px; - margin-bottom: 8px; -} - -.cube-tooltip-title { - font-size: 15px; - font-weight: 700; - color: #fff; - margin-bottom: 4px; -} - -.cube-tooltip-desc { - font-size: 12px; - color: var(--text-muted); - line-height: 1.5; -} - -/* 小三角箭头 */ -.cube-tooltip::after { - content: ''; - position: absolute; - bottom: -8px; - left: 50%; - transform: translateX(-50%); - width: 0; - height: 0; - border-left: 8px solid transparent; - border-right: 8px solid transparent; - border-top: 8px solid rgba(6, 182, 212, 0.4); -} - -/* 滚动指示器 */ -.scroll-indicator { - position: absolute; - bottom: 40px; - left: 50%; - transform: translateX(-50%); - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - color: var(--text-muted); - font-size: 13px; - animation: bounce 2s ease-in-out infinite; -} - -@keyframes bounce { - 0%, 100% { transform: translateX(-50%) translateY(0); } - 50% { transform: translateX(-50%) translateY(8px); } -} - -.scroll-mouse { - width: 24px; - height: 36px; - border: 2px solid rgba(255, 255, 255, 0.2); - border-radius: 12px; - position: relative; -} - -.scroll-mouse::after { - content: ''; - position: absolute; - top: 6px; - left: 50%; - transform: translateX(-50%); - width: 4px; - height: 8px; - background: var(--cyan); - border-radius: 2px; - animation: scroll-dot 2s ease-in-out infinite; -} - -@keyframes scroll-dot { - 0%, 100% { opacity: 1; top: 6px; } - 50% { opacity: 0.3; top: 16px; } -} - -/* 响应式 */ -@media (max-width: 1024px) { - .hero-container { - grid-template-columns: 1fr; - gap: 48px; - text-align: center; - } - .hero-desc, .hero-actions, .hero-stats { - margin-left: auto; - margin-right: auto; - } - .hero-stats { max-width: 400px; } - .stat { text-align: center; } - .ripple-container { - margin: 0 auto; - width: 280px; - height: 280px; - } - .cube-scene { - width: 160px; - height: 160px; - margin: 0 auto; - } - .cube-face { - width: 160px; - height: 160px; - } - .cube-face-front { transform: rotateY(0deg) translateZ(80px); } - .cube-face-back { transform: rotateY(180deg) translateZ(80px); } - .cube-face-right { transform: rotateY(90deg) translateZ(80px); } - .cube-face-left { transform: rotateY(-90deg) translateZ(80px); } - .cube-face-top { transform: rotateX(90deg) translateZ(80px); } - .cube-face-bottom { transform: rotateX(-90deg) translateZ(80px); } -} - -@media (max-width: 640px) { - .hero-container { - padding: 40px 16px; - } - .hero-stats { grid-template-columns: 1fr; gap: 16px; } - .hero-actions { - justify-content: center; - } - .btn { - width: 100%; - max-width: 280px; - justify-content: center; - } - .ripple-container { - width: 240px; - height: 240px; - } - .cube-scene { - width: 140px; - height: 140px; - margin: 0 auto; - } - .cube-face { - width: 140px; - height: 140px; - } - .cube-face-front { transform: rotateY(0deg) translateZ(70px); } - .cube-face-back { transform: rotateY(180deg) translateZ(70px); } - .cube-face-right { transform: rotateY(90deg) translateZ(70px); } - .cube-face-left { transform: rotateY(-90deg) translateZ(70px); } - .cube-face-top { transform: rotateX(90deg) translateZ(70px); } - .cube-face-bottom { transform: rotateX(-90deg) translateZ(70px); } - - .hero-title { - font-size: 40px; - } - .hero-subtitle { - font-size: 18px; - } - .hero-desc { - font-size: 14px; - padding: 0 8px; - } - .badge { - font-size: 12px; - padding: 6px 14px; - } -} diff --git a/website/css/main.css b/website/css/main.css deleted file mode 100644 index 87160b8..0000000 --- a/website/css/main.css +++ /dev/null @@ -1,207 +0,0 @@ -/* ===== 全局样式 ===== */ -*, *::before, *::after { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -:root { - --bg: #030712; - --bg-secondary: #020510; - --bg-glass: rgba(255, 255, 255, 0.02); - --border: rgba(255, 255, 255, 0.05); - --border-hover: rgba(6, 182, 212, 0.3); - --cyan: #06b6d4; - --cyan-light: #22d3ee; - --blue: #3b82f6; - --purple: #8b5cf6; - --text: #fff; - --text-secondary: #9ca3af; - --text-muted: #6b7280; -} - -html { - scroll-behavior: smooth; - scroll-padding-top: 80px; -} - -body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; - background: var(--bg); - color: var(--text); - line-height: 1.6; - overflow-x: hidden; -} - -/* 粒子画布 */ -#particles { - position: fixed; - inset: 0; - z-index: 0; - pointer-events: none; -} - -/* 通用 */ -.section-container { - max-width: 1200px; - margin: 0 auto; - padding: 0 24px; -} - -.section-header { - text-align: center; - margin-bottom: 64px; -} - -.section-badge { - display: inline-block; - padding: 6px 16px; - border-radius: 999px; - background: rgba(6, 182, 212, 0.1); - border: 1px solid rgba(6, 182, 212, 0.2); - color: var(--cyan-light); - font-size: 14px; - font-weight: 500; - margin-bottom: 20px; -} - -.section-title { - font-size: clamp(32px, 5vw, 48px); - font-weight: 800; - margin-bottom: 16px; - line-height: 1.2; -} - -.section-desc { - font-size: 18px; - color: var(--text-secondary); - max-width: 600px; - margin: 0 auto; -} - -.gradient-text { - background: linear-gradient(135deg, var(--cyan), var(--blue)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.glass { - /* 苹果液态玻璃效果 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.1) 0%, - rgba(255, 255, 255, 0.05) 50%, - rgba(255, 255, 255, 0.02) 100% - ); - backdrop-filter: blur(40px) saturate(200%); - -webkit-backdrop-filter: blur(40px) saturate(200%); - border: 1px solid rgba(255, 255, 255, 0.18); - border-radius: 24px; - box-shadow: - 0 8px 32px rgba(0, 0, 0, 0.12), - 0 2px 8px rgba(0, 0, 0, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.4), - inset 0 -1px 0 rgba(255, 255, 255, 0.1); -} - -/* 苹果液态玻璃 - 轻量版 */ -.liquid-glass { - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.12) 0%, - rgba(255, 255, 255, 0.06) 100% - ); - backdrop-filter: blur(30px) saturate(180%); - -webkit-backdrop-filter: blur(30px) saturate(180%); - border: 1px solid rgba(255, 255, 255, 0.15); - border-radius: 20px; - box-shadow: - 0 4px 16px rgba(0, 0, 0, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.5); -} - -/* 苹果液态玻璃 - 加强版 */ -.liquid-glass-strong { - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.15) 0%, - rgba(255, 255, 255, 0.08) 50%, - rgba(255, 255, 255, 0.03) 100% - ); - backdrop-filter: blur(50px) saturate(220%); - -webkit-backdrop-filter: blur(50px) saturate(220%); - border: 1px solid rgba(255, 255, 255, 0.22); - border-radius: 28px; - box-shadow: - 0 16px 48px rgba(0, 0, 0, 0.15), - 0 4px 12px rgba(0, 0, 0, 0.1), - inset 0 2px 0 rgba(255, 255, 255, 0.6), - inset 0 -2px 0 rgba(255, 255, 255, 0.15); -} - -/* 按钮 */ -.btn { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 14px 28px; - border-radius: 12px; - font-size: 16px; - font-weight: 600; - text-decoration: none; - transition: all 0.3s ease; - cursor: pointer; - border: none; -} - -.btn-primary { - background: linear-gradient(135deg, var(--cyan), var(--blue)); - color: #fff; -} - -.btn-primary:hover { - box-shadow: 0 8px 30px rgba(6, 182, 212, 0.3); - transform: translateY(-2px); -} - -.btn-outline { - background: transparent; - color: var(--text); - border: 1px solid rgba(6, 182, 212, 0.3); -} - -.btn-outline:hover { - background: rgba(6, 182, 212, 0.1); - transform: translateY(-2px); -} - -.btn-lg { - padding: 18px 36px; - font-size: 18px; -} - -.btn-arrow { - width: 20px; - height: 20px; - transition: transform 0.3s ease; -} - -.btn:hover .btn-arrow { - transform: translateX(4px); -} - -/* 代码样式 */ -.code-comment { color: #6b7280; font-style: italic; } -.code-str { color: #34d399; } -.code-keyword { color: #c084fc; } -.code-func { color: #60a5fa; } -.code-bool { color: #f472b6; } -.code-type { color: #fbbf24; } -.code-cmd { color: #9ca3af; } - -/* 响应式 */ -@media (max-width: 768px) { - .section-container { padding: 0 16px; } - .section-header { margin-bottom: 40px; } -} diff --git a/website/css/page.css b/website/css/page.css deleted file mode 100644 index 0912a70..0000000 --- a/website/css/page.css +++ /dev/null @@ -1,635 +0,0 @@ -/* ===== 通用页面样式 ===== */ -.page-content { - max-width: 1100px; - margin: 0 auto; - padding: 100px 80px 80px 24px; - min-height: 100vh; - perspective: 1000px; -} - -.page-header { - text-align: center; - margin-bottom: 64px; - will-change: transform; - transition: transform 0.05s linear; -} - -/* 陀螺仪权限按钮 */ -#gyro-permission-btn { - position: fixed; - inset: 0; - z-index: 9999; -} - -.gyro-permission-overlay { - position: absolute; - inset: 0; - background: rgba(0, 0, 0, 0.6); - backdrop-filter: blur(8px); - display: flex; - align-items: center; - justify-content: center; - animation: fadeIn 0.3s ease; -} - -.gyro-permission-card { - background: rgba(20, 30, 50, 0.95); - border: 1px solid rgba(6, 182, 212, 0.3); - border-radius: 20px; - padding: 40px 32px 32px; - text-align: center; - max-width: 320px; - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); -} - -.gyro-permission-card svg { - color: var(--cyan); - margin-bottom: 16px; -} - -.gyro-permission-card p { - font-size: 18px; - font-weight: 700; - margin-bottom: 8px; - color: #fff; -} - -.gyro-permission-card span { - font-size: 14px; - color: var(--text-secondary); - display: block; - margin-bottom: 24px; -} - -.gyro-permission-card button { - padding: 12px 32px; - border-radius: 12px; - border: none; - background: linear-gradient(135deg, var(--cyan), var(--blue)); - color: #fff; - font-size: 16px; - font-weight: 600; - cursor: pointer; - transition: transform 0.2s, box-shadow 0.2s; -} - -.gyro-permission-card button:hover { - transform: scale(1.05); - box-shadow: 0 8px 24px rgba(6, 182, 212, 0.3); -} - -@keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } -} - -.page-title { - font-size: clamp(32px, 5vw, 48px); - font-weight: 800; - margin-bottom: 16px; - line-height: 1.2; -} - -.page-desc { - font-size: 18px; - color: var(--text-secondary); - max-width: 600px; - margin: 0 auto; -} - -/* 特性网格 */ -.features-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 24px; -} - -.feature-card { - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.1) 0%, - rgba(255, 255, 255, 0.04) 100% - ); - backdrop-filter: blur(40px) saturate(180%); - -webkit-backdrop-filter: blur(40px) saturate(180%); - border: 1px solid rgba(255, 255, 255, 0.18); - border-radius: 24px; - padding: 32px; - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); - box-shadow: - 0 8px 24px rgba(0, 0, 0, 0.12), - 0 2px 6px rgba(0, 0, 0, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.5); -} - -.feature-card:hover { - transform: translateY(-8px); - /* 悬停时增强玻璃效果 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.15) 0%, - rgba(255, 255, 255, 0.06) 100% - ); - backdrop-filter: blur(50px) saturate(200%); - -webkit-backdrop-filter: blur(50px) saturate(200%); - border-color: rgba(255, 255, 255, 0.3); - box-shadow: - 0 20px 48px rgba(0, 0, 0, 0.18), - 0 8px 16px rgba(0, 0, 0, 0.12), - inset 0 1px 0 rgba(255, 255, 255, 0.7), - inset 0 -1px 0 rgba(255, 255, 255, 0.2); -} - -.feature-icon { - width: 56px; - height: 56px; - border-radius: 14px; - background: linear-gradient(135deg, var(--cyan), var(--blue)); - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 20px; - transition: transform 0.3s; -} - -.feature-card:hover .feature-icon { transform: scale(1.1); } - -.feature-icon svg { width: 28px; height: 28px; color: #fff; } - -.feature-card h3 { font-size: 20px; font-weight: 700; margin-bottom: 12px; } - -.feature-card p { - font-size: 15px; - color: var(--text-secondary); - line-height: 1.7; - margin-bottom: 20px; -} - -.feature-tags { display: flex; flex-wrap: wrap; gap: 8px; } - -.feature-tags span { - padding: 4px 12px; - border-radius: 6px; - background: rgba(6, 182, 212, 0.08); - border: 1px solid rgba(6, 182, 212, 0.15); - color: var(--cyan-light); - font-size: 12px; - font-weight: 500; -} - -/* 插件页面 */ -.pkg-format { text-align: center; margin-bottom: 48px; } - -.pkg-card { - font-family: 'JetBrains Mono', monospace; - font-size: clamp(20px, 4vw, 36px); - font-weight: 700; - padding: 32px; - background: var(--bg-glass); - border: 1px solid var(--border); - border-radius: 16px; - display: inline-block; - margin-bottom: 32px; -} - -.pkg-symbol { color: var(--text-muted); } -.pkg-highlight { color: var(--cyan); } -.pkg-version { color: var(--blue); } - -.pkg-explain { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 24px; - text-align: center; -} - -.explain-symbol { - font-family: 'JetBrains Mono', monospace; - font-size: 18px; - font-weight: 600; - color: var(--cyan-light); - margin-bottom: 8px; -} - -.explain-text { font-size: 14px; color: var(--text-muted); } - -/* 终端演示 */ -.install-demo { - max-width: 700px; - margin: 0 auto 48px; - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(10, 15, 30, 0.7) 0%, - rgba(10, 15, 30, 0.5) 100% - ); - backdrop-filter: blur(40px) saturate(180%); - -webkit-backdrop-filter: blur(40px) saturate(180%); - border: 1px solid rgba(255, 255, 255, 0.15); - border-radius: 20px; - overflow: hidden; - box-shadow: - 0 12px 40px rgba(0, 0, 0, 0.2), - 0 4px 10px rgba(0, 0, 0, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.demo-header { - display: flex; - align-items: center; - gap: 8px; - padding: 14px 20px; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); -} - -.demo-dot { width: 12px; height: 12px; border-radius: 50%; } -.demo-dot-red { background: #ef4444; } -.demo-dot-yellow { background: #eab308; } -.demo-dot-green { background: #22c55e; } - -.demo-title { margin-left: 12px; font-size: 13px; color: var(--text-muted); } - -.demo-body { - padding: 20px; - font-family: 'JetBrains Mono', monospace; - font-size: 14px; -} - -.cmd-line { display: flex; gap: 12px; margin-bottom: 8px; color: var(--text-secondary); } -.prompt { color: var(--cyan); font-weight: 600; } -.cmd-text { color: #e5e7eb; } -.cmd-output { color: #9ca3af; font-size: 13px; margin-bottom: 4px; } -.cmd-output.success { color: #34d399; } -.cmd-output.indent { padding-left: 24px; } - -/* 命令表格 */ -.pkg-table { max-width: 800px; margin: 0 auto; } -.pkg-table-title { font-size: 24px; font-weight: 700; margin-bottom: 20px; text-align: center; } - -.pkg-table table { - width: 100%; - border-collapse: collapse; -} - -.pkg-table th, .pkg-table td { - padding: 12px 16px; - text-align: left; - border-bottom: 1px solid var(--border); - font-size: 14px; -} - -.pkg-table th { - color: var(--text-muted); - font-weight: 600; - font-size: 13px; -} - -.pkg-table td code { - font-family: 'JetBrains Mono', monospace; - background: rgba(6, 182, 212, 0.1); - padding: 2px 8px; - border-radius: 4px; - font-size: 13px; - color: var(--cyan-light); -} - -/* 架构图 */ -.arch-diagram { max-width: 900px; margin: 0 auto 64px; } - -.arch-layer { - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.08) 0%, - rgba(255, 255, 255, 0.03) 100% - ); - backdrop-filter: blur(30px) saturate(160%); - -webkit-backdrop-filter: blur(30px) saturate(160%); - border: 1px solid rgba(255, 255, 255, 0.15); - border-radius: 20px; - padding: 24px; - box-shadow: - 0 6px 20px rgba(0, 0, 0, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.4); -} - -.arch-core { - background: linear-gradient( - 135deg, - rgba(6, 182, 212, 0.15) 0%, - rgba(6, 182, 212, 0.08) 100% - ); - border-color: rgba(6, 182, 212, 0.3); - box-shadow: - 0 8px 24px rgba(6, 182, 212, 0.15), - 0 2px 8px rgba(6, 182, 212, 0.08), - inset 0 1px 0 rgba(6, 182, 212, 0.2); -} - -.arch-label { - text-align: center; - font-size: 18px; - font-weight: 700; - margin-bottom: 16px; - color: var(--cyan-light); -} - -.arch-modules { - display: flex; - flex-wrap: wrap; - gap: 12px; - justify-content: center; -} - -.arch-module { - padding: 10px 20px; - background: rgba(6, 182, 212, 0.1); - border: 1px solid rgba(6, 182, 212, 0.2); - border-radius: 8px; - font-size: 14px; - font-weight: 500; -} - -.arch-connector { - height: 40px; - width: 2px; - background: linear-gradient(to bottom, var(--cyan), var(--blue)); - margin: 0 auto; - position: relative; -} - -.arch-connector::before, -.arch-connector::after { - content: ''; - position: absolute; - left: 50%; - transform: translateX(-50%); - width: 12px; - height: 12px; - border-radius: 50%; - background: var(--cyan); -} - -.arch-connector::before { top: -6px; } -.arch-connector::after { bottom: -6px; } - -.arch-plugins { background: var(--bg-glass); } - -.arch-plugin-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 16px; -} - -.arch-plugin { - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.06) 0%, - rgba(255, 255, 255, 0.02) 100% - ); - backdrop-filter: blur(20px) saturate(150%); - -webkit-backdrop-filter: blur(20px) saturate(150%); - border: 1px solid rgba(255, 255, 255, 0.12); - border-radius: 16px; - padding: 20px; - text-align: center; - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - box-shadow: - 0 4px 12px rgba(0, 0, 0, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.arch-plugin:hover { - transform: translateY(-4px); - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.1) 0%, - rgba(255, 255, 255, 0.04) 100% - ); - backdrop-filter: blur(30px) saturate(170%); - -webkit-backdrop-filter: blur(30px) saturate(170%); - border-color: rgba(255, 255, 255, 0.22); - box-shadow: - 0 10px 28px rgba(0, 0, 0, 0.12), - 0 3px 8px rgba(0, 0, 0, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.5); -} - -.arch-plugin-title { - font-weight: 700; - font-size: 15px; - margin-bottom: 12px; - color: var(--cyan-light); -} - -.arch-plugin-items { - font-size: 13px; - color: var(--text-muted); - margin-bottom: 4px; -} - -/* 数据流 */ -.arch-flow { max-width: 900px; margin: 0 auto; } -.arch-flow-title { text-align: center; font-size: 28px; font-weight: 800; margin-bottom: 32px; } - -.arch-flow-steps { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - gap: 12px; -} - -.flow-step { - display: flex; - align-items: center; - gap: 10px; - padding: 12px 20px; - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.08) 0%, - rgba(255, 255, 255, 0.03) 100% - ); - backdrop-filter: blur(20px) saturate(150%); - -webkit-backdrop-filter: blur(20px) saturate(150%); - border: 1px solid rgba(255, 255, 255, 0.15); - border-radius: 16px; - font-size: 14px; - font-weight: 500; - box-shadow: - 0 4px 12px rgba(0, 0, 0, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.4); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -.flow-step:hover { - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.12) 0%, - rgba(255, 255, 255, 0.05) 100% - ); - backdrop-filter: blur(30px) saturate(170%); - -webkit-backdrop-filter: blur(30px) saturate(170%); - border-color: rgba(255, 255, 255, 0.25); - box-shadow: - 0 8px 24px rgba(0, 0, 0, 0.12), - 0 2px 6px rgba(0, 0, 0, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.6); - transform: translateY(-2px); -} - -.flow-step-num { - display: flex; - align-items: center; - justify-content: center; - width: 28px; - height: 28px; - border-radius: 50%; - background: linear-gradient(135deg, var(--cyan), var(--blue)); - font-size: 13px; - font-weight: 700; - flex-shrink: 0; -} - -.flow-arrow { color: var(--cyan); font-size: 20px; font-weight: 700; } - -/* 快速开始 */ -.steps-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 24px; - margin-bottom: 64px; -} - -.step-card { - /* 苹果液态玻璃 */ - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.08) 0%, - rgba(255, 255, 255, 0.03) 100% - ); - backdrop-filter: blur(30px) saturate(160%); - -webkit-backdrop-filter: blur(30px) saturate(160%); - border: 1px solid rgba(255, 255, 255, 0.15); - border-radius: 20px; - padding: 32px; - text-align: center; - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - box-shadow: - 0 6px 20px rgba(0, 0, 0, 0.1), - 0 2px 6px rgba(0, 0, 0, 0.06), - inset 0 1px 0 rgba(255, 255, 255, 0.4); -} - -.step-card:hover { - transform: translateY(-4px); - background: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.12) 0%, - rgba(255, 255, 255, 0.05) 100% - ); - backdrop-filter: blur(40px) saturate(180%); - -webkit-backdrop-filter: blur(40px) saturate(180%); - border-color: rgba(255, 255, 255, 0.25); - box-shadow: - 0 12px 32px rgba(0, 0, 0, 0.15), - 0 4px 10px rgba(0, 0, 0, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.6); -} - -.step-number { - display: inline-flex; - align-items: center; - justify-content: center; - width: 48px; - height: 48px; - border-radius: 50%; - background: linear-gradient(135deg, var(--cyan), var(--blue)); - font-size: 20px; - font-weight: 800; - margin-bottom: 20px; -} - -.step-title { font-size: 20px; font-weight: 700; margin-bottom: 16px; } - -.step-code { - font-family: 'JetBrains Mono', monospace; - font-size: 13px; - line-height: 1.8; - color: var(--text-secondary); - text-align: left; - background: rgba(10, 15, 30, 0.6); - padding: 16px; - border-radius: 8px; -} - -.quickstart-links { - display: flex; - justify-content: center; - gap: 16px; - flex-wrap: wrap; -} - -/* 响应式 */ -@media (max-width: 1024px) { - .features-grid { grid-template-columns: repeat(2, 1fr); } - .arch-plugin-grid { grid-template-columns: repeat(2, 1fr); } -} - -@media (max-width: 768px) { - .page-content { - padding: 80px 20px 60px; - } - .features-grid { grid-template-columns: 1fr; } - .arch-plugin-grid { grid-template-columns: 1fr; } - .steps-grid { grid-template-columns: 1fr; } - .arch-flow-steps { flex-direction: column; } - .flow-arrow { transform: rotate(90deg); } - .pkg-explain { grid-template-columns: 1fr; } - .pkg-table { overflow-x: auto; } - - /* 移动端页面标题区域 */ - .page-header { - margin-bottom: 40px; - } - .page-title { - font-size: 28px; - } - .page-desc { - font-size: 15px; - } - - /* 移动端特性卡片 */ - .feature-card { - padding: 24px; - } - .feature-icon { - width: 48px; - height: 48px; - } - .feature-icon svg { - width: 24px; - height: 24px; - } -} - -@media (max-width: 480px) { - .page-content { - padding: 60px 16px 40px; - } - .page-header { - margin-bottom: 32px; - } - .page-title { - font-size: 24px; - } - .page-desc { - font-size: 14px; - } - .feature-card { - padding: 20px; - } -} diff --git a/website/css/plugins.css b/website/css/plugins.css deleted file mode 100644 index 2d92bdb..0000000 --- a/website/css/plugins.css +++ /dev/null @@ -1,110 +0,0 @@ -/* ===== 插件生态 ===== */ -#plugins { - padding: 120px 0; - background: var(--bg-secondary); - position: relative; - z-index: 1; -} - -.plugins-content { - max-width: 900px; - margin: 0 auto; -} - -.pkg-format { text-align: center; margin-bottom: 48px; } - -.pkg-card { - font-family: 'JetBrains Mono', monospace; - font-size: clamp(20px, 4vw, 36px); - font-weight: 700; - padding: 32px; - background: var(--bg-glass); - border: 1px solid var(--border); - border-radius: 16px; - display: inline-block; - margin-bottom: 32px; -} - -.pkg-symbol { color: var(--text-muted); } -.pkg-highlight { color: var(--cyan); } -.pkg-version { color: var(--blue); } - -.pkg-explain { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 24px; - text-align: center; -} - -.explain-symbol { - font-family: 'JetBrains Mono', monospace; - font-size: 18px; - font-weight: 600; - color: var(--cyan-light); - margin-bottom: 8px; -} - -.explain-text { - font-size: 14px; - color: var(--text-muted); -} - -.install-demo { - background: rgba(10, 15, 30, 0.9); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 16px; - overflow: hidden; -} - -.demo-header { - display: flex; - align-items: center; - gap: 8px; - padding: 14px 20px; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); -} - -.demo-dot { - width: 12px; - height: 12px; - border-radius: 50%; -} - -.demo-dot-red { background: #ef4444; } -.demo-dot-yellow { background: #eab308; } -.demo-dot-green { background: #22c55e; } - -.demo-title { - margin-left: 12px; - font-size: 13px; - color: var(--text-muted); -} - -.demo-body { - padding: 20px; - font-family: 'JetBrains Mono', monospace; - font-size: 14px; -} - -.cmd-line { - display: flex; - gap: 12px; - margin-bottom: 8px; - color: var(--text-secondary); -} - -.prompt { color: var(--cyan); font-weight: 600; } -.cmd-text { color: #e5e7eb; } - -.cmd-output { - color: #9ca3af; - font-size: 13px; - margin-bottom: 4px; -} - -.cmd-output.success { color: #34d399; } -.cmd-output.indent { padding-left: 24px; } - -@media (max-width: 640px) { - .pkg-explain { grid-template-columns: 1fr; } -} diff --git a/website/css/stats.css b/website/css/stats.css deleted file mode 100644 index 7ee4b8e..0000000 --- a/website/css/stats.css +++ /dev/null @@ -1,52 +0,0 @@ -/* ===== 统计区域 ===== */ -#stats { - padding: 80px 0; - position: relative; - z-index: 1; - background: linear-gradient(135deg, rgba(6, 182, 212, 0.05), rgba(59, 130, 246, 0.05)); - border-top: 1px solid var(--border); - border-bottom: 1px solid var(--border); -} - -.stats-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 32px; - max-width: 1000px; - margin: 0 auto; - text-align: center; -} - -.stat-card { - padding: 24px; -} - -.stat-number { - font-size: 48px; - font-weight: 900; - background: linear-gradient(135deg, var(--cyan), var(--blue)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.stat-suffix { - font-size: 32px; - font-weight: 800; - background: linear-gradient(135deg, var(--cyan), var(--blue)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.stat-label { - display: block; - margin-top: 8px; - font-size: 16px; - color: var(--text-muted); - font-weight: 500; -} - -@media (max-width: 768px) { - .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 24px; } -} diff --git a/website/docs/architecture.html b/website/docs/architecture.html deleted file mode 100644 index 311f0a7..0000000 --- a/website/docs/architecture.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - 架构设计 - Future OSS 文档 - - - - - - - - -
    - -
    -
    - -
    - - - - 文档中心 -
    -
    入门 · 架构设计
    -
    - 完整 Wiki -
    -
    - -
    - -
    -
    -
    -
    入门
    - 什么是 FutureOSS/ 项目介绍 - 为什么选择 Python/ 技术选型 - 架构设计/ 三层架构 -
    -
    -
    快速开始
    -
    -
    -
    插件
    - 官方插件列表/ 12+ 插件 - 插件开发指南/ 开发基础 -
    -
    - -
    -
    -

    🏗️ 架构设计

    - -

    三层架构

    -

    核心层 (oss/) — 插件管理、事件总线、消息总线、配置系统、日志系统。框架的核心基础设施。

    -

    插件层 (store/) — 协议插件(HTTP/WS/TCP)、工具插件(依赖解析、存储、桥接)、中间件插件(熔断、热重载、生命周期)。

    -

    应用层 (data/) — 第三方插件(HTML 渲染、Web 工具包)+ 运行时数据(配置文件、共享存储)。

    - -

    启动流程

    -
      -
    1. 加载 config.yaml → Config 对象
    2. -
    3. 初始化 Logger
    4. -
    5. 创建 PluginManager,只加载 plugin-loader
    6. -
    7. plugin-loader 扫描 store/ 目录,加载所有插件
    8. -
    9. 使用 dependency 插件进行拓扑排序
    10. -
    11. 按拓扑顺序 init() → start() 所有插件
    12. -
    13. HTTP 服务器启动,注册路由
    14. -
    15. 信号监听 → Ctrl+C 时优雅关闭(逆序 stop)
    16. -
    - -

    目录结构

    -
    FutureOSS/
    -├── oss/                    # 核心框架
    -│   ├── cli.py              # CLI 入口
    -│   ├── config/             # 配置加载
    -│   ├── logger/             # 日志系统
    -│   ├── plugin/             # 插件核心
    -│   │   ├── types.py        # 类型定义
    -│   │   ├── loader.py       # 动态加载器
    -│   │   ├── manager.py      # 插件管理器
    -│   │   └── event_bus.py    # 事件总线
    -│   └── server/             # HTTP 服务器
    -├── store/                  # 本地插件仓库
    -│   └── @{FutureOSS}/       # 官方插件
    -└── data/                   # 运行时数据
    -
    -
    -
    -
    - - - - - - 获取更多信息 - - - - - - - - - - - diff --git a/website/docs/development.html b/website/docs/development.html deleted file mode 100644 index 1b9eb7f..0000000 --- a/website/docs/development.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - 插件开发指南 - Future OSS 文档 - - - - - - - - -
    - -
    -
    - -
    - - - - 文档中心 -
    -
    插件 · 开发指南
    -
    - 完整 Wiki -
    -
    - -
    - -
    -
    -
    -
    入门
    - 什么是 FutureOSS/ 项目介绍 - 为什么选择 Python/ 技术选型 - 架构设计/ 三层架构 -
    -
    -
    快速开始
    -
    -
    -
    插件
    - 官方插件列表/ 12+ 插件 - 插件开发指南/ 开发基础 -
    -
    - -
    -
    -

    🛠️ 插件开发指南

    - -

    插件结构

    -
    store/@{作者}/插件名/
    -├── main.py          # 插件入口(必须实现 Plugin 接口)
    -└── manifest.json    # 插件元数据(名称、版本、依赖)
    - -

    插件接口

    -
    from oss.plugin.types import Plugin
    -
    -class MyPlugin(Plugin):
    -    def init(self, deps: dict = None):
    -        # 初始化逻辑
    -        pass
    -
    -    def start(self):
    -        # 启动逻辑
    -        pass
    -
    -    def stop(self):
    -        # 停止逻辑
    -        pass
    -
    -    @property
    -    def manifest(self):
    -        return {
    -            "name": "my-plugin",
    -            "version": "1.0.0",
    -            "dependencies": [],
    -            "description": "我的插件"
    -        }
    - -

    关键原则

    -
      -
    • 插件通过 from oss.plugin.types import Plugin 使用框架定义的接口
    • -
    • 插件的 main.py 被 importlib 加载到框架的 Python 进程中
    • -
    • 插件可以直接 from oss.xxx import xxx 引用框架模块
    • -
    • 所有插件通过 config.json 配置,不修改源码
    • -
    - -

    依赖声明

    -
    // manifest.json
    -{
    -    "name": "html-render",
    -    "version": "1.0.0",
    -    "dependencies": ["http-api", "plugin-storage"],
    -    "description": "HTML 渲染插件"
    -}
    - -

    框架会自动调用 set_http_api() 和 set_plugin_storage() 注入依赖实例。

    - -

    安装格式

    -

    格式为 @{作者名称}/插件名称,例如 @{Falck}/html-render。

    -
    -
    -
    -
    - - - - - - 获取更多信息 - - - - - - - - - - - diff --git a/website/docs/index.html b/website/docs/index.html deleted file mode 100644 index da5df44..0000000 --- a/website/docs/index.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - 什么是 FutureOSS - Future OSS 文档 - - - - - - - - -
    - -
    -
    - -
    - - - - 文档中心 -
    -
    入门 · 项目介绍
    -
    - 完整 Wiki -
    -
    - -
    - -
    -
    -
    -
    入门
    - 什么是 FutureOSS/ 项目介绍 - 为什么选择 Python/ 技术选型 - 架构设计/ 三层架构 -
    -
    -
    快速开始
    -
    -
    -
    插件
    - 官方插件列表/ 12+ 插件 - 插件开发指南/ 开发基础 -
    -
    - -
    -
    -

    🧩 什么是 FutureOSS?

    - -

    FutureOSS 是一个一切皆为插件的开发者工具运行时框架。框架本身是空壳,所有功能均以插件形式加载。

    - -

    项目定位

    -

    协议、中间件、通知渠道……所有功能均以插件形式加载。内置熔断降级、依赖自动解析、事件驱动等企业级稳定性机制。

    - -

    核心特性

    -
      -
    • 一切皆插件 — 框架本身不提供任何业务功能,所有能力通过插件扩展
    • -
    • 热插拔 — 插件运行时加载与卸载,改完即生效,零编译
    • -
    • 依赖自动解析 — 拓扑排序 (Kahn 算法) + 循环依赖检测
    • -
    • 熔断与降级 — 自动熔断,支持 closed/open/half-open 状态切换
    • -
    • 包管理系统 — 一键安装/卸载/更新插件,支持 @{作者}/插件名 格式
    • -
    • 事件驱动 — 发布/订阅 + 通配符匹配 + RPC 桥接
    • -
    • 统一存储 — plugin-storage 为每个插件提供隔离的文件读写入口
    • -
    - -
    - -

    关键原则

    - -

    类型共享

    -

    框架在 oss/plugin/types.py 中定义所有数据类型和接口,插件通过 from oss.plugin.types import Plugin 直接使用。插件不应重复定义 Logger、EventBus 等类型。

    - -

    配置驱动

    -

    所有插件通过 config.json 配置,不修改源码。配置文件使用相对路径,相对于 config.json 所在目录。

    - -

    插件安装格式

    -

    格式为 @{作者名称}/插件名称,命令:oss pkg install @{Falck}/http-server

    -
    -
    -
    -
    - - - - - - 获取更多信息 - - - - - - - - - - - - - diff --git a/website/docs/plugins.html b/website/docs/plugins.html deleted file mode 100644 index 60142ec..0000000 --- a/website/docs/plugins.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - 官方插件列表 - Future OSS 文档 - - - - - - - - -
    - -
    -
    - -
    - - - - 文档中心 -
    -
    插件 · 官方插件列表
    -
    - 完整 Wiki -
    -
    - -
    - -
    -
    -
    -
    入门
    - 什么是 FutureOSS/ 项目介绍 - 为什么选择 Python/ 技术选型 - 架构设计/ 三层架构 -
    -
    -
    快速开始
    -
    -
    -
    插件
    - 官方插件列表/ 12+ 插件 - 插件开发指南/ 开发基础 -
    -
    - -
    -
    -

    📦 官方插件列表

    - - - - - - - - - - - - - - - - - -
    插件名说明依赖
    plugin-loader核心插件,扫描/加载/管理所有插件无
    dependency拓扑排序 (Kahn 算法) + 循环依赖检测无
    http-apiHTTP 服务器 (8080) + 路由 + 中间件 + CORS无
    http-tcpHTTP TCP 服务器 (8082)无
    ws-apiWebSocket 服务器 (8081) + 事件总线无
    plugin-storage统一文件读写 + JSON 键值存储 + 目录隔离无
    plugin-bridge事件总线 + 广播 + RPC + 桥接plugin-storage
    circuit-breaker熔断器 (closed/open/half-open)无
    hot-reload文件监听 + 热加载/卸载/更新插件无
    lifecycle生命周期状态机 (pending/running/stopped)无
    json-codecJSON 序列化/反序列化 + Schema 验证无
    pkg包管理 (搜索/安装/卸载/更新)无
    -
    -
    -
    -
    - - - - - - 获取更多信息 - - - - - - - - - - - diff --git a/website/docs/why-python.html b/website/docs/why-python.html deleted file mode 100644 index 043ba94..0000000 --- a/website/docs/why-python.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - 为什么选择 Python - Future OSS 文档 - - - - - - - - -
    - -
    -
    - -
    - - - - 文档中心 -
    -
    入门 · 为什么用Python
    -
    - 完整 Wiki -
    -
    - -
    - -
    -
    -
    -
    入门
    - 什么是 FutureOSS/ 项目介绍 - 为什么选择 Python/ 技术选型 - 架构设计/ 三层架构 -
    -
    -
    快速开始
    -
    -
    -
    插件
    - 官方插件列表/ 12+ 插件 - 插件开发指南/ 开发基础 -
    -
    - -
    -
    -

    🐍 为什么从 Go 重构为 Python?

    - -

    Go 的 plugin 包不适合热插拔场景。.so 文件与主程序是独立编译单元,类型不共享,依赖注入后接口不匹配会导致 panic。Python 的动态特性天然适合插件化架构。

    - -

    技术对比

    - - - - - - - - - - -
    问题Go 方案Python 方案
    插件热插拔plugin.Open(".so")importlib 动态加载 .py
    依赖注入反射注入,类型不匹配 → panic直接传 dict/对象,无编译隔离
    开发效率每次改插件需重新编译改完即生效,零编译
    配置类型map[string]string 限制dict[str, Any] 原生支持任意类型
    - -

    Go 插件系统的致命问题

    -

    Go 的插件机制依赖 plugin.Open() 加载编译好的 .so 文件。每个 .so 是独立的编译单元,无法共享类型定义。这意味着插件中定义的接口与框架中的接口即使签名相同,也被视为不同类型,导致依赖注入后接口为 nil,运行时直接 panic。

    - -

    Python 的优势

    -
      -
    • 动态类型 — 没有编译时类型检查,插件直接使用框架定义的类型
    • -
    • importlib — 运行时动态加载 .py 文件,零编译开销
    • -
    • 类型共享 — 插件通过 from oss.plugin.types import Plugin 直接引用框架类型
    • -
    • 开发迭代快 — 改完代码即生效,无需重新编译
    • -
    -
    -
    -
    -
    - - - - - - 获取更多信息 - - - - - - - - - - - diff --git a/website/features.html b/website/features.html deleted file mode 100644 index 1c3a809..0000000 --- a/website/features.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - 核心特性 - Future OSS - - - - - - - - - - - - - - - - - -
    - -
    -
    - 核心能力 -

    为何选择 Future OSS

    -

    每个模块都为生产环境而设计,为企业提供开箱即用的稳定性保障

    -
    - -
    -
    -
    - -
    -

    一切皆插件

    -

    协议适配、中间件、通知渠道、数据库驱动……所有功能均以插件形式加载。框架本身是空壳,只提供插件管理、事件总线和配置系统。

    -
    热插拔按需加载隔离运行
    -
    -
    -
    - -
    -

    依赖自动解析

    -

    自动识别多级上游依赖,拓扑排序决定加载顺序,循环依赖检测。插件只需声明依赖关系,运行时自动注入。

    -
    拓扑排序循环检测自动注入
    -
    -
    -
    - -
    -

    熔断与降级

    -

    内置熔断器,失败 N 次后自动熔断。支持 6 种降级策略:静态值、缓存、默认值、上游、空、自定义函数。

    -
    自动熔断6 种降级自动恢复
    -
    -
    -
    - -
    -

    包管理系统

    -

    类似 npm 的包管理体验。@{作者/插件名}<版本> 格式,一键安装、卸载、更新、同步。从 Gitee 仓库自动拉取。

    -
    一键安装版本管理自动同步
    -
    -
    -
    - -
    -

    事件驱动架构

    -

    发布/订阅事件总线,支持通配符匹配。12 种系统事件,插件间松耦合通信。消息总线支持点对点通信。

    -
    发布订阅通配符点对点
    -
    -
    -
    - -
    -

    丰富配置系统

    -

    100+ 配置参数,覆盖服务器、日志、认证、数据库、缓存、监控、安全、消息队列、任务调度、插件系统等模块。

    -
    100+ 参数热重载文件监听
    -
    -
    -
    - - - - - - - - - diff --git a/website/index.html b/website/index.html deleted file mode 100644 index 619bf21..0000000 --- a/website/index.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - Future OSS - 一切皆为插件的开发者工具运行时框架 - - - - - - - - - - - - - - - - - -
    - - -
    -
    -
    -
    - - 2026 · 插件驱动 · 一切皆可扩展 -
    -

    - Future - OSS -

    -

    一切皆为插件的开发者工具运行时框架

    -

    协议、中间件、通知渠道……所有功能均以插件形式加载。内置熔断降级、依赖自动解析、事件驱动等企业级稳定性机制。

    -
    - - 快速开始 - - - 了解更多 -
    -
    -
    100+配置参数
    -
    10插件类型
    -
    自动依赖解析
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - - - - - - - - - diff --git a/website/js/animations.js b/website/js/animations.js deleted file mode 100644 index 83acbfa..0000000 --- a/website/js/animations.js +++ /dev/null @@ -1,35 +0,0 @@ -// 动画入口 -gsap.registerPlugin(ScrollTrigger); - -// 页面元素入场 -gsap.utils.toArray('.feature-card, .step-card, .arch-layer, .arch-plugin').forEach((el, i) => { - gsap.fromTo(el, - { y: 40, opacity: 0 }, - { - y: 0, opacity: 1, duration: 0.6, - ease: 'power3.out', - scrollTrigger: { trigger: el, start: 'top 85%' }, - delay: (i % 4) * 0.1 - } - ); -}); - -// Hero 动画 -if (document.querySelector('.hero-content')) { - gsap.fromTo('.hero-content > *', - { y: 50, opacity: 0 }, - { y: 0, opacity: 1, duration: 0.8, stagger: 0.1, ease: 'power3.out', delay: 0.2 } - ); - gsap.fromTo('.hero-visual', - { scale: 0.85, opacity: 0 }, - { scale: 1, opacity: 1, duration: 1, ease: 'back.out(1.4)', delay: 0.4 } - ); -} - -// 平滑滚动 -document.querySelectorAll('a[href^="#"]').forEach(a => { - a.addEventListener('click', e => { - const target = document.querySelector(a.getAttribute('href')); - if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth' }); } - }); -}); diff --git a/website/js/app.js b/website/js/app.js deleted file mode 100644 index 84eedba..0000000 --- a/website/js/app.js +++ /dev/null @@ -1,16 +0,0 @@ -// 主应用入口 -document.addEventListener('DOMContentLoaded', () => { - // 平滑滚动到锚点 - document.querySelectorAll('a[href^="#"]').forEach(anchor => { - anchor.addEventListener('click', function(e) { - e.preventDefault(); - const target = document.querySelector(this.getAttribute('href')); - if (target) { - target.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - }); - }); - - console.log('%c Future OSS ', 'background: linear-gradient(135deg, #06b6d4, #3b82f6); color: #fff; padding: 8px 16px; border-radius: 4px; font-weight: bold;'); - console.log('%c一切皆为插件的开发者工具运行时框架', 'color: #9ca3af; font-size: 14px;'); -}); diff --git a/website/js/cube.js b/website/js/cube.js deleted file mode 100644 index 004fa81..0000000 --- a/website/js/cube.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * 3D 交互立方体(requestAnimationFrame 驱动) - * - 纯白正方体 + 青绿色发光边框,自动旋转 - * - 鼠标悬停某面时平滑过渡到该面正对用户,弹出对话框 - * - 鼠标离开 2 秒后平滑恢复旋转 - */ -(function () { - 'use strict'; - - const cube = document.getElementById('feature-cube'); - const tooltip = document.getElementById('cube-tooltip'); - if (!cube || !tooltip) return; - - const tooltipIcon = tooltip.querySelector('.cube-tooltip-icon'); - const tooltipTitle = tooltip.querySelector('.cube-tooltip-title'); - const tooltipDesc = tooltip.querySelector('.cube-tooltip-desc'); - const faces = cube.querySelectorAll('.cube-face'); - - // 旋转状态 - let angleX = -20; - let angleY = 0; - let isSpinning = true; - let resumeTimer = null; - let currentFace = null; - - // 目标角度(悬停时设置) - let targetX = null; - let targetY = null; - - const SPEED_Y = 0.5; // Y 轴每帧旋转速度 - const SPEED_X = 0.15; // X 轴微动速度 - const LERP = 0.05; // 平滑插值系数 - - // 六个面的特性数据 - const faceData = { - front: { icon: '🧩', title: '一切皆为插件', desc: '协议、中间件、通知渠道,所有功能均以插件形式加载' }, - back: { icon: '🔄', title: '热插拔', desc: '插件运行时加载与卸载,改完即生效,零编译' }, - right: { icon: '🔗', title: '依赖自动解析', desc: '拓扑排序 + 循环依赖检测,自动处理加载顺序' }, - left: { icon: '🛡️', title: '熔断降级', desc: '内置熔断器,支持 closed/open/half-open 状态切换' }, - top: { icon: '📡', title: '事件驱动', desc: '发布/订阅 + 通配符匹配 + RPC 桥接' }, - bottom: { icon: '📦', title: '统一存储', desc: 'plugin-storage 提供隔离的文件读写入口' } - }; - - /** - * 角度差(处理 360° 环绕,返回最短方向) - */ - function angleDiff(from, to) { - let diff = ((to - from) % 360 + 540) % 360 - 180; - return diff; - } - - /** - * 动画循环 - */ - function animate() { - if (targetX !== null && targetY !== null) { - // 平滑过渡到目标角度 - const diffX = angleDiff(angleX, targetX); - const diffY = angleDiff(angleY, targetY); - - if (Math.abs(diffX) < 0.2 && Math.abs(diffY) < 0.2) { - angleX = targetX; - angleY = targetY; - // 到达目标后停止插值,保持静止 - targetX = null; - targetY = null; - } else { - angleX += diffX * LERP; - angleY += diffY * LERP; - } - } else if (isSpinning) { - // 自动旋转:Y 轴匀速 + X 轴微动 - angleY += SPEED_Y; - angleX = -20 + Math.sin(Date.now() * 0.001) * 8; - } - - cube.style.transform = `rotateX(${angleX}deg) rotateY(${angleY}deg)`; - requestAnimationFrame(animate); - } - - /** - * 计算某个面的目标角度(Y 轴自动选最近的对齐角度,避免跳帧) - */ - function calcFaceTarget(baseX, baseY) { - // Y 轴:找到距离当前 angleY 最近的对齐角度(baseY + n*360) - const n = Math.round((angleY - baseY) / 360); - const snappedY = baseY + n * 360; - return { x: baseX, y: snappedY }; - } - - /** - * 暂停旋转,显示对话框 - */ - function pauseAndShow(faceName) { - if (currentFace === faceName) return; - currentFace = faceName; - - // 清除恢复定时器 - if (resumeTimer) { - clearTimeout(resumeTimer); - resumeTimer = null; - } - - // 计算目标角度(Y 轴自动对齐最近角度,避免跳帧) - const faceBaseTargets = { - front: { x: -20, y: 0 }, - back: { x: -20, y: 180 }, - right: { x: -20, y: -90 }, - left: { x: -20, y: 90 }, - top: { x: -90, y: 0 }, - bottom: { x: 90, y: 0 } - }; - - const base = faceBaseTargets[faceName]; - if (base) { - const snapped = calcFaceTarget(base.x, base.y); - targetX = snapped.x; - targetY = snapped.y; - } - - isSpinning = false; - - // 填充并显示对话框 - const data = faceData[faceName]; - if (!data) return; - - tooltipIcon.textContent = data.icon; - tooltipTitle.textContent = data.title; - tooltipDesc.textContent = data.desc; - void tooltip.offsetWidth; - tooltip.classList.add('is-visible'); - } - - /** - * 隐藏对话框 - */ - function hideTooltip() { - currentFace = null; - tooltip.classList.remove('is-visible'); - } - - /** - * 恢复旋转 - */ - function resumeSpin() { - hideTooltip(); - targetX = null; - targetY = null; - isSpinning = true; - } - - // 为每个面绑定 mouseenter - faces.forEach(function (face) { - face.addEventListener('mouseenter', function () { - const faceName = face.getAttribute('data-face'); - pauseAndShow(faceName); - }); - - face.addEventListener('touchstart', function () { - const faceName = face.getAttribute('data-face'); - pauseAndShow(faceName); - }, { passive: true }); - }); - - // 整个场景 mouseleave → 2 秒后恢复(用 scene 而非 cube,避免子元素事件干扰) - const scene = cube.parentElement; - if (scene) { - scene.addEventListener('mouseleave', function () { - hideTooltip(); - if (resumeTimer) clearTimeout(resumeTimer); - resumeTimer = setTimeout(function () { - resumeSpin(); - }, 2000); - }); - } - - // 启动动画 - animate(); - -})(); diff --git a/website/js/dock.js b/website/js/dock.js deleted file mode 100644 index e4428b3..0000000 --- a/website/js/dock.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Dock 侧边栏组件 - * 在所有 HTML 页面中统一引用 - */ - -(function () { - 'use strict'; - - // 获取当前页面相对于网站根目录的深度 - // 返回 '../' 或 '../../' 等,根目录页面返回 '' - function getPathPrefix() { - const path = window.location.pathname; - // 去掉文件名,得到目录部分 - const dir = path.substring(0, path.lastIndexOf('/') + 1); - // 计算目录层级数(排除开头的 /) - const segments = dir.split('/').filter(s => s.length > 0); - // 每个层级需要一个 '../' - return segments.map(() => '../').join(''); - } - - // Dock HTML 模板 - // current: 当前页面文件名,用于设置 active 状态 - function renderDock(current) { - const prefix = getPathPrefix(); - const items = [ - { href: prefix + 'index.html', tooltip: '首页', svg: 'M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6' }, - { href: prefix + 'features.html', tooltip: '特性', svg: 'M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z' }, - { href: prefix + 'docs/index.html', tooltip: '文档', svg: 'M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253' }, - { href: prefix + 'plugins.html', tooltip: '插件', svg: 'M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z' }, - { href: prefix + 'architecture.html', tooltip: '架构', svg: 'M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z' }, - { separator: true }, - { href: 'https://gitee.com/starlight-apk/feature-oss', tooltip: '源码', svg: 'M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4', target: '_blank' } - ]; - - let html = '
    \n'; - - items.forEach(item => { - if (item.separator) { - html += '
    \n'; - } else { - const isActive = item.href === current ? ' active' : ''; - const targetAttr = item.target ? ` target="${item.target}"` : ''; - html += ` \n`; - html += ` \n`; - html += ` \n`; - } - }); - - html += '
    '; - return html; - } - - // 获取当前页面文件名 - function getCurrentPage() { - const path = window.location.pathname; - const filename = path.substring(path.lastIndexOf('/') + 1); - return filename || 'index.html'; - } - - // 初始化:将 dock 插入到 body 的第一个子元素之前 - function initDock() { - const current = getCurrentPage(); - const dockHTML = renderDock(current); - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = dockHTML; - const dockElement = tempDiv.firstElementChild; - - const body = document.body; - const firstChild = body.firstChild; - if (firstChild) { - body.insertBefore(dockElement, firstChild); - } else { - body.appendChild(dockElement); - } - } - - // DOM 加载完成后初始化 - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initDock); - } else { - initDock(); - } - - // 对外暴露(如果需要手动调用) - window.OSSDock = { init: initDock, render: renderDock }; -})(); diff --git a/website/js/mouse-tracker.js b/website/js/mouse-tracker.js deleted file mode 100644 index 8d1dc88..0000000 --- a/website/js/mouse-tracker.js +++ /dev/null @@ -1,83 +0,0 @@ -// 通用鼠标位置追踪器 -// 提供全局鼠标位置状态,供其他模块使用 - -class MouseTracker { - constructor() { - this.x = 0; // 原始 X (0 ~ window.innerWidth) - this.y = 0; // 原始 Y (0 ~ window.innerHeight) - this.normalizedX = 0; // 归一化 X (-1 ~ 1) - this.normalizedY = 0; // 归一化 Y (-1 ~ 1) - this.smoothX = 0; // 平滑后的 X - this.smoothY = 0; // 平滑后的 Y - this.listeners = []; - this.smoothing = 0.1; // 平滑系数 (0~1,越小越平滑) - this.isInside = false; - - this._init(); - } - - _init() { - document.addEventListener('mousemove', (e) => { - this.x = e.clientX; - this.y = e.clientY; - this.normalizedX = (e.clientX / window.innerWidth) * 2 - 1; - this.normalizedY = (e.clientY / window.innerHeight) * 2 - 1; - this.isInside = true; - - this._notify(); - }); - - document.addEventListener('mouseleave', () => { - this.isInside = false; - }); - - // 平滑动画循环 - this._animate(); - } - - _animate() { - // 平滑插值 - this.smoothX += (this.normalizedX - this.smoothX) * this.smoothing; - this.smoothY += (this.normalizedY - this.smoothY) * this.smoothing; - - requestAnimationFrame(() => this._animate()); - } - - _notify() { - this.listeners.forEach(cb => { - cb({ - x: this.x, - y: this.y, - normalizedX: this.normalizedX, - normalizedY: this.normalizedY, - smoothX: this.smoothX, - smoothY: this.smoothY, - isInside: this.isInside - }); - }); - } - - // 添加监听器 - onUpdate(callback) { - this.listeners.push(callback); - } - - // 移除监听器 - offUpdate(callback) { - const index = this.listeners.indexOf(callback); - if (index > -1) this.listeners.splice(index, 1); - } - - // 设置平滑系数 - setSmoothing(value) { - this.smoothing = Math.max(0, Math.min(1, value)); - } - - // 获取当前平滑值 - getSmooth() { - return { x: this.smoothX, y: this.smoothY }; - } -} - -// 导出全局实例 -window.mouseTracker = new MouseTracker(); diff --git a/website/js/parallax.js b/website/js/parallax.js deleted file mode 100644 index e47f2a7..0000000 --- a/website/js/parallax.js +++ /dev/null @@ -1,261 +0,0 @@ -// 统一视差追踪器 -// 自动检测并使用最佳输入源:鼠标 > 陀螺仪 > 触摸滑动 - -class ParallaxTracker { - constructor() { - this.smoothX = 0; - this.smoothY = 0; - this.targetX = 0; - this.targetY = 0; - this.elements = []; - this.listeners = []; - this.maxMove = 100; // 最大移动像素 - this.smoothing = 0.08; // 平滑系数 - this.isReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; - this.activeSource = null; // 'mouse' | 'gyro' | 'touch' - this.rafId = null; - - if (this.isReducedMotion) { - console.log('[Parallax] 用户偏好减少动画,已跳过'); - return; - } - - this._init(); - } - - _init() { - // 自动检测文档页面 - const docsContent = document.querySelector('.docs-content'); - if (docsContent && !docsContent.hasAttribute('data-parallax-speed')) { - docsContent.setAttribute('data-parallax-speed', '0.5'); - } - - // 自动检测首页 - const heroContent = document.querySelector('.hero-content'); - if (heroContent && !heroContent.hasAttribute('data-parallax-speed')) { - heroContent.setAttribute('data-parallax-speed', '0.5'); - } - - const heroSection = document.querySelector('.page-hero'); - if (heroSection && !heroSection.hasAttribute('data-parallax-speed')) { - heroSection.setAttribute('data-parallax-speed', '0.5'); - } - - // 查找视差元素 - document.querySelectorAll('[data-parallax-speed]').forEach(el => { - const speed = parseFloat(el.dataset.parallaxSpeed) || 0.1; - this.elements.push({ el, speed }); - el.style.willChange = 'transform'; - }); - - if (this.elements.length === 0) return; - - const isMobile = this._isMobileDevice(); - - // 按优先级尝试输入源 - if (isMobile) { - // 移动端优先使用陀螺仪 - if (this._initGyroscope()) { - this.activeSource = 'gyro'; - console.log('[Parallax] 使用陀螺仪输入'); - } else { - // 陀螺仪不可用时使用触摸滑动 - this._initTouchFallback(); - this.activeSource = 'touch'; - console.log('[Parallax] 使用触摸滑动输入'); - } - } else { - // 桌面端使用鼠标 - this._initMouse(); - this.activeSource = 'mouse'; - console.log('[Parallax] 使用鼠标输入'); - } - - // 启动动画循环 - this._animate(); - console.log(`[Parallax] 已初始化 ${this.elements.length} 个元素,输入源: ${this.activeSource}`); - } - - // 检测是否为移动设备 - _isMobileDevice() { - return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) - || (navigator.maxTouchPoints && navigator.maxTouchPoints > 2); - } - - // ── 鼠标输入 ── - _initMouse() { - // 支持鼠标和触摸指针的设备 - const hasFinePointer = window.matchMedia('(pointer: fine)').matches; - - document.addEventListener('mousemove', (e) => { - this.targetX = (e.clientX / window.innerWidth) * 2 - 1; - this.targetY = (e.clientY / window.innerHeight) * 2 - 1; - }); - - // 即使没有 fine pointer 也返回 true,让鼠标事件始终生效 - return true; - } - - // ── 陀螺仪输入 ── - _initGyroscope() { - if (!window.DeviceOrientationEvent) { - console.log('[Parallax] 设备不支持 DeviceOrientationEvent'); - return false; - } - - let hasFired = false; - const handler = (e) => { - // gamma: 左右倾斜 (-90 ~ 90) - // beta: 前后倾斜 (-180 ~ 180) - if (e.gamma === null && e.beta === null) return; - - if (!hasFired) { - hasFired = true; - console.log('[Parallax] 陀螺仪数据已就绪'); - } - - // 归一化到 -1 ~ 1(限制在 ±45 度范围内) - this.targetX = Math.max(-1, Math.min(1, e.gamma / 45)); - this.targetY = Math.max(-1, Math.min(1, (e.beta - 45) / 45)); // 减去 45° 自然持握角度 - }; - - // iOS 13+ 需要用户授权 - if (typeof DeviceOrientationEvent.requestPermission === 'function') { - // 添加点击按钮请求权限的提示 - this._addGyroPermissionButton(handler); - return false; // 等待用户授权后再启用 - } - - // Android 和其他设备直接监听 - window.addEventListener('deviceorientation', handler); - console.log('[Parallax] 陀螺仪监听已启动(无需权限)'); - return true; - } - - _addGyroPermissionButton(handler) { - // iOS 设备需要用户交互才能请求陀螺仪权限 - // 检查是否已经显示过权限按钮 - if (document.getElementById('gyro-permission-btn')) { - return; - } - - const btn = document.createElement('div'); - btn.id = 'gyro-permission-btn'; - btn.innerHTML = ` -
    -
    - - - -

    开启陀螺仪视差

    - 移动设备时页面会跟随滚动 - -
    -
    - `; - document.body.appendChild(btn); - - btn.querySelector('button').addEventListener('click', async () => { - try { - const permission = await DeviceOrientationEvent.requestPermission(); - if (permission === 'granted') { - window.addEventListener('deviceorientation', handler); - this.activeSource = 'gyro'; - console.log('[Parallax] 陀螺仪权限已授予'); - btn.remove(); - } else { - console.warn('[Parallax] 陀螺仪权限被拒绝'); - btn.remove(); - // 权限被拒绝后使用触摸滑动 - this._initTouchFallback(); - this.activeSource = 'touch'; - } - } catch (err) { - console.warn('[Parallax] 陀螺仪权限请求失败', err); - btn.remove(); - // 出错时使用触摸滑动 - this._initTouchFallback(); - this.activeSource = 'touch'; - } - }); - - // 点击遮罩关闭 - btn.querySelector('.gyro-permission-overlay').addEventListener('click', () => { - btn.remove(); - // 用户关闭后使用触摸滑动 - this._initTouchFallback(); - this.activeSource = 'touch'; - }); - } - - // ── 触摸滑动输入 ── - _initTouchFallback() { - let startX = 0, startY = 0; - let currentX = 0, currentY = 0; - let isTouching = false; - - document.addEventListener('touchstart', (e) => { - isTouching = true; - startX = e.touches[0].clientX; - startY = e.touches[0].clientY; - currentX = startX; - currentY = startY; - }, { passive: true }); - - document.addEventListener('touchmove', (e) => { - if (!isTouching) return; - currentX = e.touches[0].clientX; - currentY = e.touches[0].clientY; - - // 计算相对于起始点的偏移 - const deltaX = (currentX - startX) / window.innerWidth; - const deltaY = (currentY - startY) / window.innerHeight; - - this.targetX = Math.max(-1, Math.min(1, deltaX * 4)); // 放大灵敏度 - this.targetY = Math.max(-1, Math.min(1, deltaY * 4)); - }, { passive: true }); - - document.addEventListener('touchend', () => { - isTouching = false; - // 缓慢回归中心 - const resetInterval = setInterval(() => { - this.targetX *= 0.9; - this.targetY *= 0.9; - if (Math.abs(this.targetX) < 0.01 && Math.abs(this.targetY) < 0.01) { - this.targetX = 0; - this.targetY = 0; - clearInterval(resetInterval); - } - }, 16); - }, { passive: true }); - } - - // ── 动画循环 ── - _animate() { - // 平滑插值(指数移动平均) - this.smoothX += (this.targetX - this.smoothX) * this.smoothing; - this.smoothY += (this.targetY - this.smoothY) * this.smoothing; - - // 应用变换 - this.elements.forEach(({ el, speed }) => { - const moveX = -this.smoothX * speed * this.maxMove; - const moveY = -this.smoothY * speed * this.maxMove; - el.style.transform = `translate3d(${moveX}px, ${moveY}px, 0)`; - }); - - requestAnimationFrame(() => this._animate()); - } - - // 添加监听器(供其他模块使用) - onUpdate(callback) { - this.listeners.push(callback); - } - - // 获取当前平滑值 - getSmooth() { - return { x: this.smoothX, y: this.smoothY }; - } -} - -// 导出全局实例 -window.parallaxTracker = new ParallaxTracker(); diff --git a/website/js/particles.js b/website/js/particles.js deleted file mode 100644 index 2337d98..0000000 --- a/website/js/particles.js +++ /dev/null @@ -1,83 +0,0 @@ -// 粒子背景动画 -const canvas = document.getElementById('particles'); -const ctx = canvas.getContext('2d'); - -let width, height, particles = []; - -function resize() { - width = canvas.width = window.innerWidth; - height = canvas.height = window.innerHeight; -} - -class Particle { - constructor() { - this.reset(); - } - - reset() { - this.x = Math.random() * width; - this.y = Math.random() * height; - this.size = 1 + Math.random() * 2; - this.speedX = -0.2 + Math.random() * 0.4; - this.speedY = -0.2 + Math.random() * 0.4; - this.opacity = 0.1 + Math.random() * 0.3; - } - - update() { - this.x += this.speedX; - this.y += this.speedY; - - if (this.x < 0 || this.x > width || this.y < 0 || this.y > height) { - this.reset(); - } - } - - draw() { - ctx.beginPath(); - ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); - ctx.fillStyle = `rgba(6, 182, 212, ${this.opacity})`; - ctx.fill(); - } -} - -function init() { - resize(); - const count = Math.min(80, Math.floor((width * height) / 15000)); - particles = Array.from({ length: count }, () => new Particle()); -} - -function animate() { - ctx.clearRect(0, 0, width, height); - - // 绘制连线 - for (let i = 0; i < particles.length; i++) { - for (let j = i + 1; j < particles.length; j++) { - const dx = particles[i].x - particles[j].x; - const dy = particles[i].y - particles[j].y; - const dist = Math.sqrt(dx * dx + dy * dy); - - if (dist < 120) { - ctx.beginPath(); - ctx.moveTo(particles[i].x, particles[i].y); - ctx.lineTo(particles[j].x, particles[j].y); - ctx.strokeStyle = `rgba(6, 182, 212, ${0.05 * (1 - dist / 120)})`; - ctx.lineWidth = 0.5; - ctx.stroke(); - } - } - } - - particles.forEach(p => { - p.update(); - p.draw(); - }); - - requestAnimationFrame(animate); -} - -window.addEventListener('resize', () => { - resize(); -}); - -init(); -animate(); diff --git a/website/js/spa.js b/website/js/spa.js deleted file mode 100644 index 2900bac..0000000 --- a/website/js/spa.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 极简软重定向 (SPA Router) - * 拦截所有站内链接,使用 fetch + DOM 替换实现无刷新跳转 - */ -(function() { - document.addEventListener('click', function(e) { - const link = e.target.closest('a'); - if (!link || link.target === '_blank' || link.href.startsWith('javascript:')) return; - - const url = new URL(link.href); - if (url.origin !== window.location.origin) return; // 仅拦截站内 - - e.preventDefault(); - navigate(url.pathname + url.search, true); - }); - - window.addEventListener('popstate', function(e) { - if (e.state && e.state.html) { - document.title = e.state.title; - document.querySelector('main').innerHTML = e.state.html; - initPage(); - } else { - navigate(window.location.pathname + window.location.search, false); - } - }); - - async function navigate(url, push) { - try { - const res = await fetch(url); - if (!res.ok) { window.location.href = url; return; } - - const html = await res.text(); - const doc = new DOMParser().parseFromString(html, 'text/html'); - - // 1. 更新标题 - document.title = doc.title; - - // 2. 替换 Main 内容 - const newMain = doc.querySelector('main'); - const oldMain = document.querySelector('main'); - if (newMain && oldMain) { - oldMain.innerHTML = newMain.innerHTML; - } - - // 3. 更新 URL - if (push) { - history.pushState({ - url: url, - html: newMain ? newMain.innerHTML : '', - title: doc.title - }, '', url); - window.scrollTo(0, 0); - } - - // 4. 更新 Dock 高亮 - document.querySelectorAll('#dock .dock-item').forEach(el => { - const href = el.getAttribute('href'); - el.classList.toggle('active', href && url.startsWith(href)); - }); - - // 5. 重新注入脚本/逻辑 - injectScripts(doc); - initPage(); - - } catch (err) { - console.error(err); - window.location.href = url; - } - } - - function injectScripts(doc) { - doc.scripts.forEach(oldScript => { - const newScript = document.createElement('script'); - Array.from(oldScript.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value)); - if (oldScript.src) { - newScript.src = oldScript.src; - document.body.appendChild(newScript); - } else { - newScript.textContent = oldScript.textContent; - document.body.appendChild(newScript); - } - }); - } - - // 通用页面初始化入口 - function initPage() { - // 尝试调用社区模块初始化 - if (typeof initCommunity === 'function') { - // 如果脚本已加载,直接调用 - initCommunity(); - } else { - // 否则动态加载 - if (location.pathname.includes('/community/') || location.pathname.endsWith('/community/')) { - const s = document.createElement('script'); - s.src = '/community/assets/js/community.js'; - document.body.appendChild(s); - } - } - } -})(); \ No newline at end of file diff --git a/website/plugins.html b/website/plugins.html deleted file mode 100644 index 639b5b2..0000000 --- a/website/plugins.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - 插件生态 - Future OSS - - - - - - - - - - - - - - - - - -
    - -
    -
    - 插件生态 -

    包名格式与安装流程

    -

    简洁且富有表现力的包名格式,让插件管理像呼吸一样自然

    -
    - -
    -
    -
    - @{ - 作者名称 - }/ - 插件名称 -
    -
    -
    -
    @{ }
    -
    大括号包裹作者名称
    -
    -
    -
    /
    -
    分隔作者与插件名称
    -
    -
    -
    - -
    -
    - - - - 终端 -
    -
    -
    - $ - oss pkg install @{Falck}/http-server -
    -
    ✅ @{Falck}/http-server 安装完成
    -
    - $ - oss pkg list -
    -
    已安装插件:
    -
    @{Falck}/http-server - HTTP 协议适配器
    -
    - $ - oss pkg update -
    -
    ✅ 所有插件已更新至最新版本
    -
    -
    - -
    -

    常用命令

    - - - - - - - - - - - - - -
    命令别名说明
    oss pkg install @{作者名称}/插件名称i / add安装指定作者的插件
    oss pkg remove @{作者名称}/插件名称rm / uninstall卸载指定的插件
    oss pkg listls列出所有已安装的插件
    oss pkg update [插件名]—更新单个或所有插件
    oss pkg sync—从远程仓库同步所有插件
    oss pkg search 关键词find搜索可用的插件
    oss pkg clean—清理下载缓存
    -
    -
    -
    - - - - - - - - - diff --git a/website/sitemap.xml b/website/sitemap.xml deleted file mode 100644 index 9bc2a31..0000000 --- a/website/sitemap.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - https://oss-runtime.dev/ - 2026-04-05 - weekly - 1.0 - - - - https://oss-runtime.dev/features - 2026-04-05 - monthly - 0.8 - - - - https://oss-runtime.dev/architecture - 2026-04-05 - monthly - 0.7 - - - - https://oss-runtime.dev/plugins - 2026-04-05 - weekly - 0.8 - - - - - https://oss-runtime.dev/community/ - 2026-04-05 - daily - 0.7 - - - - https://oss-runtime.dev/community/post.php - 2026-04-05 - daily - 0.6 - - - - https://oss-runtime.dev/community/profile.php - 2026-04-05 - weekly - 0.5 - - - - https://oss-runtime.dev/community/my-posts.php - 2026-04-05 - weekly - 0.4 - - - - https://oss-runtime.dev/community/editor.php - 2026-04-05 - monthly - 0.4 - - - - https://oss-runtime.dev/community/edit-profile.php - 2026-04-05 - monthly - 0.3 - - - - https://oss-runtime.dev/community/login.php - 2026-04-05 - monthly - 0.3 - - - - https://oss-runtime.dev/community/register.php - 2026-04-05 - monthly - 0.3 - - - diff --git a/website/update.php b/website/update.php deleted file mode 100644 index b8efdf9..0000000 --- a/website/update.php +++ /dev/null @@ -1,126 +0,0 @@ - $path, 'sha' => $item['sha'], 'size' => $item['size'] ?? 0]; - } - } - - $log .= "获取到 " . count($websiteFiles) . " 个远程文件\n"; - - $updated = 0; $created = 0; $errors = 0; - $shaCacheFile = CACHE_DIR . '/file_shas.json'; - $localShas = file_exists($shaCacheFile) ? json_decode(@file_get_contents($shaCacheFile), true) : []; - if (!is_array($localShas)) $localShas = []; - - foreach ($websiteFiles as $file) { - $relativePath = substr($file['path'], strlen('website/')); - $localPath = __DIR__ . '/' . $relativePath; - $remoteSha = $file['sha']; - - $dir = dirname($localPath); - if (!is_dir($dir)) @mkdir($dir, 0755, true); - - $needsUpdate = false; - $reason = ''; - - if (!file_exists($localPath)) { - $needsUpdate = true; $reason = '文件缺失'; - } else { - $localSha = $localShas[$relativePath] ?? ''; - if ($localSha !== $remoteSha) { $needsUpdate = true; $reason = '内容已变更'; } - } - - if ($needsUpdate) { - $contentUrl = sprintf('%s/%s/%s/contents/%s?ref=%s', GITEE_API_BASE, GITEE_OWNER, GITEE_REPO, $file['path'], GITEE_BRANCH); - $contentData = httpGetJson($contentUrl); - if ($contentData && isset($contentData['content'])) { - $content = base64_decode(str_replace(["\n", "\r"], '', $contentData['content'])); - if (@file_put_contents($localPath, $content) !== false) { - $localShas[$relativePath] = $remoteSha; - if ($reason === '文件缺失') { $created++; $log .= "✅ 创建: $relativePath\n"; } - else { $updated++; $log .= "🔄 更新: $relativePath ($reason)\n"; } - } else { $errors++; $log .= "❌ 写入失败: $relativePath\n"; } - } else { $errors++; $log .= "❌ 获取内容失败: $relativePath\n"; } - } - } - - @file_put_contents($shaCacheFile, json_encode($localShas)); - @file_put_contents(CACHE_DIR . '/update_check.json', json_encode([ - 'timestamp' => time(), 'files' => count($websiteFiles), - 'updated' => $updated, 'created' => $created, 'errors' => $errors - ], JSON_PRETTY_PRINT)); - - $log .= "完成: 更新 $updated 个,创建 $created 个,错误 $errors 个\n"; - $log .= "下次检查: " . date('Y-m-d H:i:s', time() + UPDATE_INTERVAL) . "\n\n"; - @file_put_contents($logFile, $log, FILE_APPEND); - - } catch (Exception $e) { - $log .= "异常: " . $e->getMessage() . "\n"; - @file_put_contents($logFile, $log, FILE_APPEND); - } -} - -function httpGetJson($url) { - $context = stream_context_create(['http' => ['method' => 'GET', 'header' => ['User-Agent: OSS-AutoUpdate/1.0', 'Accept: application/json'], 'timeout' => 30], 'ssl' => ['verify_peer' => true, 'verify_peer_name' => true]]); - $response = @file_get_contents($url, false, $context); - if ($response === false) return null; - return json_decode($response, true); -} - -register_shutdown_function('autoUpdateWebsite');