16 Commits
1.1.4 ... 1.1.5

Author SHA1 Message Date
cppla
51e2f664cd update theme set bug 2024-08-18 21:16:38 +08:00
cppla
937b1ea90f fix some bug 2024-08-18 21:13:53 +08:00
cppla
b95d1945bf Update README.md 2024-08-18 19:44:57 +08:00
cppla
e8446cd52f 我震惊的是AI已经能够帮助重构前端页面
我震惊的是AI已经能够帮助重构前端页面
2024-08-18 13:09:25 +08:00
cppla
6098f0fb1a commit new css by ai 2024-08-18 13:00:45 +08:00
cppla
fc89a76cc2 resize css 2024-08-17 18:50:43 +08:00
cppla
f290947b2c update theme 2024-08-17 17:36:57 +08:00
cppla
b3adc6b782 update all 2024-08-17 17:31:40 +08:00
cppla
705a957606 bai piao copilot 2024-08-15 19:32:50 +08:00
cppla
a307ad7d19 ai niu bi 2024-08-15 15:59:26 +08:00
cppla
ad95e00723 不更新代码 无法续Copilot 2024-08-15 14:46:49 +08:00
cppla
31330168f3 ai modify 2024-08-15 14:18:34 +08:00
cppla
d9e8f8a7c1 del ie 2024-08-15 14:02:33 +08:00
cppla
08f15ebdc5 15s -> 25s 2024-04-18 15:34:43 +08:00
cppla
adb05818b9 改为15秒再次判断是否离线 2024-04-08 14:25:53 +08:00
cppla
4e73e8185e Update README.md 2024-04-03 22:06:15 +08:00
15 changed files with 758 additions and 950 deletions

View File

