diff --git a/luci-app-open-box/Makefile b/luci-app-open-box/Makefile new file mode 100644 index 000000000..4a9696dd2 --- /dev/null +++ b/luci-app-open-box/Makefile @@ -0,0 +1,125 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-open-box +PKG_VERSION:=0.1.263 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=liandu2024 +PKG_LICENSE:=GPL-3.0-or-later + +# 1. 自动判断目标编译架构,映射至 Open-Box Release 预编译资产名 +ifeq ($(ARCH),x86_64) + OPENBOX_ARCH:=x64 +endif +ifeq ($(ARCH),aarch64) + OPENBOX_ARCH:=arm64 +endif + +PKG_SOURCE:=open-box-linux-$(OPENBOX_ARCH).tar.gz +PKG_SOURCE_URL:=https://github.com/liandu2024/Open-Box/releases/download/v$(PKG_VERSION)/ +PKG_HASH:=skip + +include $(INCLUDE_DIR)/package.mk + +define Package/luci-app-open-box + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=LuCI support for Open-Box Transparent Proxy (Full Core Included) + # 架构约束:仅在目标平台为 x86_64 或 aarch64 时在 menuconfig 中展示,防止误选到不支持的 MIPS/ARMv7 平台 + DEPENDS:=@(x86_64||aarch64) +kmod-tun +kmod-nft-queue +kmod-nft-nat +kmod-veth +ip-full +ca-bundle +luci-base +endef + +define Package/luci-app-open-box/description + Open-Box all-in-one transparent proxy management suite for OpenWrt. + Pre-packaged with full sing-box core, embedded Node.js runtime, GeoSite/GeoIP databases and web dashboard. +endef + +define Package/luci-app-open-box/conffiles +/etc/config/openbox +/opt/open-box/data/ +endef + +# 2. 构建准备:解压下载的对应架构核心资产包至构建目录 +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR)/_core + tar -xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR)/_core +endef + +define Build/Configure +endef + +define Build/Compile +endef + +# 3. 安装与打包:同时铺装 LuCI 页面、系统脚本以及 /opt/open-box 核心 +define Package/luci-app-open-box/install + # 安装 LuCI 菜单与权限声明 + $(INSTALL_DIR) $(1)/usr/share/luci/menu.d + $(INSTALL_DATA) ./root/usr/share/luci/menu.d/luci-app-openbox.json $(1)/usr/share/luci/menu.d/ + + $(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d + $(INSTALL_DATA) ./root/usr/share/rpcd/acl.d/luci-app-openbox.json $(1)/usr/share/rpcd/acl.d/ + + $(INSTALL_DIR) $(1)/www/luci-static/resources/view/openbox + $(INSTALL_DATA) ./root/www/luci-static/resources/view/openbox/main.js $(1)/www/luci-static/resources/view/openbox/ + + # 安装系统服务与默认配置 + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./root/etc/init.d/openbox $(1)/etc/init.d/openbox + $(INSTALL_BIN) ./root/etc/init.d/openbox-panel $(1)/etc/init.d/openbox-panel + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./root/etc/config/openbox $(1)/etc/config/openbox + + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./root/etc/uci-defaults/99-luci-app-openbox $(1)/etc/uci-defaults/99-luci-app-openbox + + # 创建 CLI 管理命令软链接(直接指向 /opt/open-box/openwrt/bin/open-box 原版脚本) + $(INSTALL_DIR) $(1)/usr/bin + ln -sf /opt/open-box/openwrt/bin/open-box $(1)/usr/bin/open-box + + # 仅复制 _core 子目录内容,避免递归包含 + $(INSTALL_DIR) $(1)/opt/open-box + $(CP) $(PKG_BUILD_DIR)/_core/* $(1)/opt/open-box/ + chmod -R 0755 $(1)/opt/open-box/bin $(1)/opt/open-box/node/bin $(1)/opt/open-box/openwrt/bin 2>/dev/null || true + chmod +x $(1)/opt/open-box/update.sh $(1)/opt/open-box/uninstall.sh 2>/dev/null || true + echo "3036" > $(1)/opt/open-box/data/panel-port +endef + +define Package/luci-app-open-box/extra_provides + echo "libc.musl-x86_64.so.1"; +endef + +define Package/luci-app-open-box/prerm +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] || { + /etc/init.d/openbox stop >/dev/null 2>&1 || true + /etc/init.d/openbox-panel stop >/dev/null 2>&1 || true +} +exit 0 +endef + +# 6. 包卸载后钩子:清理残留静态资源与防火墙规则 +define Package/luci-app-open-box/postrm +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] || { + rm -rf /tmp/luci-*cache* 2>/dev/null || true + rm -rf /www/luci-static/resources/view/openbox 2>/dev/null || true + uci -q delete firewall.openbox_panel || true + uci -q delete firewall.openbox_dns || true + uci -q delete firewall.openbox_tun_forward || true + uci -q delete firewall.openbox_tun_input || true + uci -q delete firewall.openbox_v6block || true + for _ob_rule in $$(uci -q show firewall 2>/dev/null | sed -n 's/^firewall\.\(openbox_srv_[A-Za-z0-9_]*\)=rule$$/\1/p'); do + uci -q delete "firewall.$$_ob_rule" || true + done + if [ -n "$$(uci -q changes firewall)" ]; then + uci -q commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 || true + fi +} +exit 0 +endef + +$(eval $(call BuildPackage,luci-app-open-box)) \ No newline at end of file diff --git a/luci-app-open-box/README.md b/luci-app-open-box/README.md new file mode 100644 index 000000000..d29e74dea --- /dev/null +++ b/luci-app-open-box/README.md @@ -0,0 +1 @@ +来自 https://github.com/liandu2024/Open-Box diff --git a/luci-app-open-box/po/zh-cn b/luci-app-open-box/po/zh-cn new file mode 120000 index 000000000..8d69574dd --- /dev/null +++ b/luci-app-open-box/po/zh-cn @@ -0,0 +1 @@ +zh_Hans \ No newline at end of file diff --git a/luci-app-open-box/po/zh_Hans/openbox.po b/luci-app-open-box/po/zh_Hans/openbox.po new file mode 100644 index 000000000..c3ea3081d --- /dev/null +++ b/luci-app-open-box/po/zh_Hans/openbox.po @@ -0,0 +1,65 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "Open-Box" +msgstr "Open-Box" + +msgid "Open-Box 管理面板" +msgstr "Open-Box 管理面板" + +msgid "服务运行状态" +msgstr "服务运行状态" + +msgid "面板服务 (openbox-panel)" +msgstr "面板服务 (openbox-panel)" + +msgid "内核代理服务 (openbox)" +msgstr "内核代理服务 (openbox)" + +msgid "组件与更新维护" +msgstr "组件与更新维护" + +msgid "核心组件状态" +msgstr "核心组件状态" + +msgid "更新加速镜像" +msgstr "更新加速镜像" + +msgid "系统升级与维护" +msgstr "系统升级与维护" + +msgid "打开管理面板" +msgstr "打开管理面板" + +msgid "修改端口" +msgstr "修改端口" + +msgid "复制密码" +msgstr "复制密码" + +msgid "启动面板" +msgstr "启动面板" + +msgid "停止面板" +msgstr "停止面板" + +msgid "重启面板" +msgstr "重启面板" + +msgid "启动内核" +msgstr "启动内核" + +msgid "紧急停止内核 (恢复直连)" +msgstr "紧急停止内核 (恢复直连)" + +msgid "按配置重载/重启" +msgstr "按配置重载/重启" + +msgid "检查并升级到最新版" +msgstr "检查并升级到最新版" + +msgid "回退到上个版本 (Rollback)" +msgstr "回退到上个版本 (Rollback)" + +msgid "卸载 Open-Box" +msgstr "卸载 Open-Box" diff --git a/luci-app-open-box/root/etc/config/openbox b/luci-app-open-box/root/etc/config/openbox new file mode 100644 index 000000000..f9ca30b71 --- /dev/null +++ b/luci-app-open-box/root/etc/config/openbox @@ -0,0 +1,6 @@ +config openbox 'main' + option enabled '1' + option port '3036' + option channel 'mirror' + option mirror_prefix 'https://ghfast.top' + option auto_restart '1' diff --git a/luci-app-open-box/root/etc/init.d/openbox b/luci-app-open-box/root/etc/init.d/openbox new file mode 100755 index 000000000..983ab3b7a --- /dev/null +++ b/luci-app-open-box/root/etc/init.d/openbox @@ -0,0 +1,96 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2026 OpenWrt.org +# Open-Box Core Service (sing-box transparent proxy) + +START=96 +STOP=09 +USE_PROCD=1 + +INSTALL_ROOT="/opt/open-box" + +openbox_cleanup() { + if command -v uci >/dev/null 2>&1; then + local changed=0 + for rule in openbox_dns openbox_tun_forward openbox_tun_input openbox_v6block; do + if [ -n "$(uci -q get firewall.$rule 2>/dev/null)" ]; then + uci -q delete firewall.$rule + changed=1 + fi + done + for _ob_rule in $(uci -q show firewall 2>/dev/null | sed -n 's/^firewall\.\(openbox_srv_[A-Za-z0-9_]*\)=rule$/\1/p'); do + uci -q delete "firewall.$_ob_rule" || true + changed=1 + done + if [ "$changed" = "1" ] && [ -n "$(uci -q changes firewall)" ]; then + uci -q commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 || true + fi + fi + + if command -v nft >/dev/null 2>&1; then + nft delete table inet openbox 2>/dev/null || true + fi +} + +start_service() { + if [ -f "$INSTALL_ROOT/openwrt/initd/openbox" ] && [ ! -L "$INSTALL_ROOT/openwrt/initd/openbox" ]; then + "$INSTALL_ROOT/openwrt/initd/openbox" start + return $? + fi + + if [ ! -d "$INSTALL_ROOT" ]; then + echo "[openbox] 核心组件尚未安装在 $INSTALL_ROOT,请先安装或下载核心组件。" >&2 + return 1 + fi + + local deploy_cli="$INSTALL_ROOT/panel/server/cli/deploy.mjs" + local node_bin="$INSTALL_ROOT/node/bin/node" + local core_bin="$INSTALL_ROOT/bin/sing-box" + + if [ -x "$node_bin" ] && [ -f "$deploy_cli" ]; then + OPENBOX_ROOT="$INSTALL_ROOT" ZASHBOARD_DB_PATH="$INSTALL_ROOT/data/openbox.sqlite" \ + OPENSSL_CONF=/dev/null LD_LIBRARY_PATH="$INSTALL_ROOT/node/lib" \ + "$node_bin" "$deploy_cli" >/dev/null 2>&1 + return $? + elif [ -x "$core_bin" ] && [ -f "$INSTALL_ROOT/etc/config.json" ]; then + procd_open_instance openbox + procd_set_param command "$core_bin" run -c "$INSTALL_ROOT/etc/config.json" -D "$INSTALL_ROOT" + procd_set_param respawn + procd_set_param limits core="unlimited" + procd_close_instance + else + echo "[openbox] 核心服务未就绪,请在面板完成订阅或分流配置后启动。" >&2 + return 1 + fi +} + +stop_service() { + if [ -f "$INSTALL_ROOT/openwrt/initd/openbox" ] && [ ! -L "$INSTALL_ROOT/openwrt/initd/openbox" ]; then + "$INSTALL_ROOT/openwrt/initd/openbox" stop + return $? + fi + + if [ -x "$INSTALL_ROOT/bin/sing-box" ]; then + killall -9 sing-box 2>/dev/null || true + fi + openbox_cleanup +} + +restart() { + stop + sleep 1 + start +} + +status() { + if [ -x "$INSTALL_ROOT/bin/sing-box" ] && pidof sing-box >/dev/null; then + echo "openbox is running (pid $(pidof sing-box))" + return 0 + fi + echo "openbox is not running" + return 1 +} + +reload_service() { + restart +} diff --git a/luci-app-open-box/root/etc/init.d/openbox-panel b/luci-app-open-box/root/etc/init.d/openbox-panel new file mode 100755 index 000000000..2392a7893 --- /dev/null +++ b/luci-app-open-box/root/etc/init.d/openbox-panel @@ -0,0 +1,98 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2026 OpenWrt.org +# Open-Box Panel Web Service + +START=95 +STOP=10 +USE_PROCD=1 + +INSTALL_ROOT="/opt/open-box" + +openbox_get_port() { + local p="" + [ -f "$INSTALL_ROOT/data/panel-port" ] && p=$(cat "$INSTALL_ROOT/data/panel-port" 2>/dev/null | tr -dc '0-9') + if [ -z "$p" ]; then + config_load openbox + config_get p main port 3036 + fi + [ -n "$p" ] || p=3036 + echo "$p" +} + +ensure_firewall_rule() { + local port="$1" + command -v uci >/dev/null 2>&1 || return 0 + + local cur_port=$(uci -q get firewall.openbox_panel.dest_port 2>/dev/null) + if [ "$cur_port" != "$port" ]; then + uci -q delete firewall.openbox_panel 2>/dev/null || true + uci -q set firewall.openbox_panel=rule + uci -q set firewall.openbox_panel.name='Open-Box Panel' + uci -q set firewall.openbox_panel.src='lan' + uci -q set firewall.openbox_panel.proto='tcp' + uci -q set firewall.openbox_panel.dest_port="$port" + uci -q set firewall.openbox_panel.target='ACCEPT' + uci -q commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 || true + fi +} + +start_service() { + if [ -f "$INSTALL_ROOT/openwrt/initd/openbox-panel" ] && [ ! -L "$INSTALL_ROOT/openwrt/initd/openbox-panel" ]; then + "$INSTALL_ROOT/openwrt/initd/openbox-panel" start + return $? + fi + + if [ ! -d "$INSTALL_ROOT" ] || [ ! -x "$INSTALL_ROOT/node/bin/node" ]; then + echo "[openbox-panel] 核心未安装在 $INSTALL_ROOT,请先执行 open-box install 或在 LuCI 页面下载安装核心。" >&2 + return 1 + fi + + local node_bin="$INSTALL_ROOT/node/bin/node" + local panel_app="$INSTALL_ROOT/panel/server/index.mjs" + [ -f "$panel_app" ] || panel_app="$INSTALL_ROOT/panel/server/index.js" + + local port=$(openbox_get_port) + mkdir -p "$INSTALL_ROOT/data" 2>/dev/null || true + echo "$port" > "$INSTALL_ROOT/data/panel-port" + ensure_firewall_rule "$port" + + if [ -f "$INSTALL_ROOT/openwrt/bin/open-box" ] && [ ! -e /usr/bin/open-box ]; then + ln -sf "$INSTALL_ROOT/openwrt/bin/open-box" /usr/bin/open-box 2>/dev/null || true + fi + + procd_open_instance openbox-panel + procd_set_param command "$node_bin" "$panel_app" + procd_set_param env OPENBOX_ROOT="$INSTALL_ROOT" OPENSSL_CONF=/dev/null LD_LIBRARY_PATH="$INSTALL_ROOT/node/lib" PORT="$port" + procd_set_param respawn 3600 5 0 + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_close_instance +} + +stop_service() { + if [ -f "$INSTALL_ROOT/openwrt/initd/openbox-panel" ] && [ ! -L "$INSTALL_ROOT/openwrt/initd/openbox-panel" ]; then + "$INSTALL_ROOT/openwrt/initd/openbox-panel" stop + return $? + fi + return 0 +} + +status() { + if pgrep -f "$INSTALL_ROOT/panel/server" >/dev/null 2>&1; then + local pid=$(pgrep -f "$INSTALL_ROOT/panel/server" | head -n 1) + local port=$(openbox_get_port) + echo "openbox-panel is running (pid $pid, port $port)" + return 0 + fi + echo "openbox-panel is not running" + return 1 +} + +reload_service() { + restart +} + +service_triggers() { + procd_add_reload_trigger "openbox" +} diff --git a/luci-app-open-box/root/etc/uci-defaults/99-luci-app-openbox b/luci-app-open-box/root/etc/uci-defaults/99-luci-app-openbox new file mode 100644 index 000000000..1871a2b12 --- /dev/null +++ b/luci-app-open-box/root/etc/uci-defaults/99-luci-app-openbox @@ -0,0 +1,26 @@ +#!/bin/sh + +# Set default firewall rule for openbox-panel +uci -q get firewall.openbox_panel >/dev/null || { + uci -q set firewall.openbox_panel=rule + uci -q set firewall.openbox_panel.name='Open-Box Panel' + uci -q set firewall.openbox_panel.src='lan' + uci -q set firewall.openbox_panel.proto='tcp' + uci -q set firewall.openbox_panel.dest_port='3036' + uci -q set firewall.openbox_panel.target='ACCEPT' + uci -q commit firewall +} + +# Create open-box CLI link if available +[ -e /usr/bin/open-box ] || { + if [ -f /usr/share/openbox/open-box ]; then + ln -sf /usr/share/openbox/open-box /usr/bin/open-box + elif [ -f /opt/open-box/openwrt/bin/open-box ]; then + ln -sf /opt/open-box/openwrt/bin/open-box /usr/bin/open-box + fi +} + +# Clean LuCI cache +rm -rf /tmp/luci-*cache* 2>/dev/null || true + +exit 0 diff --git a/luci-app-open-box/root/usr/bin/open-box b/luci-app-open-box/root/usr/bin/open-box new file mode 100755 index 000000000..6522ccf8c --- /dev/null +++ b/luci-app-open-box/root/usr/bin/open-box @@ -0,0 +1,208 @@ +#!/bin/sh +# Open-Box 命令行管理工具 +INSTALL_ROOT="/opt/open-box" +OPENBOX_PORT_FILE="$INSTALL_ROOT/data/panel-port" +OPENBOX_PORT_FALLBACK=2026 +OPENBOX_PORT_DEFAULT=3036 +OPENBOX_RESERVED_PORTS="9095 7853 7854 7891 53 22 80 443" + +if [ -f "$INSTALL_ROOT/openwrt/bin/open-box" ] && [ "$0" != "$INSTALL_ROOT/openwrt/bin/open-box" ] && [ ! -L "$INSTALL_ROOT/openwrt/bin/open-box" ]; then + exec "$INSTALL_ROOT/openwrt/bin/open-box" "$@" +fi + +openbox_port_problem() { + _p="$1" + case "$_p" in + ''|*[!0-9]*) echo "端口要填 1024-65535 的数字"; return 0 ;; + esac + if [ "$_p" -lt 1024 ] || [ "$_p" -gt 65535 ]; then + echo "端口要在 1024-65535 之间(1024 以下是系统保留端口)" + return 0 + fi + for _r in $OPENBOX_RESERVED_PORTS; do + if [ "$_p" = "$_r" ]; then + echo "$_p 是 Open-Box 自己或系统服务在用的端口(内核 API / DNS / SSH / HTTP 等),换一个" + return 0 + fi + done + _busy="" + if command -v ss >/dev/null 2>&1; then + _busy=$(ss -ltn 2>/dev/null | awk 'NR>1 {print $4}' | sed 's/.*[:.]//' | grep -x "$_p" | head -n 1) + elif command -v netstat >/dev/null 2>&1; then + _busy=$(netstat -ltn 2>/dev/null | awk '{print $4}' | sed 's/.*[:.]//' | grep -x "$_p" | head -n 1) + fi + if [ -n "$_busy" ]; then + echo "$_p 已经被别的程序占用(已在监听)" + return 0 + fi + return 1 +} + +openbox_current_port() { + _cp=$(cat "$OPENBOX_PORT_FILE" 2>/dev/null | tr -dc '0-9') + [ -n "$_cp" ] || _cp="$OPENBOX_PORT_DEFAULT" + printf '%s\n' "$_cp" +} + +openbox_get_lan_ip() { + LAN_IP="" + command -v uci >/dev/null 2>&1 && LAN_IP=$(uci -q get network.lan.ipaddr 2>/dev/null | tr " " "\n" | head -n 1 | cut -d/ -f1) + if [ -z "$LAN_IP" ] && command -v ip >/dev/null 2>&1; then + LAN_IP=$(ip -4 -o addr show br-lan 2>/dev/null | awk '{ print $4 }' | cut -d/ -f1 | head -n 1) + fi + [ -n "$LAN_IP" ] || LAN_IP="192.168.1.1" + printf '%s\n' "$LAN_IP" +} + +openbox_get_password() { + if [ -f "$INSTALL_ROOT/data/openbox.sqlite" ] && [ -x "$INSTALL_ROOT/node/bin/node" ]; then + _pw=$(OPENSSL_CONF=/dev/null LD_LIBRARY_PATH="$INSTALL_ROOT/node/lib" "$INSTALL_ROOT/node/bin/node" -e ' + try { + const sqlite3 = require("sqlite3"); + const db = new sqlite3.Database("'$INSTALL_ROOT'/data/openbox.sqlite", sqlite3.OPEN_READONLY, (err) => { + if (err) process.exit(1); + db.get("SELECT value FROM settings WHERE key = ?", ["password"], (e, row) => { + if (row && row.value) console.log(row.value); + db.close(); + }); + }); + } catch (_) {} + ' 2>/dev/null) + if [ -n "$_pw" ]; then + printf '%s\n' "$_pw" + return 0 + fi + fi + if [ -f "$INSTALL_ROOT/data/password" ]; then + cat "$INSTALL_ROOT/data/password" 2>/dev/null + return 0 + fi + echo "尚未设置(首次打开面板设置管理密码)" +} + +openbox_get_version() { + _ver=$(sed -n 's/.*"version" *: *"\([^"]*\)".*/\1/p' "$INSTALL_ROOT/meta.json" 2>/dev/null | head -n 1) + [ -n "$_ver" ] || _ver="未安装" + printf '%s\n' "$_ver" +} + +cmd="${1:-}" + +case "$cmd" in + password) + openbox_get_password + exit 0 + ;; + port) + if [ $# -ge 2 ]; then + new_port="$2" + _reason=$(openbox_port_problem "$new_port") && { + echo "面板端口不能用:$_reason" >&2 + exit 1 + } + mkdir -p "$INSTALL_ROOT/data" + printf '%s\n' "$new_port" > "$OPENBOX_PORT_FILE" + if command -v uci >/dev/null 2>&1; then + uci -q set openbox.main.port="$new_port" + uci -q set firewall.openbox_panel.dest_port="$new_port" + uci -q commit openbox 2>/dev/null || true + uci -q commit firewall 2>/dev/null || true + /etc/init.d/firewall reload >/dev/null 2>&1 || true + fi + echo "面板端口已修改为: $new_port" + /etc/init.d/openbox-panel restart >/dev/null 2>&1 || true + exit 0 + else + openbox_current_port + exit 0 + fi + ;; + check) + if [ -f "$INSTALL_ROOT/update.sh" ]; then + sh "$INSTALL_ROOT/update.sh" --probe direct + elif [ -f /usr/share/openbox/update.sh ]; then + sh /usr/share/openbox/update.sh --probe direct + else + echo "未找到更新脚本" + fi + exit 0 + ;; + update) + shift + if [ -f "$INSTALL_ROOT/update.sh" ]; then + sh "$INSTALL_ROOT/update.sh" "$@" + elif [ -f /usr/share/openbox/update.sh ]; then + sh /usr/share/openbox/update.sh "$@" + else + echo "未找到更新脚本" >&2 + exit 1 + fi + exit 0 + ;; + restart) + /etc/init.d/openbox restart + /etc/init.d/openbox-panel restart + echo "已重启 Open-Box 服务与面板" + exit 0 + ;; + uninstall) + shift + if [ -f "$INSTALL_ROOT/uninstall.sh" ]; then + sh "$INSTALL_ROOT/uninstall.sh" "$@" + elif [ -f /usr/share/openbox/uninstall.sh ]; then + sh /usr/share/openbox/uninstall.sh "$@" + else + /etc/init.d/openbox stop + /etc/init.d/openbox-panel stop + rm -rf "$INSTALL_ROOT" + echo "已停止并清理" + fi + exit 0 + ;; + install) + shift + if [ -f /usr/share/openbox/install.sh ]; then + sh /usr/share/openbox/install.sh "$@" + else + curl -fsSL https://raw.githubusercontent.com/liandu2024/Open-Box/main/scripts/install.sh | sh -s -- "$@" + fi + exit 0 + ;; + *) + VERSION=$(openbox_get_version) + echo "" + echo "Open-Box $VERSION" + echo " 1) 当前密码" + echo " 2) 重新启动" + echo " 3) 检查升级" + echo " 4) 卸载" + echo " 5) 退出" + printf '请选择 [1-5]: ' + read -r choice + case "$choice" in + 1) + port=$(openbox_current_port) + lan_ip=$(openbox_get_lan_ip) + pw=$(openbox_get_password) + echo "" + echo " 面板地址: http://$lan_ip:$port" + echo " 当前密码: $pw" + echo "" + ;; + 2) + /etc/init.d/openbox restart + /etc/init.d/openbox-panel restart + echo "服务已重启。" + ;; + 3) + sh "$0" update + ;; + 4) + sh "$0" uninstall + ;; + 5|*) + exit 0 + ;; + esac + ;; +esac diff --git a/luci-app-open-box/root/usr/share/luci/menu.d/luci-app-openbox.json b/luci-app-open-box/root/usr/share/luci/menu.d/luci-app-openbox.json new file mode 100644 index 000000000..7bc54201c --- /dev/null +++ b/luci-app-open-box/root/usr/share/luci/menu.d/luci-app-openbox.json @@ -0,0 +1,12 @@ +{ + "admin/services/openbox": { + "title": "Open-Box", + "action": { + "type": "view", + "path": "openbox/main" + }, + "depends": { + "acl": [ "luci-app-openbox" ] + } + } +} diff --git a/luci-app-open-box/root/usr/share/openbox/install.sh b/luci-app-open-box/root/usr/share/openbox/install.sh new file mode 100755 index 000000000..11369f3ac --- /dev/null +++ b/luci-app-open-box/root/usr/share/openbox/install.sh @@ -0,0 +1,136 @@ +#!/bin/sh +# Open-Box 一键安装脚本 +set -eu +umask 022 + +REPO="liandu2024/Open-Box" +INSTALL_ROOT="/opt/open-box" +CHANNEL="mirror" +MIRROR_PREFIX="https://ghfast.top" +PANEL_PORT="3036" + +info() { echo "[open-box] $*"; } +warn() { echo "[open-box] 警告:$*" >&2; } +die() { echo "[open-box] 错误:$*" >&2; exit 1; } + +while [ $# -gt 0 ]; do + case "$1" in + --mirror) + CHANNEL="mirror" + shift + if [ $# -ge 1 ]; then + case "$1" in + --*) ;; + *) MIRROR_PREFIX="$1"; shift ;; + esac + fi + ;; + --direct) + CHANNEL="direct" + MIRROR_PREFIX="" + shift + ;; + --port) + shift + [ $# -ge 1 ] || die "--port 后面要跟端口号" + PANEL_PORT="$1" + shift + ;; + *) shift ;; + esac +done + +detect_arch() { + RAW_ARCH=$(uname -m 2>/dev/null || true) + case "$RAW_ARCH" in + x86_64) ARCH="x64" ;; + aarch64) ARCH="arm64" ;; + *) die "不支持的 CPU 架构:${RAW_ARCH:-未知}。Open-Box 目前仅支持 x86_64 与 aarch64(arm64)。" ;; + esac +} + +detect_arch + +if [ -f "/etc/config/openbox" ]; then + p=$(uci -q get openbox.main.port 2>/dev/null || true) + [ -n "$p" ] && PANEL_PORT="$p" +fi + +TMP_DL=$(mktemp -d /tmp/openbox-inst.XXXXXX 2>/dev/null || echo "/tmp/openbox-inst.$$") +mkdir -p "$TMP_DL" +trap 'rm -rf "$TMP_DL"' EXIT INT TERM + +ASSET="open-box-linux-${ARCH}.tar.gz" +ASSET_URL="https://github.com/$REPO/releases/latest/download/$ASSET" +SHA_URL="$ASSET_URL.sha256" + +build_url() { + url="$1" + if [ "$CHANNEL" = "mirror" ] && [ -n "$MIRROR_PREFIX" ]; then + case "$MIRROR_PREFIX" in + http://*|https://*) printf '%s/%s +' "${MIRROR_PREFIX%/}" "$url" ;; + *) printf 'https://%s/%s +' "${MIRROR_PREFIX%/}" "$url" ;; + esac + else + printf '%s +' "$url" + fi +} + +info "下载校验和与发布包: $ASSET ..." +curl -fsSL -o "$TMP_DL/$ASSET.sha256" "$(build_url "$SHA_URL")" 2>/dev/null || wget -q -O "$TMP_DL/$ASSET.sha256" "$(build_url "$SHA_URL")" || die "下载校验文件失败" +curl -fsSL -o "$TMP_DL/$ASSET" "$(build_url "$ASSET_URL")" 2>/dev/null || wget -q -O "$TMP_DL/$ASSET" "$(build_url "$ASSET_URL")" || die "下载发布包失败" + +info "校验 SHA256 ..." +( cd "$TMP_DL" && sha256sum -c "$ASSET.sha256" >/dev/null 2>&1 ) || die "安装包校验失败 (SHA256 不匹配)" + +info "解包到 $INSTALL_ROOT ..." +mkdir -p "$INSTALL_ROOT" +tar -xzf "$TMP_DL/$ASSET" -C "$INSTALL_ROOT" || die "解包失败" +chown -R 0:0 "$INSTALL_ROOT" 2>/dev/null || true + +mkdir -p "$INSTALL_ROOT/data" +printf '%s +' "$PANEL_PORT" > "$INSTALL_ROOT/data/panel-port" +if [ "$CHANNEL" = "mirror" ]; then + printf 'mirror +%s +' "$MIRROR_PREFIX" > "$INSTALL_ROOT/data/channel" +else + printf 'direct +' > "$INSTALL_ROOT/data/channel" +fi + +cp -f "$INSTALL_ROOT/openwrt/initd/openbox" /etc/init.d/openbox 2>/dev/null || true +cp -f "$INSTALL_ROOT/openwrt/initd/openbox-panel" /etc/init.d/openbox-panel 2>/dev/null || true +chmod +x /etc/init.d/openbox /etc/init.d/openbox-panel 2>/dev/null || true + +if [ -f "$INSTALL_ROOT/openwrt/bin/open-box" ]; then + chmod +x "$INSTALL_ROOT/openwrt/bin/open-box" 2>/dev/null || true + ln -sf "$INSTALL_ROOT/openwrt/bin/open-box" /usr/bin/open-box 2>/dev/null || true +fi + +if [ -d "$INSTALL_ROOT/openwrt/luci/htdocs/luci-static/resources/view/openbox" ]; then + mkdir -p /www/luci-static/resources/view/openbox + cp -f "$INSTALL_ROOT/openwrt/luci/htdocs/luci-static/resources/view/openbox/"*.js /www/luci-static/resources/view/openbox/ 2>/dev/null || true +fi + +if [ -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/luci/menu.d/luci-app-openbox.json" ]; then + mkdir -p /usr/share/luci/menu.d + cp -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/luci/menu.d/luci-app-openbox.json" /usr/share/luci/menu.d/ 2>/dev/null || true +fi + +if [ -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/rpcd/acl.d/luci-app-openbox.json" ]; then + mkdir -p /usr/share/rpcd/acl.d + cp -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/rpcd/acl.d/luci-app-openbox.json" /usr/share/rpcd/acl.d/ 2>/dev/null || true +fi + +rm -rf /tmp/luci-*cache* 2>/dev/null || true +/etc/init.d/rpcd restart >/dev/null 2>&1 || true + +/etc/init.d/openbox-panel enable >/dev/null 2>&1 || true +/etc/init.d/openbox-panel restart >/dev/null 2>&1 || true + +info "Open-Box 核心组件安装完成!" diff --git a/luci-app-open-box/root/usr/share/openbox/uninstall.sh b/luci-app-open-box/root/usr/share/openbox/uninstall.sh new file mode 100755 index 000000000..b32993e2a --- /dev/null +++ b/luci-app-open-box/root/usr/share/openbox/uninstall.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# Open-Box 卸载清理脚本 +set -eu + +INSTALL_ROOT="/opt/open-box" +STATUS_PATH="/tmp/openbox-uninstall.status" +PURGE=0 +DETACH=0 + +while [ $# -gt 0 ]; do + case "$1" in + --purge) PURGE=1; shift ;; + --detach) DETACH=1; shift ;; + *) shift ;; + esac +done + +if [ "$DETACH" = "1" ]; then + _args="" + [ "$PURGE" = "1" ] && _args="--purge" + nohup sh "$0" $_args >/dev/null 2>&1 & + echo "卸载已在后台启动" + exit 0 +fi + +{ + echo "pid=$$" + echo "stage=stopping" +} > "$STATUS_PATH" 2>/dev/null || true + +/etc/init.d/openbox stop >/dev/null 2>&1 || true +/etc/init.d/openbox-panel stop >/dev/null 2>&1 || true +/etc/init.d/openbox disable >/dev/null 2>&1 || true +/etc/init.d/openbox-panel disable >/dev/null 2>&1 || true + +{ + echo "pid=$$" + echo "stage=firewall" +} > "$STATUS_PATH" 2>/dev/null || true + +if command -v uci >/dev/null 2>&1; then + uci -q delete firewall.openbox_panel || true + uci -q delete firewall.openbox_dns || true + uci -q delete firewall.openbox_tun_forward || true + uci -q delete firewall.openbox_tun_input || true + uci -q delete firewall.openbox_v6block || true + for _ob_rule in $(uci -q show firewall 2>/dev/null | sed -n 's/^firewall\.\(openbox_srv_[A-Za-z0-9_]*\)=rule$/\1/p'); do + uci -q delete "firewall.$_ob_rule" || true + done + if [ -n "$(uci -q changes firewall)" ]; then + uci -q commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 || true + fi +fi + +{ + echo "pid=$$" + echo "stage=files" +} > "$STATUS_PATH" 2>/dev/null || true + +rm -f /etc/init.d/openbox /etc/init.d/openbox-panel +rm -f /www/luci-static/resources/view/openbox/main.js /www/luci-static/resources/view/openbox/status.js +rmdir /www/luci-static/resources/view/openbox 2>/dev/null || true +rm -f /usr/share/luci/menu.d/luci-app-openbox.json +rm -f /usr/share/rpcd/acl.d/luci-app-openbox.json +[ -L /usr/bin/open-box ] && rm -f /usr/bin/open-box +rm -rf /tmp/luci-*cache* 2>/dev/null || true + +if [ "$PURGE" = "1" ]; then + rm -rf "$INSTALL_ROOT" +else + for entry in "$INSTALL_ROOT"/*; do + [ -e "$entry" ] || continue + base=$(basename -- "$entry") + [ "$base" = "data" ] && continue + rm -rf "$entry" + done +fi + +{ + echo "pid=$$" + echo "stage=done" +} > "$STATUS_PATH" 2>/dev/null || true + +echo "Open-Box 卸载完成" diff --git a/luci-app-open-box/root/usr/share/openbox/update.sh b/luci-app-open-box/root/usr/share/openbox/update.sh new file mode 100755 index 000000000..b60f24eba --- /dev/null +++ b/luci-app-open-box/root/usr/share/openbox/update.sh @@ -0,0 +1,204 @@ +#!/bin/sh +# Open-Box 更新/回退脚本 +set -eu +umask 022 + +REPO="liandu2024/Open-Box" +INSTALL_ROOT="/opt/open-box" +STATUS_PATH="/tmp/openbox-update.status" +CANCEL_FLAG="/tmp/openbox-update.cancel" +UPDATE_LOG="/tmp/openbox-update.log" +STATUS_PID="$$" + +DETACH=0 +ROLLBACK_MODE=0 +CHANNEL="direct" +MIRROR_PREFIX="" +PROBE_CHANNEL="" +CANCEL_MODE=0 + +info() { echo "[open-box] $*"; } +warn() { echo "[open-box] 警告:$*" >&2; } +die() { + echo "[open-box] 错误:$*" >&2 + write_status failed "" "" "$*" + exit 1 +} + +write_status() { + [ -n "$STATUS_PID" ] || return 0 + _ws_tmp="$STATUS_PATH.$$.tmp" + { + echo "pid=$STATUS_PID" + echo "stage=$1" + echo "bytes=${2:-}" + echo "total=${3:-}" + echo "message=${4:-}" + } > "$_ws_tmp" 2>/dev/null && mv -f "$_ws_tmp" "$STATUS_PATH" 2>/dev/null || true +} + +check_cancel() { + if [ -e "$CANCEL_FLAG" ]; then + write_status cancelled "" "" "已取消更新" + exit 0 + fi +} + +while [ $# -gt 0 ]; do + case "$1" in + --detach) DETACH=1; shift ;; + --rollback) ROLLBACK_MODE=1; shift ;; + --cancel) CANCEL_MODE=1; shift ;; + --direct) CHANNEL="direct"; MIRROR_PREFIX=""; shift ;; + --mirror) + CHANNEL="mirror" + shift + if [ $# -ge 1 ]; then + case "$1" in + --*) ;; + *) MIRROR_PREFIX="$1"; shift ;; + esac + fi + ;; + --probe) + shift + PROBE_CHANNEL="$1" + shift + ;; + *) shift ;; + esac +done + +if [ "$CANCEL_MODE" = "1" ]; then + touch "$CANCEL_FLAG" 2>/dev/null || true + echo "requested" + exit 0 +fi + +if [ -n "$PROBE_CHANNEL" ]; then + start_time=$(date +%s%N 2>/dev/null || date +%s) + target="https://github.com/$REPO/releases/latest/download/open-box-linux-x64.tar.gz.sha256" + if [ "$PROBE_CHANNEL" != "direct" ]; then + case "$PROBE_CHANNEL" in + http://*|https://*) target="${PROBE_CHANNEL%/}/$target" ;; + *) target="https://${PROBE_CHANNEL%/}/$target" ;; + esac + fi + if curl -fsSL --connect-timeout 8 --max-time 15 -o /dev/null "$target" 2>/dev/null || wget -q --timeout=15 -O /dev/null "$target" 2>/dev/null; then + end_time=$(date +%s%N 2>/dev/null || date +%s) + ms=$(( (end_time - start_time) / 1000000 2>/dev/null || 100 )) + [ "$ms" -le 0 ] && ms=80 + echo "ok $ms ms" + else + echo "fail 连接超时或无法访问" + fi + exit 0 +fi + +if [ "$DETACH" = "1" ]; then + : > "$UPDATE_LOG" 2>/dev/null || true + write_status starting "" "" "" + rm -f "$CANCEL_FLAG" 2>/dev/null || true + _args="" + [ "$ROLLBACK_MODE" = "1" ] && _args="$_args --rollback" + if [ "$CHANNEL" = "mirror" ]; then + _args="$_args --mirror $MIRROR_PREFIX" + else + _args="$_args --direct" + fi + nohup sh "$0" $_args >"$UPDATE_LOG" 2>&1 /dev/null || true) +case "$RAW_ARCH" in + x86_64) ARCH="x64" ;; + aarch64) ARCH="arm64" ;; + *) die "不支持的 CPU 架构: $RAW_ARCH" ;; +esac + +ASSET="open-box-linux-${ARCH}.tar.gz" +ASSET_URL="https://github.com/$REPO/releases/latest/download/$ASSET" +SHA_URL="$ASSET_URL.sha256" + +build_url() { + url="$1" + if [ "$CHANNEL" = "mirror" ] && [ -n "$MIRROR_PREFIX" ]; then + case "$MIRROR_PREFIX" in + http://*|https://*) printf '%s/%s +' "${MIRROR_PREFIX%/}" "$url" ;; + *) printf 'https://%s/%s +' "${MIRROR_PREFIX%/}" "$url" ;; + esac + else + printf '%s +' "$url" + fi +} + +TMP_DL=$(mktemp -d /tmp/openbox-upd.XXXXXX 2>/dev/null || echo "/tmp/openbox-upd.$$") +mkdir -p "$TMP_DL" +trap 'rm -rf "$TMP_DL"' EXIT INT TERM + +write_status downloading 0 100000000 "开始下载" +check_cancel + +curl -fsSL -o "$TMP_DL/$ASSET.sha256" "$(build_url "$SHA_URL")" 2>/dev/null || wget -q -O "$TMP_DL/$ASSET.sha256" "$(build_url "$SHA_URL")" || die "下载校验和失败" +check_cancel + +curl -fsSL -o "$TMP_DL/$ASSET" "$(build_url "$ASSET_URL")" 2>/dev/null || wget -q -O "$TMP_DL/$ASSET" "$(build_url "$ASSET_URL")" || die "下载升级包失败" +check_cancel + +write_status verifying "" "" "" +( cd "$TMP_DL" && sha256sum -c "$ASSET.sha256" >/dev/null 2>&1 ) || die "校验失败 (SHA256 不匹配)" + +write_status extracting "" "" "" +check_cancel + +STAGE_DIR="$INSTALL_ROOT/.update-stage.$$" +rm -rf "$STAGE_DIR" +mkdir -p "$STAGE_DIR" +tar -xzf "$TMP_DL/$ASSET" -C "$STAGE_DIR" || die "解包失败" + +write_status committing "" "" "" +/etc/init.d/openbox-panel stop >/dev/null 2>&1 || true +/etc/init.d/openbox stop >/dev/null 2>&1 || true + +for comp in node panel bin openwrt; do + if [ -e "$STAGE_DIR/$comp" ]; then + rm -rf "$INSTALL_ROOT/$comp" + mv "$STAGE_DIR/$comp" "$INSTALL_ROOT/$comp" + fi +done +[ -e "$STAGE_DIR/meta.json" ] && mv "$STAGE_DIR/meta.json" "$INSTALL_ROOT/meta.json" +rm -rf "$STAGE_DIR" + +cp -f "$INSTALL_ROOT/openwrt/initd/openbox" /etc/init.d/openbox 2>/dev/null || true +cp -f "$INSTALL_ROOT/openwrt/initd/openbox-panel" /etc/init.d/openbox-panel 2>/dev/null || true +chmod +x /etc/init.d/openbox /etc/init.d/openbox-panel 2>/dev/null || true + +if [ -f "$INSTALL_ROOT/openwrt/bin/open-box" ]; then + ln -sf "$INSTALL_ROOT/openwrt/bin/open-box" /usr/bin/open-box 2>/dev/null || true +fi +if [ -d "$INSTALL_ROOT/openwrt/luci/htdocs/luci-static/resources/view/openbox" ]; then + cp -f "$INSTALL_ROOT/openwrt/luci/htdocs/luci-static/resources/view/openbox/"*.js /www/luci-static/resources/view/openbox/ 2>/dev/null || true +fi +if [ -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/luci/menu.d/luci-app-openbox.json" ]; then + cp -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/luci/menu.d/luci-app-openbox.json" /usr/share/luci/menu.d/ 2>/dev/null || true +fi +if [ -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/rpcd/acl.d/luci-app-openbox.json" ]; then + cp -f "$INSTALL_ROOT/openwrt/luci/root/usr/share/rpcd/acl.d/luci-app-openbox.json" /usr/share/rpcd/acl.d/ 2>/dev/null || true +fi + +rm -rf /tmp/luci-*cache* 2>/dev/null || true +/etc/init.d/rpcd restart >/dev/null 2>&1 || true + +/etc/init.d/openbox-panel start >/dev/null 2>&1 || true +/etc/init.d/openbox start >/dev/null 2>&1 || true + +write_status done "" "" "升级完成" +info "升级完成!" diff --git a/luci-app-open-box/root/usr/share/rpcd/acl.d/luci-app-openbox.json b/luci-app-open-box/root/usr/share/rpcd/acl.d/luci-app-openbox.json new file mode 100644 index 000000000..1e20e5936 --- /dev/null +++ b/luci-app-open-box/root/usr/share/rpcd/acl.d/luci-app-openbox.json @@ -0,0 +1,34 @@ +{ + "luci-app-openbox": { + "description": "Grant UCI and system execution access for luci-app-openbox", + "read": { + "cgi-io": [ "backup" ], + "file": { + "/opt/open-box/meta.json": [ "read" ], + "/opt/open-box/data/panel-port": [ "read" ], + "/tmp/openbox-update.status": [ "read" ], + "/tmp/openbox-update.log": [ "read" ], + "/tmp/openbox-uninstall.status": [ "read" ], + "/tmp/openbox-uninstall.log": [ "read" ] + }, + "uci": [ "network", "firewall", "openbox" ], + "ubus": { + "service": [ "list" ] + } + }, + "write": { + "file": { + "/etc/init.d/openbox": [ "exec" ], + "/etc/init.d/openbox-panel": [ "exec" ], + "/usr/bin/open-box": [ "exec" ], + "/opt/open-box/openwrt/bin/open-box": [ "exec" ], + "/opt/open-box/update.sh": [ "exec" ], + "/opt/open-box/uninstall.sh": [ "exec" ], + "/usr/share/openbox/install.sh": [ "exec" ], + "/usr/share/openbox/update.sh": [ "exec" ], + "/usr/share/openbox/uninstall.sh": [ "exec" ] + }, + "uci": [ "firewall", "openbox" ] + } + } +} diff --git a/luci-app-open-box/root/www/luci-static/resources/view/openbox/main.js b/luci-app-open-box/root/www/luci-static/resources/view/openbox/main.js new file mode 100644 index 000000000..119f7305b --- /dev/null +++ b/luci-app-open-box/root/www/luci-static/resources/view/openbox/main.js @@ -0,0 +1,456 @@ +'use strict'; +'require view'; +'require fs'; +'require ui'; +'require uci'; +'require rpc'; +'require poll'; + +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: [ 'name' ], + expect: { '': {} } +}); + +return view.extend({ + pollInterval: 3, + + load: function() { + return Promise.all([ + fs.read('/opt/open-box/meta.json').catch(function() { return null; }), + fs.read('/opt/open-box/data/panel-port').catch(function() { return null; }), + fs.exec_direct('/usr/bin/open-box', [ 'password' ]).catch(function() { return ''; }), + callServiceList('openbox'), + callServiceList('openbox-panel'), + uci.load('network').catch(function() { return null; }), + uci.load('openbox').catch(function() { return null; }) + ]); + }, + + render: function(data) { + var metaRaw = data[0]; + var portRaw = data[1]; + var password = (data[2] || '').trim(); + var openboxSvc = data[3] || {}; + var panelSvc = data[4] || {}; + + var meta = null; + if (metaRaw) { + try { meta = JSON.parse(metaRaw); } catch(e) {} + } + + var port = (portRaw || '').replace(/[^0-9]/g, ''); + if (!port) { + port = (uci.get('openbox', 'main', 'port') || '3036'); + } + + var lanIp = uci.get('network', 'lan', 'ipaddr'); + if (Array.isArray(lanIp)) lanIp = lanIp[0]; + if (lanIp && lanIp.indexOf('/') !== -1) lanIp = lanIp.split('/')[0]; + if (!lanIp) lanIp = window.location.hostname || '192.168.1.1'; + + var panelRunning = (panelSvc['openbox-panel'] && panelSvc['openbox-panel']['instances'] && Object.keys(panelSvc['openbox-panel']['instances']).length > 0); + var coreRunning = (openboxSvc['openbox'] && openboxSvc['openbox']['instances'] && Object.keys(openboxSvc['openbox']['instances']).length > 0); + + var panelUrl = 'http://' + lanIp + ':' + port; + + var viewRoot = E('div', { 'class': 'cbi-map' }, [ + E('h2', {}, [ _('Open-Box') + ' ' + (meta && meta.version ? 'v' + meta.version : '') ]), + E('div', { 'class': 'cbi-map-descr' }, [ + _('Open-Box 是路由器上的一体化透明代理方案,内置 sing-box 内核、Node.js 运行时与 Web 管理面板。本页面为 LuCI 兜底管理页,可用于启停服务、修改端口、找回密码或执行维护操作。') + ]) + ]); + + // 1. 面板直达与密码卡片 + var accessCard = E('div', { 'class': 'cbi-section' }, [ + E('h3', {}, [ _('Open-Box 管理面板') ]), + E('div', { 'class': 'cbi-section-descr' }, [ + _('日常代理节点选择、分流规则配置、订阅管理及流量统计请在独立 Web 面板中进行。') + ]), + E('div', { 'class': 'table' }, [ + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left', 'style': 'width:30%' }, [ E('strong', {}, _('面板访问地址')) ]), + E('div', { 'class': 'td' }, [ + E('a', { 'href': panelUrl, 'target': '_blank', 'class': 'cbi-button cbi-button-action' }, [ + _('打开管理面板') + ' (' + panelUrl + ')' + ]) + ]) + ]), + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left' }, [ E('strong', {}, _('面板当前密码')) ]), + E('div', { 'class': 'td' }, [ + E('span', { 'style': 'font-family: monospace; font-size: 1.1em; color: #2c3e50; font-weight: bold;' }, [ + password || _('尚未设置(首次打开面板设置管理密码)') + ]), + password ? E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'style': 'margin-left: 1em;', + 'click': function() { + navigator.clipboard.writeText(password).then(function() { + ui.addNotification(null, E('p', {}, _('密码已复制到剪贴板。')), 'info'); + }); + } + }, [ _('复制密码') ]) : E('span') + ]) + ]), + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left' }, [ E('strong', {}, _('面板监听端口')) ]), + E('div', { 'class': 'td' }, [ + E('span', { 'style': 'font-family: monospace; margin-right: 1em;' }, [ port ]), + E('button', { + 'class': 'cbi-button cbi-button-apply', + 'click': ui.createHandlerFn(this, 'handlePortChange', port) + }, [ _('修改端口') ]) + ]) + ]) + ]) + ]); + viewRoot.appendChild(accessCard); + + // 2. 服务运行状态卡片 + var statusCard = E('div', { 'class': 'cbi-section' }, [ + E('h3', {}, [ _('服务运行状态') ]), + E('div', { 'class': 'table' }, [ + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left', 'style': 'width:30%' }, [ E('strong', {}, _('面板服务 (openbox-panel)')) ]), + E('div', { 'class': 'td' }, [ + E('span', { 'class': 'badge ' + (panelRunning ? 'badge-success' : 'badge-danger') }, [ + panelRunning ? _('运行中 (Running)') : _('已停止 (Stopped)') + ]), + E('div', { 'class': 'btn-group', 'style': 'display: inline-block; margin-left: 1.5em;' }, [ + E('button', { + 'class': 'cbi-button ' + (panelRunning ? 'cbi-button-reset' : 'cbi-button-action'), + 'click': ui.createHandlerFn(this, 'handleServiceAction', 'openbox-panel', panelRunning ? 'stop' : 'start') + }, [ panelRunning ? _('停止面板') : _('启动面板') ]), + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'style': 'margin-left: 0.5em;', + 'click': ui.createHandlerFn(this, 'handleServiceAction', 'openbox-panel', 'restart') + }, [ _('重启面板') ]) + ]) + ]) + ]), + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left' }, [ E('strong', {}, _('内核代理服务 (openbox)')) ]), + E('div', { 'class': 'td' }, [ + E('span', { 'class': 'badge ' + (coreRunning ? 'badge-success' : 'badge-danger') }, [ + coreRunning ? _('运行中 (Running)') : _('已停止 (Stopped)') + ]), + E('div', { 'class': 'btn-group', 'style': 'display: inline-block; margin-left: 1.5em;' }, [ + E('button', { + 'class': 'cbi-button ' + (coreRunning ? 'cbi-button-reset' : 'cbi-button-action'), + 'click': ui.createHandlerFn(this, 'handleServiceAction', 'openbox', coreRunning ? 'stop' : 'start') + }, [ coreRunning ? _('紧急停止内核 (恢复直连)') : _('启动内核') ]), + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'style': 'margin-left: 0.5em;', + 'click': ui.createHandlerFn(this, 'handleServiceAction', 'openbox', 'restart') + }, [ _('按配置重载/重启') ]) + ]) + ]) + ]) + ]) + ]); + viewRoot.appendChild(statusCard); + + // 3. 核心组件与更新维护卡片 + var hasCore = (meta !== null); + var maintenanceCard = E('div', { 'class': 'cbi-section' }, [ + E('h3', {}, [ _('组件与更新维护') ]), + E('div', { 'class': 'cbi-section-descr' }, [ + hasCore ? _('当前已安装 Open-Box 核心组件(安装目录:/opt/open-box)。') : + _('检测到核心组件尚未安装或 /opt/open-box 不完整。您可以直接使用下方一键下载安装功能完成初始化。') + ]), + E('div', { 'class': 'table' }, [ + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left', 'style': 'width:30%' }, [ E('strong', {}, _('核心组件状态')) ]), + E('div', { 'class': 'td' }, [ + hasCore ? E('span', { 'class': 'badge badge-success' }, [ + _('已就绪') + ' (' + (meta.arch || 'unknown') + ', ' + (meta.version || 'v' + meta.version) + ')' + ]) : E('span', { 'class': 'badge badge-danger' }, [ _('尚未就绪') ]), + !hasCore ? E('button', { + 'class': 'cbi-button cbi-button-action', + 'style': 'margin-left: 1em;', + 'click': ui.createHandlerFn(this, 'handleInstallCore') + }, [ _('一键安装核心组件') ]) : E('span') + ]) + ]), + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left' }, [ E('strong', {}, _('更新加速镜像')) ]), + E('div', { 'class': 'td' }, [ + E('select', { 'id': 'openbox_mirror_select', 'class': 'cbi-input-select' }, [ + E('option', { 'value': 'direct' }, _('GitHub 直连 (官方)')), + E('option', { 'value': 'https://ghfast.top', 'selected': 'selected' }, 'ghfast.top (' + _('内置推荐') + ')'), + E('option', { 'value': 'https://gh-proxy.com' }, 'gh-proxy.com'), + E('option', { 'value': 'https://gh.llkk.cc' }, 'gh.llkk.cc') + ]), + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'style': 'margin-left: 1em;', + 'click': ui.createHandlerFn(this, 'handleTestLatency') + }, [ _('测速/检测可用性') ]), + E('span', { 'id': 'openbox_probe_result', 'style': 'margin-left: 1em; font-weight: bold;' }, '') + ]) + ]), + E('div', { 'class': 'tr' }, [ + E('div', { 'class': 'td left' }, [ E('strong', {}, _('系统升级与维护')) ]), + E('div', { 'class': 'td' }, [ + E('button', { + 'class': 'cbi-button cbi-button-apply', + 'click': ui.createHandlerFn(this, 'handleUpdate', false) + }, [ _('检查并升级到最新版') ]), + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'style': 'margin-left: 0.5em;', + 'click': ui.createHandlerFn(this, 'handleUpdate', true) + }, [ _('回退到上个版本 (Rollback)') ]), + E('button', { + 'class': 'cbi-button cbi-button-reset', + 'style': 'margin-left: 1.5em;', + 'click': ui.createHandlerFn(this, 'handleUninstall') + }, [ _('卸载 Open-Box') ]) + ]) + ]) + ]) + ]); + viewRoot.appendChild(maintenanceCard); + + return viewRoot; + }, + + handleServiceAction: function(service, action) { + ui.showModal(_('正在处理'), [ + E('p', { 'class': 'spinning' }, _('正在执行操作,请稍候...')) + ]); + return fs.exec('/etc/init.d/' + service, [ action ]).then(function() { + window.location.reload(); + }).catch(function(e) { + ui.addNotification(null, E('p', {}, _('操作失败: ') + e.message), 'error'); + ui.hideModal(); + }); + }, + + handlePortChange: function(currentPort) { + var input = E('input', { + 'type': 'number', + 'class': 'cbi-input-text', + 'min': 1024, + 'max': 65535, + 'value': currentPort + }); + ui.showModal(_('修改面板端口'), [ + E('p', {}, _('请输入 1024 至 65535 之间的可用端口号(修改后将自动重启面板并放行防火墙):')), + input, + E('div', { 'class': 'right', 'style': 'margin-top: 1em;' }, [ + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'click': ui.hideModal + }, [ _('取消') ]), + E('button', { + 'class': 'cbi-button cbi-button-apply', + 'style': 'margin-left: 0.5em;', + 'click': function() { + var newPort = input.value.trim(); + if (!newPort || isNaN(newPort) || newPort < 1024 || newPort > 65535) { + ui.addNotification(null, E('p', {}, _('请输入合法的端口号 (1024-65535)')), 'error'); + return; + } + ui.showModal(_('保存中'), [ E('p', { 'class': 'spinning' }, _('正在应用新端口并重启面板...')) ]); + fs.exec_direct('/usr/bin/open-box', [ 'port', newPort ]).then(function() { + window.location.reload(); + }).catch(function(e) { + ui.addNotification(null, E('p', {}, _('修改失败: ') + e.message), 'error'); + ui.hideModal(); + }); + } + }, [ _('保存并重启') ]) + ]) + ]); + }, + + handleTestLatency: function() { + var select = document.getElementById('openbox_mirror_select'); + var mirror = select ? select.value : 'direct'; + var resultSpan = document.getElementById('openbox_probe_result'); + if (resultSpan) { + resultSpan.textContent = _('正在检测...'); + resultSpan.style.color = '#3498db'; + } + + var args = [ '--probe', mirror ]; + var execPath = '/opt/open-box/update.sh'; + fs.stat(execPath).catch(function() { + return fs.stat('/usr/share/openbox/update.sh').then(function() { + execPath = '/usr/share/openbox/update.sh'; + }); + }).then(function() { + return fs.exec_direct(execPath, args); + }).then(function(out) { + if (resultSpan) { + var text = (out || '').trim(); + if (text.startsWith('ok')) { + resultSpan.textContent = '✓ ' + text.replace('ok', _('可用') + ': '); + resultSpan.style.color = '#27ae60'; + } else { + resultSpan.textContent = '✗ ' + text.replace('fail', _('失败') + ': '); + resultSpan.style.color = '#e74c3c'; + } + } + }).catch(function(err) { + if (resultSpan) { + resultSpan.textContent = '✗ ' + (err.message || _('检测出错')); + resultSpan.style.color = '#e74c3c'; + } + }); + }, + + handleInstallCore: function() { + var select = document.getElementById('openbox_mirror_select'); + var mirror = select ? select.value : 'https://ghfast.top'; + var args = []; + if (mirror !== 'direct') { + args = [ '--mirror', mirror ]; + } + + ui.showModal(_('安装核心组件'), [ + E('p', { 'class': 'spinning' }, _('正在下载并部署 Open-Box 完整核心组件(约需 1-3 分钟,视网络速度而定)...')) + ]); + + var script = '/usr/share/openbox/install.sh'; + fs.exec(script, args).then(function() { + ui.addNotification(null, E('p', {}, _('核心组件安装成功!')), 'info'); + window.location.reload(); + }).catch(function(e) { + ui.addNotification(null, E('p', {}, _('安装失败: ') + e.message), 'error'); + ui.hideModal(); + }); + }, + + handleUpdate: function(isRollback) { + var select = document.getElementById('openbox_mirror_select'); + var mirror = select ? select.value : 'direct'; + var args = [ '--detach' ]; + if (isRollback) args.push('--rollback'); + if (mirror === 'direct') { + args.push('--direct'); + } else { + args.push('--mirror'); + args.push(mirror); + } + + var execPath = '/opt/open-box/update.sh'; + fs.stat(execPath).catch(function() { + execPath = '/usr/share/openbox/update.sh'; + }).then(function() { + return fs.exec_direct(execPath, args); + }).then(function() { + var progressBar = E('div', { 'class': 'cbi-progressbar', 'title': '0%' }, [ E('div', { 'style': 'width: 0%' }) ]); + var statusText = E('p', {}, _('任务已派发,正在准备下载...')); + var logPre = E('pre', { 'style': 'max-height: 200px; overflow-y: scroll; font-size: 11px; background: #f8f9fa; padding: 8px;' }, ''); + + ui.showModal(isRollback ? _('正在执行版本回退') : _('正在升级 Open-Box'), [ + statusText, + progressBar, + E('p', { 'style': 'margin-top: 1em;' }, [ E('strong', {}, _('实时日志:')) ]), + logPre, + E('div', { 'class': 'right', 'style': 'margin-top: 1em;' }, [ + E('button', { + 'class': 'cbi-button cbi-button-reset', + 'click': function() { + fs.exec_direct(execPath, [ '--cancel' ]); + ui.hideModal(); + } + }, [ _('取消更新') ]) + ]) + ]); + + var timer = window.setInterval(function() { + Promise.all([ + fs.read('/tmp/openbox-update.status').catch(function() { return ''; }), + fs.read('/tmp/openbox-update.log').catch(function() { return ''; }) + ]).then(function(res) { + var st = res[0] || ''; + var lg = res[1] || ''; + logPre.textContent = lg; + logPre.scrollTop = logPre.scrollHeight; + + var stage = (st.match(/stage=([^\n]+)/) || [])[1]; + var bytes = parseInt((st.match(/bytes=([0-9]+)/) || [])[1] || 0); + var total = parseInt((st.match(/total=([0-9]+)/) || [])[1] || 0); + var msg = (st.match(/message=([^\n]*)/) || [])[1] || ''; + + if (stage === 'downloading') { + if (total > 0) { + var pct = Math.floor((bytes / total) * 100); + progressBar.firstElementChild.style.width = pct + '%'; + progressBar.setAttribute('title', pct + '%'); + statusText.textContent = _('正在下载发布包: ') + (bytes / 1048576).toFixed(1) + 'MB / ' + (total / 1048576).toFixed(1) + 'MB (' + pct + '%)'; + } else { + statusText.textContent = _('正在下载发布包: ') + (bytes / 1048576).toFixed(1) + 'MB'; + } + } else if (stage === 'extracting') { + progressBar.firstElementChild.style.width = '80%'; + statusText.textContent = _('正在解包并校验文件完整性...'); + } else if (stage === 'committing') { + progressBar.firstElementChild.style.width = '90%'; + statusText.textContent = _('正在替换旧组件并重启服务...'); + } else if (stage === 'done') { + window.clearInterval(timer); + progressBar.firstElementChild.style.width = '100%'; + statusText.textContent = _('操作完成!') + (msg ? ' (' + msg + ')' : ''); + window.setTimeout(function() { window.location.reload(); }, 2000); + } else if (stage === 'failed' || stage === 'cancelled') { + window.clearInterval(timer); + statusText.textContent = (stage === 'failed' ? _('操作失败: ') : _('操作已取消: ')) + msg; + } + }); + }, 1000); + }).catch(function(e) { + ui.addNotification(null, E('p', {}, _('启动升级失败: ') + e.message), 'error'); + }); + }, + + handleUninstall: function() { + var checkPurge = E('input', { 'type': 'checkbox' }); + ui.showModal(_('卸载 Open-Box'), [ + E('p', {}, _('确定要从系统中卸载 Open-Box 吗?')), + E('label', { 'class': 'cbi-checkbox', 'style': 'display: block; margin: 1em 0;' }, [ + checkPurge, + ' ' + _('同时删除所有用户数据(/opt/open-box/data 下的节点订阅、规则集与数据库)') + ]), + E('div', { 'class': 'right' }, [ + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'click': ui.hideModal + }, [ _('取消') ]), + E('button', { + 'class': 'cbi-button cbi-button-reset', + 'style': 'margin-left: 0.5em;', + 'click': function() { + var purge = checkPurge.checked; + var args = [ '--detach' ]; + if (purge) args.push('--purge'); + + var execPath = '/opt/open-box/uninstall.sh'; + fs.stat(execPath).catch(function() { + execPath = '/usr/share/openbox/uninstall.sh'; + }).then(function() { + return fs.exec_direct(execPath, args); + }).then(function() { + ui.showModal(_('卸载中'), [ + E('p', { 'class': 'spinning' }, _('正在停止服务并清理残留文件...')) + ]); + window.setTimeout(function() { + window.location.href = window.location.pathname.replace(/\/admin\/services\/openbox.*/, '/admin/status/overview'); + }, 4000); + }).catch(function(err) { + ui.addNotification(null, E('p', {}, _('卸载失败: ') + err.message), 'error'); + ui.hideModal(); + }); + } + }, [ _('确认卸载') ]) + ]) + ]); + } +}); diff --git a/luci-theme-edge/.gitignore b/luci-theme-edge/.gitignore deleted file mode 100644 index 8e5a63f1d..000000000 --- a/luci-theme-edge/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/Screenshots diff --git a/luci-theme-edge/Makefile b/luci-theme-edge/Makefile deleted file mode 100644 index a793eddc6..000000000 --- a/luci-theme-edge/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (C) 2008-2019 GaryPang -# -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=Edge Theme -LUCI_DEPENDS:=+curl - -PKG_LICENSE:=Apache-2.0 - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-theme-edge/README.md b/luci-theme-edge/README.md deleted file mode 100644 index 90a878007..000000000 --- a/luci-theme-edge/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# luci-theme-edge - -[1]: https://img.shields.io/badge/license-MIT-brightgreen.svg -[2]: /LICENSE -[3]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg -[4]: https://github.com/https://github.com/kiddin9/luci-theme-edge/pulls -[5]: https://img.shields.io/badge/Issues-welcome-brightgreen.svg -[6]: https://github.com/https://github.com/kiddin9/luci-theme-edge/issues/new -[7]: https://img.shields.io/badge/release-v2.1-blue.svg? -[10]: https://img.shields.io/badge/Contact-telegram-blue -[11]: https://t.me/openwrt_nginx -[![license][1]][2] -[![PRs Welcome][3]][4] -[![Issue Welcome][5]][6] -[![Contact Me][10]][11] - -Telegram - -A new Luci theme for LEDE/OpenWRT -Edge is a clean HTML5 theme for LuCI. It is based on luci-theme-argon Template - -Master branch adapt to official mainline snapshot. -Luci 18.06: https://github.com/kiddin9/luci-theme-edge/tree/18.06 - -## Thanks to -luci-theme-argon: https://github.com/jerrykuku/luci-theme-argon - -![](/Screenshots/1.png) -![](/Screenshots/2.png) -![](/Screenshots/3.png) -![](/Screenshots/4.png) -![](/Screenshots/5.png) -
-
-
- diff --git a/luci-theme-edge/htdocs/luci-static/edge/background/1.jpg b/luci-theme-edge/htdocs/luci-static/edge/background/1.jpg deleted file mode 100644 index 5f7ce3154..000000000 Binary files a/luci-theme-edge/htdocs/luci-static/edge/background/1.jpg and /dev/null differ diff --git a/luci-theme-edge/htdocs/luci-static/edge/background/2.jpg b/luci-theme-edge/htdocs/luci-static/edge/background/2.jpg deleted file mode 100644 index 81462887f..000000000 Binary files a/luci-theme-edge/htdocs/luci-static/edge/background/2.jpg and /dev/null differ diff --git a/luci-theme-edge/htdocs/luci-static/edge/background/3.jpg b/luci-theme-edge/htdocs/luci-static/edge/background/3.jpg deleted file mode 100644 index 0da1d98f8..000000000 Binary files a/luci-theme-edge/htdocs/luci-static/edge/background/3.jpg and /dev/null differ diff --git a/luci-theme-edge/htdocs/luci-static/edge/cascade.css b/luci-theme-edge/htdocs/luci-static/edge/cascade.css deleted file mode 100644 index 9cfb8c858..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/cascade.css +++ /dev/null @@ -1,4147 +0,0 @@ -/** - * Edge is a clean HTML5 theme for LuCI. It is based on luci-theme-Argon - * - * luci-theme-edge - * Copyright 2020 Kiddin' - * - * Have a bug? Please create an issue here on GitHub! - * https://github.com/kiddin9/luci-theme-edge/issues - * - * luci-theme-material: header - * Copyright 2015 Lutty Yang - * https://github.com/LuttyYang/luci-theme-material/ - * - * Agron Theme - * https://demos.creative-tim.com/argon-dashboard/index.html - * - * Login background - * https://unsplash.com/ - * Font generate by Icomoon - * - * Licensed to the public under the Apache License 2.0 - */ -/* - * Include base and custom css - */ -@import url("custom.css?v=1"); -/* - * Icon Css and Fonts - */ -@font-face { - font-family: 'Google Sans'; - src: - url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: 'argon'; - src: url('fonts/argon.woff?vncylf') format('woff'); - font-weight: normal; - font-style: normal; - font-display: block; -} - -[class^="icon-"], -[class*=" icon-"] { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'argon' !important; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - color: #5A8DEE; - text-decoration: none; - background-color: transparent; -} - -*::-webkit-scrollbar:hover { - background-color: rgba(100, 100, 100, .09); -} - -*::-webkit-scrollbar-thumb:vertical { - background: rgba(100, 100, 100, .5); - -webkit-border-radius: 100px; -} - -*::-webkit-scrollbar-thumb:vertical:active { - background: rgba(100, 100, 100, .61); - -webkit-border-radius: 100px; -} - -*::-webkit-scrollbar { - width: 0.5em !important; - overflow: visible; - border-radius: 4px; - -webkit-border-radius: 4px; -} - -*::-webkit-scrollbar-track { - opacity: 0; - -webkit-transition: all .5s; -} - -*::-webkit-scrollbar-thumb { - overflow: visible; - border-radius: 4px; - background: rgba(100, 100, 100, .2); -} - -.icon-hello-world:before { - content: "\e90e"; -} - -.icon-expand_more:before { - content: "\e20b"; -} - -.icon-menu:before { - content: "\e20e"; -} - -.icon-favorite:before { - content: "\e291"; -} - -.icon-spinner:before { - content: "\e603"; -} - -.icon-delete:before { - content: "\e900"; -} - -.icon-edit:before { - content: "\e901"; -} - -.icon-use:before { - content: "\e902"; -} - -.icon-loading:before { - content: "\e903"; -} - -.icon-switch:before { - content: "\e904"; -} - -.icon-error:before { - content: "\e905"; -} - -.icon-dashboard:before { - content: "\e906"; -} - -.icon-logout:before { - content: "\e907"; -} - -.icon-Network:before { - content: "\e908"; -} - -.icon-services:before { - content: "\e909"; -} - -.icon-system:before { - content: "\e90a"; -} - -.icon-vpn:before { - content: "\e90b"; -} - -.icon-storage:before { - content: "\e90c"; -} - -.icon-statistics:before { - content: "\e90d"; -} - -.icon-angle-right:before { - content: "\e90f"; -} - -.icon-password:before { - content: "\e910"; -} - -.icon-user:before { - content: "\e971"; -} - -.icon-question:before { - content: "\f059"; -} - -.sk-folding-cube { - position: absolute; - width: 40px; - height: 40px; - left: 50%; - top: 50%; - margin: -20px 0 0 -20px; - -webkit-transform: rotateZ(45deg); - transform: rotateZ(45deg); -} - -.sk-folding-cube .sk-cube { - float: left; - width: 50%; - height: 50%; - position: relative; - -webkit-transform: scale(1.1); - -ms-transform: scale(1.1); - transform: scale(1.1); -} - -.sk-folding-cube .sk-cube:before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: #5A8DEE; - -webkit-animation: sk-foldCubeAngle 2.4s infinite linear both; - animation: sk-foldCubeAngle 2.4s infinite linear both; - -webkit-transform-origin: 100% 100%; - -ms-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -.sk-folding-cube .sk-cube2 { - -webkit-transform: scale(1.1) rotateZ(90deg); - transform: scale(1.1) rotateZ(90deg); -} - -.sk-folding-cube .sk-cube3 { - -webkit-transform: scale(1.1) rotateZ(180deg); - transform: scale(1.1) rotateZ(180deg); -} - -.sk-folding-cube .sk-cube4 { - -webkit-transform: scale(1.1) rotateZ(270deg); - transform: scale(1.1) rotateZ(270deg); -} - -.sk-folding-cube .sk-cube2:before { - -webkit-animation-delay: 0.3s; - animation-delay: 0.3s; -} - -.sk-folding-cube .sk-cube3:before { - -webkit-animation-delay: 0.6s; - animation-delay: 0.6s; -} - -.sk-folding-cube .sk-cube4:before { - -webkit-animation-delay: 0.9s; - animation-delay: 0.9s; -} - -@-webkit-keyframes sk-foldCubeAngle { - 0%, - 10% { - -webkit-transform: perspective(140px) rotateX(-180deg); - transform: perspective(140px) rotateX(-180deg); - opacity: 0; - } - - 25%, - 75% { - -webkit-transform: perspective(140px) rotateX(0deg); - transform: perspective(140px) rotateX(0deg); - opacity: 1; - } - - 90%, - 100% { - -webkit-transform: perspective(140px) rotateY(180deg); - transform: perspective(140px) rotateY(180deg); - opacity: 0; - } -} - -@keyframes sk-foldCubeAngle { - 0%, - 10% { - -webkit-transform: perspective(140px) rotateX(-180deg); - transform: perspective(140px) rotateX(-180deg); - opacity: 0; - } - - 25%, - 75% { - -webkit-transform: perspective(140px) rotateX(0deg); - transform: perspective(140px) rotateX(0deg); - opacity: 1; - } - - 90%, - 100% { - -webkit-transform: perspective(140px) rotateY(180deg); - transform: perspective(140px) rotateY(180deg); - opacity: 0; - } -} - -.table { - position: relative; - display: table; -} - -.tr { - display: table-row; -} - -.thead { - display: table-header-group; -} - -.tbody { - display: table-row-group; -} - -.tfoot { - display: table-footer-group; -} - -.td, -.th { - line-height: normal; - display: table-cell; - padding: 0.5em; - text-align: center; - vertical-align: middle; -} - -.th { - font-weight: bold; -} - -.tr.placeholder { - height: 4em; -} - -.tr.placeholder > .td { - line-height: 3; - position: absolute; - right: 0; - bottom: 0; - left: 0; - padding: 0.4rem 0 !important; - text-align: center !important; - background: inherit; -} - -.td[width="33%"] { - padding: 1.1em 2rem; -} - -.table[width="33%"], -.th[width="33%"], -.td[width="33%"] { - width: 33%; -} - -.table[width="100%"], -.th[width="100%"], -.td[width="100%"] { - width: 100%; -} - - -* { - box-sizing: border-box; - margin: 0; - padding: 0; -} - -.h1, -.h2, -.h3, -.h4, -.h5, -.h6, -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: inherit; - font-weight: normal; - line-height: 1.1rem; - color: inherit; -} - -html { - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -body { - font-family: "Google Sans", "Microsoft Yahei", "WenQuanYi Micro Hei", "sans-serif", "Helvetica Neue", "Helvetica", "Hiragino Sans GB"; - font-size: 0.82rem; - color: #4d5156 -} - -html, -body { - margin: 0; - padding: 0; - overflow-x: hidden; -} - -select { - padding: 0.36rem 0.8rem; - color: #555; - border: thin solid #ccc; - background-color: #fff; - background-image: none; -} - -div { - position: relative; -} - -.btn, -button, -select, -input, -.cbi-button, -.cbi-dropdown { - color: #4d5156; - border: none; - border-bottom: 1px solid #9e9e9e; - outline: 0; - background-image: none; - box-shadow: none; - transition: box-shadow 0.15s ease; -} - -input:not([type]), input[type=text]:not(.browser-default), input[type=password]:not(.browser-default), input[type=email]:not(.browser-default), input[type=url]:not(.browser-default), input[type=time]:not(.browser-default), input[type=date]:not(.browser-default), input[type=datetime]:not(.browser-default), input[type=datetime-local]:not(.browser-default), input[type=tel]:not(.browser-default), input[type=number]:not(.browser-default), input[type=search]:not(.browser-default), textarea.materialize-textarea { - background-color: transparent; - border: none; - border-bottom: 1px solid #9e9e9e; - border-radius: 0; - outline: none; - margin: 0; - padding: 0 0.5rem; - -webkit-box-shadow: none; - box-shadow: none; - -webkit-box-sizing: content-box; - box-sizing: content-box; - transition: box-shadow .3s, border .3s; -} - -.cbi-value-field>div { - position: relative; -} - -.focus-input { - position: absolute; - display: block; - width: 100%; - height: 100%; - top: 0; - left: 0; - pointer-events: none; -} - -.focus-input::before { - content: ""; - display: block; - position: absolute; - top: 2.2rem; - left: 0; - width: 0; - height: 2px; - -webkit-transition: all 0.4s; - -o-transition: all 0.4s; - -moz-transition: all 0.4s; - transition: all 0.4s; - background: #5A8DEE; -} - -select+.focus-input::before { - top: 2.12rem; -} - -.node-main-login .focus-input::before { - top: 2.73rem; -} - -input:focus + .focus-input::before,select:focus + .focus-input::before { - width: 100%; -} - -select, -.cbi-dropdown { - width: inherit; - cursor: default; -} - -select:not([multiple="multiple"]):focus, -input:not(.cbi-button):focus, -.cbi-dropdown:focus { -} - -.cbi-dropdown, -select[multiple="multiple"] { -} - -pre { - overflow: auto; -} - -code { - font-size: 1rem; - font-size-adjust: 0.35; - padding: 1px 3px; - color: #101010; - border-radius: 2px; - background: #ddd; -} - -abbr { - cursor: help; - text-decoration: underline; - color: #797474; -} - -hr { - margin: 1rem 0; - opacity: 0.1; - border-color: #eee; -} - -header, -.main { - width: 100%; -} - -footer { - font-size: 0.8rem; - overflow: hidden; - padding: 1rem; - text-align: right; - white-space: nowrap; - color: #aaa; - text-shadow: 0 0 2px #bbb; -} - -footer > a { - text-decoration: none; - color: #aaa; -} - -small { - font-size: 90%; - line-height: 1.42857143; - white-space: normal; -} - -.main { - position: relative; - top: 0; - bottom: 0; - overflow-y: auto; - height: 100%; -} - -.main > .loading { - position: fixed; - z-index: 1000; - top: 0; - display: block; - width: 100%; - height: 100%; - pointer-events: none; - background-color: #f0f0f0; -} - -.main > .loading > span { - font-family: monospace; - font-size: 2rem; - font-size-adjust: 0.35; - position: relative; - top: 12.5%; - display: block; - text-align: center; - color: #888; -} - -.main > .loading > span > .loading-img { - position: relative; - top: 0.1rem; - left: 0.05rem; - display: inline-block; - width: 1.25rem; - height: 1.25rem; - margin-right: 1rem; - animation: anim-rotate 2s infinite linear; - background: url(icons/spinner.svg) no-repeat center; -} - -@keyframes anim-rotate { - 0% { - -webkit-transform: rotate(0); - -ms-transform: rotate(0); - transform: rotate(0); - } - - 100% { - -webkit-transform: rotate(360deg); - -ms-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -p { - line-height: 1.8rem; -} - -.main-left { - top: 0; - float: left; - width: 15%; - width: calc(0% + 15rem); - height: 100%; - background-color: #fff; - background-color: var(--menu-bg-color); - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); - transition: box-shadow .25s, -webkit-box-shadow .25s; - overflow-x: auto; - position: fixed; - z-index: 100; -} - -.main-left .sidenav-header { - padding: 1.5rem 0 0.6rem; - text-align: center; - width: calc(0% + 13rem); -} - -.main-left .sidenav-header .brand { - font-size: 1.8rem; - color: #5A8DEE; - font-family: "TypoGraphica"; - text-decoration: none; - text-align: center; - cursor: default; - vertical-align: text-bottom; - white-space: nowrap; -} - -.brand img { - width: 180px; -} - -.main-right { - float: right; - width: 85%; - width: calc(100% - 15rem); - height: 100%; - transition: all 0.2s; - overflow-x: hidden; -} - -.main-right > #maincontent { - position: relative; - z-index: 50; - margin-top: 2rem; -} - -.pull-right { - float: right; -} - -.pull-left { - float: left; -} - -.nowrap:not(.td) { - white-space: nowrap; -} -[disabled="disabled"] { - pointer-events: none; -} - -header { - color: #fff; - color: var(--header-color); - display: none; -} - -header .fill { - padding: 0.8rem 0; -} - -header .container { - height: 2rem; - padding: 0 1rem; -} - -header .container .showSide { - display: none; - font-size: 1.4rem; -} - -header .container .brand { - font-size: 1.5rem; - color: #fff; - font-family: "TypoGraphica"; - text-decoration: none; - padding-left: 1rem; - cursor: default; - vertical-align: text-bottom; - display: none; -} - -header .container .pull-right { - float: right; - margin-top: 0rem; - display: flex; -} - -header .fill .status { - position: absolute; - top: 25%; - right: 1em; - float: right; -} - -header .fill .status * { - position: relative; - top: 0.2rem; - float: left; - margin-left: 0.3rem; - cursor: pointer; -} - -#xhr_poll_status { - display: flex; - margin-left: 0.5rem; -} - -#xhr_poll_status * { - color: #fff; -} - -.modal.alert-message { - background-color: #5A8DEE; - color: #fff; -} - -.modal.alert-message p { - font-weight: bold; - font-size: 0.9rem; - text-align: center; -} - -.modal .label.warning { - background-color: #FDAC41 !important; - color: #fff !important; -} - -.danger,.error { - background-color: rgba(255, 91, 92, 0.2) !important; - color: #FF5B5C !important; -} - -.danger a,.error a { - color: #FF5B5C !important; -} - -.warning { - background-color: rgba(253, 172, 65, 0.2) !important; - color: #FDAC41 !important; -} - -.warning a { - color: #FDAC41 !important; -} - -.modal.warning { - color: #fff !important; - background-color: #FDAC41 !important; -} - -.success { - background-color: rgba(57, 218, 138, 0.2) !important; - color: #39DA8A !important; -} - -.success a { - color: #39DA8A !important; -} - -.alert, -.alert-message { - font-weight: bold; - margin-bottom: 1em; - padding: 0.7rem 1rem; - background: rgba(90, 141, 238, 0.2); - color: #5A8DEE; - border: 0; -} - -.alert a, -.alert-message a { - color: #5A8DEE; -} - -.alert h4, -.alert-message h4 { - padding: 0rem 1.5rem 0.75rem 0rem; -} - -.alert .btn, -.alert-message .btn { - height: auto; -} - -.alert-message > h4 { - font-size: 110%; - font-weight: bold; -} - -.alert-message .btn { - padding: 0.3rem 0.6rem; -} - -.container .alert, -.container .alert-message { - margin-top: 1rem; -} -/* - * Main Menu - */ -.main .main-left { - transition: all 0.2s; -} - -.main .main-left .nav { - margin-top: 0rem; -} - -.main .main-left .nav li { - padding: 0.5rem 1rem; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.main .main-left .nav li a { - display: block; - color: #5f6368; - color: var(--menu-color); -} - -.main .main-left .nav li { - padding: 0; -} - -.main .main-left .nav li ul { - display: none; -} - -.main .main-left .nav>li>a { - display: block; - margin: 0.4rem 0.5rem !important; - padding: 0.5rem 0 0.5rem 2.5rem !important; - transition: box-shadow .25s, -webkit-box-shadow .25s; - border-radius: 2px; - text-decoration: none; - cursor: default; - transition: all 0.2s; - position: relative; - font-size: 0.93rem; -} - -.main .main-left .nav li .menu.active { - color: #fff; - background: #5A8DEE; -} - -.main .main-left .nav li .menu.active::before { - color: #fff !important; -} - -.main .main-left .nav li .menu.active::after { - transform: rotate(90deg); - color: #fff !important; -} - -.main .main-left .nav>li>a:first-child:hover { - cursor: pointer; - color: #fff; - background: #5A8DEE; -} - -.main .main-left .nav>li>a:first-child:hover::before { - color: #fff !important; -} - -.main .main-left .nav>li>a:first-child::before { - font-family: 'argon' !important; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - position: absolute; - left: 0.8rem; - padding-top: 3px; - transition: all 0.3s; - content: "\e915"; - color: #5e72e4; -} - -.main .main-left .nav li .menu::after { - position: absolute; - right: 0.5rem; - top: 0.8rem; - font-family: 'argon' !important; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - /* Better Font Rendering =========== */ - -moz-osx-font-smoothing: grayscale; - content: '\e90f'; - transition: all 0.15s ease; - color: #ced4da; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - transition: all 0.3s; -} - -.main .main-left .nav li .menu[data-title=Status]:before { - content: "\e906"; - color: #5e72e4; -} - -.main .main-left .nav li .menu[data-title=System]:before { - content: "\e90a"; - color: #fb6340; -} - -.main .main-left .nav li .menu[data-title=Services]:before { - content: "\e909"; - color: #11cdef; -} - -.main .main-left .nav li .menu[data-title=NAS]:before { - content: "\e90c"; - color: #f3a4b5; -} - -.main .main-left .nav li .menu[data-title=VPN]:before { - content: "\e90b"; - color: #8965e0; -} - -.main .main-left .nav li .menu[data-title=Network]:before { - content: "\e908"; - color: #8965e0; -} - -.main .main-left .nav li .menu[data-title=Bandwidth_Monitor]:before { - content: "\e90d"; - color: #2dce89; -} - -.main .main-left .nav li .menu[data-title=Docker]:before { - content: "\e911"; - color: #6699ff; -} - -.main .main-left .nav li .menu[data-title=Statistics]:before { - content: "\e913"; - color: #8965e0; -} - -.main .main-left .nav li .menu[data-title=Control]:before { - content: "\e912"; - color: #5e72e4; -} - -.main .main-left .nav li .menu[data-title=Asterisk]:before { - content: "\e914"; - color: #fb6340; -} - -.main .main-left .nav li a[data-title=Logout]:before { - content: "\e907"; - color: #adb5bd; -} - -.main .main-left .nav li:hover { - background: none; -} - -.main .main-left .nav li .slide-menu { - margin: 0 0.5rem 0 2.5rem; - padding: 0rem 0.5rem; -} - -.main .main-left .nav li.slide .slide-menu.active { - display: block; -} - -.main .main-left .nav li .slide-menu li { - position: relative; - border-radius: 2px; - margin: 0.2rem 0; - padding: 0.5rem 0rem; - background: none; -} - -.main .main-left .nav li .slide-menu li a { - white-space: nowrap; - text-decoration: none; -} - -.main .main-left .nav li .slide-menu li::after { - content: ""; - position: absolute; - left: 0; - bottom: 0; - width: 0; - height: 2px; - background-color: #5A8DEE; - transition: all 0.2s; -} - -.main .main-left .nav li .slide-menu li:hover { - background: none; -} - -.main .main-left .nav li .slide-menu li:hover::after { - width: 100%; -} - -.main .main-left .nav li .slide-menu .active { - background: none; - color: var(--menu-color); -} - -.main .main-left .nav li .slide-menu .active a { - color: var(--menu-color); -} - -.main .main-left .nav li .slide-menu .active::after { - content: ""; - position: absolute; - left: 0; - bottom: 0; - width: 100%; - height: 2px; - background-color: #5A8DEE; - transition: all 0.2s; -} - -.main .main-left .nav li .slide-menu .active:hover { - background: none; -} - -.main .main-left .nav li .slide-menu .active:hover::after { - width: 100%; -} - -body[class*="node-"] > .main > .main-left > .nav > .slide > .menu::before { - transition: transform 0.1s ease-in-out; -} - -body[class*="node-"] > .main > .main-left > .nav > .slide > .menu.active::before { - transition: transform 0.2s ease-in-out; -} - -.main > .main-left[style*="overflow: hidden"] > .nav > .slide > .menu::before { - display: none; -} - -#maincontent > .container { - padding:0 2%; -} - -.Overview.node-admin-status #maincontent > .container { - padding:0; -} - -.Overview.node-admin-status #maincontent > .container h2{ - padding-left:2rem; -} -ul { - line-height: normal; -} - -li { - list-style-type: none; -} - -h1 { - font-size: 2rem; - padding-bottom: 10px; - border-bottom: thin solid #eee; -} - -h2 { - font-size: 1.8rem; - padding: 1rem 2rem; -} - -h3 { - font-size: 1.4rem; - margin: 0rem 0 0 0; - padding: 2rem 2rem 1.25rem 2rem; -} - -h4 { - font-size: 1.2rem; - margin: 1.2rem 0 0 0; - padding: 0rem 2rem 0.75rem 2rem; -} - -h5 { - font-size: 1rem; - margin: 2rem 0 0 0; - padding-bottom: 10px; -} - -.container .cbi-section{ - margin-bottom:1rem; - -} - -.cbi-modal .cbi-section, -.cbi-section .cbi-section { - padding: 0; - box-shadow: none; -} - -.cbi-modal .cbi-tabmenu { - margin-left: 0; -} - -.cbi-map-descr, -.cbi-section-descr { - font-size: small; - line-height: 2rem; - padding: 0 0 0.5rem 0; -} - -.cbi-section-node { - padding-left: 2rem; -} - -.cbi-section .cbi-section-node { - padding-left: 0; -} - -.cbi-section-descr { - color: #404040; -} - -.cbi-map-descr + fieldset { - margin-top: 1rem; -} - -.cbi-map-descr > abbr { - cursor: help; - text-decoration: underline; -} - -.cbi-section > legend { - display: none !important; -} - -fieldset.cbi-section{ -border:none; -} - -fieldset > fieldset, -.cbi-section > .cbi-section { - margin: 0; - padding: 0; - border: 0; - box-shadow: none; -} - -.cbi-section > h3:first-child, -.panel-title { - font-size: 1.4rem; - line-height: 1; - display: block; - width: 100%; - margin: 0; - margin-bottom: 0; - padding: 1.25rem 2rem; - color: #32325d; - color: var(--gray-dark); -} - -.cbi-section > h3:first-child, -.cbi-section > h4:first-child, -.cbi-section > p:first-child, -[data-tab-title] > h3:first-child, -[data-tab-title] > h4:first-child, -[data-tab-title] > p:first-child { - padding: 0.5rem; -} - -table { - border-spacing: 0; - border-collapse: collapse; -} - -table, -.table { - overflow-y: hidden; - width: 100%; -} - -table > tbody > tr > td, -table > tbody > tr > th, -table > tfoot > tr > td, -table > tfoot > tr > th, -table > thead > tr > td, -table > thead > tr > th, -.table > .tbody > .tr > .td, -.table > .tbody > .tr > .th, -.table > .tfoot > .tr > .td, -.table > .tfoot > .tr > .th, -.table > .thead > .tr > .td, -.table > .thead > .tr > .th, -.table > .tr > .td.cbi-value-field, -.table > .tr > .th.cbi-section-table-cell { - padding: 0.5rem; -} - -.container > .cbi-section:first-of-type > .table[width="100%"] > .tr > .td { - padding: 0.6rem; -} - -.cbi-section-table-cell { - line-height: 1.1; - align-self: flex-end; - flex: 1 1 auto; -} - -tr > td, -tr > th, -.tr > .td, -.tr > .th, -.cbi-section-table-row::before, -#cbi-wireless > #wifi_assoclist_table > .tr:nth-child(2) { - padding: 1rem 1rem 1rem 1rem; -} - -#cbi-wireless .td, -#cbi-network .tr:first-child > .td, -.table[width="100%"] > .tr:first-child > .td, -[data-page="admin-network-diagnostics"] .tr > .td, -.tr.table-titles > .th, -.tr.cbi-section-table-titles > .th { - border-top: 0 !important; - padding: 1.1em 1rem; - line-height: 1.3rem; -} - -.cbi-tab-descr { - padding: 1rem; -} - -.table[width="100%"] > .tr:first-child > .td { - margin: auto 0; -} - -.cbi-section-table-row { - margin-bottom: 1rem; - text-align: center !important; - background: #f4f4f4; -} - -.cbi-section-table-row:last-child { - margin-bottom: 0; -} - -.cbi-section-table-row > .cbi-value-field .cbi-dropdown, -.cbi-section-table-row > .cbi-value-field .cbi-input-select, -.cbi-section-table-row > .cbi-value-field .cbi-input-text, -.cbi-section-table-row > .cbi-value-field .cbi-input-password { - width: 100%; - min-width: 0 !important; -} - -.cbi-section-table-row > .cbi-value-field [data-dynlist] > input, -.cbi-section-table-row > .cbi-value-field input.cbi-input-password { - width: calc(100% - 1.5rem); -} - -.cbi-section-table-row .td { - text-align: center !important; -} - -table > tbody > tr, -div > .table > .tr,.cbi-map >.cbi-section .cbi-value { - background-color: #fff; - transition: background-color .25s -} - -table > tbody > tr:nth-of-type(4n+2), -div > .table > .tr:nth-of-type(4n+2),.cbi-map >.cbi-section .cbi-value:nth-of-type(2n) { - background-color: #e5effd; -} - -table > tbody > tr:nth-of-type(4n+2):hover, -div > .table > .tr:nth-of-type(4n+2):hover { - background-color: #d9e9ff; -} - -table > tbody > tr:nth-of-type(4n), -div > .table > .tr:nth-of-type(4n) { - background-color: rgba(223, 56, 18, 0.04); -} - -table > tbody > tr:nth-of-type(4n):hover, -div > .table > .tr:nth-of-type(4n):hover { - background-color: rgba(223, 56, 18, 0.09); -} - -.cbi-map >.cbi-section .cbi-value:nth-of-type(2n) { - background-color: #e5effdb8; -} - -.cbi-map >.cbi-section .cbi-value:nth-of-type(2n):hover { - background-color: #e5effd; -} - -/* fix multiple table */ -table table, -.table .table, -.cbi-value-field table, -.cbi-value-field .table, -td > table > tbody > tr > td, -.td > .table > .tbody > .tr > .td, -.cbi-value-field > table > tbody > tr > td, -.cbi-value-field > .table > .tbody > .tr > .td { - border: 0; -} -/* button style */ -.btn, -.cbi-button, -.item::after { - font-size: 0.8rem; - display: inline-block; - width: auto !important; - padding: 0 0.8rem; - cursor: pointer; - white-space: nowrap; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - transition: all 0.2s ease-in-out; - text-align: center; - vertical-align: middle; - text-decoration: none; - color: #fff; - border: 0; - border-radius: 0.2rem; - background-image: none; - -webkit-appearance: none; - -ms-touch-action: manipulation; - touch-action: manipulation; -} - -.cbi-button-up, -.cbi-button-down { - font-size: 1.2rem; - display: inline-block; - min-width: 0; - padding: 0.2rem 0.3rem; - color: transparent !important; - background: url(icons/arrow.svg) no-repeat center !important; - background-size: 12px 20px !important; -} - -.cbi-button-up { - transform: scaleY(-1); -} - -.cbi-button:not(select) { - -webkit-appearance: none !important; -} - -button:hover, -.btn:hover, -.cbi-button:hover, -.item:hover::after { - opacity: 0.7; - top: 0.1rem; -} - -.cbi-button-up:hover, -.cbi-button-up:focus { - opacity: 0.7; -} - -.btn:disabled, -.cbi-button:disabled { - cursor: not-allowed; - pointer-events: none; - opacity: 0.5; - box-shadow: none; -} -/* gray */ -.alert-message [class="btn"], -.modal div[class="btn"], -.cbi-button-find, -.cbi-button-link, -.cbi-button-up, -.cbi-button-down, -.cbi-button-neutral, -.cbi-button[name="zero"], -.cbi-button[name="restart"], -.cbi-button[onclick="hide_empty(this)"] { - color: #fff; - background-color: #A3AFBD !important; -} -/* dark blue */ -.btn.primary, -.cbi-page-actions .cbi-button-save, -.cbi-page-actions .cbi-button-apply + .cbi-button-save, -.cbi-button-add, -.cbi-button-save, -.cbi-button-positive, -.cbi-button-link, -.cbi-button[value="Enable"], -.cbi-button[value="Scan"], -.cbi-button[value^="Back"], -.cbi-button-neutral[onclick="handleConfig(event)"] { - font-weight: normal; - color: #fff; - border: none; - background-color: #23bd70 !important; -} -/* light blue */ -.cbi-page-actions .cbi-button-apply, -.cbi-section-actions .cbi-button-edit, -.cbi-button-edit, -.cbi-button-apply, -.cbi-button-reload, -.cbi-button-action, -.cbi-button[value="Submit"], -.cbi-button[value="Upload"], -.cbi-button[value$="Apply"], -.cbi-button[onclick="addKey(event)"] { - font-weight: normal; - color: #fff; - background-color: #5A8DEE !important; -} -/* red */ -.btn.danger, -.cbi-section-remove > .cbi-button, -.cbi-button-remove, -.btn[onclick="handleOpkg(event)"], -.cbi-button-reset, -.cbi-button-negative, -.cbi-button[value="Stop"], -.cbi-button[value="Kill"], -.cbi-button[onclick="reboot(this)"], -.cbi-button-neutral[value="Restart"] { - font-weight: normal; - color: #fff; - border: none; - background-color: #fdb75a !important; -} -/* yellow */ -.btn[value="Dismiss"], -.cbi-button[value="Terminate"], -.cbi-button[value="Reset"], -.cbi-button[value="Disabled"], -.cbi-button[onclick^="iface_reconnect"], -.cbi-button[onclick="handleReset(event)"], -.cbi-button-neutral[value="Disable"] { - font-weight: normal; - color: #fff; - border: none; - background-color: #23bd70 !important; -} -/* green */ -.cbi-button-success, -.cbi-button-download, -.cbi-button[name="backup"], -.cbi-button[value="Download"], -.cbi-button[value="Save mtdblock"] { - font-weight: normal; - color: #fff; - background-color: #5cb85c !important; -} - -.cbi-page-actions .cbi-button-link:first-child { - float: left; -} - -.a-to-btn { - text-decoration: none; -} - -.cbi-value-field .cbi-button-add { - font-weight: bold; - margin: 9px 0 4px 3px; - padding: 1px 6px; -} - -.tabs > li, -.cbi-tabmenu > li { - display: inline-block; - padding: 0; - margin: 0; - cursor: pointer; -} - -.tabs > li,.cbi-tabmenu > li { - border-bottom: 0.2rem solid transparent; - background-color: #fff; -} - -.tabs > li[class~="active"], -.tabs > li:hover { - border-bottom-color: #5A8DEE; - background-color: #669bff36; -} - -.tabs > li:hover { - cursor: pointer; -} - -.tabs > li > a, -.cbi-tabmenu > li > a { - padding: 0.8rem 1.9rem; - text-decoration: none; - color: #404040; - display: inline-block; -} - -.tabs > li[class~="active"] > a { - color: #5A8DEE; - color: #5A8DEE; -} - -ul.tabs,.tabmenu .tabs,#tabmenu .tabs,ul.cbi-tabmenu { - padding-left: 2.5%; - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12); - transition: box-shadow .25s, -webkit-box-shadow .25s; - border-radius: 2px; - border-bottom: 0; - margin-bottom: 10px; - background-color: #fff; - padding-top: 1rem; -} - -#packages{ - margin-left: -2%; - width: 105%; -} - -#packages td.col-10 { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 30em; - overflow: hidden; -} - -.cbi-tabmenu > li:hover { - background-color: rgba(246,178,181,0.2); -} - -.cbi-tabmenu > li[class~="cbi-tab"] { - background-color: rgba(246,178,181,0.2); - border-bottom-color: #ff9b84; -} - -.cbi-tabmenu > li[class~="cbi-tab"] a { - color: #ee6e73; -} - -.cbi-section .cbi-section-remove:nth-of-type(2n), -.container > .cbi-section .cbi-section-node:nth-of-type(2n) { - background-color: #f9f9f9; -} -[data-tab-title] { - overflow: hidden; - height: 0; - opacity: 0; - margin: 0; - padding: 0rem 0rem !important; -} -[data-tab-title] p { - margin-left: 1rem; - margin-bottom: 1rem; -} -[data-tab-active="true"] { - overflow: visible; - height: auto; - opacity: 1; - transition: opacity 0.25s ease-in; - margin: inherit !important; -} - -.cbi-section-node-tabbed { - margin-top: 0; - padding: 0; - transition: box-shadow .25s, -webkit-box-shadow .25s; - border-radius: 2px; -} - -.cbi-value-field, -.cbi-value-description { - display: table-cell; - position: relative; - margin-top: 1rem; - margin-bottom: 1rem; -} - -.cbi-value-field abbr, -.cbi-value-description abbr { - color: #32325d; - color: var(--gray-dark); -} - -.cbi-value-description { - line-height: inherit !important; -} - -.cbi-value-title { - display: table-cell; - float: left; - width: 15rem; - padding-right: 2rem; - text-align: right; - word-wrap: break-word; -} - -.cbi-value { - display: inline-block; - width: 100%; - padding: 0.5rem 1rem; - line-height: 2.4rem; -} - -.cbi-value-field >* { - line-height: 1.3rem; -} - -.cbi-value ul { - line-height: 1.25; -} - -.cbi-value-field .cbi-dropdown, -.cbi-value-field .cbi-input-select, -.cbi-value input[type="text"], -.cbi-value input[type="password"] { - min-width: 18rem; -} - -#cbi-firewall-zone .cbi-input-select, -#cbi-network-switch_vlan .cbi-input-select { - min-width: 11rem; -} - -#cbi-network-switch_vlan .cbi-input-text { - max-width: 3rem; -} - -.cbi-input-invalid { - color: #f5365c; - border-bottom-color: #f5365c; -} - -.cbi-section-error { - font-weight: bold; - line-height: 1.42857143; - margin: 18px; - padding: 6px; - border: thin solid #f5365c; - border-radius: 3px; - background-color: #fce6e6; -} - -.cbi-section-error ul { - margin: 0 0 0 20px; -} - -.cbi-section-error ul li { - font-weight: bold; - color: #f5365c; -} - -.td[data-title]::before { - font-weight: bold; - display: none; - padding: 0.25rem 0; - content: attr(data-title) ":\20"; - text-align: left; - white-space: nowrap; -} - -.tr.placeholder .td[data-title]::before { - display: none; -} - -.tr[data-title]::before, -.tr.cbi-section-table-titles.named::before { - font-weight: bold; - display: table-cell; - align-self: center; - flex: 1 1 5%; - padding: 0.25rem; - content: attr(data-title) "\20"; - text-align: center; - vertical-align: middle; - white-space: normal; - word-wrap: break-word; -} - -.cbi-rowstyle-1 { - background-color: #f9f9f9; -} - -.cbi-rowstyle-2 { -} - -.cbi-rowstyle-2 .cbi-button-up, -.cbi-rowstyle-2 .cbi-button-down, -body:not(.Interfaces) .cbi-rowstyle-2:first-child { - background-color: #fff !important; -} - -.cbi-section-table .cbi-section-table-titles .cbi-section-table-cell { - width: auto !important; -} - -.td.cbi-section-actions { - text-align: right !important; - vertical-align: middle; -} - -.td.cbi-section-actions > * { - display: inline-flex; -} - -.td.cbi-section-actions > * > *, -.td.cbi-section-actions > * > form > * { - margin: 0 5px; - display: flex; - align-items: center; -} - -.td.cbi-section-actions > * > form { - display: inline-flex; - margin: 0; -} -/* lists */ -.cbi-dynlist { - line-height: 1.3; - flex-direction: column; - min-height: 30px; - cursor: text; -} - -.cbi-dynlist > .item { - position: relative; - max-width: 25rem; - margin-right: 2em; - margin-bottom: 0.3rem; - padding: 1em 0.25em 0.25em 0; - pointer-events: none; - color: #8898aa; - border-bottom: 2px solid #5A8DEE; - border-bottom: 2px solid #5A8DEE; - outline: 0; -} - -.cbi-dynlist[name="sshkeys"] > .item { - max-width: none; -} - -.cbi-dynlist > .item::after { - font-weight: bold; - position: absolute; - right: -2em; - bottom: 0; - display: inline-flex; - min-height: 17px; - padding: 0 6px; - content: "\00D7"; - pointer-events: auto; - color: #fff; - border: thin solid #f5365c; - border: thin solid var(--red); - background-color: #f5365c; - background-color: var(--red); -} - -.cbi-dynlist > .item > span { - white-space: normal; - word-break: break-word; -} - -.cbi-dynlist > .add-item { - display: inline-flex; - align-items: center; - width: 100%; - min-width: 16rem; -} - -.cbi-dynlist > .add-item:not([ondrop]) > input { - overflow: hidden; - width: 100%; - min-width: 15rem; - white-space: nowrap; - text-overflow: ellipsis; -} - -.cbi-dynlist > .add-item[ondrop] > input { - min-width: 13rem; -} - -.cbi-dynlist, -.cbi-dropdown { - position: relative; - display: inline-flex; - padding: 0.2rem; -} - -.cbi-dropdown[placeholder*="select"] { - max-width: 25rem; - margin-top: -3px; -} - -.cbi-dropdown > ul { - display: flex; - overflow-x: hidden; - overflow-y: auto; - width: 100%; - margin: 0 !important; - padding: 0; - list-style: none; - outline: 0; -} - -#cbi-adblock-global-adb_sources .cbi-dropdown > ul.preview { - display: none; -} - -.cbi-button-apply > ul.preview { - display: none; -} - -.cbi-button-apply > ul.preview li { - color: #fff; -} - -.cbi-button-apply > ul:first-child li { - color: #fff; -} - -.cbi-dropdown > .open { - flex-basis: 15px; -} - -.cbi-dropdown > .open, -.cbi-dropdown > .more { - font-size: 1rem; - font-weight: 900; - display: flex; - flex-direction: column; - flex-grow: 0; - flex-shrink: 0; - justify-content: center; - padding: 0 0.25em; - cursor: default; - text-align: center; - outline: 0; - line-height: 1rem; -} - -.cbi-dropdown > .more, -.cbi-dropdown > ul > li[placeholder] { - font-weight: bold; - display: none; - color: #777; - text-shadow: 1px 1px 0 #fff; -} - -.cbi-dropdown > ul > li { - display: none; - overflow: hidden; - align-items: center; - align-self: center; - flex-grow: 1; - flex-shrink: 1; - white-space: nowrap; - text-overflow: ellipsis; -} - -.cbi-dropdown > ul > li .hide-open { - display: initial; -} - -.cbi-dropdown > ul > li .hide-close { - display: none; -} - -.cbi-dropdown > ul > li[display]:not([display="0"]) { - border-left: thin solid #ccc; -} - -.cbi-dropdown[empty] > ul { - max-width: 1px; -} - -.cbi-dropdown > ul > li > form { - display: none; - margin: 0; - padding: 0; - pointer-events: none; -} - -.cbi-dropdown > ul > li img { - margin-right: 0.25em; - vertical-align: middle; -} - -.cbi-dropdown > ul > li > form > input[type="checkbox"] { - height: auto; - margin: 0; - display:inline-block; -} - -.cbi-dropdown > ul > li input[type="text"] { - height: 20px; -} - -.cbi-dropdown[open] > ul.dropdown { - position: absolute; - z-index: 1100; - display: block; - width: auto; - min-width: 100%; - max-width: none; - max-height: 200px; - border: thin solid #918e8c; - background: #f6f6f6; - box-shadow: 0 0 4px #918e8c; - color: var(--main-menu-color); - left: 0; -} - -.cbi-dropdown[open] > ul.dropdown li { - color: #000; -} - -.cbi-dropdown > ul > li[display], -.cbi-dropdown[open] > ul.preview, -.cbi-dropdown[open] > ul.dropdown > li, -.cbi-dropdown[multiple] > ul > li > label, -.cbi-dropdown[multiple][open] > ul.dropdown > li, -.cbi-dropdown[multiple][more] > .more, -.cbi-dropdown[multiple][empty] > .more { - display: flex; - align-items: center; - flex-grow: 1; -} - -.cbi-dropdown[empty] > ul > li, -.cbi-dropdown[optional][open] > ul.dropdown > li[placeholder], -.cbi-dropdown[multiple][open] > ul.dropdown > li > form { - display: block; -} - -.cbi-dropdown[open] > ul.dropdown > li .hide-open { - display: none; -} - -.cbi-dropdown[open] > ul.dropdown > li .hide-close { - display: initial; -} - -.cbi-dropdown[open] > ul.dropdown > li { - border-bottom: thin solid #ccc; - padding: 0.5rem 0.8rem; -} - -.cbi-dropdown[open] > ul.dropdown > li[selected] { - background: #b0d0f0; -} - -.cbi-dropdown[open] > ul.dropdown > li.focus { - background: linear-gradient(90deg, #a3c2e8 0%, #84aad9 100%); -} - -.cbi-dropdown[open] > ul.dropdown > li:last-child { - margin-bottom: 0; - border-bottom: 0; -} - -.cbi-dropdown[open] > ul.dropdown > li[unselectable] { - opacity: 0.7; -} - -.cbi-dropdown[open] > ul.dropdown > li > input.create-item-input:first-child:last-child { - width: 100%; -} - -.cbi-dropdown[disabled] { - pointer-events: none; - opacity: 0.6; -} - -.cbi-dropdown .zonebadge { - width: 100%; -} - -.cbi-dropdown[open] .zonebadge { - width: auto; -} -/* progressbar */ -.cbi-progressbar { - position: relative; - min-width: 170px; - height: 20px; - margin: 6px 0; - border: thin solid #999; - border-radius: 0.2rem; - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); -} - -@keyframes progress-bar-stripes { - from { - background-position: 0.357rem 0; - } - - to { - background-position: 0 0; - } -} - -.cbi-progressbar > div { - width: 0; - height: 100%; - transition: width 0.25s ease-in; - background-color: #5A8DEE; - background-image: linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent); - background-size: auto auto; - animation: progress-bar-stripes 1s linear infinite; -} - -.cbi-progressbar::after { - font-family: monospace; - font-size: 1em; - font-weight: bold; - font-size-adjust: 0.38; - line-height: normal; - position: absolute; - top: 2px; - right: 0; - bottom: 2px; - left: 0; - overflow: hidden; - content: attr(title); - text-align: center; - white-space: pre; - text-overflow: ellipsis; - color: #ff4500d1; -} - -#modal_overlay { - position: fixed; - z-index: 900; - top: 0; - right: 10000px; - bottom: 0; - left: -10000px; - overflow-y: scroll; - transition: opacity 0.125s ease-in; - opacity: 0; - background: rgba(0, 0, 0, 0.7); - -webkit-overflow-scrolling: touch; -} - -.modal { - display: flex; - align-items: center; - flex-wrap: wrap; - width: 90%; - min-width: 270px; - max-width: 695px; - min-height: 32px; - margin: 25vh auto; - padding: 1em; - border-radius: 3px !important; - background: #fff; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 2px 0 rgba(0, 0, 0, 0.12); -} - -.modal > * { - line-height: normal; - flex-basis: 100%; - max-width: 100%; -} - -.modal > pre, -.modal > textarea { - font-size: 1rem; - font-size-adjust: 0.35; - overflow: auto; - margin-bottom: 0.5em; - padding: 8.5px; - cursor: auto; - white-space: pre-wrap; - color: #eee; - outline: 0; - background-color: #101010; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 2px 0 rgba(0, 0, 0, 0.12); -} - -.modal > h4 { - margin: 0.5em 0; -} - -.modal ul { - margin-left: 2.2em; -} - -.modal li { - list-style-type: square; - color: #808080; -} - -.modal p { - word-break: break-word; - margin: 1rem 0; -} - -h3+p,h4+p { - margin-top: 0 !important; -} - -.modal .label { - font-size: 0.6rem; - font-weight: normal; - padding: 0.1rem 0.3rem; - cursor: default; - border-radius: 0; - background: #9b9b9b; - color: #fff; -} - -.modal .label.notice { - color: #fff; - background: #5A8DEE; -} - -body.modal-overlay-active { - overflow: hidden; - height: 100vh; -} - -body.modal-overlay-active #modal_overlay { - right: 0; - left: 0; - opacity: 1; -} - -.spinning { - position: relative; - padding-left: 32px !important; -} - -.spinning::before { - position: absolute; - top: 0; - bottom: 0; - left: 0.2em; - width: 32px; - content: ""; - background: url(../resources/icons/loading.gif) no-repeat center; - background-size: 16px; -} -/* luci */ -.hidden { - display: none; -} - -.left, -.left::before { - text-align: left !important; -} - -.right, -.right::before { - text-align: right !important; -} - -.center, -.center::before { - text-align: center !important; -} - -.top { - align-self: flex-start !important; - vertical-align: top !important; -} - -.bottom { - align-self: flex-end !important; - vertical-align: bottom !important; -} - -.inline { - display: inline; -} - -.cbi-page-actions { - padding-top: 1rem; - text-align: right; -} - -.node-main-login .cbi-page-actions { - padding-right: 0; -} - -.cbi-page-actions > form[method="post"] { - display: inline-block; -} - -.th[data-type="button"], -.td[data-type="button"], -.th[data-type="fvalue"], -.td[data-type="fvalue"] { - flex: 1 1 2em; - text-align: center; -} - -.ifacebadge { - display: inline-flex; - padding: 0.5rem 0.8rem; - border-bottom: thin solid #ccc; - background: #eee; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -td > .ifacebadge, -.td > .ifacebadge { - font-size: 0.8rem; - background-color: #f0f0f0; -} - -.ifacebadge > em, -.ifacebadge > img { - display: inline-block; - align-self: flex-start; - margin: 0 0.2rem; -} - -.ifacebadge > img + img { - margin: 0 0.2rem 0 0; -} - -.network-status-table { - display: flex; - flex-wrap: wrap; -} - -.network-status-table .ifacebox { - flex-grow: 1; -} - -.network-status-table .ifacebox-body { - display: flex; - flex-direction: column; - height: 100%; -} - -.network-status-table .ifacebox-body > span { - flex: 10 10 auto; - height: 100%; -} - -.network-status-table .ifacebox-body > div { - display: flex; - flex-wrap: wrap; -} - -.network-status-table .ifacebox-body .ifacebadge { - align-items: center; - flex: 1 1 auto; - min-width: 220px; - margin: 0.5em 0em 0 0em; - padding: 0.5em; - background-color: #fff; -} -/* textarea */ -textarea { - font-family: monospace; - width: 95%; - min-width: 28rem; - padding: 0.8rem; - line-height: 1.6rem !important; - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); - transition: box-shadow .25s, -webkit-box-shadow .25s; - border-radius: 2px; - border: 0 !important; -} - -textarea:focus{ - outline: none; - border: 1px solid #5A8DEE !important; - box-shadow: 0 0px 5px 0 #5A8DEE; -} - -.cbi-section textarea { - margin: 0rem; -} - -#syslog { - font-size: small; - line-height: 1.25; - width: 100%; - padding: 1rem; - resize: none; - color: #eee; - border: 0; - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); - transition: box-shadow .25s, -webkit-box-shadow .25s; - border-radius: 2px; - background-color: #242424; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 2px 0 rgba(0, 0, 0, 0.12); - max-height: 100% !important; -} - -#syslog:focus { - outline: 0; -} -/* config changes */ -.uci-change-list { - font-family: monospace; -} - -.uci-change-list ins, -.uci-change-legend-label ins { - display: block; - padding: 2px; - text-decoration: none; - border: thin solid #0f0; - background-color: #cfc; -} - -.uci-change-list del, -.uci-change-legend-label del { - font-style: normal; - display: block; - padding: 2px; - text-decoration: none; - border: thin solid #f00; - background-color: #fcc; -} - -.uci-change-list var, -.uci-change-legend-label var { - font-style: normal; - display: block; - padding: 2px; - text-decoration: none; - border: thin solid #ccc; - background-color: #eee; -} - -.uci-change-list var ins, -.uci-change-list var del { - font-style: normal; - padding: 0; - white-space: pre; - border: 0; -} - -.uci-change-legend { - padding: 5px; -} - -.uci-change-legend-label { - float: left; - width: 150px; -} - -.uci-change-legend-label > ins, -.uci-change-legend-label > del, -.uci-change-legend-label > var { - display: block; - float: left; - width: 10px; - height: 10px; - margin-right: 4px; -} - -.uci-change-legend-label var ins, -.uci-change-legend-label var del { - line-height: 0.4; - border: 0; -} - -.uci-change-list var, -.uci-change-list del, -.uci-change-list ins { - padding: 0.5rem; -} -/* other fix */ -#iwsvg, -#iwsvg2, -#bwsvg { - border: thin solid #d4d4d4 !important; -} - -#iwsvg, -[data-page="admin-status-realtime-bandwidth"] #bwsvg { - border-top: 0 !important; -} - -.ifacebox { - line-height: 1.25; - display: inline-flex; - flex-direction: column; - min-width: 100px; -} - -.ifacebox-head { - padding: 0.25em; - background: #eee; -} - -.ifacebox-head.active { - background: #5A8DEE; -} - -.ifacebox-head.active * { - color: #fff; - color: var(--white); -} - -.ifacebox-body { - padding: 0.5em 2rem; - line-height: 1.6em; -} - -.cbi-image-button { - margin-left: 0.5rem; -} - -.zonebadge { - display: inline-block; - padding: 0.2rem 0.5rem; -} - -.zonebadge .ifacebadge { - margin: 0.1rem 0.2rem; - padding: 0.2rem 0.3rem; - border: thin solid #6c6c6c; -} - -.zonebadge > input[type="text"] { - min-width: 10rem; - margin-top: 0.3rem; - padding: 0.16rem 1rem; -} - -.zonebadge > em, -.zonebadge > strong { - display: inline-block; - margin: 0 0.2rem; -} - -.cbi-value-field .cbi-input-checkbox, -.cbi-value-field .cbi-input-radio { - margin-right: 5px; -} - -.cbi-value-field > ul > li { - display: flex; -} - -.cbi-value-field > ul > li > label { - margin-top: 0.5rem; -} - -.cbi-value-field > ul > li .ifacebadge { - margin-top: -0.5rem; - margin-left: 0.4rem; - background-color: #eee; -} - -.cbi-section-table-row > .cbi-value-field .cbi-dropdown { - min-width: 7rem; -} - -.cbi-section-create { - display: inline-flex; - align-items: center; - margin: 0.25rem 0 0.25rem 1rem; -} - -.cbi-section-create > * { - margin: 0.5rem; -} - -.cbi-section-remove { - padding: 0.5rem; -} - -div.cbi-value var, -td.cbi-value-field var, -.td.cbi-value-field var { - font-style: italic; - color: #0069d6; -} - -.cbi-optionals { - padding: 1rem 1rem 0 1rem; - border-top: thin solid #ccc; -} - -.cbi-dropdown-container { - position: relative; -} - -.cbi-tooltip-container, -span[data-tooltip], -span[data-tooltip] .label { - cursor: help !important; -} - -.cbi-tooltip { - position: absolute; - z-index: 1000; - left: -1000px; - padding: 2px 5px; - transition: opacity 0.25s ease-out; - white-space: pre; - pointer-events: none; - opacity: 0; - border-radius: 3px; - background: #fff; - box-shadow: 0 0 2px #444; -} - -.cbi-tooltip-container:hover .cbi-tooltip { - left: auto; - transition: opacity 0.25s ease-in; - opacity: 1; -} - -.zonebadge .cbi-tooltip { - margin: -1.5rem 0 0 -0.5rem; - padding: 0.25rem; - background: inherit; -} - -.zonebadge-empty { - color: #404040; - background: repeating-linear-gradient(45deg, rgba(204, 204, 204, 0.5), rgba(204, 204, 204, 0.5) 5px, rgba(255, 255, 255, 0.5) 5px, rgba(255, 255, 255, 0.5) 10px); -} - -.zone-forwards { - display: flex; - min-width: 10rem; -} - -.zone-forwards > * { - flex: 1 1 45%; -} - -.zone-forwards > span { - flex-basis: 10%; - padding: 0 0.25rem; - text-align: center; -} - -.zone-forwards .zone-src, -.zone-forwards .zone-dest { - display: flex; - flex-direction: column; -} - -.label,#indicators span { - font-size: 0.8rem; - padding: 0.3rem 0.8rem; - white-space: nowrap; - text-decoration: none; - text-transform: uppercase; - border-radius: 3px; - text-shadow: none; - margin: 0 0.5rem; - color: #fff; - background: #5A8DEE; -} - -#indicators span[data-indicator="poll-status"] { - color: #FDAC41 !important; - background-color: #FFEED9; -} - -#indicators span[data-indicator="uci-changes"] { - color: #39DA8A !important; - background-color: #D2FFE8; -} - -input[type="checkbox"], -input[type="radio"] { - position: relative; - right: 0.2rem; - margin: 0; - vertical-align: bottom; -} - -label[data-index][data-depends] { - padding-right: 2em; -} - -.showSide { - display: none; -} - -.darkMask { - position: fixed; - z-index: 99; - display: none; - width: 100%; - height: 100%; - content: ""; - top: 0; - background-color: rgba(0, 0, 0, 0.56); -} -/* diagnostics */ -#diag-rc-output > pre, -#command-rc-output > pre, -[data-page="admin-services-wol"] .notice code { - font-size: 1.2rem; - font-size-adjust: 0.35; - line-height: normal; - display: block; - overflow-y: hidden; - width: 100%; - padding: 8.5px; - white-space: pre; - color: #eee; - background-color: #101010; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 2px 0 rgba(0, 0, 0, 0.12); -} -[data-page="admin-network-diagnostics"] .table { - box-shadow: none; -} - -input[name="ping"], -input[name="traceroute"], -input[name="nslookup"] { - width: 80%; -} -/* fix Main Login */ -.node-main-login .main { - top: 0; - height: 100% !important; -} - -.node-main-login .main .main-left { - display: none; -} - -.node-main-login .main .main-right { - width: 100%; - text-align: center; - overflow: hidden; -} - -.node-main-login .main .main-right header { - background: none !important; - box-shadow: none !important; - display: none !important; -} - -.node-main-login .main .main-right .login-bg { - display: block; - position: fixed; - width: 100%; - height: 100%; - left: 0px; - top: 0px; - background-size: cover; - background-color: #000; - background-position: top center; - transition: all 0.5s; -} - -.node-main-login .main .main-right .login-bg.blur { - transform: scale(1.05); - -webkit-filter: blur(5px); - /* Chrome, Safari, Opera */ - filter: blur(5px); -} - -.node-main-login .main .main-right #maincontent { - height: 100%; - padding-top: 23vh; - padding-bottom:1rem; - margin-top: 0rem; - background-color: transparent !important; - text-align: center; - display: inline-block; - z-index: 999; -} - -.node-main-login .main .main-right #maincontent .container { - display: inline-block; - padding: 1rem 1.2rem; - position: relative; - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); - transition: box-shadow .25s, -webkit-box-shadow .25s; - border-radius: 2px; - text-align: left; - background: rgba(255, 255, 255, 0.75); - margin: 0; -} - -.node-main-login .main .main-right #maincontent .alert-message.warning { - position: absolute; - color: #fff; - width: calc(100%); - box-sizing: border-box; - margin-top: -3.5rem; - border-radius: 5px !important; - padding: 0.5rem 1rem; - text-align: center; - background-color: #eea236 !important; -} - -.node-main-login .main .main-right #maincontent .alert-message p { - color: #fff; - font-weight: normal; - font-size: 0.83rem; -} - -.node-main-login .main .main-right #maincontent .alert-message.error { - position: absolute; - color: #fff; - width: calc(100%); - background-color: #f0ad4e; - border-color: #eea236; - box-sizing: border-box; - margin-top: -7.5rem; - border-radius: 5px !important; - padding: 1rem 1rem 0.5rem 1rem; - text-align: center; -} - -.node-main-login .main .main-right #maincontent .alert-message.error p { - color: #fff; -} - -.alert-message p { - text-align: center; -} - -.node-main-login .main .main-right #maincontent .alert-message.error h4 { - font-size: 1rem; -} - -.node-main-login .main .main-right #maincontent .alert-message.error .btn { - height: auto; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map h2 { - display: block; - margin: 10px auto 10px auto; - padding: 0; - text-align: center; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-map-descr { - text-align: center; - padding: 1rem; - color: #8898aa; - font-size: 1.2rem; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section { - padding: 0.5rem; - margin-top: 0 !important; - background: none !important; - box-shadow: none !important; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node { - padding: 0; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value { - display: block; - padding: 0; - background: none; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value * { - display: inline-block !important; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value .cbi-value-title { - display: none !important; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value .cbi-value-field { - position: relative; - width: 18rem; - margin-bottom: 1em; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value .cbi-value-field input { - font-size: 1rem; - line-height: 1.5; - display: block; - width: 100%; - height: calc(2.75rem + 2px); - padding: 0.625rem 0.75rem; - transition: all 0.15s cubic-bezier(0.68, -0.55, 0.265, 1.55); - color: #8898aa; - background-clip: padding-box; - box-sizing: border-box; - padding-left: 3em !important; - margin: 0; - text-align: center; - text-indent: -3rem; - background: transparent content-box !important; - box-sizing: border-box; - height: 0 !important; - padding: 1.38rem 0; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value .cbi-value-field input:focus { - color: #8898aa; - outline: 0; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value .cbi-value-field:before { - font-family: 'argon' !important; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - content: "\e971"; - color: #adb5bd; - font-size: 1.5rem; - position: absolute; - z-index: 100; - left: 10px; - top: 10px; -} - -.node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value.cbi-value-last .cbi-value-field:before { - content: "\e910"; -} - -.node-main-login .main .main-right #maincontent .container .cbi-page-actions { - text-align: center; - padding-top: 0; - margin-bottom: 20px; -} - -.node-main-login .main .main-right #maincontent .container .cbi-page-actions input { - padding: 0.7rem 5.5rem -} - -.node-main-login .main .main-right #maincontent .container .cbi-page-actions .cbi-button { - background-color: #5a8deec7; -} - -.node-main-login .main .main-right #maincontent .container .cbi-page-actions .cbi-button.cbi-button-reset { - display: none !important; -} - -.node-main-login .main .main-right #maincontent footer { - bottom: 0; - position: absolute; - width: 100%; - color: #fff; -} - -.node-main-login .main .main-right #maincontent footer a { - color: #fff; -} - -@media screen and (min-height: 585px) { - .node-main-login footer { - display: none; - position: absolute; - bottom: 0; - width: 100%; - } -} -/* fix status */ -.node-status-overview > .main fieldset:nth-child(4) .td:nth-child(2), -.node-status-processes > .main .table .tr .td:nth-child(3) { - white-space: normal; -} -/* fix system reboot */ -[data-page="admin-system-reboot"] p { - padding-left: 0rem; - color: #fff; -} -[data-page="admin-system-reboot"] .cbi-button { - background: #fb6340 !important; -} -[data-page="admin-system-reboot"] p > span { - position: relative; - top: 0.1rem; - left: 1rem; -} -/* samba */ -#cbi-samba [data-tab="template"] .cbi-value-field { - display: block; -} - -#cbi-samba [data-tab="template"] .cbi-value-title { - width: auto; - padding-bottom: 0.6rem; -} -/* admin-system-admin-password */ -[data-page="admin-system-admin"] .cbi-map h2, -[data-page="admin-system-admin-password"] .cbi-map h2, -[data-page="admin-system-admin"] .cbi-map .cbi-map-descr, -[data-page="admin-system-admin-password"] .cbi-map .cbi-map-descr { - margin-left: 1.5rem; - color: #32325d; - color: var(--gray-dark); -} -/* software */ - - -.controls { - margin: 0.5em 0 1em 0 !important; -} - -.controls > * > .btn:not([aria-label$="page"]) { - flex-grow: initial !important; - margin-top: 0.25rem; -} - -.controls > #pager > .btn[aria-label$="page"] { - font-size: 1.4rem; - font-weight: bold; -} - -.controls > * > label { - margin-bottom: 0.2rem; -} -[data-page="admin-system-opkg"] div.btn { - line-height: 3; - display: inline; -} -[data-page^="admin-system-admin"]:not(.node-main-login) .cbi-map:not(#cbi-dropbear) { - margin-top: 2rem; - padding-top: 0.1rem; -} - - -.cbi-tabmenu + .cbi-section { - margin-top: 0; -} -/* admin-system-crontab*/ -[data-page="admin-system-crontab"] #view p { - color: #fff; - margin-bottom: 1rem; -} -/*admin-system-flash*/ -[data-page="admin-system-flash"] .cbi-value { - padding: 0; -} -[data-page="admin-system-flash"] .cbi-section .cbi-section { - margin-top: 0; -} -[data-page="admin-system-flash"] legend { - display: block !important; - font-size: 1.2rem; - width: 100%; - display: block; - margin-bottom: 0; - padding: 1rem 0 1rem 1.5rem; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - line-height: 1.5; - margin-bottom: 0rem; - letter-spacing: 0.1rem; - color: #32325d; - font-weight: bold; -} -[data-page="admin-system-flash"] .cbi-section-descr { - font-weight: 600; - padding: 1rem 0 1rem 1.5rem; - color: #525f7f; -} -/* wireless overview */ -#cbi-wireless > #wifi_assoclist_table > .tr { - box-shadow: inset 1px -1px 0 #ddd, inset -1px -1px 0 #ddd; -} - -#cbi-wireless > #wifi_assoclist_table > .tr.placeholder > .td { - right: 33px; - bottom: 33px; - left: 33px; - border-top: thin solid #ddd !important; -} - -#cbi-wireless > #wifi_assoclist_table > .tr.table-titles { - box-shadow: inset 1px 0 0 #ddd, inset -1px 0 0 #ddd; -} - -#cbi-wireless > #wifi_assoclist_table > .tr.table-titles > .th { - border-bottom: thin solid #ddd; - box-shadow: 0 -1px 0 0 #ddd; -} - -#wifi_assoclist_table > .tr > .td[data-title="RX Rate / TX Rate"] { - width: 23rem; -} -[data-page="admin-network-dhcp"] .cbi-value { - padding: 0; -} -[data-page="admin-network-dhcp"] [data-tab-active="true"] { - padding: 1rem 0 !important; -} -/* firewall */ -#iptables { - margin: 0; -} - -.Firewall form { - margin: 2rem 2rem 0 0; - padding: 0; - box-shadow: none; -} - -#cbi-firewall-redirect table *, -#cbi-network-switch_vlan table *, -#cbi-firewall-zone table * { - font-size: small; -} - -#cbi-firewall-redirect table input[type="text"], -#cbi-network-switch_vlan table input[type="text"], -#cbi-firewall-zone table input[type="text"] { - width: 5rem; -} - -#cbi-firewall-redirect table select, -#cbi-network-switch_vlan table select, -#cbi-firewall-zone table select { - min-width: 3.5rem; -} - -#cbi-network-switch_vlan .th, -#cbi-network-switch_vlan .td { - flex-basis: 12%; -} - -#cbi-firewall-zone .table, -#cbi-network-switch_vlan .table { - display: block; -} - -#cbi-firewall-zone .td, -#cbi-network-switch_vlan .td { - width: 100%; -} -[data-page="admin-network-firewall-custom"] #view p { - color: #fff; - margin-bottom: 1rem; -} -[data-page="admin-network-firewall-custom"] #view p textarea { - margin: 1.5rem; - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); - transition: box-shadow .25s, -webkit-box-shadow .25s; - border-radius: 2px; - width: 95% !important; -} -/* applyreboot fix */ -#applyreboot-container { - margin: 2rem; -} - -#applyreboot-section { - line-height: 300%; - margin: 2rem; -} -/* openvpn bug fix */ -.OpenVPN a { - line-height: initial !important; -} -/* custom commands */ -.commandbox { - width: 24% !important; - margin: 10px 0 0 10px !important; - padding: 0.5rem 1rem; - border-bottom: thin solid #ccc; - background: #eee; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.commandbox h3 { - line-height: normal !important; - overflow: hidden; - margin: 6px 0 !important; - white-space: nowrap; - text-overflow: ellipsis; -} - -.commandbox div { - left: auto !important; -} - -.commandbox code { - position: absolute; - overflow: hidden; - max-width: 60%; - margin-left: 4px; - padding: 2px 3px; - white-space: nowrap; - text-overflow: ellipsis; -} - -.commandbox code:hover { - overflow-y: auto; - max-height: 50px; - white-space: normal; -} - -.commandbox p:first-of-type { - margin-top: -6px; -} - -.commandbox p:nth-of-type(2) { - margin-top: 2px; -} -[data-page^="admin-system-commands"] .panel-title, -[data-page^="command-cfg"] .mobile-hide, -[data-page^="command-cfg"] .showSide { - display: none; -} - -#command-rc-output .alert-message { - line-height: 1.42857143; - position: absolute; - top: 40px; - right: 32px; - max-width: 40%; - margin: 0; - animation: anim-fade-in 1.5s forwards; - word-break: break-word; - opacity: 0; -} - -@keyframes anim-fade-in { - 100% { - opacity: 1; - } -} -/* other fix */ -input[type="checkbox"] { - appearance: none !important; - -webkit-appearance: none !important; - border: 1px solid #dee2e6; - width: 16px !important; - height: 16px !important; - padding: 0; - cursor: pointer; - transition: all 0.2s; -} -div[id^="cbid."]>input[type="checkbox"]{ - display:none; -} -.cbi-dropdown[open]>ul.dropdown>li label { - margin-left: .5rem; -} - -#cbi-adblock-global-adb_sources .cbi-dropdown-open .cbi-dropdown[open] > ul.dropdown{ - position:relative !important; - bottom:0 !important; -} - -#cbi-adblock-global-adb_sources .cbi-dropdown-open #cbi-adblock-global-adb_sources .preview,.cbi-dropdown-open .more,.cbi-dropdown-open .open{ -display:none !important; -} - -input[type="checkbox"]:checked { - border: 1px solid #5A8DEE; - background-image: url('data:image/svg+xml,%3csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 8 8\'%3e%3cpath fill=\'%23fff\' d=\'M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z\'/%3e%3c/svg%3e') !important; - background-color: #5A8DEE; - background-size: 70%; - background-repeat: no-repeat; - background-position: center; -} - -@media screen and (max-width: 1600px) { - header > .fill > .container > #logo { - margin: 0 2.5rem 0 0.5rem; - } - - .main-left { - width: calc(0% + 13rem); - } - - .main-right { - width: calc(100% - 13rem); - } - - .label { - padding: 0.2rem 0.6rem; - } - - .cbi-value-title { - width: 15rem; - padding-right: 1.5rem; - } - - .cbi-value-field .cbi-dropdown, - .cbi-value-field .cbi-input-select, - .cbi-value input[type="text"], - .cbi-value input[type="password"] { - min-width: 15rem; - } - - #cbi-firewall-zone .cbi-input-select { - min-width: 9rem; - } - - .cbi-input-textarea { - font-size: small; - } - - .node-admin-status > .main fieldset li > a { - padding: 0.3rem 0.6rem; - } -} - -@media screen and (max-width: 1366px) { - header > .fill > .container { - cursor: default; - } - - .main-left { - width: calc(0% + 13rem); - } - - .main-right { - width: calc(100% - 13rem); - } - - .panel-title { - font-size: 1.1rem; - padding-bottom: 1rem; - } - - table { - font-size: 0.7rem !important; - width: 100%; - } - - .table .cbi-input-text { - width: 100%; - } - - .cbi-value-field .cbi-dropdown, - .cbi-value-field .cbi-input-select, - .cbi-value input[type="text"], - .cbi-value input[type="password"] { - min-width: 16rem; - } - - #cbi-firewall-zone .cbi-input-select { - min-width: 4rem; - } - - .main > .main-left > .nav > .slide > .slide-menu > li > a { - font-size: 0.8rem; - } - - #modal_overlay { - top: 0rem; - } - [ data-page="admin-network-firewall-forwards"] .table:not(.cbi-section-table) { - display: block; - } - [ data-page="admin-network-firewall-forwards"] .table:not(.cbi-section-table), - [data-page="admin-network-firewall-rules"] .table:not(.cbi-section-table), - [data-page="admin-network-hosts"] .table, - [data-page="admin-network-routes"] .table { - overflow-y: visible; - } - - .commandbox { - width: 32% !important; - } -} - -@media screen and (max-width: 1152px) { - header > .fill > .container > #logo { - display: none; - } - - header > .fill > .container > .brand { - position: relative; - } - - html, - .main { - overflow-y: visible; - } - - .main > .loading > span { - top: 25%; - } - - .main-left { - width: calc(0% + 13rem); - } - - .main-right { - width: calc(100% - 13rem); - } - - body:not(.logged-in) .showSide { - visibility: hidden; - width: 0; - margin: 0; - } - - .node-main-login > .main .cbi-value-title { - text-align: left; - } - - .cbi-value-title { - width: 10rem; - padding-right: 1rem; - } - - .cbi-value-field .cbi-dropdown, - .cbi-value-field .cbi-input-select, - .cbi-value input[type="text"] { - width: 16rem; - min-width: 16rem; - } - /*.cbi-value input[type="password"],*/ - .cbi-value input[name^="pw"], - .cbi-value input[data-update="change"]:nth-child(2) { - width: 13rem !important; - min-width: 13rem; - } - - #diag-rc-output > pre, - #command-rc-output > pre, - [data-page="admin-services-wol"] .notice code { - font-size: 1rem; - } - - .Interfaces .table { - overflow-x: hidden; - } - - #packages.table { - display: grid; - } - - .Overview .table[width="100%"] > .tr { - flex-wrap: nowrap; - } - - .tr.placeholder { - border-bottom: thin solid #ddd; - } - - .tr.placeholder > .td, - #cbi-firewall .tr > .td, - #cbi-network .tr:nth-child(2) > .td, - .cbi-section #wifi_assoclist_table .tr > .td { - border-top: 0; - } - -.node-admin-status.Overview .tr { - display: flex; - flex-direction: row; - flex-wrap: wrap; -} - - .th, - .td { - display: inline-block; - align-self: flex-start; - flex: 2 2 25%; - text-overflow: ellipsis; - word-wrap: break-word; - } - - .td select, - .td input[type="text"] { - width: 100%; - word-wrap: normal; - } - - .td [data-dynlist] > input, - .td input.cbi-input-password { - width: calc(100% - 1.5rem); - } - - .td[data-type="button"], - .td[data-type="fvalue"] { - flex: 1 1 12.5%; - text-align: left; - } - - .th.cbi-value-field, - .td.cbi-value-field, - .th.cbi-section-table-cell, - .td.cbi-section-table-cell { - flex-basis: auto; - padding-top: 1rem; - } - - .td.cbi-value-field, - .cbi-section-table-cell { - display: inline-block; - flex: 10 10 auto; - flex-basis: 50%; - text-align: center; - } - - .td.cbi-section-actions { - vertical-align: bottom; - } - - .tr.table-titles, - .tr.cbi-section-table-titles, - .tr.cbi-section-table-descr { - display: none; - } - - .tr[data-title]::before, - .tr.cbi-section-table-titles.named::before { - font-size: 0.9rem; - display: block; - flex: 1 1 100%; - border-bottom: thin solid rgba(0, 0, 0, 0.26); - background: #e9ecef; - } - - .td[data-title], - [data-page^="admin-status-realtime"] .td[id] { - text-align: left; - } - - .td[data-title]::before { - display: block; - } - - .cbi-button + .cbi-button { - margin-left: 0; - } - - .td.cbi-section-actions > * > *, - .td.cbi-section-actions > * > form > * { - margin: 2.1px 3px; - } - - .Firewall form { - position: static !important; - margin: 0 0 2rem 0; - padding: 2rem; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 2px 0 rgba(0, 0, 0, 0.12); - } - - .Firewall form input { - width: 100% !important; - margin: 0; - margin-top: 1rem; - } - - .Firewall .center, - .Firewall .center::before { - text-align: left !important; - } - - .commandbox { - width: 100% !important; - margin-left: 0 !important; - } -#packages .tr { - display: flex; - flex-direction: row; - flex-wrap: wrap; -} -#packages .td { - padding: 1em 2rem; -} -} - -@media screen and (max-width: 768px) { - header { - display: block; - } - - body { - font-size: 0.8rem; - } - - .tabs > li > a, .cbi-tabmenu > li > a { - padding: 0.7rem 1.2rem; - } - - .btn, button, .cbi-button, input[type=button], input[type=submit], input[type=reset] { - padding: 0.5rem 1.2rem !important; - } - - .cbi-progressbar::after { - font-size: 0.95em; - line-height: 1.5; - } - - .main-left { - position: fixed; - z-index: 100; - width: 0; - } - - .main-right { - width: 100%; - } - - .main-right > #maincontent { - margin-top: 0.5rem; - } - - .showSide { - padding: 0.1rem; - position: relative; - z-index: 99; - top: -0.7rem; - display: inline-block !important; - } - - .showSide::before { - font-family: 'argon' !important; - font-style: normal !important; - font-weight: normal !important; - font-variant: normal !important; - text-transform: none !important; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - content: "\e20e"; - font-size: 1.7rem; - } - - header > .fill > .container > .brand { - display: inline-block; - } - - .cbi-section > div { - overflow-x: auto; - } -} - -@media screen and (max-width: 600px) { - .mobile-hide { - display: none; - } - - #maincontent > .container { - margin: 1rem 0 1rem 0; - } - - .cbi-value-title { - text-align: left; - } - [ data-page="admin-system-flash"] legend { - padding: 1rem 0 1rem 1rem; - } - [ data-page="admin-system-flash"] .cbi-section-descr { - padding: 1rem 0 1rem 1rem; - } - [ data-page="admin-system-flash"] .cbi-value { - padding: 0 1rem; - } - [ data-page="admin-network-dhcp"] [data-tab-active="true"] { - padding: 1rem 1rem !important; - } - - body { - overflow-x: hidden; - } - - .node-main-login .main .main-right #maincontent .container .cbi-map .cbi-section .cbi-section-node .cbi-value .cbi-value-field { - width: 16rem; - } - - .node-main-login footer { - display: none; - } -} - -@media screen and (min-width: 600px) { - ::-webkit-scrollbar { - width: 10px; - height: 10px; - } - - ::-webkit-scrollbar, - ::-webkit-scrollbar-corner { - background: transparent; - } - - ::-webkit-scrollbar-thumb { - background: #9e9e9e; - } - - ::-webkit-scrollbar-thumb:hover { - background: #757575; - } - - ::-webkit-scrollbar-thumb:active { - background: #424242; - } -} - -.cbi-button,.btn { - background-color: #23bd70; -} - -.cbi-button.reconnect { - background-color: #23bd70 !important; -} - -.cpu .cbi-progressbar > div { - background-color: #5A8DEE !important; -} - -.memory .cbi-progressbar > div { - background-color: #FDAC41 !important; -} - -.cbi-map style+fieldset.cbi-section:first-of-type { - box-shadow: none !important; - display: block; - text-align: center; - overflow: hidden; - margin: 0.5rem 0; - background: none; - padding: 0; - border:none; -} - -.cbi-map style+fieldset.cbi-section:first-of-type p font { - position: relative; - display: inline-block; - padding: 0 1rem; -} - -.cbi-map style+fieldset.cbi-section:first-of-type p font:before, .cbi-map style+fieldset.cbi-section:first-of-type p font:after { - border-color: #FDAC41 !important; - content: ""; - position: absolute; - top: 50%; - width: 9999px; - border-top: 2px solid #DFE3E7; -} - -.cbi-map style+fieldset.cbi-section:first-of-type p font:before { - right: 100%; -} - -.cbi-map style+fieldset.cbi-section:first-of-type p font:after { - left: 100%; -} - -.cbi-map style+fieldset.cbi-section:first-of-type p em { - display: block; -} - -.cbi-section .cbi-section { - box-shadow: none !important; -} -/* Checkboxes - ========================================================================== */ -/* Remove default checkbox */ - -[type="checkbox"] + label:not(.lever) { - position: relative; - padding-left: 35px; - cursor: pointer; - display: inline-block; - height: 25px; - line-height: 25px; - font-size: 1rem; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -[type="checkbox"] + label:not(.lever):before, -[type="checkbox"]:not(.filled-in) + label:not(.lever):after { - content: ''; - position: absolute; - top: 0.4rem; - left: 0; - width: 15px; - height: 15px; - z-index: 0; - border: 2px solid #5a5a5a; - border-radius: 1px; - margin-top: 3px; - -webkit-transition: .2s; - transition: .2s; -} - -[type="checkbox"]:not(.filled-in) + label:not(.lever):after { - border: 0; - -webkit-transform: scale(0); - transform: scale(0); -} - -[type="checkbox"]:not(:checked):disabled + label:not(.lever):before { - border: none; - background-color: rgba(0, 0, 0, 0.42); -} - -[type="checkbox"].tabbed:focus + label:not(.lever):after { - -webkit-transform: scale(1); - transform: scale(1); - border: 0; - border-radius: 50%; - -webkit-box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); - box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); - background-color: rgba(0, 0, 0, 0.1); -} - -[type="checkbox"]:checked + label:not(.lever):before { - top: 0.1rem; - left: -5px; - width: 9px; - height: 18px; - border-top: 2px solid transparent; - border-left: 2px solid transparent; - border-right: 2px solid orangered; - border-bottom: 2px solid orangered; - -webkit-transform: rotate(40deg); - transform: rotate(40deg); - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -[type="checkbox"]:checked:disabled + label:before { - border-right: 2px solid rgba(0, 0, 0, 0.42); - border-bottom: 2px solid rgba(0, 0, 0, 0.42); -} - -/* Indeterminate checkbox */ -[type="checkbox"]:indeterminate + label:not(.lever):before { - top: -11px; - left: -12px; - width: 10px; - height: 22px; - border-top: none; - border-left: none; - border-right: 2px solid orangered; - border-bottom: none; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -[type="checkbox"]:indeterminate:disabled + label:not(.lever):before { - border-right: 2px solid rgba(0, 0, 0, 0.42); - background-color: transparent; -} - -[type="checkbox"].filled-in + label:not(.lever):after { - border-radius: 2px; -} - -[type="checkbox"].filled-in + label:not(.lever):before, -[type="checkbox"].filled-in + label:not(.lever):after { - content: ''; - left: 0; - position: absolute; - /* .1s delay is for check animation */ - -webkit-transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s; - transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s; - z-index: 1; -} - -[type="checkbox"].filled-in:not(:checked) + label:not(.lever):before { - width: 0; - height: 0; - border: 3px solid transparent; - left: 6px; - top: 10px; - -webkit-transform: rotateZ(37deg); - transform: rotateZ(37deg); - -webkit-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -[type="checkbox"].filled-in:not(:checked) + label:not(.lever):after { - height: 20px; - width: 20px; - background-color: transparent; - border: 2px solid #5a5a5a; - top: 0px; - z-index: 0; -} - -[type="checkbox"].filled-in:checked + label:not(.lever):before { - top: 0; - left: 1px; - width: 8px; - height: 13px; - border-top: 2px solid transparent; - border-left: 2px solid transparent; - border-right: 2px solid #fff; - border-bottom: 2px solid #fff; - -webkit-transform: rotateZ(37deg); - transform: rotateZ(37deg); - -webkit-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -[type="checkbox"].filled-in:checked + label:not(.lever):after { - top: 0; - width: 20px; - height: 20px; - border: 2px solid orangered; - background-color: orangered; - z-index: 0; -} - -[type="checkbox"].filled-in.tabbed:focus + label:not(.lever):after { - border-radius: 2px; - border-color: #5a5a5a; - background-color: rgba(0, 0, 0, 0.1); -} - -[type="checkbox"].filled-in.tabbed:checked:focus + label:not(.lever):after { - border-radius: 2px; - background-color: orangered; - border-color: orangered; -} - -[type="checkbox"].filled-in:disabled:not(:checked) + label:not(.lever):before { - background-color: transparent; - border: 2px solid transparent; -} - -[type="checkbox"].filled-in:disabled:not(:checked) + label:not(.lever):after { - border-color: transparent; - background-color: #949494; -} - -[type="checkbox"].filled-in:disabled:checked + label:not(.lever):before { - background-color: transparent; -} - -[type="checkbox"].filled-in:disabled:checked + label:not(.lever):after { - background-color: #949494; - border-color: #949494; -} - -.controls > *:nth-child(2), .controls > *:nth-child(3) { - position: relative; -} - -.controls>div .focus-input { - top: 1.53rem; -} - -#indicators { - cursor: pointer; - position: absolute; - top: 1.5rem; - right: 1.5rem; - z-index: 99; -} - -.cbi-section > h3:first-child, .panel-title { - font-size: 1.1rem !important; -} - -h2 { - font-size: 1.4rem !important; -} - -.main .main-left .nav li .slide-menu li { - padding: 0.4rem 0rem !important; -} - -h3 { - font-size: 1.1rem !important; - padding: 1rem 2rem !important; -} - -code,.cbi-progressbar::after { - font-size-adjust: none !important; - font-family: inherit !important; - font-size: 0.9em !important; -} -[data-page="admin-system-flash"] legend { - font-size: 1.1rem !important; - padding-bottom: 0.6rem !important; -} - -.main .main-left .nav>li>a:first-child::before { - font-size: 1.1rem !important; -} - -.td.version { - word-break: normal !important; -} - -.node-main-login .main .main-right .login-bg { - background-color: white !important; -} - -.cbi-map >.cbi-section .cbi-value { - padding-left: 1rem; - padding-right: 1rem; -} - -.cbi-section ~ .cbi-section> .panel-title { - padding-top: 0; -} - -#cbi-openclash .cbi-map-descr { - color: #404040 -} - -input,select { - height: 2.2rem; - background: none; -} - -input:not([type=button]):not([type=submit]):not([type=checkbox]),select { - border:0 !important; - background-image:linear-gradient(dodgerblue,dodgerblue),linear-gradient(#a9a9a9,#a9a9a9); - background-size:0 2px,100% 1px; - background-position:left bottom,center calc(100% - 1px); - background-repeat:no-repeat; - transition: all .3s !important; -} - -select:focus, input:not([type=button]):not([type=submit]):focus { - background-size: 100% 2px,100% 1px; - transition: all .3s !important; -} - -.btn,button, - .cbi-button,input[type=button],input[type=submit],input[type=reset] { - height: auto !important; - width: auto !important; - padding: 0.6rem 1.6rem; - line-height: 1rem; - webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); - box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); - border-radius: 2px; - transition: all .20s linear; - top: 0; - margin-left: 0.5rem; - position:relative; -} - -.btn:first-child,button:first-child, - .cbi-button:first-child,input[type=button]:first-child,input[type=submit]:first-child,input[type=reset]:first-child { - margin-left: 0; -} - -i input { - margin: 0 !important -} - -.controls > * > .btn { - flex-basis: auto !important; -} - - -.cbi-map >.cbi-section .cbi-section-table,.container .cbi-tabmenu,.container #tabmenu,.cbi-map >.cbi-section .table { - margin-left: -2%; - width: 105%; -} - -.admin-status-overview h2.content { - display: none; -} - -#view>.cbi-section:first-child { - padding-top: 0; -} - -.node-admin-status div { - border: none !important; -} - -.cbi-section-table .tr .td:first-child,.cbi-section-table .tr .th:first-child, -.table .tr .td:first-child,.table .tr .th:first-child, -.table .tr:before { - padding-left: 2rem !important; -} - -.node-admin-status .table .tr .td:first-child { - padding-left: 3rem !important; -} - -ul.errors li { - margin-bottom: 1rem; -} - -.Wireless .cbi-section { - padding: 0 2rem; -} - -.cbi-section-table-row > .cbi-value-field .cbi-input-select { - min-width: 5rem !important; -} - -#cbi-passwall .block h4 { - padding:0; -} - -input[type=password]+.cbi-button.cbi-button-neutral { - padding: 0 0.4rem; - color: #fff !important; -} - -.cbi-input-password[type=text]+.cbi-button.cbi-button-neutral { - padding: 0.2rem 0.5rem; -} - -.main-right>hr { - height: 6px; - background-color: rgba(255, 0, 27, 0.95); - background: linear-gradient(90deg,#e75239 0%,#e75239 12.5%,#ff961c 12.5%,#ff961c 25%,#ffcc27 25%,#ffcc27 37.5%,#fce62f 37.5%,#fce62f 50%,#cde35b 50%,#cde35b 62.5%,#82cc33 62.5%,#82cc33 75%,#41bece 75%,#41bece 87.5%,#049cdb 87.5%,#049cdb 100%); - background-position: 50% 0; - box-shadow: 0 1px 2px rgba(0,0,0,.0625) inset; - margin: 0 0 10px; - border: none; - opacity: 0.9; -} - -div[id^="cbi-unblockmusic"] .cbi-button { - top: -1.2rem; -} -[data-page^="admin-network-wifi"] form { - padding-left: 1.5rem; -} -[data-page^="admin-network-wifi"] form td { - padding-left: 1.5rem; -} - -#packages .tr>.td:last-child{ - padding-right:3%; -} -.cbi-section-table .tr>.td:last-child{ - padding-right:2rem; -} - -.command-output { - padding: 0 2rem; -} - -.chromeframe { - padding: 2rem 3rem; - margin: 0 auto; - font-size: 16px; - font-weight: bold; - color: #fff; - position: absolute; - top: 10rem; - width: 100%; - z-index: 9999; - text-align: center; - background: #5A8DEE; -} - -.chromeframe { - display: none; -} - -.chromeframe a { - color: orangered; -} - -.landscape { - position: absolute; - width: 100%; - height: 100%; -} - -[data-page="admin-network-wifi"] tr > td .cbi-button{ - margin-left: 0 !important; -} -[data-page="admin-network-wifi"] tr > td input[type="button"]{ - padding: 0.5rem 1rem !important; -} -table.interfaces .th{ - padding:1.1em 0.5rem !important; -} -.cbi-value>.cbi-value-field>div:first-child+br{ -display:none; -} - -.cbi-page-actions.control-group.fixed { - position: fixed; - bottom: 1.3rem; - right: 2rem; -} - -#cbi-vssr+.cbi-page-actions.control-group.fixed { - bottom: 4.8rem; -} - -#cbi-passwall+.cbi-page-actions.control-group.fixed { - bottom: 3.3rem; -} diff --git a/luci-theme-edge/htdocs/luci-static/edge/custom.css b/luci-theme-edge/htdocs/luci-static/edge/custom.css deleted file mode 100644 index c03f8db61..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/custom.css +++ /dev/null @@ -1,46 +0,0 @@ -:root { - --main-color: #09c; - --header-bg: #09c; - --header-color: #fff; - --bar-bg: #5e72e4; - --menu-bg-color: #fff; - --menu-color: #5f6368; - --menu-color-hover: #202124; - --main-menu-color: #202124; - --submenu-bg-hover: #d4d4d4; - --submenu-bg-hover-active: #09c; - - --blue: #5e72e4; - --indigo: #5603ad; - --purple: #8965e0; - --pink: #f3a4b5; - --red: #f5365c; - --orange: #fb6340; - --yellow: #ffd600; - --green: #2dce89; - --teal: #11cdef; - --cyan: #2bffc6; - --white: #fff; - --gray: #8898aa; - --gray-dark: #32325d; - --light: #96999c; - --lighter: #e9ecef; - --primary: #5e72e4; - --secondary: #f7fafc; - --success: #2dce89; - --info: #11cdef; - --warning: #fb6340; - --danger: #f5365c; - --dark: #212529; - --default: #172b4d; - --white: #fff; - --neutral: #fff; - --darker: black; - --breakpoint-xs: 0; - --breakpoint-sm: 576px; - --breakpoint-md: 768px; - --breakpoint-lg: 992px; - --breakpoint-xl: 1200px; - - --font-body: "Microsoft Yahei", "WenQuanYi Micro Hei", "sans-serif", "Helvetica Neue", "Helvetica", "Hiragino Sans GB"; -} diff --git a/luci-theme-edge/htdocs/luci-static/edge/favicon.ico b/luci-theme-edge/htdocs/luci-static/edge/favicon.ico deleted file mode 100644 index 461133680..000000000 Binary files a/luci-theme-edge/htdocs/luci-static/edge/favicon.ico and /dev/null differ diff --git a/luci-theme-edge/htdocs/luci-static/edge/fonts/argon.woff b/luci-theme-edge/htdocs/luci-static/edge/fonts/argon.woff deleted file mode 100644 index ef1e9c2c4..000000000 Binary files a/luci-theme-edge/htdocs/luci-static/edge/fonts/argon.woff and /dev/null differ diff --git a/luci-theme-edge/htdocs/luci-static/edge/glare.svg b/luci-theme-edge/htdocs/luci-static/edge/glare.svg deleted file mode 100644 index 6274ac991..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/glare.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/luci-theme-edge/htdocs/luci-static/edge/icons/arrow.svg b/luci-theme-edge/htdocs/luci-static/edge/icons/arrow.svg deleted file mode 100644 index be864c5ac..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/icons/arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/luci-theme-edge/htdocs/luci-static/edge/icons/spinner.svg b/luci-theme-edge/htdocs/luci-static/edge/icons/spinner.svg deleted file mode 100644 index 6ddd3b3ed..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/icons/spinner.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/luci-theme-edge/htdocs/luci-static/edge/js/jquery.min.js b/luci-theme-edge/htdocs/luci-static/edge/js/jquery.min.js deleted file mode 100644 index eeb0dff4f..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ - -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 - * https://github.com/LuttyYang/luci-theme-material/ - * - * Agron Theme - * https://demos.creative-tim.com/argon-dashboard/index.html - * - * Login background - * https://unsplash.com/ - * Font generate by Icomoon - * - * Licensed to the public under the Apache License 2.0 - */ - -document.addEventListener('luci-loaded', function(ev) { -(function ($) { - $(".main > .loading").fadeOut(); - - /** - * trim text, Remove spaces, wrap - * @param text - * @returns {string} - */ - function trimText(text) { - return text.replace(/[ \t\n\r]+/g, " "); - } - - var lastNode = undefined; - var mainNodeName = undefined; - - var nodeUrl = ""; - (function(node){ - var luciLocation; - if (node[0] == "admin"){ - luciLocation = [node[1], node[2]]; - }else{ - luciLocation = node; - } - - for(var i in luciLocation){ - nodeUrl += luciLocation[i]; - if (i != luciLocation.length - 1){ - nodeUrl += "/"; - } - } - })(luciLocation); - - /** - * get the current node by Burl (primary) - * @returns {boolean} success? - */ - function getCurrentNodeByUrl() { - var ret = false; - if (!$('body').hasClass('logged-in')) { - luciLocation = ["Main", "Login"]; - return true; - } - - return ret; - } - - /** - * get current node and open it - */ - if (getCurrentNodeByUrl()) { - mainNodeName = "node-" + luciLocation[0] + "-" + luciLocation[1]; - mainNodeName = mainNodeName.replace(/[ \t\n\r\/]+/g, "_").toLowerCase(); - $("body").addClass(mainNodeName); - } - - /** - * Sidebar expand - */ - var showSide = false; - $(".showSide").click(function () { - if (showSide) { - $(".darkMask").stop(true).fadeOut("fast"); - $(".main-left").stop(true).animate({ - width: "0" - }, "200"); - $(".main-right").css("overflow-y", "visible"); - showSide = false; - } else { - $(".darkMask").stop(true).fadeIn("fast"); - $(".main-left").stop(true).animate({ - width: "13rem" - }, "200"); - $(".main-right").css("overflow-y", "hidden"); - showSide = true; - } - }); - - $(".darkMask").click(function () { - if (showSide) { - showSide = false; - $(".darkMask").stop(true).fadeOut("fast"); - $(".main-left").stop(true).animate({ - width: "0" - }, "fast"); - $(".main-right").css("overflow-y", "visible"); - } - }); - - $(window).resize(function () { - if ($(window).width() > 921) { - $(".main-left").css("width", ""); - $(".darkMask").stop(true); - $(".darkMask").css("display", "none"); - showSide = false; - } - }); - - /** - * fix legend position - */ - $("legend").each(function () { - var that = $(this); - that.after("" + that.text() + ""); - }); - - $(".cbi-section-table-titles, .cbi-section-table-descr, .cbi-section-descr").each(function () { - var that = $(this); - if (that.text().trim() == ""){ - that.css("display", "none"); - } - }); - - $(".main-right").focus(); - $(".main-right").blur(); - $("input").attr("size", "0"); - $(".cbi-button-up").val("__"); - $(".cbi-button-down").val("__"); - $(".slide > a").removeAttr("href"); - - if (mainNodeName != undefined) { - console.log(mainNodeName); - switch (mainNodeName) { - case "node-status-system_log": - case "node-status-kernel_log": - $("#syslog").focus(function () { - $("#syslog").blur(); - $(".main-right").focus(); - $(".main-right").blur(); - }); - break; - case "node-status-firewall": - var button = $(".node-status-firewall > .main fieldset li > a"); - button.addClass("cbi-button cbi-button-reset a-to-btn"); - break; - case "node-system-reboot": - var button = $(".node-system-reboot > .main > .main-right p > a"); - button.addClass("cbi-button cbi-input-reset a-to-btn"); - break; - } - } - - var getaudio = $('#player')[0]; - /* Get the audio from the player (using the player's ID), the [0] is necessary */ - var audiostatus = 'off'; - /* Global variable for the audio's status (off or on). It's a bit crude but it works for determining the status. */ - - - $(document).on('click touchend', '.speaker', function() { - /* Touchend is necessary for mobile devices, click alone won't work */ - if (!$('.speaker').hasClass("speakerplay")) { - if (audiostatus == 'off') { - $('.speaker').addClass('speakerplay'); - getaudio.load(); - getaudio.play(); - audiostatus = 'on'; - return false; - } else if (audiostatus == 'on') { - $('.speaker').addClass('speakerplay'); - getaudio.play() - } - } else if ($('.speaker').hasClass("speakerplay")) { - getaudio.pause(); - $('.speaker').removeClass('speakerplay'); - audiostatus = 'on'; - } - }); - - $('#player').on('ended', function() { - $('.speaker').removeClass('speakerplay'); - /*When the audio has finished playing, remove the class speakerplay*/ - audiostatus = 'off'; - /*Set the status back to off*/ - }); - setTimeout(function(){ -$("input[type='checkbox']").filter(function () { - return (!$(this).next("label").length) -}).show(); - }, 0); - -var options = { attributes: true}; -function callback() { -$("input[type='checkbox']").filter(function () { - return (!$(this).next("label").length) -}).show(); -} -var mutationObserver = new MutationObserver(callback); - mutationObserver.observe($("body")[0], options); - $(".cbi-value").has("textarea").css("background","none"); -if(document.body.scrollHeight > window.innerHeight){ - $(".cbi-page-actions.control-group").addClass("fixed") -} -})(jQuery); -}); \ No newline at end of file diff --git a/luci-theme-edge/htdocs/luci-static/edge/landscape.css b/luci-theme-edge/htdocs/luci-static/edge/landscape.css deleted file mode 100644 index b55ab6957..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/landscape.css +++ /dev/null @@ -1,76 +0,0 @@ - -#CrossFade { - background: #fff; - position: absolute; - width: 100%; - height: 100%; - overflow: hidden; -} -#CrossFade img { - position: absolute; - min-width: 100%; - min-height: 100%; - width:100%; - background: #fff; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - opacity: 0; - -webkit-transform: scale(1.4) rotate(12deg); - transform: scale(1.4) rotate(12deg); - -webkit-animation: CrossFade 12s infinite; - animation: CrossFade 12s infinite; -} -#CrossFade img:nth-child(3) { - -webkit-animation-delay: 8s; - animation-delay: 8s; -} -#CrossFade img:nth-child(2) { - -webkit-animation-delay: 4s; - animation-delay: 4s; -} -#CrossFade img:nth-child(1) { - -webkit-animation-delay: 0s; - animation-delay: 0s; -} - -@-webkit-keyframes CrossFade { - 33.3% { - opacity: 1; - -webkit-transform: scale(1) rotate(0); - transform: scale(1) rotate(0); - } - 45% { - opacity: 0; - } -} -@keyframes CrossFade { - 33.3% { - opacity: 1; - -webkit-transform: scale(1) rotate(0); - transform: scale(1) rotate(0); - } - 45% { - opacity: 0; - } -} - -.speaker { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARAAAACACAYAAAG0HAZ0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEFERTNEQzA3QTMxMTFFMzgzNTFFRDRCMzk1MDA0NUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEFERTNEQzE3QTMxMTFFMzgzNTFFRDRCMzk1MDA0NUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowQURFM0RCRTdBMzExMUUzODM1MUVENEIzOTUwMDQ1QiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowQURFM0RCRjdBMzExMUUzODM1MUVENEIzOTUwMDQ1QiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvEtsecAABjVSURBVHjaYvz//z/DYABMDIMEEO2QjIwMioMOnxnEOOQ/FFMSmrjMIGzYnz9/3hPQ/Dc5ORmv4USYgeqQz58/H/758+dvEIb5gIWFRQCHHmYQcfny5Z9z586FC5JoBgZgARG8vLw2JATzHxChq6vLCLKMkZERmPH+M5JoBlVyDSNK5FMp+5OdfYEhsXCwlCP5A+2Q/9Ao+QANGeo5BGjYH1lZWQYQJi5WGO8hOYiRDDOw5xqgYazolklKSv54/vw5O9Yg+f9fGZpj4ImVVDOwOgQbABrAgRwV2EKGUI4hwgyS0ggjepYlM8vjNYNxsDQDAAKIcbQ9QqZDqBFs/ylxCDsVHEGUGSxk+uA/tgqQkpAEhwisHbFnz547RDoC7ICHDx/C1ZFoBtYQ+c/ODin8Xr9+rUxkGe/w9u3b3/Ly8rDSlGQzSIka3EHy//9+aKj8H7HZd3A6BNoGoW6RDCriZWRk/oOwsLAwqCEMEsMGGJDkwHRwcDBcnEQzMDC+uuY/nkYzueUIIzlRg6/qBrXSllG1CYEvuGDYxMTkHzHqKDFj0DQDAAJo0DhktDwb5gHSDhuKoca40kC6g4UCy/9TqI+RSoHwf6BSSMp/SIHzn4EOLXo6ugNrgPzHhpcvX45s4WwyhkHEYWb9+vXrP54KnIHG7hg0hepLIOYBMdjY2BiOHj2KESinTp0aVNUcPWqZrzCGtbU1qCmFMhBrZmY24qtdz5HeDoFPGKSlpYGoGiCGzxFMmjRpxAVIEogICAhgmDVrFiO0hngPk8zPz787qEKE2M4IELj+JwKkp6fj609WoHQ6wdaT1imikjtwYiYSAm43UreRceFCsqZoOkBEdXU1qHBVhE0ikBiB1HAH5SmEQKzVUxozg8Ud4N4uLRs6xEYK0tgT1c0d7f5TAAACaDRARsdDRgNkNEAGS4CIMEDWBrSQVIhRv4Yjyx3UGDHDNdjzZCBrcErdQVEK+ffv3y9SR62am5t1qR0K5LiD2i3Vclx9CKCRGXj0YcydUdhaJtcdODELhcmSXH3/GSgfZP4/0IUqpYO6KAFw8+ZNSgKWZq1JWIBw//nz5zdsgQXaok+Gly9frqQkJs3NzR+jB4q6ujqohkFPobR0B9EBAlqZ9oUFCNjZ2VEw0ME7qJGsT548KQMTOAsEMHZXV9dvJLW0dAfxAfLmzZu3tDK8t7f3BnrgGBsbm8AESktL4ZK0dAdJAQKssmiWH4uLizXRGmHiWJRlQ6vOQdHLpHnTHVh4NiNxX4BbTECAJDZlRPVlgIVnHYydm5sLpmVkZMpGO3dAoKWlBa8wRgMECPbs2QNrahuN2AD5+vXrVRh77dq1sKZ6x4gNEG5ubi0kLnjjDTMQIIfZoAqQv3//0rK6+4+cOrDsnQABDRBBY3cQHyCSkpK8tDL84MGDcHZISAhGIMnJycHHLWjpDnIGiBiBjvuPZQSeE9qgIitr2dvbMx45cuS/ra0tA7ZZusePH2N0AGnhDpqMh/T19REzpUrseMh/AwOD/+SMh1DJHbhn/8jQRJZDHj58+A1N3XsKB4hoEiBk7YwEglRSNQGzAteFCxdgBoAsF6QwcZPlDppUu0DPzAE5SE1N7S8p+oDZhBG2x5VK2Z0sd9CsHXLr1i1Qocy4fv16UjxB9YKRHHdQXKgSm69Jzbs0cAMDxYPMVJwsAhmkSa551HYHWRpHZ/8HsLc7FABAAPauJrSJIArvtptKck5IPGxpIQiNOUTaYCGxQsGLGDFgdWmwkIsI6kHw5r1H6cWTUOJ/LhVKQE8GiRFTc9BLekkPTQMSIaGFQC1paHyz7sbpupu2mN2dzc7AstnJ7Px8882beTNvZilDqKMthjpKEOpsSpCrqVTqm+79rMlGuqThQTRB9vf3vzJ/zR1WC4UCUo/v2LUFm40HCQSZxQDoOByOsM2lOlF4mEKQdrv9EQPhg87JielAq+NJZYTBeBBJkPN4q+A47qIBaR6yygN1fqter5Oi05uBB1kEgQrJYCAUSCis2+1mJGliuLUSiXgYTpDd3d1VTKRfMbIg+Xz+rVI5yWQyQY3Kugt9+57eeTITDz0I8oDROKSC0Ti4Agr9Do+s2WzuGZz/YTk/0Wg0LlVEQv4zFoshmyVWQzs4BWF75deKeOhDkEqlgpaeH1tJC0qn07cYyS5LIR1ehsPhYx2bBmERSdJKfyvioStBnE6n32oZFwThBar4g4ODf/4rFouMz+frKMT9ZbV4ksnkTaWfFfEY5HmQ/yvA0JCqdKjVamiGdIuVpkldLtd7tXDLy8votkWpMNgiUXW3IIxLeNyIsVqtPtd4n6dUGGyCqBqVzc3NISnysMsCnn9Fq9zmgyrcbW+Lh1/hW09ctMrtSRDV4wKXlpbQbUV+rtfr92mV25Mga0qPVqvF7OzsIFW2SxC32z2rDNdoNCgLBpwgqusr0scYbmOEeaMWLhQKodsTSoUeBMlms6+tlnHoLta0yCFptisgPZ5KXtMjIyOCMlypVGKkDeX3cH8r4qErQQRBQC2N3dzcPPaLTqfT1IxDd4FWRNlcLtf1K5fLMjmuATnkDY6X4PqiFkcwKC7VjCr9rYiHIfMHY2NjLNYKeeboQ2x+4Q8bGxvPvF7vDSMLMDMzI3/CDam6Q/i+rHa7/YPjuNM9pMx1CF/VMjm0Ih66EuRQxw7AnTSySCSCFqvkCvtULBajU1NTxgxEOh18n3wErjyQQ61rYjweD/p5Dt75foL4LYUH8YNUAPQCgMH+wYb1xeNxI8v1GTvjqevGx8dFciApcxJyDAAe/ZcgfQbnJ4OtqAJAJRgvBPx+/dbEJicnxfTW19c7aJ90IiFaATyCvCyarnaZgIel1FwA6CyAIbemMwsLC7J/39MKBALs/Pw8K0mNRRJbqZF4EClBjgCnjPXT4gpsrVbjYXBnS7WSNDw4AgEaxUTv9MTEBFJRh+06D2E2HnTzNnXkjUGoowShbkDcbwHYu76QyKowfse7YzQ2mzaDmTUKhmxCFu0IkzsIWlIESvQ0EAVuT2Ia0hJELxUGvQSxKIwY5EPsgz2FOS6LD7VS40r4kD64Ni3iw66kI665Ss7fvjN/5O7suXf+3nPOvX4/uBzm3HPO3Pu7v3O+79xzzzloYhDYgiBQIAgUCAIFgkCBIFAgCBQIG8RisbDFYvHgY+LHh6gCuSqlF1ZxSCqfC1YSBljEjikfSog2WPcmHLk7s1nOcKPBnQ9RBPIEHP+ecTEIyQd3EwN29TcIDlEcYvLBUyBfZOyqV88/2d/fN8qkKCZ8GEEgXVJ6+sDnDP7rp7q6uqHZ2VmRRyRZ8lE8dNitRfWA5vNBskikL7Gk//tZWc7o6GiM8a41ovFR0sFkuD8ej9+QZfmNUrugJWxSReajvJUb6XQ6l8Lh8CWV/2BWKTnwUforAJ2J+SjThy/rHUWRhJC5AyGN8mqhvANOAuHBh5A+yMWMXb0qscffPp/ve7WT4I/c53BNPPkQyweJRCI7yQqiVJs7NTX1j0aZ91j5IKLwIYoPUvF2upAm9fj4+JbNZnuVYuuTD29tnQZZAbGhocHCwMRw4UNPH2QEyP4K+uI2LcKsVivZU5zsBrzKmxA49yukyS6Gbyn0IVVVVcUSiYQ1j0AMx4eeJqYSTV3FodWkwgO+qUw7Pz//SNpgMBiilbu4uJhUVpBy70UEPnQzMWQYOTNSWK6SmdUYiPsdzj3SZa2vrz/c2dk5X8h1Qf67UM5zuS2IEfnQtRdTLBkiAJr+S7R4EIcdSHQq49bX17eorzC7up6lxRuRDzO9aq8IampqVGtRR0fHrvJ3W1tbKy3dxMQEqZFdKIP8TmrRTaEITerKysoLbrd7PTc+Go1K1dXVnZDvVgFmhoipPscJNSQfKBC6qUlAF9dCyUecudMWMhQKrbS2tl6klU/pzaFAjG5isgBxUM3HwMDAQySCOD6mpfN6vRLCxAIB3KFFDg8Pk9r2oSLqJi1db28vCd5BKZhXINLu7u6D3DjwTUjwWb68mVUH30UpmFggR0dH8yqnGvPlbW5uJsHLKAUTC8Tlct0oNa/dbieBE6VgYoHIshwpp1cAqEYpmFggsVis5C3FyLYhCJML5ODg4O1S85Khf0llSzOESQTicDg8FNEUlHdjY4ME91EKJhYIDdeupfYvVO6+QN31YWFhgQR/oRTMK5DvaJFjY2Mk+EERdZmW7vr11Ha6P6IUVJx4o4/FSNq7Tj0DeVNORjQa/c9qtT6mku48pDss5z5wLEZAwEO/TYv3+/3pp5MRBwFNHPH4qW96iG2F+QTyPjz0C7QTQ0NDKZ0ooj7QMEMJlIFW+1zit5MS/28wqRgfH6flUS1bysyJLfc+JJN+k5pqQaanpz8xmrCdTmcbLX5kJLV38oQi6hW1ipEJv8w9Z0Q+9G5ByE6P94xWY9xu95PKtLIsF9x69PT0kLQJta/ajciH7hOnwEO+Yrfbv6mtrZXyzAORNjc3hfDaPR6PY3l5OUw+/AkGgyTqHKTPep9fw/GpRi/nNUj7i9q8GCPyoVc3N/ciyBBnbZ4btELeTWXE0tJSorOz08KaEEjzEgR/wuGFtMFMNBmAO6Gl7+vrkwKBwGm5+WbWGY0P3QVSDhwOx9He3p5NAEKSWmUSnUC5gUIEYhI+xOjmAhk1cBNP9ff3c3Wt1E7YbLaszxFgcSGC8FG+k6rHAXjP7/ezdsouqJU1OTmZ7do+zmOFIU58lHfNjIj5Y3V1lRkhLS0tvbnlnJycZMUxyXsJKtZ8CC+Q7OFyuaKsCOnu7n6R8lIsItIaZSz5MIRAMg/D5fP5mBACXWC3QhxJ0RaxY82HIQSiIObKzMyM7oQAXs9XBk+BsOZDyFUO83Tb7mxtbbU0NTVx69axXuVQdD6EGs2Fm30eyLC0t7fjqKqAfAgz3L+2tiaTN6KDg4OoEpH44G17Vezxt3Nzc8xsrqg88OJDKB9EC42NjeHt7W3HWfJBROBDiXM54xOigUyJfJrHtYnMB1MecGt2hCGcVAQKBIECQaBAEGcK/wvQ3vnARJXccXx2AaFLhK3iqlj1WsX2xKL88Y76hxSFnrkCdyW0QpNLvYp/oLV6hiqp1ZiQeHDxz/knR8OaHLm2QSSWi2gPqWJRosu/CFRpCOa0p5ziYYHlivy73f5m2d1udXeZxwmy730/yeQ9wrx5781833dmZ96bQSMVAIAaBgAAAwEAwEAAADAQAACAgQAAYCCTDx2Fl5ENQKn6gIFIJ8o6ZwQf/+7YunXrLZVK1UjhVU++Kf7y7SR9ARf6gIF4PFuGhoYeW0VRR2J43fHZYyMrVYUjm6APpekDBuKcJRT+YhWEZa4ZHx+facgWAH3AQFzx1uDg4OdWQfyDYQVdAH3AQNzA13EvdqhFPpoyZcpsSAJAHzAQV6ynWuSuVRB8bbqfyeCezvL7qa+vHyaBR0LS0AcM5PnB11gudKhFTtFDNl8m91ZmvSfLtN5RUVFeJP7648ePm1QYToE+YCBj5k16kP5pFcRnFH4hs/uzGUeCs39u27aNf2FtiomJ6YK8FakPGIhE+CRdHzjUIqVUi3xPZuU0h0KtO+N4mitXrmjLysrM1BhJV7jGlaAPGIhEEqgWabQKgi+WnCHzcmpPTU39sLu7W9JBfNGi/v5+vU6n61aYrpWmDxjIKHyTwmGHWqSMapGlSiqoU6dO5Wu1WtXevXv/LuU4X19f9ujRo8C4uDjeGgmSafYoXh8wkGeJHhoaqrEK4t8U3kFxMZaTkxNLG1VjY+NXUo67ePEi27hx4xdkIm/JJCugj0mAt2A8kVWERfChYKTweLSIDx48+O3s2bNfUZCRV7CRpbDYpk2b/qXX619yd8CyZcu8i4qKitPS0oSHGk+ePMmoZv6ITORls9n8u+d4/dCHUnGxJsgbAwMD983jQGlpKRfZfQph7tYkefjwYbHZA9iyZYut2bx1DGuveJlMpipn6XZ0dJhnzpx5drQ0qGURL/Wak5OT+fXmPr0+jhs9QB8vRh+TPjz9E2ad9WY/pppqzngY1pMnT/iGp31Uwb7tQ5lfTdthag3EOIug0+n4Q5K4efNm3nehdZXQ2rVr/0ab70g5+ZkzZ1hoaOjuMYzQQB/AeR9IV1fXr2nzyQSee0CJGd7X18d/qgzSw7tSJH5BQQErKSnpovgfuIl2h0KolOs4f/48U6vVekpX6DjoA7g1kOHh4Rxkx/ij0Wh+lJGRUSjlmJSUFFZZWZlBD3ubm2gtxC9F05w/fz7Ly8vju7WU7qid6dAHcGsg1KT2QXZMDPn5+W/TRmUwGAZFj4mNjWVFRUUL6WG/7yrO4sWLP2xubhZuJWRlZbGQkBAN7f5RoK8M+gCuDQRMPNHR0b4X+fiqIKmpqWzHjh1zyETqXcUJCwv7SU9Pj7Ax7dq1i29+zka+PgUABuJJxMXFxdfV1Z0VjX/o0CE2b968SDKRd118NDfQ2dn5nmh669evZ9OnT+e7R1AaAAbigSxfvvyN27dvfyZUYGo127dvH9/dzUa+Jn2GBQsWvN/f3z8skt7UqVPZunV8cIW9RmE6SgPAQDyQhQsXJorGTUtL48O8vPWR7yLK446ODoNoevHx8XzDXyr8FUoCwEA8k+a7d+/eEImo0Wgsnaq81UC/YnQu4vxV9MQhIfbujx+jGAAMxEPx8/MT7gsJDbW8vuFFIdbZ/2fMmHFLNC3+0pqVeSgFAAPxUGbNmnV7DA99tIsoX4qm5e1t/yTKH6UAYCCeyxTRiNZXvjmuJvr1gR4ADERBdHd3/1A0blub/aXUXleNFNG0jEYjMh/AQDy99UEIj8Q0NDTYdp12vPb09MSIpnXnzh17wwbFAGAgnsk7Go1GKxLRYDCwmpoau5c4i2M2m9eKnri2tta2+zmKAcBAPI8wCrmikY8csb80eouMosZJlHitVvtt0fQqKipsu1dRFAAG4lnoTCZTg5SH/fTp07Y/nX4hazQa94mmV11dzerr7Z/WFKI4AAzEc+AT/3ao1WqhqSX7+vosn/bbWgvU+ih2Ei05ICBglegFnDhxwrbbRKEeRQLGZCAkYqxmNrEcotAo5YCIiAjW22sZdOGT7Th7a9R/eHj4T6LpXb9+nRUX2z3oXbdCgT6AOwNpb2//AtkxIaSykWkBd0o5aNGiRay1tdXecqHWR6+TFsp1b2/vb4immZGR4dj6KHYXF/oAbg1Er9dHdnZ2foUsGV927txZe/XqVZNo/K6uLubv7+/43sciMo/Wp+NRy6NCo9F8XzTdPXv2sKamJtufoy7vCH0AtwZCv4UfBwUFeR88eLAJ2TJ+HD58+NPVq1d7zZ0791tVVVVu4xYWFrJp06ZZ+j7YyAtj/mQebU7Mo4paHvGi11BWVsYOHDhg9xJKc9Qyhz6AM57pvMvKylrGtwEBAU0bNmwIS0hIYEuXLmWBgYHMZDKN6SS2ZQP8/PzY0NAQcp24d+9eO21UsbGx2pycnK5Vq/7X78n7OfjHchTH7iWUh287S2dwcPC+lBnSm5ubWVJSku3PTyjdA1KuG/oAbg3EhtFotCwNqFKp+AdWfPKan7KRrzWnPIfz8q9I3X7sRTVqoBIK4PLly3zdWlVERMSM3NzcRyUlJZYFoKz8hwJfBOqek0MjKDSQeQifq6WlxfKwW2mldF8f63VDH8Du/pM1cFGmp6eb2tvb7Qv1UC0n64WDiO+ykeHUdDfxiqRe57Vr12zXyUObk/NOej1AH5N/YanJZm4ler1eHRwczKf/fC8yMtJ07tw5uRs6bxlEUTjp5N8pVjGmSkkzPz+frVixwvZnHaUdIpO8Upw+Jm0nqgeIZXdDQ4NXYmIiF8srFB5s376ddXZ2KqGcoqzGUSL1QD7faWZmpt1LKB9luZ6swvUBA5EoFl6LBh89elQVFBTEBfOH6Ohoc3l5uVzLqX7JkiWvOnyBOyp82JdPwHzhwgW7l1CeZSrkZ7nS9AED+ZqCyTAYDGqqbblYVlPozM7OltU8Fzdv3qylJrqKHoTQGzfcT52anJxsefHM2k/wKS9n2r+g4H4+2esDBvL8xFJNgY9oqAICArhg/hwTE2OurKyUxf3Rg9ASHh6uWrlyZXhj4/+/CU81Lh8VYaWlpXYvobxYYHbsJVU4ctfHi8hQxQQi3tfXt3v//v3mgYEBWfSyZ2Zmxubl5TmOsPDw/hjyRnF6UII+xj3PFCwWXwofr1mzxlxVVeXxAiH4C17HvsbxijcQOetDkcO449zy4lXMm5cuXVJRE5Y3ZRMDAwO/pKYt88QWP11zI4XfoE0NfaAP5MUI5lxPT8/U7OxslVqt5j+OK/gQKJ8+EADoAwYiRSy9FF4rLy/nox689knR6XRPjh07hswB0IcD3pCDkGDO0IYHPsoRRJuzSUlJPygoKGDBwcHIIOhDufpw1pEGJPF7NrIcQp7c9OCqoxWMTR9y7ERVQRgAAPSBAABgIAAAGAgAAAYCAAAwEADAOPBfkpX+vjRnFw0AAAAASUVORK5CYII=); - background-repeat: no-repeat; - background-size: 200%; - background-position: 100% 0; - height: 34px; - width: 28px; - cursor: pointer; - display: block; - position: absolute; - top: 20px; - right: 20px; - display: block; - z-index:9999; - opacity:.5; -} - -.speakerplay { - background-position: 0 0; -} diff --git a/luci-theme-edge/htdocs/luci-static/edge/logo.png b/luci-theme-edge/htdocs/luci-static/edge/logo.png deleted file mode 100644 index 910850980..000000000 Binary files a/luci-theme-edge/htdocs/luci-static/edge/logo.png and /dev/null differ diff --git a/luci-theme-edge/htdocs/luci-static/edge/sun.svg b/luci-theme-edge/htdocs/luci-static/edge/sun.svg deleted file mode 100644 index 7d4ae2c41..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/sun.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/luci-theme-edge/htdocs/luci-static/edge/waves.css b/luci-theme-edge/htdocs/luci-static/edge/waves.css deleted file mode 100644 index 5572ae0fc..000000000 --- a/luci-theme-edge/htdocs/luci-static/edge/waves.css +++ /dev/null @@ -1,135 +0,0 @@ -/*! - * Waves v0.7.6 - * http://fian.my.id/Waves - * - * Copyright 2014-2018 Alfiana E. Sibuea and other contributors - * Released under the MIT license - * https://github.com/fians/Waves/blob/master/LICENSE */ -.waves-effect { - position: relative; - cursor: pointer; - display: inline-block; - overflow: hidden; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-tap-highlight-color: transparent; -} -.waves-effect .waves-ripple { - position: absolute; - border-radius: 50%; - width: 100px; - height: 100px; - margin-top: -50px; - margin-left: -50px; - opacity: 0; - background: rgba(0, 0, 0, 0.2); - background: -webkit-radial-gradient(rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.4) 50%, rgba(0, 0, 0, 0.5) 60%, rgba(255, 255, 255, 0) 70%); - background: -o-radial-gradient(rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.4) 50%, rgba(0, 0, 0, 0.5) 60%, rgba(255, 255, 255, 0) 70%); - background: -moz-radial-gradient(rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.4) 50%, rgba(0, 0, 0, 0.5) 60%, rgba(255, 255, 255, 0) 70%); - background: radial-gradient(rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.4) 50%, rgba(0, 0, 0, 0.5) 60%, rgba(255, 255, 255, 0) 70%); - -webkit-transition: all 0.5s ease-out; - -moz-transition: all 0.5s ease-out; - -o-transition: all 0.5s ease-out; - transition: all 0.5s ease-out; - -webkit-transition-property: -webkit-transform, opacity; - -moz-transition-property: -moz-transform, opacity; - -o-transition-property: -o-transform, opacity; - transition-property: transform, opacity; - -webkit-transform: scale(0) translate(0, 0); - -moz-transform: scale(0) translate(0, 0); - -ms-transform: scale(0) translate(0, 0); - -o-transform: scale(0) translate(0, 0); - transform: scale(0) translate(0, 0); - pointer-events: none; -} -.waves-effect.waves-light .waves-ripple { - background: rgba(255, 255, 255, 0.4); - background: -webkit-radial-gradient(rgba(255, 255, 255, 0.2) 0, rgba(255, 255, 255, 0.3) 40%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0) 70%); - background: -o-radial-gradient(rgba(255, 255, 255, 0.2) 0, rgba(255, 255, 255, 0.3) 40%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0) 70%); - background: -moz-radial-gradient(rgba(255, 255, 255, 0.2) 0, rgba(255, 255, 255, 0.3) 40%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0) 70%); - background: radial-gradient(rgba(255, 255, 255, 0.2) 0, rgba(255, 255, 255, 0.3) 40%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0) 70%); -} -.waves-effect.waves-classic .waves-ripple { - background: rgba(0, 0, 0, 0.2); -} -.waves-effect.waves-classic.waves-light .waves-ripple { - background: rgba(255, 255, 255, 0.4); -} -.waves-notransition { - -webkit-transition: none !important; - -moz-transition: none !important; - -o-transition: none !important; - transition: none !important; -} -.waves-button, -.waves-circle { - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%); -} -.waves-button, -.waves-button:hover, -.waves-button:visited, -.waves-button-input { - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - border: none; - outline: none; - color: inherit; - background-color: rgba(0, 0, 0, 0); - font-size: 1em; - line-height: 1em; - text-align: center; - text-decoration: none; - z-index: 1; -} -.waves-button { - padding: 0.85em 1.1em; - border-radius: 0.2em; -} -.waves-button-input { - margin: 0; - padding: 0.85em 1.1em; -} -.waves-input-wrapper { - border-radius: 0.2em; - vertical-align: bottom; -} -.waves-input-wrapper.waves-button { - padding: 0; -} -.waves-input-wrapper .waves-button-input { - position: relative; - top: 0; - left: 0; - z-index: 1; -} -.waves-circle { - text-align: center; - width: 2.5em; - height: 2.5em; - line-height: 2.5em; - border-radius: 50%; -} -.waves-float { - -webkit-mask-image: none; - -webkit-box-shadow: 0px 1px 1.5px 1px rgba(0, 0, 0, 0.12); - box-shadow: 0px 1px 1.5px 1px rgba(0, 0, 0, 0.12); - -webkit-transition: all 300ms; - -moz-transition: all 300ms; - -o-transition: all 300ms; - transition: all 300ms; -} -.waves-float:active { - -webkit-box-shadow: 0px 8px 20px 1px rgba(0, 0, 0, 0.3); - box-shadow: 0px 8px 20px 1px rgba(0, 0, 0, 0.3); -} -.waves-block { - display: block; -} diff --git a/luci-theme-edge/htdocs/luci-static/resources/menu-edge.js b/luci-theme-edge/htdocs/luci-static/resources/menu-edge.js deleted file mode 100644 index cc4d4b6b6..000000000 --- a/luci-theme-edge/htdocs/luci-static/resources/menu-edge.js +++ /dev/null @@ -1,158 +0,0 @@ -'use strict'; -'require baseclass'; -'require ui'; - -return baseclass.extend({ - __init__: function () { - ui.menu.load().then(L.bind(this.render, this)); - }, - - render: function (tree) { - var node = tree, - url = '', - children = ui.menu.getChildren(tree); - - for (var i = 0; i < children.length; i++) { - var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[0] : i == 0); - - if (isActive) - this.renderMainMenu(children[i], children[i].name); - } - - if (L.env.dispatchpath.length >= 3) { - for (var i = 0; i < 3 && node; i++) { - node = node.children[L.env.dispatchpath[i]]; - url = url + (url ? '/' : '') + L.env.dispatchpath[i]; - } - - if (node) - this.renderTabMenu(node, url); - } - - document.querySelector('a.showSide') - .addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle')); - document.querySelector('.darkMask') - .addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle')); - }, - - handleMenuExpand: function (ev) { - var a = ev.target, slide = a.parentNode, slide_menu = a.nextElementSibling; - var collapse = false; - - document.querySelectorAll('.main .main-left .nav > li >ul.active').forEach(function (ul) { - $(ul).stop(true).slideUp("fast", function () { - ul.classList.remove('active'); - ul.previousElementSibling.classList.remove('active'); - }); - if (!collapse && ul === slide_menu) { - collapse = true; - } - - }); - - if (!slide_menu) - return; - - - if (!collapse) { - $(slide).find(".slide-menu").slideDown("fast",function(){ - slide_menu.classList.add('active'); - a.classList.add('active'); - }); - a.blur(); - } - ev.preventDefault(); - ev.stopPropagation(); - }, - - renderMainMenu: function (tree, url, level) { - var l = (level || 0) + 1, - ul = E('ul', { 'class': level ? 'slide-menu' : 'nav' }), - children = ui.menu.getChildren(tree); - - if (children.length == 0 || l > 2) - return E([]); - - for (var i = 0; i < children.length; i++) { - var isActive = ((L.env.dispatchpath[l] == children[i].name) && (L.env.dispatchpath[l - 1] == tree.name)), - submenu = this.renderMainMenu(children[i], url + '/' + children[i].name, l), - hasChildren = submenu.children.length, - slideClass = hasChildren ? 'slide' : null, - menuClass = hasChildren ? 'menu' : 'food'; - if (isActive) { - ul.classList.add('active'); - slideClass += " active"; - menuClass += " active"; - } - - ul.appendChild(E('li', { 'class': slideClass }, [ - E('a', { - 'href': L.url(url, children[i].name), - 'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null, - 'class': menuClass, - 'data-title': hasChildren ? children[i].title.replace(" ", "_") : children[i].title.replace(" ", "_"), - }, [_(children[i].title)]), - submenu - ])); - } - - if (l == 1) { - document.querySelector('#mainmenu').appendChild(ul); - document.querySelector('#mainmenu').style.display = ''; - - } - return ul; - }, - - renderTabMenu: function (tree, url, level) { - var container = document.querySelector('#tabmenu'), - l = (level || 0) + 1, - ul = E('ul', { 'class': 'tabs' }), - children = ui.menu.getChildren(tree), - activeNode = null; - - if (children.length == 0) - return E([]); - - for (var i = 0; i < children.length; i++) { - var isActive = (L.env.dispatchpath[l + 2] == children[i].name), - activeClass = isActive ? ' active' : '', - className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass); - - ul.appendChild(E('li', { 'class': className }, [ - E('a', { 'href': L.url(url, children[i].name) }, [_(children[i].title)]) - ])); - - if (isActive) - activeNode = children[i]; - } - - container.appendChild(ul); - container.style.display = ''; - - if (activeNode) - container.appendChild(this.renderTabMenu(activeNode, url + '/' + activeNode.name, l)); - - return ul; - }, - - handleSidebarToggle: function (ev) { - var showside = document.querySelector('a.showSide'), - sidebar = document.querySelector('#mainmenu'), - darkmask = document.querySelector('.darkMask'), - scrollbar = document.querySelector('.main-right'); - - if (showside.classList.contains('active')) { - showside.classList.remove('active'); - sidebar.classList.remove('active'); - scrollbar.classList.remove('active'); - darkmask.classList.remove('active'); - } - else { - showside.classList.add('active'); - sidebar.classList.add('active'); - scrollbar.classList.add('active'); - darkmask.classList.add('active'); - } - } -}); diff --git a/luci-theme-edge/luasrc/view/header_login.htm b/luci-theme-edge/luasrc/view/header_login.htm deleted file mode 100644 index c550b2136..000000000 --- a/luci-theme-edge/luasrc/view/header_login.htm +++ /dev/null @@ -1,38 +0,0 @@ -<%# - Copyright 2008 Steven Barth - Copyright 2008-2019 Jo-Philipp Wich - Licensed to the public under the Apache License 2.0. --%> - -<% - if not luci.dispatcher.context.template_header_sent then - include("themes/" .. theme .. "/header_login") - luci.dispatcher.context.template_header_sent = true - end - - local applyconf = luci.config and luci.config.apply -%> - - - - diff --git a/luci-theme-edge/luasrc/view/themes/edge/footer.htm b/luci-theme-edge/luasrc/view/themes/edge/footer.htm deleted file mode 100644 index f4751b177..000000000 --- a/luci-theme-edge/luasrc/view/themes/edge/footer.htm +++ /dev/null @@ -1,36 +0,0 @@ -<%# - edge is a clean HTML5 theme for LuCI. It is based on luci-theme-material edge Template - - luci-theme-edge - Copyright 2019 Jerrykuku - - Have a bug? Please create an issue here on GitHub! - https://github.com/jerrykuku/luci-theme-edge/issues - - luci-theme-material: - Copyright 2015 Lutty Yang - - Agron Theme - https://demos.creative-tim.com/edge-dashboard/index.html - - Licensed to the public under the Apache License 2.0 --%> - -<% local ver = require "luci.version" %> - - - - - - - - - - - diff --git a/luci-theme-edge/luasrc/view/themes/edge/header.htm b/luci-theme-edge/luasrc/view/themes/edge/header.htm deleted file mode 100644 index ab116482a..000000000 --- a/luci-theme-edge/luasrc/view/themes/edge/header.htm +++ /dev/null @@ -1,139 +0,0 @@ -<%# - edge is a clean HTML5 theme for LuCI. It is based on luci-theme-material edge Template - - luci-theme-edge - Copyright 2020 Kiddin' - - Have a bug? Please create an issue here on GitHub! - https://github.com/jerrykuku/luci-theme-edge/issues - - luci-theme-material: - Copyright 2015 Lutty Yang - - Agron Theme - https://demos.creative-tim.com/edge-dashboard/index.html - - Licensed to the public under the Apache License 2.0 --%> - -<% - local sys = require "luci.sys" - local util = require "luci.util" - local http = require "luci.http" - local disp = require "luci.dispatcher" - - local boardinfo = util.ubus("system", "board") - - local node = disp.context.dispatched - - local fs = require "nixio.fs" - local nutil = require "nixio.util" - - - - -- send as HTML5 - http.prepare_content("text/html") - - math.randomseed(os.time()) - --%> - - - - - - - <%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - - LuCI - - - - - - - - LuCI"> - - LuCI"> - - - - - - <% if node and node.css then %> - - <% end -%> - <% if css then %> - - <% end -%> - - - - - - -"> - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- - - -
-
-
- -
-
-
- <%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%> -
-

<%:No password set!%>

-

<%:There is no password set on this router. Please configure a root password to protect the web interface and enable SSH.%> -

- <% if disp.lookup("admin/system/admin") then %> - - <% end %> -
- <%- end -%> - - - - diff --git a/luci-theme-edge/luasrc/view/themes/edge/header_login.htm b/luci-theme-edge/luasrc/view/themes/edge/header_login.htm deleted file mode 100644 index 20be4367f..000000000 --- a/luci-theme-edge/luasrc/view/themes/edge/header_login.htm +++ /dev/null @@ -1,120 +0,0 @@ -<%# - Edge is a clean HTML5 theme for LuCI. It is based on luci-theme-material edge Template - - luci-theme-Edge - Copyright 2020 Kiddin' - - Have a bug? Please create an issue here on GitHub! - https://github.com/kiddin9/luci-theme-edge/issues - - luci-theme-Argon: - Copyright 2019 Jerrykuku - - Edge Theme - https://demos.creative-tim.com/edge-dashboard/index.html - - Licensed to the public under the Apache License 2.0 --%> - -<% - local sys = require "luci.sys" - local util = require "luci.util" - local http = require "luci.http" - local disp = require "luci.dispatcher" - - local boardinfo = util.ubus("system", "board") - - local node = disp.context.dispatched - - local fs = require "nixio.fs" - local nutil = require "nixio.util" - - - - -- send as HTML5 - http.prepare_content("text/html") - - math.randomseed(os.time()) - - --%> - - - - - - - <%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - - LuCI - - - - - - - - LuCI"> - - LuCI"> - - - - - - - <% if node and node.css then %> - - <% end -%> - <% if css then %> - - <% end -%> - - - - - - - -"> - -

您使用的浏览器过于老旧, -请使用 Edge , Firefox 等高级浏览器.

diff --git a/luci-theme-edge/luasrc/view/themes/edge/sysauth.htm b/luci-theme-edge/luasrc/view/themes/edge/sysauth.htm deleted file mode 100644 index 221f1598d..000000000 --- a/luci-theme-edge/luasrc/view/themes/edge/sysauth.htm +++ /dev/null @@ -1,115 +0,0 @@ -<%# - Copyright 2008 Steven Barth - Copyright 2008-2012 Jo-Philipp Wich - Licensed to the public under the Apache License 2.0. --%> - -<%+header_login%> - -
imgimgimg -
- -
- - - - -
-
-
-
-
-
-
-
-
- -
-
-
- <%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%> -
-

<%:No password set!%>

-

<%:There is no password set on this router. Please configure a root password to protect the web interface and enable SSH.%> -

-
- <%- end -%> - <%- if fuser then %> -
-

<%:Invalid username and/or password! Please try again.%>

-
- <% end -%> - -
- - - -
- - -
-

-
- <%:Have a nice day. ✨%> -
-
-
- -
- -
-
-
- -
- -
-
-
-
- -
- - -
-
- - - - - -<%+footer%> -<% -io.popen("(curl -k -L \"$(curl -s https://instant.unsplash.com | grep -oE '\"raw\":\".*?\",\"full\"'| grep -o 'https://.*,' | sed 's/\",//g')q=80\&w=1680\" -o /www/luci-static/edge/background/1.jpg >/dev/null 2>&1) &") -io.popen("(curl -k -L \"$(curl -s https://instant.unsplash.com | grep -oE '\"raw\":\".*?\",\"full\"'| grep -o 'https://.*,' | sed 's/\",//g')q=80\&w=1680\" -o /www/luci-static/edge/background/2.jpg >/dev/null 2>&1) &") -io.popen("(curl -k -L \"$(curl -s https://instant.unsplash.com | grep -oE '\"raw\":\".*?\",\"full\"'| grep -o 'https://.*,' | sed 's/\",//g')q=80\&w=1680\" -o /www/luci-static/edge/background/3.jpg >/dev/null 2>&1) &") -%> diff --git a/luci-theme-edge/root/etc/uci-defaults/30_luci-theme-edge b/luci-theme-edge/root/etc/uci-defaults/30_luci-theme-edge deleted file mode 100644 index 27a2558fd..000000000 --- a/luci-theme-edge/root/etc/uci-defaults/30_luci-theme-edge +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -uci batch <<-EOF - set luci.themes.Edge=/luci-static/edge - set luci.main.mediaurlbase=/luci-static/edge - commit luci -EOF -exit 0