├── README.md ├── install.sh ├── soga-tool-amd64 ├── soga-tool-arm64 └── soga.sh /README.md: -------------------------------------------------------------------------------- 1 | soga 2 | 3 | [doc](https://soga.yougotme.cc/) 4 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | red='\033[0;31m' 4 | green='\033[0;32m' 5 | yellow='\033[0;33m' 6 | plain='\033[0m' 7 | 8 | cur_dir=$(pwd) 9 | 10 | # check root 11 | [[ $EUID -ne 0 ]] && echo -e "${red}错误:${plain} 必须使用root用户运行此脚本!\n" && exit 1 12 | 13 | # check os 14 | if [[ -f /etc/redhat-release ]]; then 15 | release="centos" 16 | elif cat /etc/issue | grep -Eqi "debian"; then 17 | release="debian" 18 | elif cat /etc/issue | grep -Eqi "ubuntu"; then 19 | release="ubuntu" 20 | elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then 21 | release="centos" 22 | elif cat /proc/version | grep -Eqi "debian"; then 23 | release="debian" 24 | elif cat /proc/version | grep -Eqi "ubuntu"; then 25 | release="ubuntu" 26 | elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then 27 | release="centos" 28 | else 29 | echo -e "${red}未检测到系统版本,请联系脚本作者!${plain}\n" && exit 1 30 | fi 31 | 32 | arch=$(arch) 33 | 34 | if [[ $arch == "x86_64" || $arch == "x64" || $arch == "amd64" ]]; then 35 | arch="amd64" 36 | elif [[ $arch == "aarch64" || $arch == "arm64" ]]; then 37 | arch="arm64" 38 | else 39 | arch="amd64" 40 | echo -e "${red}检测架构失败,使用默认架构: ${arch}${plain}" 41 | fi 42 | 43 | echo "架构: ${arch}" 44 | 45 | if [ "$(getconf WORD_BIT)" != '32' ] && [ "$(getconf LONG_BIT)" != '64' ] ; then 46 | echo "本软件不支持 32 位系统(x86),请使用 64 位系统(x86_64),如果检测有误,请联系作者" 47 | exit 2 48 | fi 49 | 50 | #os_version="" 51 | # 52 | ## os version 53 | #if [[ -f /etc/os-release ]]; then 54 | # os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release) 55 | #fi 56 | #if [[ -z "$os_version" && -f /etc/lsb-release ]]; then 57 | # os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release) 58 | #fi 59 | # 60 | #if [[ x"${release}" == x"centos" ]]; then 61 | # if [[ ${os_version} -le 6 ]]; then 62 | # echo -e "${red}请使用 CentOS 7 或更高版本的系统!${plain}\n" && exit 1 63 | # fi 64 | #elif [[ x"${release}" == x"ubuntu" ]]; then 65 | # if [[ ${os_version} -lt 16 ]]; then 66 | # echo -e "${red}请使用 Ubuntu 16 或更高版本的系统!${plain}\n" && exit 1 67 | # fi 68 | #elif [[ x"${release}" == x"debian" ]]; then 69 | # if [[ ${os_version} -lt 8 ]]; then 70 | # echo -e "${red}请使用 Debian 8 或更高版本的系统!${plain}\n" && exit 1 71 | # fi 72 | #fi 73 | 74 | function is_cmd_exist() { 75 | local cmd="$1" 76 | if [ -z "$cmd" ]; then 77 | return 1 78 | fi 79 | 80 | which "$cmd" > /dev/null 2>&1 81 | if [ $? -eq 0 ]; then 82 | return 0 83 | fi 84 | 85 | return 2 86 | } 87 | 88 | install_base() { 89 | if [[ x"${release}" == x"centos" ]]; then 90 | yum install epel-release -y 91 | yum install wget curl tar crontabs socat tzdata -y 92 | else 93 | apt install wget curl tar cron socat tzdata -y 94 | fi 95 | } 96 | 97 | # 0: running, 1: not running, 2: not installed 98 | check_status() { 99 | if [[ ! -f /etc/systemd/system/soga.service ]]; then 100 | return 2 101 | fi 102 | temp=$(systemctl status soga | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1) 103 | if [[ x"${temp}" == x"running" ]]; then 104 | return 0 105 | else 106 | return 1 107 | fi 108 | } 109 | 110 | install_acme() { 111 | curl https://get.acme.sh | sh 112 | /root/.acme.sh/acme.sh --set-default-ca --server letsencrypt 113 | } 114 | 115 | install_soga() { 116 | cd /usr/local/ 117 | if [[ -e /usr/local/soga/ ]]; then 118 | rm /usr/local/soga/ -rf 119 | fi 120 | 121 | if [ $# == 0 ] ;then 122 | # last_version=$(curl -Ls "https://api.github.com/repos/vaxilu/soga/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') 123 | # if [[ ! -n "$last_version" ]]; then 124 | # echo -e "${red}检测 soga 版本失败,可能是超出 Github API 限制,请稍后再试,或手动指定 soga 版本安装${plain}" 125 | # exit 1 126 | # fi 127 | echo -e "开始安装 soga 最新版" 128 | wget -N --no-check-certificate -O /usr/local/soga.tar.gz https://github.com/vaxilu/soga/releases/latest/download/soga-linux-${arch}.tar.gz 129 | if [[ $? -ne 0 ]]; then 130 | echo -e "${red}下载 soga 失败,请确保你的服务器能够下载 Github 的文件${plain}" 131 | exit 1 132 | fi 133 | else 134 | last_version=$1 135 | url="https://github.com/vaxilu/soga/releases/download/${last_version}/soga-linux-${arch}.tar.gz" 136 | echo -e "开始安装 soga v$1" 137 | wget -N --no-check-certificate -O /usr/local/soga.tar.gz ${url} 138 | if [[ $? -ne 0 ]]; then 139 | echo -e "${red}下载 soga v$1 失败,请确保此版本存在${plain}" 140 | exit 1 141 | fi 142 | fi 143 | 144 | tar zxvf soga.tar.gz 145 | rm soga.tar.gz -f 146 | cd soga 147 | chmod +x soga 148 | last_version="$(./soga -v)" 149 | mkdir /etc/soga/ -p 150 | rm /etc/systemd/system/soga.service -f 151 | rm /etc/systemd/system/soga@.service -f 152 | cp -f soga.service /etc/systemd/system/ 153 | cp -f soga@.service /etc/systemd/system/ 154 | systemctl daemon-reload 155 | systemctl stop soga 156 | systemctl enable soga 157 | echo -e "${green}soga v${last_version}${plain} 安装完成,已设置开机自启" 158 | if [[ ! -f /etc/soga/soga.conf ]]; then 159 | cp soga.conf /etc/soga/ 160 | echo -e "" 161 | echo -e "全新安装,请先配置必要的内容" 162 | else 163 | systemctl start soga 164 | sleep 2 165 | check_status 166 | echo -e "" 167 | if [[ $? == 0 ]]; then 168 | echo -e "${green}soga 重启成功${plain}" 169 | else 170 | echo -e "${red}soga 可能启动失败,请稍后使用 soga log 查看日志信息${plain}" 171 | fi 172 | fi 173 | 174 | if [[ ! -f /etc/soga/blockList ]]; then 175 | cp blockList /etc/soga/ 176 | fi 177 | if [[ ! -f /etc/soga/whiteList ]]; then 178 | cp whiteList /etc/soga/ 179 | fi 180 | if [[ ! -f /etc/soga/dns.yml ]]; then 181 | cp dns.yml /etc/soga/ 182 | fi 183 | if [[ ! -f /etc/soga/routes.toml ]]; then 184 | cp routes.toml /etc/soga/ 185 | fi 186 | curl -o /usr/bin/soga -Ls https://raw.githubusercontent.com/vaxilu/soga/master/soga.sh 187 | chmod +x /usr/bin/soga 188 | curl -o /usr/bin/soga-tool -Ls https://raw.githubusercontent.com/vaxilu/soga/master/soga-tool-${arch} 189 | chmod +x /usr/bin/soga-tool 190 | echo -e "" 191 | echo "soga 管理脚本使用方法: " 192 | echo "------------------------------------------" 193 | echo "soga - 显示管理菜单 (功能更多)" 194 | echo "soga start - 启动 soga" 195 | echo "soga stop - 停止 soga" 196 | echo "soga restart - 重启 soga" 197 | echo "soga status - 查看 soga 状态" 198 | echo "soga enable - 设置 soga 开机自启" 199 | echo "soga disable - 取消 soga 开机自启" 200 | echo "soga log - 查看 soga 日志" 201 | echo "soga log n - 查看 soga 最后 n 行日志" 202 | echo "soga update - 更新 soga" 203 | echo "soga update x.x.x - 更新 soga 指定版本" 204 | echo "soga config - 显示配置文件内容" 205 | echo "soga config xx=xx yy=yy - 自动设置配置文件" 206 | echo "soga install - 安装 soga" 207 | echo "soga uninstall - 卸载 soga" 208 | echo "soga version - 查看 soga 版本" 209 | echo "------------------------------------------" 210 | } 211 | 212 | is_cmd_exist "systemctl" 213 | if [[ $? != 0 ]]; then 214 | echo "systemctl 命令不存在,请使用较新版本的系统,例如 Ubuntu 18+、Debian 9+" 215 | exit 1 216 | fi 217 | 218 | echo -e "${green}开始安装${plain}" 219 | install_base 220 | install_acme 221 | install_soga $1 222 | -------------------------------------------------------------------------------- /soga-tool-amd64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaxilu/soga/074c2486d930be067b5881893ace8a0602b1ac93/soga-tool-amd64 -------------------------------------------------------------------------------- /soga-tool-arm64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaxilu/soga/074c2486d930be067b5881893ace8a0602b1ac93/soga-tool-arm64 -------------------------------------------------------------------------------- /soga.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | red='\033[0;31m' 4 | green='\033[0;32m' 5 | yellow='\033[0;33m' 6 | plain='\033[0m' 7 | 8 | version="v1.0.0" 9 | 10 | # check root 11 | [[ $EUID -ne 0 ]] && echo -e "${red}错误: ${plain} 必须使用root用户运行此脚本!\n" && exit 1 12 | 13 | # check os 14 | if [[ -f /etc/redhat-release ]]; then 15 | release="centos" 16 | elif cat /etc/issue | grep -Eqi "debian"; then 17 | release="debian" 18 | elif cat /etc/issue | grep -Eqi "ubuntu"; then 19 | release="ubuntu" 20 | elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then 21 | release="centos" 22 | elif cat /proc/version | grep -Eqi "debian"; then 23 | release="debian" 24 | elif cat /proc/version | grep -Eqi "ubuntu"; then 25 | release="ubuntu" 26 | elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then 27 | release="centos" 28 | else 29 | echo -e "${red}未检测到系统版本,请联系脚本作者!${plain}\n" && exit 1 30 | fi 31 | 32 | os_version="" 33 | 34 | # os version 35 | if [[ -f /etc/os-release ]]; then 36 | os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release) 37 | fi 38 | if [[ -z "$os_version" && -f /etc/lsb-release ]]; then 39 | os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release) 40 | fi 41 | 42 | if [[ x"${release}" == x"centos" ]]; then 43 | if [[ ${os_version} -le 6 ]]; then 44 | echo -e "${red}请使用 CentOS 7 或更高版本的系统!${plain}\n" && exit 1 45 | fi 46 | elif [[ x"${release}" == x"ubuntu" ]]; then 47 | if [[ ${os_version} -lt 16 ]]; then 48 | echo -e "${red}请使用 Ubuntu 16 或更高版本的系统!${plain}\n" && exit 1 49 | fi 50 | elif [[ x"${release}" == x"debian" ]]; then 51 | if [[ ${os_version} -lt 8 ]]; then 52 | echo -e "${red}请使用 Debian 8 或更高版本的系统!${plain}\n" && exit 1 53 | fi 54 | fi 55 | 56 | confirm() { 57 | if [[ $# > 1 ]]; then 58 | echo && read -p "$1 [默认$2]: " temp 59 | if [[ x"${temp}" == x"" ]]; then 60 | temp=$2 61 | fi 62 | else 63 | read -p "$1 [y/n]: " temp 64 | fi 65 | if [[ x"${temp}" == x"y" || x"${temp}" == x"Y" ]]; then 66 | return 0 67 | else 68 | return 1 69 | fi 70 | } 71 | 72 | confirm_restart() { 73 | confirm "是否重启soga" "y" 74 | if [[ $? == 0 ]]; then 75 | restart 76 | else 77 | show_menu 78 | fi 79 | } 80 | 81 | before_show_menu() { 82 | echo && echo -n -e "${yellow}按回车返回主菜单: ${plain}" && read temp 83 | show_menu 84 | } 85 | 86 | install() { 87 | bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/soga/master/install.sh) 88 | if [[ $? == 0 ]]; then 89 | if [[ $# == 0 ]]; then 90 | start 91 | else 92 | start 0 93 | fi 94 | fi 95 | } 96 | 97 | update() { 98 | if [[ $# == 0 ]]; then 99 | echo && echo -n -e "输入指定版本(默认最新版): " && read version 100 | else 101 | version=$2 102 | fi 103 | # confirm "本功能会强制重装当前最新版,数据不会丢失,是否继续?" "n" 104 | # if [[ $? != 0 ]]; then 105 | # echo -e "${red}已取消${plain}" 106 | # if [[ $1 != 0 ]]; then 107 | # before_show_menu 108 | # fi 109 | # return 0 110 | # fi 111 | bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/soga/master/install.sh) $version 112 | if [[ $? == 0 ]]; then 113 | echo -e "${green}更新完成,已自动重启 soga,请使用 soga log 查看运行日志${plain}" 114 | exit 115 | fi 116 | 117 | if [[ $# == 0 ]]; then 118 | before_show_menu 119 | fi 120 | } 121 | 122 | config() { 123 | soga-tool $* 124 | } 125 | 126 | uninstall() { 127 | confirm "确定要卸载 soga 吗?" "n" 128 | if [[ $? != 0 ]]; then 129 | if [[ $# == 0 ]]; then 130 | show_menu 131 | fi 132 | return 0 133 | fi 134 | systemctl stop soga 135 | systemctl disable soga 136 | rm /etc/systemd/system/soga.service -f 137 | systemctl daemon-reload 138 | systemctl reset-failed 139 | rm /etc/soga/ -rf 140 | rm /usr/local/soga/ -rf 141 | 142 | echo "" 143 | echo -e "卸载成功,如果你想删除此脚本,则退出脚本后运行 ${green}rm /usr/bin/soga -f${plain} 进行删除" 144 | echo "" 145 | 146 | if [[ $# == 0 ]]; then 147 | before_show_menu 148 | fi 149 | } 150 | 151 | start() { 152 | check_status 153 | if [[ $? == 0 ]]; then 154 | echo "" 155 | echo -e "${green}soga已运行,无需再次启动,如需重启请选择重启${plain}" 156 | else 157 | systemctl reset-failed soga 158 | systemctl start soga 159 | sleep 2 160 | check_status 161 | if [[ $? == 0 ]]; then 162 | echo -e "${green}soga 启动成功,请使用 soga log 查看运行日志${plain}" 163 | else 164 | echo -e "${red}soga可能启动失败,请稍后使用 soga log 查看日志信息${plain}" 165 | fi 166 | fi 167 | 168 | if [[ $# == 0 ]]; then 169 | before_show_menu 170 | fi 171 | } 172 | 173 | stop() { 174 | systemctl stop soga 175 | sleep 2 176 | check_status 177 | if [[ $? == 1 ]]; then 178 | echo -e "${green}soga 停止成功${plain}" 179 | else 180 | echo -e "${red}soga停止失败,可能是因为停止时间超过了两秒,请稍后查看日志信息${plain}" 181 | fi 182 | 183 | if [[ $# == 0 ]]; then 184 | before_show_menu 185 | fi 186 | } 187 | 188 | restart() { 189 | systemctl reset-failed soga 190 | systemctl restart soga 191 | sleep 2 192 | check_status 193 | if [[ $? == 0 ]]; then 194 | echo -e "${green}soga 重启成功,请使用 soga log 查看运行日志${plain}" 195 | else 196 | echo -e "${red}soga可能启动失败,请稍后使用 soga log 查看日志信息${plain}" 197 | fi 198 | if [[ $# == 0 ]]; then 199 | before_show_menu 200 | fi 201 | } 202 | 203 | enable() { 204 | systemctl enable soga 205 | if [[ $? == 0 ]]; then 206 | echo -e "${green}soga 设置开机自启成功${plain}" 207 | else 208 | echo -e "${red}soga 设置开机自启失败${plain}" 209 | fi 210 | 211 | if [[ $# == 0 ]]; then 212 | before_show_menu 213 | fi 214 | } 215 | 216 | disable() { 217 | systemctl disable soga 218 | if [[ $? == 0 ]]; then 219 | echo -e "${green}soga 取消开机自启成功${plain}" 220 | else 221 | echo -e "${red}soga 取消开机自启失败${plain}" 222 | fi 223 | 224 | if [[ $# == 0 ]]; then 225 | before_show_menu 226 | fi 227 | } 228 | 229 | show_log() { 230 | n="$2" 231 | if [[ $2 == "" ]]; then 232 | n="1000" 233 | fi 234 | journalctl -u soga.service -e --no-pager -f -n "${n}" 235 | if [[ $# == 0 ]]; then 236 | before_show_menu 237 | fi 238 | } 239 | 240 | update_shell() { 241 | wget -O /usr/bin/soga -N --no-check-certificate https://github.com/vaxilu/soga/raw/master/soga.sh 242 | if [[ $? != 0 ]]; then 243 | echo "" 244 | echo -e "${red}下载脚本失败,请检查本机能否连接 Github${plain}" 245 | before_show_menu 246 | else 247 | chmod +x /usr/bin/soga 248 | echo -e "${green}升级脚本成功,请重新运行脚本${plain}" && exit 0 249 | fi 250 | } 251 | 252 | # 0: running, 1: not running, 2: not installed 253 | check_status() { 254 | if [[ ! -f /etc/systemd/system/soga.service ]]; then 255 | return 2 256 | fi 257 | temp=$(systemctl status soga | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1) 258 | if [[ x"${temp}" == x"running" ]]; then 259 | return 0 260 | else 261 | return 1 262 | fi 263 | } 264 | 265 | check_enabled() { 266 | temp=$(systemctl is-enabled soga) 267 | if [[ x"${temp}" == x"enabled" ]]; then 268 | return 0 269 | else 270 | return 1; 271 | fi 272 | } 273 | 274 | check_uninstall() { 275 | check_status 276 | if [[ $? != 2 ]]; then 277 | echo "" 278 | echo -e "${red}soga已安装,请不要重复安装${plain}" 279 | if [[ $# == 0 ]]; then 280 | before_show_menu 281 | fi 282 | return 1 283 | else 284 | return 0 285 | fi 286 | } 287 | 288 | check_install() { 289 | check_status 290 | if [[ $? == 2 ]]; then 291 | echo "" 292 | echo -e "${red}请先安装soga${plain}" 293 | if [[ $# == 0 ]]; then 294 | before_show_menu 295 | fi 296 | return 1 297 | else 298 | return 0 299 | fi 300 | } 301 | 302 | show_status() { 303 | check_status 304 | case $? in 305 | 0) 306 | echo -e "soga状态: ${green}已运行${plain}" 307 | show_enable_status 308 | ;; 309 | 1) 310 | echo -e "soga状态: ${yellow}未运行${plain}" 311 | show_enable_status 312 | ;; 313 | 2) 314 | echo -e "soga状态: ${red}未安装${plain}" 315 | esac 316 | } 317 | 318 | show_enable_status() { 319 | check_enabled 320 | if [[ $? == 0 ]]; then 321 | echo -e "是否开机自启: ${green}是${plain}" 322 | else 323 | echo -e "是否开机自启: ${red}否${plain}" 324 | fi 325 | } 326 | 327 | show_soga_version() { 328 | echo -n "soga 版本:" 329 | /usr/local/soga/soga -v 330 | echo "" 331 | if [[ $# == 0 ]]; then 332 | before_show_menu 333 | fi 334 | } 335 | 336 | show_usage() { 337 | echo "soga 管理脚本使用方法: " 338 | echo "------------------------------------------" 339 | echo "soga - 显示管理菜单 (功能更多)" 340 | echo "soga start - 启动 soga" 341 | echo "soga stop - 停止 soga" 342 | echo "soga restart - 重启 soga" 343 | echo "soga enable - 设置 soga 开机自启" 344 | echo "soga disable - 取消 soga 开机自启" 345 | echo "soga log - 查看 soga 日志" 346 | echo "soga update - 更新 soga 最新版" 347 | echo "soga update x.x.x - 安装 soga 指定版本" 348 | echo "soga config - 显示配置文件内容" 349 | echo "soga config xx=xx yy=yy - 自动设置配置文件" 350 | echo "soga install - 安装 soga" 351 | echo "soga uninstall - 卸载 soga" 352 | echo "soga version - 查看 soga 版本" 353 | echo "------------------------------------------" 354 | } 355 | 356 | show_menu() { 357 | echo -e " 358 | ${green}soga 后端管理脚本,${plain}${red}不适用于docker${plain} 359 | 360 | ${green}0.${plain} 退出脚本 361 | ———————————————— 362 | ${green}1.${plain} 安装 soga 363 | ${green}2.${plain} 更新 soga 364 | ${green}3.${plain} 卸载 soga 365 | ———————————————— 366 | ${green}4.${plain} 启动 soga 367 | ${green}5.${plain} 停止 soga 368 | ${green}6.${plain} 重启 soga 369 | ${green}7.${plain} 查看 soga 日志 370 | ———————————————— 371 | ${green}8.${plain} 设置 soga 开机自启 372 | ${green}9.${plain} 取消 soga 开机自启 373 | ———————————————— 374 | ${green}10.${plain} 查看 soga 版本 375 | " 376 | show_status 377 | echo && read -p "请输入选择 [0-10]: " num 378 | 379 | case "${num}" in 380 | 0) exit 0 381 | ;; 382 | 1) check_uninstall && install 383 | ;; 384 | 2) check_install && update 385 | ;; 386 | 3) check_install && uninstall 387 | ;; 388 | 4) check_install && start 389 | ;; 390 | 5) check_install && stop 391 | ;; 392 | 6) check_install && restart 393 | ;; 394 | 7) check_install && show_log 395 | ;; 396 | 8) check_install && enable 397 | ;; 398 | 9) check_install && disable 399 | ;; 400 | 10) check_install && show_soga_version 401 | ;; 402 | *) echo -e "${red}请输入正确的数字 [0-10]${plain}" 403 | ;; 404 | esac 405 | } 406 | 407 | 408 | if [[ $# > 0 ]]; then 409 | case $1 in 410 | "start") check_install 0 && start 0 411 | ;; 412 | "stop") check_install 0 && stop 0 413 | ;; 414 | "restart") check_install 0 && restart 0 415 | ;; 416 | "enable") check_install 0 && enable 0 417 | ;; 418 | "disable") check_install 0 && disable 0 419 | ;; 420 | "log") check_install 0 && show_log 0 $2 421 | ;; 422 | "update") check_install 0 && update 0 $2 423 | ;; 424 | "config") config $* 425 | ;; 426 | "install") check_uninstall 0 && install 0 427 | ;; 428 | "uninstall") check_install 0 && uninstall 0 429 | ;; 430 | "version") check_install 0 && show_soga_version 0 431 | ;; 432 | *) show_usage 433 | esac 434 | else 435 | show_menu 436 | fi 437 | --------------------------------------------------------------------------------