@@ -6,10 +6,9 @@
[![Python Support](https://img.shields.io/badge/python-3.6%2B%20-blue.svg)](https://github.com/cppla/ServerStatus)
[![C++ Compiler](http://img.shields.io/badge/C++-GNU-blue.svg?style=flat&logo=cplusplus)](https://github.com/cppla/ServerStatus)
[![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](https://github.com/cppla/ServerStatus)
[![Version](https://img.shields.io/badge/Version-Build%201.1.3-red)](https://github.com/cppla/ServerStatus)
[![Version](https://img.shields.io/badge/Version-Build%201.1.5-red)](https://github.com/cppla/ServerStatus)
![Latest Host Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_host.png)
![Latest Server Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_server.png)
![Latest Host Version](https://dl.cpp.la/Archive/serverstatus_1.1.5.png)
`Watchdog触发式告警interval只是为了防止频繁收到报警信息造成的骚扰并不是探测间隔。值得注意的是Exprtk库默认使用窄字符类型中文等Unicode字符无法解析计算等待修复。 `
@@ -70,12 +69,13 @@ cd ServerStatus/server && make
```diff
! watchdog rule 可以为任何已知字段的表达式。注意Exprtk库默认使用窄字符类型中文等Unicode字符无法解析计算等待修复
! watchdog interval 最小通知间隔
! watchdog callback 可自定义为Post方法的URL告警内容将拼接其后并发起回调
! watchdog callback 可自定义为Post方法的URL告警内容将拼接其后并发起回调
! Server酱注册https://sct.ftqq.com/r/13682
! watchdog callback Telegram: https://api.telegram.org/bot你自己的密钥/sendMessage?parse_mode=HTML&disable_web_page_preview=true&chat_id=你自己的标识&text=
! watchdog callback Server酱: https://sctapi.ftqq.com/你自己的密钥.send?title=ServerStatus&desp=
! watchdog callback PushDeer: https://api2.pushdeer.com/message/push?pushkey=你自己的密钥&text=
! watchdog callback BasicAuth: https://用户名:密码@你自己的域名/api/push?message=
! Telegram: https://api.telegram.org/bot你自己的密钥/sendMessage?parse_mode=HTML&disable_web_page_preview=true&chat_id=你自己的标识&text=
! Server酱: https://sctapi.ftqq.com/你自己的密钥.send?title=ServerStatus&desp=
! PushDeer: https://api2.pushdeer.com/message/push?pushkey=你自己的密钥&text=
! HttpBasicAuth: https://用户名:密码@你自己的域名/api/push?message=
```
```

View File

@@ -506,7 +506,7 @@ void CMain::offlineAlarmThread(void *pUser)
CClient *pClients = m_OfflineAlarmThreadData->pClients;
CWatchDog *pWatchDogs = m_OfflineAlarmThreadData->pWatchDogs;
volatile short ClientID = m_OfflineAlarmThreadData->m_ReloadRequired;
thread_sleep(6000);
thread_sleep(25000);
if(!pClients[ClientID].m_Connected)
{
int ID = 0;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,48 +1,182 @@
body { background: #212e36 url('../img/dark.png'); color: #dcdcdc; }
.navbar { min-height: 40px; }
.navbar-brand { color: #FFF !important; padding: 10px; font-size: 20px; }
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; }
.dropdown-menu > li > a { color: #FFF !important; background-color: #222222 !important; }
.dropdown-menu > li > a:hover { color: #FFF !important; background: #000 !important; }
.dropdown-menu { background: #222 !important; background-color: #222222 !important; }
.navbar-inverse .navbar-inner { background-color:#1B1B1B; background-image:-moz-linear-gradient(top, #222222, #111111); background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); background-image:-webkit-linear-gradient(top, #222222, #111111); background-image:-o-linear-gradient(top, #222222, #111111); background-image:linear-gradient(to bottom, #212e36, #212e36); background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); border-color: #252525; }
.content { background: #212e36; padding: 20px; border-radius: 5px; border: 1px #212e36 solid; -webkit-box-shadow: 0 0px 0px rgba(0, 0, 0, 0); -moz-box-shadow: 0 0px 0px rgba(0, 0, 0, 0); box-shadow: 0 0px 0px rgba(0, 0, 0, 0); margin-bottom: 20px; }
.table { background: #363b40; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; }
.table th { text-align: center; }
.table-striped tbody > tr.even > td, .table-striped tbody > tr.even > th { background-color: #212e36; }
.table-striped tbody > tr.odd > td, .table-striped tbody > tr.odd > th { background-color: #212e36; }
.table td { text-align: center; border-color: #2F2F2F; }
.progress { margin-bottom: 0; background: #363b40; }
.table-hover > tbody > tr:hover > td { background: #414141; }
tr.even.expandRow > :hover { background: #212e36 !important; }
tr.odd.expandRow > :hover { background: #212e36 !important; }
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
#month_traffic { min-width: 85px; max-width: 95px;}
#network { min-width: 110px; }
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
#ping { max-width: 115px; }
body {
background: #212e36 url('../img/dark.png') repeat;
color: #dcdcdc;
font-size: 15px;
padding-top: 70px;
padding-bottom: 30px;
}
.navbar {
min-height: 40px;
background-color: #1B1B1B;
}
.navbar-brand {
color: #FFF !important;
padding: 10px;
font-size: 20px;
}
.dropdown .dropdown-toggle {
padding-bottom: 10px;
padding-top: 10px;
}
.dropdown-menu > li > a {
color: #FFF !important;
background-color: #222222 !important;
}
.dropdown-menu > li > a:hover {
color: #FFF !important;
background: #000 !important;
}
.dropdown-menu {
background: #222 !important;
background-color: #222222 !important;
}
.navbar-inverse .navbar-inner {
background-color: #1B1B1B;
background-image: linear-gradient(to bottom, #212e36, #212e36);
background-repeat: repeat-x;
border-color: #252525;
}
.content {
background: #212e36;
padding: 20px;
border-radius: 5px;
border: 1px solid #212e36;
box-shadow: 0 0px 0px rgba(0, 0, 0, 0);
margin-bottom: 20px;
}
.table {
background-color: #212e36 !important;
margin-bottom: 0;
border-collapse: collapse;
border-radius: 3px;
width: 100%;
}
.table th, .table td {
background-color: #212e36 !important;
color: #dcdcdc !important;
text-align: center;
padding: 8px;
}
.table-striped tbody tr:nth-child(even) {
background-color: #212e36;
}
.table-striped tbody tr:nth-child(odd) {
background-color: #212e36;
}
.progress {
margin-bottom: 0;
background: #363b40;
}
.progress-bar {
overflow: visible;
}
.table-hover tbody tr:hover td {
background: #414141;
}
tr.even.expandRow:hover {
background: #212e36 !important;
}
tr.odd.expandRow:hover {
background: #212e36 !important;
}
.expandRow td {
padding: 0 !important;
border-top: 0 !important;
}
#month_traffic {
min-width: 85px;
max-width: 95px;
}
#traffic, #network {
width: 158px;
}
#cpu, #ram, #hdd {
min-width: 45px;
max-width: 68px;
}
#ping {
width: 115px;
}
@media only screen and (max-width: 1200px) {
#type { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body {
font-size: 10px;
}
.content {
padding: 0;
}
#traffic, #network {
width: 115px;
}
#type, #location, #uptime, #ping {
display: none;
visibility: hidden;
}
}
@media only screen and (max-width: 720px) {
body { font-size: 10px; }
.content { padding: 0; }
#type { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body {
font-size: 10px;
}
.content {
padding: 0;
}
#traffic, #network {
width: 115px;
}
#month_traffic, #type, #location, #uptime, #ping {
display: none;
visibility: hidden;
}
}
@media only screen and (max-width: 620px) {
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic { display:none; visibility:hidden; }
#type { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body {
font-size: 10px;
}
.content {
padding: 0;
}
#network {
width: 115px;
}
#month_traffic, #type, #location, #uptime, #traffic, #ping {
display: none;
visibility: hidden;
}
}
.navbar-nav .nav-link {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
line-height: 1.5;
}
.navbar-nav .dropdown-toggle::after {
vertical-align: 0.15em;
}

View File

@@ -1,45 +1,163 @@
body { background: #ebebeb url('../img/light.png'); }
.navbar { min-height: 40px; }
.navbar-brand { color: #fff; padding: 10px; font-size: 20px; }
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; }
.navbar-inverse .navbar-brand { color: #fff; padding: 10px; font-size: 20px; }
.content { background: #ffffff; padding: 20px; border-radius: 5px; border: 1px #cecece solid; -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); box-shadow: 0 1px 10px rgba(0, 0, 0, .1); margin-bottom: 20px; }
.table { background: #ffffff; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; }
.table th, .table td { text-align: center; }
.table-striped tbody > tr.even > td, .table-striped tbody > tr.even > th { background-color: #F9F9F9; }
.table-striped tbody > tr.odd > td, .table-striped tbody > tr.odd > th { background-color: #FFF; }
.progress { margin-bottom: 0; }
.progress-bar { color: #000; }
.table-hover > tbody > tr:hover > td { background: #E6E6E6; }
tr.even.expandRow > :hover { background: #F9F9F9 !important; }
tr.odd.expandRow > :hover { background: #FFF !important; }
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
#month_traffic { min-width: 85px; max-width: 95px;}
#network { min-width: 110px; }
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
#ping { max-width: 115px; }
body {
background: #ebebeb url('../img/light.png') repeat;
font-size: 15px;
padding-top: 70px;
padding-bottom: 30px;
}
.navbar {
min-height: 40px;
background-color: #333;
}
.navbar-brand {
color: #fff;
padding: 10px;
font-size: 20px;
}
.dropdown .dropdown-toggle {
padding-bottom: 10px;
padding-top: 10px;
}
.navbar-inverse .navbar-brand {
color: #fff;
padding: 10px;
font-size: 20px;
}
.content {
background: #ffffff;
padding: 20px;
border-radius: 5px;
border: 1px solid #cecece;
box-shadow: 0 1px 10px rgba(0, 0, 0, .1);
margin-bottom: 20px;
}
.table {
background: #ffffff;
margin-bottom: 0;
border-collapse: collapse;
border-radius: 3px;
width: 100%;
}
.table th, .table td {
text-align: center;
padding: 8px;
}
.table-striped tbody tr:nth-child(even) {
background-color: #F9F9F9;
}
.table-striped tbody tr:nth-child(odd) {
background-color: #FFF;
}
.progress {
margin-bottom: 0;
}
.progress-bar {
color: #000;
overflow: visible;
}
.table-hover tbody tr:hover td {
background: #E6E6E6;
}
tr.even.expandRow:hover {
background: #F9F9F9 !important;
}
tr.odd.expandRow:hover {
background: #FFF !important;
}
.expandRow td {
padding: 0 !important;
border-top: 0 !important;
}
#month_traffic {
min-width: 85px;
max-width: 95px;
}
#traffic, #network {
width: 158px;
}
#cpu, #ram, #hdd {
min-width: 45px;
max-width: 68px;
}
#ping {
width: 115px;
}
@media only screen and (max-width: 1200px) {
#type { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body {
font-size: 10px;
}
.content {
padding: 0;
}
#traffic, #network {
width: 115px;
}
#type, #location, #uptime, #ping {
display: none;
visibility: hidden;
}
}
@media only screen and (max-width: 720px) {
body { font-size: 10px; }
.content { padding: 0; }
#type { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body {
font-size: 10px;
}
.content {
padding: 0;
}
#traffic, #network {
width: 115px;
}
#month_traffic, #type, #location, #uptime, #ping {
display: none;
visibility: hidden;
}
}
@media only screen and (max-width: 620px) {
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic { display:none; visibility:hidden; }
#type { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body {
font-size: 10px;
}
.content {
padding: 0;
}
#network {
width: 115px;
}
#month_traffic, #type, #location, #uptime, #traffic, #ping {
display: none;
visibility: hidden;
}
}
.navbar-nav .nav-link {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
line-height: 1.5;
}
.navbar-nav .dropdown-toggle::after {
vertical-align: 0.15em;
}

View File

@@ -1,140 +1,111 @@
<!DOCTYPE html>
<!--
json字段保持完整, 自行自定义前端展示
ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)
follow me, better solution for you. by:https://cpp.la
-->
<html>
<head>
<title>云监控</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="云监控">
<meta name="author" content="BotoX">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-theme.min.css">
<link rel="stylesheet" href="css/light.css" title="light">
<link rel="stylesheet" href="css/dark.css" title="dark">
<style>
body {
padding-top: 70px;
padding-bottom: 30px;
}
</style>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div role="navigation" class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<div class="navbar-header">
<button data-target=".navbar-collapse" data-toggle="collapse" class="navbar-toggle" type="button">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="#" class="navbar-brand">云监控</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a data-toggle="tab" class="dropdown-toggle" href="#server">首页</a>
</li>
<li class="dropdown">
<a data-toggle="tab" class="dropdown-toggle" href="#monitor">服务</a>
</li>
<li class="dropdown">
<a data-toggle="dropdown" class="dropdown-toggle" href="#">风格<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#" onclick="setActiveStyleSheet('dark', true)">黑夜</a></li>
<li><a href="#" onclick="setActiveStyleSheet('light', true)">白天</a></li>
<li><a href="/index3.html">简洁</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="云监控,ServerStatus中文版,ServerStatus,ServerStatus cppla">
<meta name="author" content="ServerStatus Theme by AI">
<title>云监控</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/light.css" title="light">
<link rel="stylesheet" href="css/dark.css" title="dark">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top" role="navigation">
<div class="container">
<a class="navbar-brand" href="#">云监控</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#server" data-bs-toggle="tab">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#monitor" data-bs-toggle="tab">服务</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
风格
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#" onclick="setActiveStyleSheet('dark')">黑夜</a></li>
<li><a class="dropdown-item" href="#" onclick="setActiveStyleSheet('light')">白天</a></li>
<li><a class="dropdown-item" href="/index3.html">简洁</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div class="container content">
<div id="loading-notice">
<noscript>
<div class="alert alert-danger" style="text-align: center;">
<strong>Enable JavaScript</strong> , please do it.
</div>
</noscript>
<div style="text-align: center;">
警告:如果出现此消息请确保您已启用Javascript! <br />否则云监控主服务没启动或已关闭.
</div>
<p></p>
</div>
<div class="container content">
<noscript>
<div class="alert alert-danger text-center">
<strong>请启用 JavaScript</strong>,否则无法正常使用本站功能。
</div>
</noscript>
<div id="loading-notice" class="text-center">
警告:如果出现此消息,请确保您已启用 Javascript<br>
否则云监控主服务没启动或已关闭
</div>
<div class="tab-content">
<div class="tab-pane fade in active" id="server">
<!--主机-->
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th id="online_status" style="text-align: center;">🔗协议</th>
<th id="month_traffic" style="text-align: center;">📊月流量↓|↑</th>
<th id="name">📌节点</th>
<th id="type">🗂️虚拟化</th>
<th id="location">🌍位置</th>
<th id="uptime">⏱️在线</th>
<th id="load">负载</th>
<th id="network">🚦网络↓|↑</th>
<th id="traffic">📋总流量↓|↑</th>
<th id="cpu">🎯核芯</th>
<th id="ram">⚡️内存</th>
<th id="hdd">💾硬盘</th>
<th id="ping">🌐CU|CT|CM</th>
</tr>
</thead>
<tbody id="servers">
<!-- Servers here \o/ -->
</tbody>
</table>
</div>
<div class="tab-pane fade" id="monitor">
<!--服务-->
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th id="monitor_status" style="text-align: center;">🔗协议</th>
<th id="monitor_node">📌监测节点</th>
<th id="monitor_location">🌍监测位置</th>
<th id="monitor_text" style="text-align: center;">📋监测内容</th>
</tr>
</thead>
<tbody id="monitors">
<!-- Monitors here \o/ -->
</tbody>
</table>
</div>
</div>
<div class="tab-content">
<div class="tab-pane fade show active" id="server">
<!--主机-->
<table class="table table-striped table-hover">
<thead>
<tr>
<th id="online_status" style="text-align: center;">🔗协议</th>
<th id="month_traffic" style="text-align: center;">📊月流量↓|↑</th>
<th id="name">📌节点</th>
<th id="type">🗂️虚拟化</th>
<th id="location">🌍位置</th>
<th id="uptime">⏱️在线</th>
<th id="load">负载</th>
<th id="network">🚦网络↓|↑</th>
<th id="traffic">📋总流量↓|↑</th>
<th id="cpu">🎯核芯</th>
<th id="ram">⚡️内存</th>
<th id="hdd">💾硬盘</th>
<th id="ping">🌐CU|CT|CM</th>
</tr>
</thead>
<tbody id="servers">
<!-- Servers here \o/ -->
</tbody>
</table>
</div>
<div class="tab-pane fade" id="monitor">
<!--服务-->
<table class="table table-striped table-hover">
<thead>
<tr>
<th id="monitor_status" style="text-align: center;">🔗协议</th>
<th id="monitor_node">📌监测节点</th>
<th id="monitor_location">🌍监测位置</th>
<th id="monitor_text" style="text-align: center;">📋监测内容</th>
</tr>
</thead>
<tbody id="monitors">
<!-- Monitors here \o/ -->
</tbody>
</table>
</div>
</div>
<br />
<div id="updated">Updating...</div>
</div>
<br/>
<div id="updated">更新中...</div>
</div>
<div class="container">
<p style="text-align: center; font-size: 10px;">
<a href="https://github.com/cppla/ServerStatus">ServerStatus中文版</a>
</p>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/serverstatus.js"></script>
</body>
</html>
<footer class="container">
<p class="text-center" style="font-size: 10px;">
<a href="https://github.com/cppla/ServerStatus">ServerStatus中文版</a>
</p>
</footer>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/serverstatus.js"></script>
</body>
</html>

7
web/js/bootstrap.bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

326
web/js/html5shiv.js vendored
View File

@@ -1,326 +0,0 @@
/**
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
;(function(window, document) {
/*jshint evil:true */
/** version */
var version = '3.7.3';
/** Preset options */
var options = window.html5 || {};
/** Used to skip problem elements */
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
/** Not all elements can be cloned in IE **/
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
/** Detect whether the browser supports default html5 styles */
var supportsHtml5Styles;
/** Name of the expando, to work with multiple documents or to re-shiv one document */
var expando = '_html5shiv';
/** The id for the the documents expando */
var expanID = 0;
/** Cached data for each document */
var expandoData = {};
/** Detect whether the browser supports unknown elements */
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '<xyz></xyz>';
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
// assign a false positive if unable to shiv
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
// assign a false positive if detection fails => unable to shiv
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}());
/*--------------------------------------------------------------------------*/
/**
* Creates a style sheet with the given CSS text and adds it to the document.
* @private
* @param {Document} ownerDocument The document.
* @param {String} cssText The CSS text.
* @returns {StyleSheet} The style element.
*/
function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x<style>' + cssText + '</style>';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
/**
* Returns the value of `html5.elements` as an array.
* @private
* @returns {Array} An array of shived element node names.
*/
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
/**
* Extends the built-in list of html5 elements
* @memberOf html5
* @param {String|Array} newElements whitespace separated list or array of new element names to shiv
* @param {Document} ownerDocument The context document.
*/
function addElements(newElements, ownerDocument) {
var elements = html5.elements;
if(typeof elements != 'string'){
elements = elements.join(' ');
}
if(typeof newElements != 'string'){
newElements = newElements.join(' ');
}
html5.elements = elements +' '+ newElements;
shivDocument(ownerDocument);
}
/**
* Returns the data associated to the given document
* @private
* @param {Document} ownerDocument The document.
* @returns {Object} An object of data.
*/
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
/**
* returns a shived element for the given nodeName and document
* @memberOf html5
* @param {String} nodeName name of the element
* @param {Document|DocumentFragment} ownerDocument The context document.
* @returns {Object} The shived element.
*/
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
// Avoid adding some elements to fragments in IE < 9 because
// * Attributes like `name` or `type` cannot be set/changed once an element
// is inserted into a document/fragment
// * Link elements with `src` attributes that are inaccessible, as with
// a 403 response, will cause the tab/window to crash
// * Script elements appended to fragments will execute when their `src`
// or `text` property is set
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
}
/**
* returns a shived DocumentFragment for the given document
* @memberOf html5
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived DocumentFragment.
*/
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i<l;i++){
clone.createElement(elems[i]);
}
return clone;
}
/**
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
* @private
* @param {Document|DocumentFragment} ownerDocument The document.
* @param {Object} data of the document.
*/
function shivMethods(ownerDocument, data) {
if (!data.cache) {
data.cache = {};
data.createElem = ownerDocument.createElement;
data.createFrag = ownerDocument.createDocumentFragment;
data.frag = data.createFrag();
}
ownerDocument.createElement = function(nodeName) {
//abort shiv
if (!html5.shivMethods) {
return data.createElem(nodeName);
}
return createElement(nodeName, ownerDocument, data);
};
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
'var n=f.cloneNode(),c=n.createElement;' +
'h.shivMethods&&(' +
// unroll the `createElement` calls
getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
data.createElem(nodeName);
data.frag.createElement(nodeName);
return 'c("' + nodeName + '")';
}) +
');return n}'
)(html5, data.frag);
}
/*--------------------------------------------------------------------------*/
/**
* Shivs the given document.
* @memberOf html5
* @param {Document} ownerDocument The document to shiv.
* @returns {Document} The shived document.
*/
function shivDocument(ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
}
var data = getExpandoData(ownerDocument);
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
data.hasCSS = !!addStyleSheet(ownerDocument,
// corrects block display not defined in IE6/7/8/9
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
// adds styling not present in IE6/7/8/9
'mark{background:#FF0;color:#000}' +
// hides non-rendered elements
'template{display:none}'
);
}
if (!supportsUnknownElements) {
shivMethods(ownerDocument, data);
}
return ownerDocument;
}
/*--------------------------------------------------------------------------*/
/**
* The `html5` object is exposed so that more elements can be shived and
* existing shiving can be detected on iframes.
* @type Object
* @example
*
* // options can be changed before the script is included
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
*/
var html5 = {
/**
* An array or space separated string of node names of the elements to shiv.
* @memberOf html5
* @type Array|String
*/
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
/**
* current version of html5shiv
*/
'version': version,
/**
* A flag to indicate that the HTML5 style sheet should be inserted.
* @memberOf html5
* @type Boolean
*/
'shivCSS': (options.shivCSS !== false),
/**
* Is equal to true if a browser supports creating unknown/HTML5 elements
* @memberOf html5
* @type boolean
*/
'supportsUnknownElements': supportsUnknownElements,
/**
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
* methods should be overwritten.
* @memberOf html5
* @type Boolean
*/
'shivMethods': (options.shivMethods !== false),
/**
* A string to describe the type of `html5` object ("default" or "default print").
* @memberOf html5
* @type String
*/
'type': 'default',
// shivs the document according to the specified `html5` object options
'shivDocument': shivDocument,
//creates a shived element
createElement: createElement,
//creates a shived documentFragment
createDocumentFragment: createDocumentFragment,
//extends list of elements
addElements: addElements
};
/*--------------------------------------------------------------------------*/
// expose html5
window.html5 = html5;
// shiv the document
shivDocument(document);
if(typeof module == 'object' && module.exports){
module.exports = html5;
}
}(typeof window !== "undefined" ? window : this, document));

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
* Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
* */
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);

View File

@@ -4,424 +4,350 @@ var d = 0;
var server_status = new Array();
function timeSince(date) {
if(date == 0)
return "从未.";
var seconds = Math.floor((new Date() - date) / 1000);
var interval = Math.floor(seconds / 60);
if (interval > 1)
return interval + " 分钟前.";
else
return "几秒前.";
if (date == 0) return "从未.";
var seconds = Math.floor((new Date() - date) / 1000);
var interval = Math.floor(seconds / 60);
return interval > 1 ? interval + " 分钟前." : "几秒前.";
}
function bytesToSize(bytes, precision, si)
{
var ret;
si = typeof si !== 'undefined' ? si : 0;
if(si != 0) {
var megabyte = 1000 * 1000;
var gigabyte = megabyte * 1000;
var terabyte = gigabyte * 1000;
} else {
var megabyte = 1024 * 1024;
var gigabyte = megabyte * 1024;
var terabyte = gigabyte * 1024;
}
if ((bytes >= megabyte) && (bytes < gigabyte)) {
ret = (bytes / megabyte).toFixed(precision) + ' M';
} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
ret = (bytes / gigabyte).toFixed(precision) + ' G';
} else if (bytes >= terabyte) {
ret = (bytes / terabyte).toFixed(precision) + ' T';
} else {
return bytes + ' B';
}
return ret;
/*if(si != 0) {
return ret + 'B';
} else {
return ret + 'iB';
}*/
function bytesToSize(bytes, precision, si = false) {
const units = si ? ['B', 'KB', 'MB', 'GB', 'TB'] : ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
if (bytes === 0) return '0 B';
const k = si ? 1000 : 1024;
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(precision)) + ' ' + units[i];
}
function uptime() {
$.getJSON("json/stats.json", function(result) {
$("#loading-notice").remove();
if(result.reload)
setTimeout(function() { location.reload() }, 1000);
fetch("json/stats.json")
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(result => {
document.getElementById("loading-notice")?.remove();
if (result.reload) setTimeout(location.reload, 1000);
for (var i = 0, rlen=result.servers.length; i < rlen; i++) {
var TableRow = $("#servers tr#r" + i);
var MableRow = $("#monitors tr#r" + i);
var ExpandRow = $("#servers #rt" + i);
var hack; // fuck CSS for making me do this
if(i%2) hack="odd"; else hack="even";
if (!TableRow.length) {
$("#servers").append(
"<tr id=\"r" + i + "\" data-toggle=\"collapse\" data-target=\"#rt" + i + "\" class=\"accordion-toggle " + hack + "\">" +
"<td id=\"online_status\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"month_traffic\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"name\">加载中</td>" +
"<td id=\"type\">加载中</td>" +
"<td id=\"location\">加载中</td>" +
"<td id=\"uptime\">加载中</td>" +
"<td id=\"load\">加载中</td>" +
"<td id=\"network\">加载中</td>" +
"<td id=\"traffic\">加载中</td>" +
"<td id=\"cpu\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"memory\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"hdd\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"ping\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"</tr>" +
"<tr class=\"expandRow " + hack + "\"><td colspan=\"16\"><div class=\"accordian-body collapse\" id=\"rt" + i + "\">" +
"<div id=\"expand_mem\">加载中</div>" +
"<div id=\"expand_hdd\">加载中</div>" +
"<div id=\"expand_tupd\">加载中</div>" +
"<div id=\"expand_ping\">加载中</div>" +
"</div></td></tr>"
);
TableRow = $("#servers tr#r" + i);
ExpandRow = $("#servers #rt" + i);
server_status[i] = true;
}
if (!MableRow.length) {
$("#monitors").append(
"<tr id=\"r" + i + "\" data-target=\"#rt" + i + "\" class=\"accordion-toggle " + hack + "\">" +
"<td id=\"monitor_status\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"monitor_node\">加载中</td>" +
"<td id=\"monitor_location\">加载中</td>" +
"<td id=\"monitor_text\">加载中</td>" +
"</tr>"
);
MableRow = $("#monitors tr#r" + i);
}
TableRow = TableRow[0];
MableRow = MableRow[0];
if(error) {
TableRow.setAttribute("data-target", "#rt" + i);
MableRow.setAttribute("data-target", "#rt" + i);
server_status[i] = true;
}
result.servers.forEach((server, i) => {
let TableRow = document.querySelector(`#servers tr#r${i}`);
let MableRow = document.querySelector(`#monitors tr#r${i}`);
let ExpandRow = document.querySelector(`#servers #rt${i}`);
let hack = i % 2 ? "odd" : "even";
// online_status
if (result.servers[i].online4 && !result.servers[i].online6) {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>IPv4</small>";
MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success";
MableRow.children["monitor_status"].children[0].children[0].innerHTML = "<small>IPv4</small>";
} else if (result.servers[i].online4 && result.servers[i].online6) {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>双栈</small>";
MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success";
MableRow.children["monitor_status"].children[0].children[0].innerHTML = "<small>双栈</small>";
} else if (!result.servers[i].online4 && result.servers[i].online6) {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>IPv6</small>";
MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success";
MableRow.children["monitor_status"].children[0].children[0].innerHTML = "<small>IPv6</small>";
} else {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>关闭</small>";
MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-danger";
MableRow.children["monitor_status"].children[0].children[0].innerHTML = "<small>关闭</small>";
}
if (!TableRow) {
document.getElementById("servers").insertAdjacentHTML(
"beforeend",
`<tr id="r${i}" data-bs-toggle="collapse" data-bs-target="#rt${i}" class="accordion-toggle ${hack}">
<td id="online_status"><div class="progress"><div style="width: 100%;" class="progress-bar bg-warning"><small>加载中</small></div></div></td>
<td id="month_traffic"><div class="progress"><div style="width: 100%;" class="progress-bar bg-warning"><small>加载中</small></div></div></td>
<td id="name">加载中</td>
<td id="type">加载中</td>
<td id="location">加载中</td>
<td id="uptime">加载中</td>
<td id="load">加载中</td>
<td id="network">加载中</td>
<td id="traffic">加载中</td>
<td id="cpu"><div class="progress"><div style="width: 100%;" class="progress-bar bg-warning"><small>加载中</small></div></div></td>
<td id="memory"><div class="progress"><div style="width: 100%;" class="progress-bar bg-warning"><small>加载中</small></div></div></td>
<td id="hdd"><div class="progress"><div style="width: 100%;" class="progress-bar bg-warning"><small>加载中</small></div></div></td>
<td id="ping"><div class="progress"><div style="width: 100%;" class="progress-bar bg-warning"><small>加载中</small></div></div></td>
</tr>
<tr class="expandRow ${hack}"><td colspan="16"><div class="accordian-body collapse" id="rt${i}">
<div id="expand_mem">加载中</div>
<div id="expand_hdd">加载中</div>
<div id="expand_tupd">加载中</div>
<div id="expand_ping">加载中</div>
</div></td></tr>`
);
TableRow = document.querySelector(`#servers tr#r${i}`);
ExpandRow = document.querySelector(`#servers #rt${i}`);
server_status[i] = true;
}
// Name
TableRow.children["name"].innerHTML = result.servers[i].name;
MableRow.children["monitor_node"].innerHTML = result.servers[i].name;
if (!MableRow) {
document.getElementById("monitors").insertAdjacentHTML(
"beforeend",
`<tr id="r${i}" data-bs-target="#rt${i}" class="accordion-toggle ${hack}">
<td id="monitor_status"><div class="progress"><div style="width: 100%;" class="progress-bar bg-warning"><small>加载中</small></div></div></td>
<td id="monitor_node">加载中</td>
<td id="monitor_location">加载中</td>
<td id="monitor_text">加载中</td>
</tr>`
);
MableRow = document.querySelector(`#monitors tr#r${i}`);
}
// Type
TableRow.children["type"].innerHTML = result.servers[i].type;
if (error) {
TableRow.setAttribute("data-bs-target", `#rt${i}`);
MableRow.setAttribute("data-bs-target", `#rt${i}`);
server_status[i] = true;
}
// Location
TableRow.children["location"].innerHTML = result.servers[i].location;
MableRow.children["monitor_location"].innerHTML = result.servers[i].location;
if (!result.servers[i].online4 && !result.servers[i].online6) {
if (server_status[i]) {
TableRow.children["uptime"].innerHTML = "";
TableRow.children["load"].innerHTML = "";
TableRow.children["network"].innerHTML = "";
TableRow.children["traffic"].innerHTML = "";
TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-warning";
TableRow.children["month_traffic"].children[0].children[0].innerHTML = "<small>关闭</small>";
TableRow.children["cpu"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["cpu"].children[0].children[0].style.width = "100%";
TableRow.children["cpu"].children[0].children[0].innerHTML = "<small>关闭</small>";
TableRow.children["memory"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["memory"].children[0].children[0].style.width = "100%";
TableRow.children["memory"].children[0].children[0].innerHTML = "<small>关闭</small>";
TableRow.children["hdd"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["hdd"].children[0].children[0].style.width = "100%";
TableRow.children["hdd"].children[0].children[0].innerHTML = "<small>关闭</small>";
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["ping"].children[0].children[0].style.width = "100%";
TableRow.children["ping"].children[0].children[0].innerHTML = "<small>关闭</small>";
MableRow.children["monitor_text"].innerHTML = "-";
if(ExpandRow.hasClass("in")) {
ExpandRow.collapse("hide");
}
TableRow.setAttribute("data-target", "");
MableRow.setAttribute("data-target", "");
server_status[i] = false;
}
} else {
if (!server_status[i]) {
TableRow.setAttribute("data-target", "#rt" + i);
MableRow.setAttribute("data-target", "#rt" + i);
server_status[i] = true;
}
const statusClass = server.online4 || server.online6 ? "progress-bar bg-success" : "progress-bar bg-danger";
const statusText = server.online4 && server.online6 ? "双栈" : server.online4 ? "IPv4" : server.online6 ? "IPv6" : "关闭";
// month traffic
var monthtraffic = "";
var trafficdiff_in = result.servers[i].network_in - result.servers[i].last_network_in;
var trafficdiff_out = result.servers[i].network_out - result.servers[i].last_network_out;
if(trafficdiff_in < 1024*1024*1024*1024)
monthtraffic += (trafficdiff_in/1024/1024/1024).toFixed(1) + "G";
else
monthtraffic += (trafficdiff_in/1024/1024/1024/1024).toFixed(1) + "T";
monthtraffic += " | "
if(trafficdiff_out < 1024*1024*1024*1024)
monthtraffic += (trafficdiff_out/1024/1024/1024).toFixed(1) + "G";
else
monthtraffic += (trafficdiff_out/1024/1024/1024/1024).toFixed(1) + "T";
TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["month_traffic"].children[0].children[0].innerHTML = "<small>"+monthtraffic+"</small>";
if (TableRow) {
const onlineStatusBar = TableRow.querySelector("#online_status .progress-bar");
if (onlineStatusBar) {
onlineStatusBar.setAttribute("class", statusClass);
onlineStatusBar.innerHTML = `<small>${statusText}</small>`;
}
}
// Uptime
TableRow.children["uptime"].innerHTML = result.servers[i].uptime;
if (MableRow) {
const monitorStatusBar = MableRow.querySelector("#monitor_status .progress-bar");
if (monitorStatusBar) {
monitorStatusBar.setAttribute("class", statusClass);
monitorStatusBar.innerHTML = `<small>${statusText}</small>`;
}
}
// Load: default load_1, you can change show: load_1, load_5, load_15
if(result.servers[i].load == -1) {
TableRow.children["load"].innerHTML = "";
} else {
TableRow.children["load"].innerHTML = result.servers[i].load_1.toFixed(2);
}
if (TableRow) {
TableRow.querySelector("#name").innerHTML = server.name;
TableRow.querySelector("#type").innerHTML = server.type;
TableRow.querySelector("#location").innerHTML = server.location;
}
// Network
var netstr = "";
if(result.servers[i].network_rx < 1024*1024)
netstr += (result.servers[i].network_rx/1024).toFixed(1) + "K";
else
netstr += (result.servers[i].network_rx/1024/1024).toFixed(1) + "M";
netstr += " | "
if(result.servers[i].network_tx < 1024*1024)
netstr += (result.servers[i].network_tx/1024).toFixed(1) + "K";
else
netstr += (result.servers[i].network_tx/1024/1024).toFixed(1) + "M";
TableRow.children["network"].innerHTML = netstr;
if (MableRow) {
MableRow.querySelector("#monitor_node").innerHTML = server.name;
MableRow.querySelector("#monitor_location").innerHTML = server.location;
}
//Traffic
var trafficstr = "";
if(result.servers[i].network_in < 1024*1024*1024*1024)
trafficstr += (result.servers[i].network_in/1024/1024/1024).toFixed(1) + "G";
else
trafficstr += (result.servers[i].network_in/1024/1024/1024/1024).toFixed(1) + "T";
trafficstr += " | "
if(result.servers[i].network_out < 1024*1024*1024*1024)
trafficstr += (result.servers[i].network_out/1024/1024/1024).toFixed(1) + "G";
else
trafficstr += (result.servers[i].network_out/1024/1024/1024/1024).toFixed(1) + "T";
TableRow.children["traffic"].innerHTML = trafficstr;
if (!server.online4 && !server.online6) {
if (server_status[i]) {
if (TableRow) {
TableRow.querySelector("#uptime").innerHTML = "";
TableRow.querySelector("#load").innerHTML = "";
TableRow.querySelector("#network").innerHTML = "";
TableRow.querySelector("#traffic").innerHTML = "";
const monthTrafficBar = TableRow.querySelector("#month_traffic .progress-bar");
if (monthTrafficBar) {
monthTrafficBar.setAttribute("class", "progress-bar bg-warning");
monthTrafficBar.innerHTML = "<small>关闭</small>";
}
const cpuBar = TableRow.querySelector("#cpu .progress-bar");
if (cpuBar) {
cpuBar.setAttribute("class", "progress-bar bg-danger");
cpuBar.style.width = "100%";
cpuBar.innerHTML = "<small>关闭</small>";
}
const memoryBar = TableRow.querySelector("#memory .progress-bar");
if (memoryBar) {
memoryBar.setAttribute("class", "progress-bar bg-danger");
memoryBar.style.width = "100%";
memoryBar.innerHTML = "<small>关闭</small>";
}
const hddBar = TableRow.querySelector("#hdd .progress-bar");
if (hddBar) {
hddBar.setAttribute("class", "progress-bar bg-danger");
hddBar.style.width = "100%";
hddBar.innerHTML = "<small>关闭</small>";
}
const pingBar = TableRow.querySelector("#ping .progress-bar");
if (pingBar) {
pingBar.setAttribute("class", "progress-bar bg-danger");
pingBar.style.width = "100%";
pingBar.innerHTML = "<small>关闭</small>";
}
}
if (MableRow) {
MableRow.querySelector("#monitor_text").innerHTML = "-";
}
if (ExpandRow && ExpandRow.classList.contains("show")) ExpandRow.classList.remove("show");
if (TableRow) TableRow.setAttribute("data-bs-target", "");
if (MableRow) MableRow.setAttribute("data-bs-target", "");
server_status[i] = false;
}
} else {
if (!server_status[i]) {
if (TableRow) TableRow.setAttribute("data-bs-target", `#rt${i}`);
if (MableRow) MableRow.setAttribute("data-bs-target", `#rt${i}`);
server_status[i] = true;
}
// CPU
if (result.servers[i].cpu >= 90)
TableRow.children["cpu"].children[0].children[0].className = "progress-bar progress-bar-danger";
else if (result.servers[i].cpu >= 80)
TableRow.children["cpu"].children[0].children[0].className = "progress-bar progress-bar-warning";
else
TableRow.children["cpu"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["cpu"].children[0].children[0].style.width = result.servers[i].cpu + "%";
TableRow.children["cpu"].children[0].children[0].innerHTML = result.servers[i].cpu + "%";
const trafficdiff_in = server.network_in - server.last_network_in;
const trafficdiff_out = server.network_out - server.last_network_out;
const monthtraffic = `${bytesToSize(trafficdiff_in, 1, true)} | ${bytesToSize(trafficdiff_out, 1, true)}`;
if (TableRow) {
const monthTrafficBar = TableRow.querySelector("#month_traffic .progress-bar");
if (monthTrafficBar) {
monthTrafficBar.setAttribute("class", "progress-bar bg-success");
monthTrafficBar.innerHTML = `<small>${monthtraffic}</small>`;
}
}
// Memory
var Mem = ((result.servers[i].memory_used/result.servers[i].memory_total)*100.0).toFixed(0);
if (Mem >= 90)
TableRow.children["memory"].children[0].children[0].className = "progress-bar progress-bar-danger";
else if (Mem >= 80)
TableRow.children["memory"].children[0].children[0].className = "progress-bar progress-bar-warning";
else
TableRow.children["memory"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["memory"].children[0].children[0].style.width = Mem + "%";
TableRow.children["memory"].children[0].children[0].innerHTML = Mem + "%";
// 内存|swap
ExpandRow[0].children["expand_mem"].innerHTML = "内存|虚存: " + bytesToSize(result.servers[i].memory_used*1024, 1) + " / " + bytesToSize(result.servers[i].memory_total*1024, 1) + " | " + bytesToSize(result.servers[i].swap_used*1024, 0) + " / " + bytesToSize(result.servers[i].swap_total*1024, 0);
if (TableRow) TableRow.querySelector("#uptime").innerHTML = server.uptime;
if (TableRow) TableRow.querySelector("#load").innerHTML = server.load_1 == -1 ? "" : server.load_1.toFixed(2);
// HDD
var HDD = ((result.servers[i].hdd_used/result.servers[i].hdd_total)*100.0).toFixed(0);
if (HDD >= 90)
TableRow.children["hdd"].children[0].children[0].className = "progress-bar progress-bar-danger";
else if (HDD >= 80)
TableRow.children["hdd"].children[0].children[0].className = "progress-bar progress-bar-warning";
else
TableRow.children["hdd"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["hdd"].children[0].children[0].style.width = HDD + "%";
TableRow.children["hdd"].children[0].children[0].innerHTML = HDD + "%";
// IO Speed for HDD.
// IO 过小的B字节单位没有意义
var io = "";
if(result.servers[i].io_read < 1024*1024)
io += parseInt(result.servers[i].io_read/1024) + "K";
else
io += parseInt(result.servers[i].io_read/1024/1024) + "M";
io += " / "
if(result.servers[i].io_write < 1024*1024)
io += parseInt(result.servers[i].io_write/1024) + "K";
else
io += parseInt(result.servers[i].io_write/1024/1024) + "M";
// Expand for HDD.
ExpandRow[0].children["expand_hdd"].innerHTML = "硬盘|读写: " + bytesToSize(result.servers[i].hdd_used*1024*1024, 2) + " / " + bytesToSize(result.servers[i].hdd_total*1024*1024, 2) + " | " + io;
const netstr = `${bytesToSize(server.network_rx, 1, true)} | ${bytesToSize(server.network_tx, 1, true)}`;
if (TableRow) TableRow.querySelector("#network").innerHTML = netstr;
// delay time
const trafficstr = `${bytesToSize(server.network_in, 1, true)} | ${bytesToSize(server.network_out, 1, true)}`;
if (TableRow) TableRow.querySelector("#traffic").innerHTML = trafficstr;
// tcp, udp, process, thread count
ExpandRow[0].children["expand_tupd"].innerHTML = "TCP/UDP/进/线: " + result.servers[i].tcp_count + " / " + result.servers[i].udp_count + " / " + result.servers[i].process_count+ " / " + result.servers[i].thread_count;
const cpuClass = server.cpu >= 90 ? "progress-bar bg-danger" : server.cpu >= 80 ? "progress-bar bg-warning" : "progress-bar bg-success";
if (TableRow) {
const cpuBar = TableRow.querySelector("#cpu .progress-bar");
if (cpuBar) {
cpuBar.setAttribute("class", cpuClass);
cpuBar.style.width = `${server.cpu}%`;
cpuBar.innerHTML = `${server.cpu}%`;
}
}
// ping
var PING_10010 = result.servers[i].ping_10010.toFixed(0);
var PING_189 = result.servers[i].ping_189.toFixed(0);
var PING_10086 = result.servers[i].ping_10086.toFixed(0);
const Mem = ((server.memory_used / server.memory_total) * 100).toFixed(0);
const memClass = Mem >= 90 ? "progress-bar bg-danger" : Mem >= 80 ? "progress-bar bg-warning" : "progress-bar bg-success";
if (TableRow) {
const memoryBar = TableRow.querySelector("#memory .progress-bar");
if (memoryBar) {
memoryBar.setAttribute("class", memClass);
memoryBar.style.width = `${Mem}%`;
memoryBar.innerHTML = `${Mem}%`;
}
}
if (ExpandRow) ExpandRow.querySelector("#expand_mem").innerHTML = `内存|虚存: ${bytesToSize(server.memory_used * 1024, 1)} / ${bytesToSize(server.memory_total * 1024, 1)} | ${bytesToSize(server.swap_used * 1024, 0)} / ${bytesToSize(server.swap_total * 1024, 0)}`;
// ping ms + lost rate
ExpandRow[0].children["expand_ping"].innerHTML = "CU/CT/CM: " + result.servers[i].time_10010 + "ms ("+result.servers[i].ping_10010.toFixed(0)+"%) / " + result.servers[i].time_189 + "ms ("+result.servers[i].ping_189.toFixed(0)+"%) / " + result.servers[i].time_10086 + "ms ("+result.servers[i].ping_10086.toFixed(0)+"%)"
const HDD = ((server.hdd_used / server.hdd_total) * 100).toFixed(0);
const hddClass = HDD >= 90 ? "progress-bar bg-danger" : HDD >= 80 ? "progress-bar bg-warning" : "progress-bar bg-success";
if (TableRow) {
const hddBar = TableRow.querySelector("#hdd .progress-bar");
if (hddBar) {
hddBar.setAttribute("class", hddClass);
hddBar.style.width = `${HDD}%`;
hddBar.innerHTML = `${HDD}%`;
}
}
const io = `${bytesToSize(server.io_read, 0, true)} / ${bytesToSize(server.io_write, 0, true)}`;
if (ExpandRow) ExpandRow.querySelector("#expand_hdd").innerHTML = `硬盘|读写: ${bytesToSize(server.hdd_used * 1024 * 1024, 2)} / ${bytesToSize(server.hdd_total * 1024 * 1024, 2)} | ${io}`;
if (PING_10010 >= 20 || PING_189 >= 20 || PING_10086 >= 20)
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-danger";
else if (PING_10010 >= 10 || PING_189 >= 10 || PING_10086 >= 10)
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-warning";
else
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["ping"].children[0].children[0].innerHTML = PING_10010 + "%💻" + PING_189 + "%💻" + PING_10086 + "%";
if (ExpandRow) ExpandRow.querySelector("#expand_tupd").innerHTML = `TCP/UDP/进/线: ${server.tcp_count} / ${server.udp_count} / ${server.process_count} / ${server.thread_count}`;
// monitor
MableRow.children["monitor_text"].innerHTML = result.servers[i].custom;
}
};
const PING_10010 = server.ping_10010.toFixed(0);
const PING_189 = server.ping_189.toFixed(0);
const PING_10086 = server.ping_10086.toFixed(0);
const pingClass = PING_10010 >= 20 || PING_189 >= 20 || PING_10086 >= 20 ? "progress-bar bg-danger" : PING_10010 >= 10 || PING_189 >= 10 || PING_10086 >= 10 ? "progress-bar bg-warning" : "progress-bar bg-success";
if (TableRow) {
const pingBar = TableRow.querySelector("#ping .progress-bar");
if (pingBar) {
pingBar.setAttribute("class", pingClass);
pingBar.innerHTML = `${PING_10010}%💻${PING_189}%💻${PING_10086}%`;
}
}
if (ExpandRow) ExpandRow.querySelector("#expand_ping").innerHTML = `CU/CT/CM: ${server.time_10010}ms (${PING_10010}%) / ${server.time_189}ms (${PING_189}%) / ${server.time_10086}ms (${PING_10086}%)`;
d = new Date(result.updated*1000);
error = 0;
}).fail(function(update_error) {
if (!error) {
$("#servers > tr.accordion-toggle").each(function(i) {
var TableRow = $("#servers tr#r" + i)[0];
var MableRow = $("#monitors tr#r" + i)[0];
var ExpandRow = $("#servers #rt" + i);
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>错误</small>";
MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-error";
MableRow.children["monitor_status"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["month_traffic"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["uptime"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["uptime"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["load"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["load"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["network"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["network"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["traffic"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["traffic"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["cpu"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["cpu"].children[0].children[0].style.width = "100%";
TableRow.children["cpu"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["memory"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["memory"].children[0].children[0].style.width = "100%";
TableRow.children["memory"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["hdd"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["hdd"].children[0].children[0].style.width = "100%";
TableRow.children["hdd"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["ping"].children[0].children[0].style.width = "100%";
TableRow.children["ping"].children[0].children[0].innerHTML = "<small>错误</small>";
MableRow.children["monitor_text"].children[0].children[0].className = "progress-bar progress-bar-error";
MableRow.children["monitor_text"].children[0].children[0].innerHTML = "<small>错误</small>";
if(ExpandRow.hasClass("in")) {
ExpandRow.collapse("hide");
}
TableRow.setAttribute("data-target", "");
MableRow.setAttribute("data-target", "");
server_status[i] = false;
});
}
error = 1;
$("#updated").html("更新错误.");
});
if (MableRow) MableRow.querySelector("#monitor_text").innerHTML = server.custom;
}
});
d = new Date(result.updated * 1000);
error = 0;
})
.catch(error => {
console.error("Fetch error: ", error);
if (!error) {
document.querySelectorAll("#servers > tr.accordion-toggle").forEach((TableRow, i) => {
const MableRow = document.querySelector(`#monitors tr#r${i}`);
const ExpandRow = document.querySelector(`#servers #rt${i}`);
if (TableRow && MableRow) {
TableRow.querySelectorAll(".progress-bar").forEach(bar => {
if (bar) {
bar.setAttribute("class", "progress-bar bg-danger");
bar.innerHTML = "<small>错误</small>";
}
});
MableRow.querySelectorAll(".progress-bar").forEach(bar => {
if (bar) {
bar.setAttribute("class", "progress-bar bg-danger");
bar.innerHTML = "<small>错误</small>";
}
});
if (ExpandRow && ExpandRow.classList.contains("show")) {
ExpandRow.classList.remove("show");
}
TableRow.setAttribute("data-bs-target", "");
MableRow.setAttribute("data-bs-target", "");
server_status[i] = false;
} else {
console.error(`TableRow or MableRow is undefined for index ${i}`);
}
});
}
error = 1;
document.getElementById("updated").innerHTML = "更新错误.";
});
}
function updateTime() {
if (!error)
$("#updated").html("最后更新: " + timeSince(d));
if (!error) document.getElementById("updated").innerHTML = "最后更新: " + timeSince(d);
}
uptime();
updateTime();
// 降低改值可以减少cpu占用
setInterval(uptime, 2000);
setInterval(updateTime, 2000);
// styleswitcher.js
function setActiveStyleSheet(title, cookie=false) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
if (true==cookie) {
createCookie("style", title, 365);
function setActiveStyleSheet(title) {
var i, a, main;
for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
if (a.getAttribute("rel").indexOf("stylesheet") != -1 && a.getAttribute("title")) {
a.disabled = true;
if (a.getAttribute("title") == title) a.disabled = false;
}
}
}
function getActiveStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled)
return a.getAttribute("title");
}
return null;
return Array.from(document.getElementsByTagName("link")).find(a => a.getAttribute("rel").includes("style") && a.getAttribute("title") && !a.disabled)?.getAttribute("title") || null;
}
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else expires = "";
document.cookie = name+"="+value+expires+"; path=/";
function createCookie(name, value, days) {
const expires = days ? `; expires=${new Date(Date.now() + days * 24 * 60 * 60 * 1000).toGMTString()}` : "";
document.cookie = `${name}=${value}${expires}; path=/`;
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ')
c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0)
return c.substring(nameEQ.length,c.length);
}
return null;
const nameEQ = name + "=";
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
window.onload = function(e) {
var cookie = readCookie("style");
if (cookie && cookie != 'null' ) {
setActiveStyleSheet(cookie);
} else {
function handleChange (mediaQueryListEvent) {
if (mediaQueryListEvent.matches) {
setActiveStyleSheet('dark');
} else {
setActiveStyleSheet('light');
}
}
const mediaQueryListDark = window.matchMedia('(prefers-color-scheme: dark)');
setActiveStyleSheet(mediaQueryListDark.matches ? 'dark' : 'light');
mediaQueryListDark.addEventListener("change",handleChange);
}
}
window.onload = function() {
const cookie = readCookie("style");
if (cookie && cookie != 'null') {
setActiveStyleSheet(cookie);
} else {
const handleChange = mediaQueryListEvent => setActiveStyleSheet(mediaQueryListEvent.matches ? 'dark' : 'light');
const mediaQueryListDark = window.matchMedia('(prefers-color-scheme: dark)');
setActiveStyleSheet(mediaQueryListDark.matches ? 'dark' : 'light');
mediaQueryListDark.addEventListener("change", handleChange);
}
// 处理标签页切换
const tabs = document.querySelectorAll('.nav-link');
tabs.forEach(tab => {
tab.addEventListener('click', function(event) {
if (this.id === 'navbarDropdown') {
return; // 阻止“风格”标签的默认行为
}
event.preventDefault();
const target = this.getAttribute('href');
document.querySelectorAll('.tab-pane').forEach(pane => pane.classList.remove('show', 'active'));
document.querySelector(target).classList.add('show', 'active');
tabs.forEach(t => t.classList.remove('active'));
this.classList.add('active');
});
});
}