From 311d11a3c1d0238816924d195fbb72372082ad9a Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Fri, 12 Sep 2025 13:04:36 +0200 Subject: [PATCH 01/44] cookie: MaxAge and minor changes --- web/session/session.go | 3 +++ web/web.go | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/web/session/session.go b/web/session/session.go index 13aedad8..c793c713 100644 --- a/web/session/session.go +++ b/web/session/session.go @@ -2,6 +2,7 @@ package session import ( "encoding/gob" + "net/http" "x-ui/database/model" @@ -32,6 +33,7 @@ func SetMaxAge(c *gin.Context, maxAge int) { Path: defaultPath, MaxAge: maxAge, HttpOnly: true, + SameSite: http.SameSiteLaxMode, }) } @@ -61,5 +63,6 @@ func ClearSession(c *gin.Context) { Path: defaultPath, MaxAge: -1, HttpOnly: true, + SameSite: http.SameSiteLaxMode, }) } diff --git a/web/web.go b/web/web.go index 38eb24d6..35255104 100644 --- a/web/web.go +++ b/web/web.go @@ -31,7 +31,7 @@ import ( "github.com/robfig/cron/v3" ) -//go:embed assets/* +//go:embed assets var assetsFS embed.FS //go:embed html/* @@ -180,6 +180,15 @@ func (s *Server) initRouter() (*gin.Engine, error) { assetsBasePath := basePath + "assets/" store := cookie.NewStore(secret) + // Configure default session cookie options, including expiration (MaxAge) + if sessionMaxAge, err := s.settingService.GetSessionMaxAge(); err == nil { + store.Options(sessions.Options{ + Path: "/", + MaxAge: sessionMaxAge * 60, // minutes -> seconds + HttpOnly: true, + SameSite: http.SameSiteLaxMode, + }) + } engine.Use(sessions.Sessions("3x-ui", store)) engine.Use(func(c *gin.Context) { c.Set("base_path", basePath) @@ -201,7 +210,11 @@ func (s *Server) initRouter() (*gin.Engine, error) { i18nWebFunc := func(key string, params ...string) string { return locale.I18n(locale.Web, key, params...) } - engine.FuncMap["i18n"] = i18nWebFunc + // Register template functions before loading templates + funcMap := template.FuncMap{ + "i18n": i18nWebFunc, + } + engine.SetFuncMap(funcMap) engine.Use(locale.LocalizerMiddleware()) // set static files and template @@ -211,11 +224,12 @@ func (s *Server) initRouter() (*gin.Engine, error) { if err != nil { return nil, err } + // Use the registered func map with the loaded templates engine.LoadHTMLFiles(files...) engine.StaticFS(basePath+"assets", http.FS(os.DirFS("web/assets"))) } else { // for production - template, err := s.getHtmlTemplate(engine.FuncMap) + template, err := s.getHtmlTemplate(funcMap) if err != nil { return nil, err } From 5ee62b25ca9a3bf0ce683adbba5b1b64ddea074e Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Fri, 12 Sep 2025 18:46:20 +0200 Subject: [PATCH 02/44] clean html files move styles to css --- web/assets/css/custom.min.css | 2 +- web/html/inbounds.html | 144 +---------- web/html/index.html | 137 +++------- web/html/login.html | 469 +--------------------------------- web/html/settings.html | 61 +---- web/html/xray.html | 37 +-- 6 files changed, 47 insertions(+), 803 deletions(-) diff --git a/web/assets/css/custom.min.css b/web/assets/css/custom.min.css index 87dba544..0eb2b409 100644 --- a/web/assets/css/custom.min.css +++ b/web/assets/css/custom.min.css @@ -1 +1 @@ -:root{--color-primary-100:#008771;--dark-color-background:#0a1222;--dark-color-surface-100:#151f31;--dark-color-surface-200:#222d42;--dark-color-surface-300:#2c3950;--dark-color-surface-400:rgba(65, 85, 119, 0.5);--dark-color-surface-500:#2c3950;--dark-color-surface-600:#313f5a;--dark-color-surface-700:#111929;--dark-color-surface-700-rgb:17, 25, 41;--dark-color-table-hover:rgba(44, 57, 80, 0.2);--dark-color-text-primary:rgba(255, 255, 255, 0.75);--dark-color-stroke:#2c3950;--dark-color-btn-danger:#cd3838;--dark-color-btn-danger-border:transparent;--dark-color-btn-danger-hover:#e94b4b;--dark-color-tag-bg:rgba(255, 255, 255, 0.05);--dark-color-tag-border:rgba(255, 255, 255, 0.15);--dark-color-tag-color:rgba(255, 255, 255, 0.75);--dark-color-tag-green-bg:17, 36, 33;--dark-color-tag-green-border:25, 81, 65;--dark-color-tag-green-color:#3ad3ba;--dark-color-tag-purple-bg:#201425;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d988cd;--dark-color-tag-red-bg:#291515;--dark-color-tag-red-border:#5c2626;--dark-color-tag-red-color:#e04141;--dark-color-tag-orange-bg:#312313;--dark-color-tag-orange-border:#593914;--dark-color-tag-orange-color:#ffa031;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#1348ab;--dark-color-tag-blue-color:#529fff;--dark-color-codemirror-line-hover:rgba(0, 135, 113, 0.2);--dark-color-codemirror-line-selection:rgba(0, 135, 113, 0.3);--dark-color-login-background:var(--dark-color-background);--dark-color-login-wave:var(--dark-color-surface-200);--dark-color-tooltip:rgba(61, 76, 104, 0.9);--dark-color-back-top:rgba(61, 76, 104, 0.9);--dark-color-back-top-hover:rgba(61, 76, 104, 1);--dark-color-scrollbar:#313f5a;--dark-color-scrollbar-webkit:#7484a0;--dark-color-scrollbar-webkit-hover:#90a4c7;--dark-color-table-ring:rgb(38 52 77);--dark-color-spin-container:#151f31}html[data-theme-animations='off']{.ant-menu,.ant-layout-sider,.ant-card,.ant-tag,.ant-progress-circle>*,.ant-input,.ant-table-row-expand-icon,.ant-switch,.ant-table-thead>tr>th,.ant-select-selection,.ant-btn,.ant-input-number,.ant-input-group-addon,.ant-checkbox-inner,.ant-progress-bg,.ant-progress-success-bg,.ant-radio-button-wrapper:not(:first-child):before,.ant-radio-button-wrapper,#login,.cm-s-xq.CodeMirror{transition:border 0s,background 0s!important}.ant-menu.ant-menu-inline .ant-menu-item:not(.ant-menu-sub .ant-menu-item),.ant-layout-sider-trigger,.ant-alert-close-icon .anticon-close,.ant-tabs-nav .ant-tabs-tab,.ant-input-number-input,.ant-collapse>.ant-collapse-item>.ant-collapse-header,.Line-Hover,.ant-menu-theme-switch,.ant-menu-submenu-title{transition:color 0s!important}.wave-btn-bg{transition:width 0s!important}}html[data-theme='ultra-dark']{--dark-color-background:#21242a;--dark-color-surface-100:#0c0e12;--dark-color-surface-200:#222327;--dark-color-surface-300:#32353b;--dark-color-surface-400:rgba(255, 255, 255, 0.1);--dark-color-surface-500:#3b404b;--dark-color-surface-600:#505663;--dark-color-surface-700:#101113;--dark-color-surface-700-rgb:16, 17, 19;--dark-color-table-hover:rgba(89, 89, 89, 0.15);--dark-color-text-primary:rgb(255 255 255 / 85%);--dark-color-stroke:#202025;--dark-color-tag-green-bg:17, 36, 33;--dark-color-tag-green-border:29, 95, 77;--dark-color-tag-green-color:#59cbac;--dark-color-tag-purple-bg:#241121;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d686ca;--dark-color-tag-red-bg:#2a1215;--dark-color-tag-red-border:#58181c;--dark-color-tag-red-color:#e84749;--dark-color-tag-orange-bg:#2b1d11;--dark-color-tag-orange-border:#593815;--dark-color-tag-orange-color:#e89a3c;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#0f367e;--dark-color-tag-blue-color:#3c89e8;--dark-color-codemirror-line-hover:rgba(82, 84, 94, 0.2);--dark-color-codemirror-line-selection:rgba(82, 84, 94, 0.3);--dark-color-login-background:#0a2227;--dark-color-login-wave:#0f2d32;--dark-color-tooltip:rgba(88, 93, 100, 0.9);--dark-color-back-top:rgba(88, 93, 100, 0.9);--dark-color-back-top-hover:rgba(88, 93, 100, 1);--dark-color-scrollbar:rgb(107,107,107);--dark-color-scrollbar-webkit:#9f9f9f;--dark-color-scrollbar-webkit-hover:#d1d1d1;--dark-color-table-ring:rgb(37 39 42);--dark-color-spin-container:#1d1d1d;.ant-dropdown-menu-dark{background-color:var(--dark-color-surface-500)}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.dark .waves-header{background-color:#0a2227}.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-600)}}html,body{height:100vh;width:100vw;margin:0;padding:0;overflow:hidden}body{color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;background-color:#fff;font-feature-settings:"tnum"}html{--antd-wave-shadow-color:var(--color-primary-100);line-height:1.15;text-size-adjust:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-moz-tap-highlight-color:#fff0;-webkit-tap-highlight-color:#fff0}@supports (scrollbar-width:auto) and (not selector(::-webkit-scrollbar)){:not(.dark){scrollbar-color:#9a9a9a #fff0;scrollbar-width:thin}.dark *{scrollbar-color:var(--dark-color-scrollbar) #fff0;scrollbar-width:thin}}::-webkit-scrollbar{width:10px;height:10px;background-color:#fff0}::-webkit-scrollbar-track{background-color:#fff0;margin-block:.5em}.ant-modal-wrap::-webkit-scrollbar-track{background-color:#fff;margin-block:0}::-webkit-scrollbar-thumb{border-radius:9999px;background-color:#9a9a9a;border:2px solid #fff0;background-clip:content-box}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background-color:#828282}.dark .ant-modal-wrap::-webkit-scrollbar-track{background-color:var(--dark-color-background)}.dark ::-webkit-scrollbar-thumb{background-color:var(--dark-color-scrollbar-webkit)}.dark ::-webkit-scrollbar-thumb:hover,.dark ::-webkit-scrollbar-thumb:active{background-color:var(--dark-color-scrollbar-webkit-hover)}::-moz-selection{color:var(--color-primary-100);background-color:#cfe8e4}::selection{color:var(--color-primary-100);background-color:#cfe8e4}#app{height:100%;position:fixed;top:0;left:0;right:0;bottom:0;margin:0;padding:0;overflow:auto}.ant-layout,.ant-layout *{box-sizing:border-box}.ant-spin-container:after{border-radius:1.5rem}.dark .ant-spin-container:after{background:var(--dark-color-spin-container)}style attribute{text-align:center}.ant-table-thead>tr>th{padding:12px 8px}.ant-table-tbody>tr>td{padding:10px 8px}.ant-table-thead>tr>th{color:rgb(0 0 0 / .85);font-weight:500;text-align:left;border-bottom:1px solid #e8e8e8;transition:background 0.3s ease}.ant-table table{border-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:first-child{border-bottom-left-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:last-child{border-bottom-right-radius:1rem}.ant-table{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;font-feature-settings:"tnum";position:relative;clear:both}.ant-table .ant-table-body:not(.ant-table-expanded-row .ant-table-body){overflow-x:auto!important}.ant-card-hoverable{cursor:auto;cursor:pointer}.ant-card{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;position:relative;background-color:#fff;border-radius:2px;transition:all 0.3s}.ant-space{width:100%}.ant-layout-sider-zero-width-trigger{display:none}@media (max-width:768px){.ant-layout-sider{display:none}.ant-card,.ant-alert-error{margin:.5rem}.ant-tabs{margin:.5rem;padding:.5rem}.ant-modal-body{padding:20px}.ant-form-item-label{line-height:1.5;padding:8px 0 0}:not(.dark) ::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}.dark ::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}}.ant-layout-content{min-height:auto}.ant-card,.ant-tabs{border-radius:1.5rem}.ant-card-hoverable{cursor:auto}.ant-card+.ant-card{margin-top:20px}.drawer-handle{position:absolute;top:72px;width:41px;height:40px;cursor:pointer;z-index:0;text-align:center;line-height:40px;font-size:16px;display:flex;justify-content:center;align-items:center;background-color:#fff;right:-40px;box-shadow:2px 0 8px rgb(0 0 0 / .15);border-radius:0 4px 4px 0}.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{background-color:#006655!important;background-image:linear-gradient(270deg,#fff0 30%,#009980,#fff0 100%);background-repeat:no-repeat;animation:ma-bg-move linear 6.6s infinite;color:#fff;border-radius:.5rem}.ant-layout-sider-collapsed .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{border-radius:0}@-webkit-keyframes ma-bg-move{0%{background-position:-500px 0}100%{background-position:1000px 0}}@keyframes ma-bg-move{0%{background-position:-500px 0}50%{background-position:1000px 0}100%{background-position:1000px 0}}.ant-menu-item-active,.ant-menu-item:hover,.ant-menu-submenu-title:hover,.ant-menu-item:active,.ant-menu-submenu-title:active{color:var(--color-primary-100);background-color:#e8f4f2}.ant-menu-inline .ant-menu-item,.ant-menu-inline .ant-menu-submenu-title{border-radius:.5rem}.ant-menu-inline .ant-menu-item:after,.ant-menu{border-right-width:0}.ant-layout-sider-children,.ant-pagination ul{padding:.5rem}.ant-layout-sider-collapsed .ant-layout-sider-children{padding:.5rem 0}.ant-dropdown-menu,.ant-select-dropdown-menu{padding:.5rem}.ant-dropdown-menu-item,.ant-dropdown-menu-item:hover,.ant-select-dropdown-menu-item,.ant-select-dropdown-menu-item:hover,.ant-select-selection--multiple .ant-select-selection__choice{border-radius:.5rem}.ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item,.ant-select-dropdown--single .ant-select-dropdown-menu .ant-select-dropdown-menu-item-selected{margin-block:2px}@media (min-width:769px){.drawer-handle{display:none}.ant-tabs{padding:2rem}}.fade-in-enter,.fade-in-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.fade-in-enter-active,.fade-in-leave-active{-webkit-transition:all 0.3s cubic-bezier(.55,0,.1,1);transition:all 0.3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter-active,.zoom-in-center-leave-active{-webkit-transition:all 0.3s cubic-bezier(.55,0,.1,1);transition:all 0.3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter,.zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.zoom-in-top-enter-active,.zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.zoom-in-top-enter,.zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-bottom-enter-active,.zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.zoom-in-bottom-enter,.zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-left-enter-active,.zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.zoom-in-left-enter,.zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.list-enter-active,.list-leave-active{-webkit-transition:all 0.3s;transition:all 0.3s}.list-enter,.list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.ant-tooltip-inner{min-height:0;padding-inline:1rem}.ant-list-item-meta-title{font-size:14px}.ant-progress-inner{background-color:#ebeef5}.deactive-client .ant-collapse-header{color:#ffffff!important;background-color:#ff7f7f}.ant-table-expand-icon-th,.ant-table-row-expand-icon-cell{width:30px;min-width:30px}.ant-tabs{background-color:#fff}.ant-form-item{margin-bottom:0}.ant-setting-textarea{margin-top:1.5rem}.client-table-header{background-color:#f0f2f5}.client-table-odd-row{background-color:#fafafa}.ant-table-pagination.ant-pagination{float:left}.ant-tag{margin-right:0;margin-inline:2px;display:inline-flex;align-items:center;justify-content:space-evenly}.ant-tag:not(.qr-tag){column-gap:4px}#inbound-info-modal .ant-tag{margin-block:2px}.tr-info-table{display:inline-table;margin-block:10px;width:100%}#inbound-info-modal .tr-info-table .ant-tag{margin-block:0;margin-inline:0}.tr-info-row{display:flex;flex-direction:column;row-gap:2px;margin-block:10px}.tr-info-row a{margin-left:6px}.tr-info-row code{padding-inline:8px}.tr-info-tag{max-width:100%;text-wrap:balance;overflow:hidden;overflow-wrap:anywhere}.tr-info-title{display:inline-flex;align-items:center;justify-content:flex-start;column-gap:4px}.ant-tag-blue{background-color:#edf4fa;border-color:#a9c5e7;color:#0e49b5}.ant-tag-green{background-color:#eafff9;border-color:#76ccb4;color:#199270}.ant-tag-purple{background-color:#f2eaf1;border-color:#d5bed2;color:#7a316f}.ant-tag-orange,.ant-alert-warning{background-color:#ffeee1;border-color:#fec093;color:#f37b24}.ant-tag-red,.ant-alert-error{background-color:#ffe9e9;border-color:#ff9e9e;color:#cf3c3c}.ant-input::placeholder{opacity:.5}.ant-input:hover,.ant-input:focus{background-color:#e8f4f2}.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){background-color:#e8f4f2}.delete-icon:hover{color:#e04141}.normal-icon:hover{color:var(--color-primary-100)}.dark ::-moz-selection{color:#fff;background-color:var(--color-primary-100)}.dark ::selection{color:#fff;background-color:var(--color-primary-100)}.dark .normal-icon:hover{color:#fff}.dark .ant-layout-sider,.dark .ant-drawer-content,.ant-menu-dark,.ant-menu-dark .ant-menu-sub,.dark .ant-card,.dark .ant-table,.dark .ant-collapse-content,.dark .ant-tabs{background-color:var(--dark-color-surface-100);color:var(--dark-color-text-primary)}.dark .ant-card-hoverable:hover,.dark .ant-space-item>.ant-tabs:hover{box-shadow:0 2px 8px #fff0}.dark>.ant-layout,.dark .drawer-handle,.dark .ant-table-thead>tr>th,.dark .ant-table-expanded-row,.dark .ant-table-expanded-row:hover,.dark .ant-table-expanded-row .ant-table-tbody,.dark .ant-calendar{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-table-expanded-row .ant-table-thead>tr:first-child>th{border-radius:0}.dark .ant-calendar,.dark .ant-card-bordered{border-color:var(--dark-color-background)}.dark .ant-table-bordered,.dark .ant-table-bordered.ant-table-empty .ant-table-placeholder,.dark .ant-table-bordered .ant-table-body>table,.dark .ant-table-bordered .ant-table-fixed-left table,.dark .ant-table-bordered .ant-table-fixed-right table,.dark .ant-table-bordered .ant-table-header>table,.dark .ant-table-bordered .ant-table-thead>tr:not(:last-child)>th,.dark .ant-table-bordered .ant-table-tbody>tr>td,.dark .ant-table-bordered .ant-table-thead>tr>th{border-color:var(--dark-color-surface-400)}.dark .ant-table-tbody>tr>td,.dark .ant-table-thead>tr>th,.dark .ant-card-head,.dark .ant-modal-header,.dark .ant-collapse>.ant-collapse-item,.dark .ant-tabs-bar,.dark .ant-list-split .ant-list-item,.dark .ant-popover-title,.dark .ant-calendar-header,.dark .ant-calendar-input-wrap{border-bottom-color:var(--dark-color-surface-400)}.dark .ant-modal-footer,.dark .ant-collapse-content,.dark .ant-calendar-footer,.dark .ant-divider-horizontal.ant-divider-with-text-left:before,.dark .ant-divider-horizontal.ant-divider-with-text-left:after,.dark .ant-divider-horizontal.ant-divider-with-text-center:before,.dark .ant-divider-horizontal.ant-divider-with-text-center:after{border-top-color:var(--dark-color-surface-300)}.ant-divider-horizontal.ant-divider-with-text-left:before{width:10%}.dark .ant-progress-text,.dark .ant-card-head,.dark .ant-form,.dark .ant-collapse>.ant-collapse-item>.ant-collapse-header,.dark .ant-modal-close-x,.dark .ant-form .anticon,.dark .ant-tabs-tab-arrow-show:not(.ant-tabs-tab-btn-disabled),.dark .anticon-close,.dark .ant-list-item-meta-title,.dark .ant-select-selection i,.dark .ant-modal-confirm-title,.dark .ant-modal-confirm-content,.dark .ant-popover-message,.dark .ant-modal,.dark .ant-divider-inner-text,.dark .ant-popover-title,.dark .ant-popover-inner-content,.dark h2,.dark .ant-modal-title,.dark .ant-form-item-label>label,.dark .ant-checkbox-wrapper,.dark .ant-form-item,.dark .ant-calendar-footer .ant-calendar-today-btn,.dark .ant-calendar-footer .ant-calendar-time-picker-btn,.dark .ant-calendar-day-select,.dark .ant-calendar-month-select,.dark .ant-calendar-year-select,.dark .ant-calendar-date,.dark .ant-calendar-year-panel-year,.dark .ant-calendar-month-panel-month,.dark .ant-calendar-decade-panel-decade{color:var(--dark-color-text-primary)}.dark .ant-pagination-options-size-changer .ant-select-arrow .anticon.anticon-down.ant-select-arrow-icon{color:rgb(255 255 255 / 35%)}.dark .ant-pagination-item a,.dark .ant-pagination-next a,.dark .ant-pagination-prev a{color:var(--dark-color-text-primary)}.dark .ant-pagination-item:focus a,.dark .ant-pagination-item:hover a,.dark .ant-pagination-item-active a,.dark .ant-pagination-next:hover .ant-pagination-item-link{color:var(--color-primary-100)}.dark .ant-pagination-item-active{background-color:#fff0}.dark .ant-list-item-meta-description{color:rgb(255 255 255 / .45)}.dark .ant-pagination-disabled i,.dark .ant-tabs-tab-btn-disabled{color:rgb(255 255 255 / .25)}.dark .ant-input,.dark .ant-input-group-addon,.dark .ant-collapse,.dark .ant-select-selection,.dark .ant-input-number,.dark .ant-input-number-handler-wrap,.dark .ant-table-placeholder,.dark .ant-empty-normal,.dark .ant-select-dropdown,.dark .ant-select-dropdown li,.dark .ant-select-dropdown-menu-item,.dark .client-table-header,.dark .ant-select-selection--multiple .ant-select-selection__choice{background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.dark .ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected :not(.ant-dropdown-menu-submenu-title:hover){background-color:var(--dark-color-surface-300)}.dark .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected{background-color:var(--dark-color-surface-300)}.dark .ant-calendar-time-picker-inner{background-color:var(--dark-color-background)}.dark .ant-select-selection:hover,.dark .ant-calendar-picker-clear,.dark .ant-input-number:hover,.dark .ant-input-number:focus,.dark .ant-input:hover,.dark .ant-input:focus{background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.dark .ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){border-color:var(--color-primary-100);background-color:rgb(0 135 113 / .3)}.dark .ant-btn:not(.ant-btn-primary):not(.ant-btn-danger){color:var(--dark-color-text-primary);background-color:rgb(10 117 87 / 30%);border:1px solid var(--color-primary-100)}.dark .ant-radio-button-wrapper,.dark .ant-radio-button-wrapper:before{color:var(--dark-color-text-primary);background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){background-color:#e8f4f2}.dark .ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.dark .ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){color:#fff;background-color:rgb(10 117 87 / 50%);border-color:var(--color-primary-100)}.dark .ant-btn-primary[disabled],.dark .ant-btn-danger[disabled],.dark .ant-calendar-ok-btn-disabled{color:rgb(255 255 255 / 35%);background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300)}.dark .ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.dark .client-table-odd-row{background-color:var(--dark-color-table-hover)}.dark .ant-table-row-expand-icon{color:#fff;background-color:#fff0;border-color:rgb(255 255 255 / 20%)}.dark .ant-table-row-expand-icon:hover{color:var(--color-primary-100);background-color:#fff0;border-color:var(--color-primary-100)}.dark .ant-switch:not(.ant-switch-checked),.dark .ant-progress-line .ant-progress-inner{background-color:var(--dark-color-surface-500)}.dark .ant-progress-circle-trail{stroke:var(--dark-color-stroke)!important}.dark .ant-popover-inner{background-color:var(--dark-color-surface-500)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-500)}@media (max-width:768px){.dark .ant-popover-inner{background-color:var(--dark-color-surface-200)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-200)}}.ant-dropdown-menu-dark .ant-dropdown-menu-item:hover,.dark .ant-select-dropdown-menu-item-selected,.dark .ant-calendar-time-picker-select-option-selected{background-color:var(--dark-color-surface-600)}.ant-menu-dark .ant-menu-item:hover,.ant-menu-dark .ant-menu-submenu-title:hover{background-color:var(--dark-color-surface-300)}.dark .ant-menu-item:active,.dark .ant-menu-submenu-title:active{color:#fff;background-color:var(--dark-color-surface-300)}.dark .ant-alert-message{color:rgb(255 255 255 / .85)}.dark .ant-tag{color:var(--dark-color-tag-color);background-color:var(--dark-color-tag-bg);border-color:var(--dark-color-tag-border)}.dark .ant-tag-blue{background-color:var(--dark-color-tag-blue-bg);border-color:var(--dark-color-tag-blue-border);color:var(--dark-color-tag-blue-color)}.dark .ant-tag-red,.dark .ant-alert-error{background-color:var(--dark-color-tag-red-bg);border-color:var(--dark-color-tag-red-border);color:var(--dark-color-tag-red-color)}.dark .ant-tag-orange,.dark .ant-alert-warning{background-color:var(--dark-color-tag-orange-bg);border-color:var(--dark-color-tag-orange-border);color:var(--dark-color-tag-orange-color)}.dark .ant-tag-green{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border));color:var(--dark-color-tag-green-color)}.dark .ant-tag-purple{background-color:var(--dark-color-tag-purple-bg);border-color:var(--dark-color-tag-purple-border);color:var(--dark-color-tag-purple-color)}.dark .ant-modal-content,.dark .ant-modal-header{background-color:var(--dark-color-surface-700)}.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date{color:var(--dark-color-surface-300)}.dark .ant-calendar-selected-day .ant-calendar-date{background-color:var(--color-primary-100)!important;color:#fff}.dark .ant-calendar-date:hover,.dark .ant-calendar-time-picker-select li:hover{background-color:var(--dark-color-surface-600);color:#fff}.dark .ant-calendar-header a:hover,.dark .ant-calendar-header a:hover::before,.dark .ant-calendar-header a:hover::after{border-color:#fff}.dark .ant-calendar-time-picker-select{border-right-color:var(--dark-color-surface-300)}.has-warning .ant-select-selection,.has-warning .ant-select-selection:hover,.has-warning .ant-input,.has-warning .ant-input:hover{background-color:#ffeee1;border-color:#fec093}.has-warning .ant-input::placeholder{color:#f37b24}.has-warning .ant-input:not([disabled]):hover{border-color:#fec093}.dark .has-warning .ant-select-selection,.dark .has-warning .ant-select-selection:hover,.dark .has-warning .ant-input,.dark .has-warning .ant-input:hover{border-color:#784e1d;background:#312313}.dark .has-warning .ant-input::placeholder{color:rgb(255 160 49 / 70%)}.dark .has-warning .anticon{color:#ffa031}.dark .has-success .anticon{color:var(--color-primary-100);animation-name:diffZoomIn1!important}.dark .anticon-close-circle{color:#e04141}.dark .ant-spin-nested-loading>div>.ant-spin .ant-spin-text{text-shadow:0 1px 2px #0007}.dark .ant-spin{color:#fff}.dark .ant-spin-dot-item{background-color:#fff}.ant-checkbox-wrapper,.ant-input-group-addon,.ant-tabs-tab,.ant-input::placeholder,.ant-collapse-header,.ant-menu,.ant-radio-button-wrapper{-webkit-user-select:none;user-select:none}.ant-calendar-date,.ant-calendar-year-panel-year,.ant-calendar-decade-panel-decade,.ant-calendar-month-panel-month{border-radius:4px}.ant-checkbox-inner,.ant-checkbox-checked:after,.ant-table-row-expand-icon{border-radius:6px}.ant-calendar-date:hover{background-color:#e8f4f2}.ant-calendar-date:active{background-color:#e8f4f2;color:rgb(0 0 0 / .65)}.ant-calendar-today .ant-calendar-date{color:var(--color-primary-100);font-weight:400;border-color:var(--color-primary-100)}.dark .ant-calendar-today .ant-calendar-date{color:#fff;border-color:var(--color-primary-100)}.ant-calendar-selected-day .ant-calendar-date{background:var(--color-primary-100);color:#fff}li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(0 0 0 / .25)}.dark li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(255 255 255 / .3)}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:rgb(0 0 0 / .87)}.dark.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:#fff}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected .ant-select-selected-icon,.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected:hover .ant-select-selected-icon{color:var(--color-primary-100)}.ant-select-selection:hover,.ant-input-number-focused,.ant-input-number:hover{background-color:#e8f4f2}.dark .ant-input-number-handler:active{background-color:var(--color-primary-100)}.dark .ant-input-number-handler:hover .ant-input-number-handler-down-inner,.dark .ant-input-number-handler:hover .ant-input-number-handler-up-inner{color:#fff}.dark .ant-input-number-handler-down{border-top:1px solid rgb(217 217 217 / .3)}.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-century-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-decade-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-month-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-year-select .dark .ant-calendar-month-panel-header .ant-calendar-month-panel-century-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-decade-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-month-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-year-select{color:rgb(255 255 255 / .85)}.dark .ant-calendar-year-panel-header{border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel-last-decade-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-next-decade-cell .ant-calendar-year-panel-year{color:rgb(255 255 255 / .35)}.dark .ant-divider:not(.ant-divider-with-text-center,.ant-divider-with-text-left,.ant-divider-with-text-right),.ant-dropdown-menu-dark,.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-200)}.dark .ant-calendar-header a:hover{color:#fff}.dark .ant-calendar-month-panel-header{background-color:var(--dark-color-background);border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel,.dark .ant-calendar table{background-color:var(--dark-color-background)}.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade:hover{color:#fff;background-color:var(--color-primary-100)!important}.dark .ant-calendar-last-month-cell .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date:hover,.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-next-month-btn-day .ant-calendar-date:hover{color:rgb(255 255 255 / 25%);background:#fff0;border-color:#fff0}.dark .ant-calendar-today .ant-calendar-date:hover{color:#fff;border-color:var(--color-primary-100);background-color:var(--color-primary-100)}.dark .ant-calendar-decade-panel-last-century-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-next-century-cell .ant-calendar-decade-panel-decade{color:rgb(255 255 255 / 25%)}.dark .ant-calendar-decade-panel-header{border-bottom:1px solid var(--dark-color-surface-200);background-color:var(--dark-color-background)}.dark .ant-checkbox-inner{background-color:rgb(0 135 113 / .3);border-color:rgb(0 135 113 / .3)}.dark .ant-checkbox-checked .ant-checkbox-inner{background-color:var(--color-primary-100);border-color:var(--color-primary-100)}.dark .ant-calendar-input{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-calendar-input::placeholder{color:rgb(255 255 255 / .25)}.ant-input-group.ant-input-group-compact-addon:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact-wrap:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact>.ant-input:not(:first-child):not(:last-child),.ant-input-number-handler,.ant-input-number-handler-wrap{border-radius:0}.ant-input-number{overflow:clip}.ant-modal-body,.ant-collapse-content>.ant-collapse-content-box{overflow-x:auto}.ant-modal-body{overflow-y:hidden}.ant-calendar-year-panel-year:hover,.ant-calendar-decade-panel-decade:hover,.ant-calendar-month-panel-month:hover,.ant-dropdown-menu-item:hover,.ant-dropdown-menu-submenu-title:hover,.ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled),.ant-table-tbody>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td{background-color:#e8f4f2}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.ant-select-dropdown,.ant-popover-inner{overflow-x:hidden}.ant-popover-inner-content{max-height:450px;overflow-y:auto}@media (max-height:900px){.ant-popover-inner-content{max-height:400px}}@media (max-height:768px){.ant-popover-inner-content{max-height:300px}}@media (max-width:768px){.ant-popover-inner-content{max-height:300px}}.qr-modal{display:flex;align-items:flex-end;gap:10px;flex-direction:column;flex-wrap:wrap;row-gap:24px}.qr-box{width:220px}.qr-cv{width:100%;height:100%}.dark .qr-cv{filter:invert(1)}.qr-bg{background-color:#fff;display:flex;justify-content:center;align-content:center;padding:.8rem;border-radius:1rem;border:solid 1px #e8e8e8;height:220px;width:220px;transition:all 0.1s}.qr-bg:hover{border-color:#76ccb4;background-color:#eafff9}.qr-bg:hover:active{border-color:#76ccb4;background-color:rgb(197 241 228 / 70%)}.dark .qr-bg{background-color:var(--dark-color-surface-700);border-color:var(--dark-color-surface-300)}.dark .qr-bg:hover{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border))}.dark .qr-bg:hover:active{background-color:#17322e}@property --tr-rotate{syntax:'';initial-value:45deg;inherits:false}.qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#76ccb4,transparent,#d5bed2);display:flex;justify-content:center;align-content:center;padding:1px;border-radius:1rem;height:220px;width:220px}.dark .qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#195141,transparent,#5a2969)}.qr-bg-sub:hover{animation:tr-rotate-gradient 3.5s linear infinite}@keyframes tr-rotate-gradient{from{--tr-rotate:45deg}to{--tr-rotate:405deg}}.qr-bg-sub-inner{background-color:#fff;padding:.8rem;border-radius:1rem;transition:all 0.1s}.qr-bg-sub-inner:hover{background-color:rgb(255 255 255 / 60%);backdrop-filter:blur(25px)}.qr-bg-sub-inner:hover:active{background-color:rgb(255 255 255 / 30%)}.dark .qr-bg-sub-inner{background-color:rgb(var(--dark-color-surface-700-rgb))}.dark .qr-bg-sub-inner:hover{background-color:rgba(var(--dark-color-surface-700-rgb),.5);backdrop-filter:blur(25px)}.dark .qr-bg-sub-inner:hover:active{background-color:rgba(var(--dark-color-surface-700-rgb),.2)}.qr-tag{text-align:center;margin-bottom:10px;width:100%;overflow:hidden;margin-inline:0}@media (min-width:769px){.qr-modal{flex-direction:row;max-width:680px}}.tr-marquee{justify-content:flex-start}.tr-marquee span{padding-right:25%;white-space:nowrap;transform-origin:center}@keyframes move-ltr{0%{transform:translateX(0)}100%{transform:translateX(-100%)}}.ant-input-group-addon:not(:first-child):not(:last-child){border-radius:0rem 1rem 1rem 0rem}b,strong{font-weight:500}.ant-collapse>.ant-collapse-item>.ant-collapse-header{padding:10px 16px 10px 40px}.dark .ant-message-notice-content{background-color:var(--dark-color-surface-200);border:1px solid var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.ant-btn-danger{background-color:var(--dark-color-btn-danger);border-color:var(--dark-color-btn-danger-border)}.ant-btn-danger:focus,.ant-btn-danger:hover{background-color:var(--dark-color-btn-danger-hover);border-color:var(--dark-color-btn-danger-hover)}.dark .ant-alert-close-icon .anticon-close:hover{color:#fff}.ant-empty-small{margin:4px 0;background-color:transparent!important}.ant-empty-small .ant-empty-image{height:20px}.ant-menu-theme-switch,.ant-menu-theme-switch:hover{background-color:transparent!important;cursor:default!important}.dark .ant-tooltip-inner,.dark .ant-tooltip-arrow:before{background-color:var(--dark-color-tooltip)}.ant-select-sm .ant-select-selection__rendered{margin-left:10px}.ant-collapse{-moz-animation:collfade 0.3s ease;-webkit-animation:0.3s collfade 0.3s ease;animation:collfade 0.3s ease}@-webkit-keyframes collfade{0%{transform:scaleY(.8);transform-origin:0% 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0% 0%;opacity:1}}@keyframes collfade{0%{transform:scaleY(.8);transform-origin:0% 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0% 0%;opacity:1}}.ant-table-tbody>tr>td{border-color:#f0f0f0}.ant-table-row-expand-icon{vertical-align:middle;margin-inline-end:8px;position:relative;transform:scale(.9411764705882353)}.ant-table-row-collapsed::before{transform:rotate(-180deg);top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-collapsed::after{transform:rotate(0deg);top:3px;bottom:3px;inset-inline-start:7px;width:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-expanded::before{top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-expanded::after{top:3px;bottom:3px;inset-inline-start:7px;width:1px;transform:rotate(90deg);position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-menu-theme-switch.ant-menu-item .ant-switch:not(.ant-switch-disabled):active:after,.ant-switch:not(.ant-switch-disabled):active:before{width:16px}.dark .ant-select-disabled .ant-select-selection{background:var(--dark-color-surface-100);border-color:var(--dark-color-surface-200);color:rgb(255 255 255 / .25)}.dark .ant-select-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .1)}.dark .ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up-disabled .anticon,.dark .ant-input-number-handler-down:hover.ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up:hover.ant-input-number-handler-up-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down:active.ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up:active.ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .2)}.ant-menu-dark .ant-menu-inline.ant-menu-sub{background:var(--dark-color-surface-100);box-shadow:none}.dark .ant-layout-sider-trigger{background:var(--dark-color-surface-100);color:rgb(255 255 255 / 65%)}.ant-layout-sider{overflow:auto}.dark .ant-back-top-content{background-color:var(--dark-color-back-top)}.dark .ant-back-top-content:hover{background-color:var(--dark-color-back-top-hover)}.ant-calendar-time .ant-calendar-footer .ant-calendar-time-picker-btn{text-transform:capitalize}.ant-calendar{border-color:#fff0;border-width:0}.ant-calendar-time-picker-select li:focus,li.ant-calendar-time-picker-select-option-selected{color:rgb(0 0 0 / .65);font-weight:400;background-color:#e8f4f2}.dark li.ant-calendar-time-picker-select-option-selected{color:var(--dark-color-text-primary);font-weight:400}.dark .ant-calendar-time-picker-select li:focus{color:#fff;font-weight:400;background-color:var(--color-primary-100)}.ant-calendar-time-picker-select li:hover{background:#f5f5f5}.ant-calendar-date{transition:background .3s ease,color .3s ease}li.ant-calendar-time-picker-select-option-selected{margin-block:2px}.ant-calendar-time-picker-select{padding:4px}.ant-calendar-time-picker-select li{height:28px;line-height:28px;border-radius:4px} \ No newline at end of file +:root{--color-primary-100:#008771;--dark-color-background:#0a1222;--dark-color-surface-100:#151f31;--dark-color-surface-200:#222d42;--dark-color-surface-300:#2c3950;--dark-color-surface-400:rgba(65,85,119,.5);--dark-color-surface-500:#2c3950;--dark-color-surface-600:#313f5a;--dark-color-surface-700:#111929;--dark-color-surface-700-rgb:17,25,41;--dark-color-table-hover:rgba(44,57,80,.2);--dark-color-text-primary:rgba(255,255,255,.75);--dark-color-stroke:#2c3950;--dark-color-btn-danger:#cd3838;--dark-color-btn-danger-border:transparent;--dark-color-btn-danger-hover:#e94b4b;--dark-color-tag-bg:rgba(255,255,255,.05);--dark-color-tag-border:rgba(255,255,255,.15);--dark-color-tag-color:rgba(255,255,255,.75);--dark-color-tag-green-bg:17,36,33;--dark-color-tag-green-border:25,81,65;--dark-color-tag-green-color:#3ad3ba;--dark-color-tag-purple-bg:#201425;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d988cd;--dark-color-tag-red-bg:#291515;--dark-color-tag-red-border:#5c2626;--dark-color-tag-red-color:#e04141;--dark-color-tag-orange-bg:#312313;--dark-color-tag-orange-border:#593914;--dark-color-tag-orange-color:#ffa031;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#1348ab;--dark-color-tag-blue-color:#529fff;--dark-color-codemirror-line-hover:rgba(0,135,113,.2);--dark-color-codemirror-line-selection:rgba(0,135,113,.3);--dark-color-login-background:var(--dark-color-background);--dark-color-login-wave:var(--dark-color-surface-200);--dark-color-tooltip:rgba(61,76,104,.9);--dark-color-back-top:rgba(61,76,104,.9);--dark-color-back-top-hover:rgba(61,76,104,1);--dark-color-scrollbar:#313f5a;--dark-color-scrollbar-webkit:#7484a0;--dark-color-scrollbar-webkit-hover:#90a4c7;--dark-color-table-ring:rgb(38 52 77);--dark-color-spin-container:#151f31}html[data-theme-animations='off']{.ant-menu,.ant-layout-sider,.ant-card,.ant-tag,.ant-progress-circle>*,.ant-input,.ant-table-row-expand-icon,.ant-switch,.ant-table-thead>tr>th,.ant-select-selection,.ant-btn,.ant-input-number,.ant-input-group-addon,.ant-checkbox-inner,.ant-progress-bg,.ant-progress-success-bg,.ant-radio-button-wrapper:not(:first-child):before,.ant-radio-button-wrapper,#login,.cm-s-xq.CodeMirror{transition:border 0s,background 0s!important}.ant-menu.ant-menu-inline .ant-menu-item:not(.ant-menu-sub .ant-menu-item),.ant-layout-sider-trigger,.ant-alert-close-icon .anticon-close,.ant-tabs-nav .ant-tabs-tab,.ant-input-number-input,.ant-collapse>.ant-collapse-item>.ant-collapse-header,.Line-Hover,.ant-menu-theme-switch,.ant-menu-submenu-title{transition:color 0s!important}.wave-btn-bg{transition:width 0s!important}}html[data-theme='ultra-dark']{--dark-color-background:#21242a;--dark-color-surface-100:#0c0e12;--dark-color-surface-200:#222327;--dark-color-surface-300:#32353b;--dark-color-surface-400:rgba(255,255,255,.1);--dark-color-surface-500:#3b404b;--dark-color-surface-600:#505663;--dark-color-surface-700:#101113;--dark-color-surface-700-rgb:16,17,19;--dark-color-table-hover:rgba(89,89,89,.15);--dark-color-text-primary:rgb(255 255 255 / 85%);--dark-color-stroke:#202025;--dark-color-tag-green-bg:17,36,33;--dark-color-tag-green-border:29,95,77;--dark-color-tag-green-color:#59cbac;--dark-color-tag-purple-bg:#241121;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d686ca;--dark-color-tag-red-bg:#2a1215;--dark-color-tag-red-border:#58181c;--dark-color-tag-red-color:#e84749;--dark-color-tag-orange-bg:#2b1d11;--dark-color-tag-orange-border:#593815;--dark-color-tag-orange-color:#e89a3c;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#0f367e;--dark-color-tag-blue-color:#3c89e8;--dark-color-codemirror-line-hover:rgba(82,84,94,.2);--dark-color-codemirror-line-selection:rgba(82,84,94,.3);--dark-color-login-background:#0a2227;--dark-color-login-wave:#0f2d32;--dark-color-tooltip:rgba(88,93,100,.9);--dark-color-back-top:rgba(88,93,100,.9);--dark-color-back-top-hover:rgba(88,93,100,1);--dark-color-scrollbar:rgb(107,107,107);--dark-color-scrollbar-webkit:#9f9f9f;--dark-color-scrollbar-webkit-hover:#d1d1d1;--dark-color-table-ring:rgb(37 39 42);--dark-color-spin-container:#1d1d1d;.ant-dropdown-menu-dark{background-color:var(--dark-color-surface-500)}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.dark .waves-header{background-color:#0a2227}.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-600)}}html,body{height:100vh;width:100vw;margin:0;padding:0;overflow:hidden}body{color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;background-color:#fff;font-feature-settings:"tnum"}html{--antd-wave-shadow-color:var(--color-primary-100);line-height:1.15;text-size-adjust:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-moz-tap-highlight-color:#fff0;-webkit-tap-highlight-color:#fff0}@supports (scrollbar-width:auto) and (not selector(::-webkit-scrollbar)){:not(.dark){scrollbar-color:#9a9a9a #fff0;scrollbar-width:thin}.dark *{scrollbar-color:var(--dark-color-scrollbar) #fff0;scrollbar-width:thin}}::-webkit-scrollbar{width:10px;height:10px;background-color:#fff0}::-webkit-scrollbar-track{background-color:#fff0;margin-block:.5em}.ant-modal-wrap::-webkit-scrollbar-track{background-color:#fff;margin-block:0}::-webkit-scrollbar-thumb{border-radius:9999px;background-color:#9a9a9a;border:2px solid #fff0;background-clip:content-box}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background-color:#828282}.dark .ant-modal-wrap::-webkit-scrollbar-track{background-color:var(--dark-color-background)}.dark::-webkit-scrollbar-thumb{background-color:var(--dark-color-scrollbar-webkit)}.dark::-webkit-scrollbar-thumb:hover,.dark::-webkit-scrollbar-thumb:active{background-color:var(--dark-color-scrollbar-webkit-hover)}::-moz-selection{color:var(--color-primary-100);background-color:#cfe8e4}::selection{color:var(--color-primary-100);background-color:#cfe8e4}#app{height:100%;position:fixed;top:0;left:0;right:0;bottom:0;margin:0;padding:0;overflow:auto}.ant-layout,.ant-layout *{box-sizing:border-box}.ant-spin-container:after{border-radius:1.5rem}.dark .ant-spin-container:after{background:var(--dark-color-spin-container)}style attribute{text-align:center}.ant-table-thead>tr>th{padding:12px 8px}.ant-table-tbody>tr>td{padding:10px 8px}.ant-table-thead>tr>th{color:rgb(0 0 0 / .85);font-weight:500;text-align:left;border-bottom:1px solid #e8e8e8;transition:background .3s ease}.ant-table table{border-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:first-child{border-bottom-left-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:last-child{border-bottom-right-radius:1rem}.ant-table{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;font-feature-settings:"tnum";position:relative;clear:both}.ant-table .ant-table-body:not(.ant-table-expanded-row .ant-table-body){overflow-x:auto!important}.ant-card-hoverable{cursor:auto;cursor:pointer}.ant-card{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;position:relative;background-color:#fff;border-radius:2px;transition:all .3s}.ant-space{width:100%}.ant-layout-sider-zero-width-trigger{display:none}@media (max-width:768px){.ant-layout-sider{display:none}.ant-card,.ant-alert-error{margin:.5rem}.ant-tabs{margin:.5rem;padding:.5rem}.ant-modal-body{padding:20px}.ant-form-item-label{line-height:1.5;padding:8px 0 0}:not(.dark)::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}.dark::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}}.ant-layout-content{min-height:auto}.ant-card,.ant-tabs{border-radius:1.5rem}.ant-card-hoverable{cursor:auto}.ant-card+.ant-card{margin-top:20px}.drawer-handle{position:absolute;top:72px;width:41px;height:40px;cursor:pointer;z-index:0;text-align:center;line-height:40px;font-size:16px;display:flex;justify-content:center;align-items:center;background-color:#fff;right:-40px;box-shadow:2px 0 8px rgb(0 0 0 / .15);border-radius:0 4px 4px 0}.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{background-color:#006655!important;background-image:linear-gradient(270deg,#fff0 30%,#009980,#fff0 100%);background-repeat:no-repeat;animation:ma-bg-move linear 6.6s infinite;color:#fff;border-radius:.5rem}.ant-layout-sider-collapsed .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{border-radius:0}@-webkit-keyframes ma-bg-move{0%{background-position:-500px 0}100%{background-position:1000px 0}}@keyframes ma-bg-move{0%{background-position:-500px 0}50%{background-position:1000px 0}100%{background-position:1000px 0}}.ant-menu-item-active,.ant-menu-item:hover,.ant-menu-submenu-title:hover,.ant-menu-item:active,.ant-menu-submenu-title:active{color:var(--color-primary-100);background-color:#e8f4f2}.ant-menu-inline .ant-menu-item,.ant-menu-inline .ant-menu-submenu-title{border-radius:.5rem}.ant-menu-inline .ant-menu-item:after,.ant-menu{border-right-width:0}.ant-layout-sider-children,.ant-pagination ul{padding:.5rem}.ant-layout-sider-collapsed .ant-layout-sider-children{padding:.5rem 0}.ant-dropdown-menu,.ant-select-dropdown-menu{padding:.5rem}.ant-dropdown-menu-item,.ant-dropdown-menu-item:hover,.ant-select-dropdown-menu-item,.ant-select-dropdown-menu-item:hover,.ant-select-selection--multiple .ant-select-selection__choice{border-radius:.5rem}.ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item,.ant-select-dropdown--single .ant-select-dropdown-menu .ant-select-dropdown-menu-item-selected{margin-block:2px}@media (min-width:769px){.drawer-handle{display:none}.ant-tabs{padding:2rem}}.fade-in-enter,.fade-in-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.fade-in-enter-active,.fade-in-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter-active,.zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter,.zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.zoom-in-top-enter-active,.zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.zoom-in-top-enter,.zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-bottom-enter-active,.zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.zoom-in-bottom-enter,.zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-left-enter-active,.zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.zoom-in-left-enter,.zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.list-enter-active,.list-leave-active{-webkit-transition:all .3s;transition:all .3s}.list-enter,.list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.ant-tooltip-inner{min-height:0;padding-inline:1rem}.ant-list-item-meta-title{font-size:14px}.ant-progress-inner{background-color:#ebeef5}.deactive-client .ant-collapse-header{color:#ffffff!important;background-color:#ff7f7f}.ant-table-expand-icon-th,.ant-table-row-expand-icon-cell{width:30px;min-width:30px}.ant-tabs{background-color:#fff}.ant-form-item{margin-bottom:0}.ant-setting-textarea{margin-top:1.5rem}.client-table-header{background-color:#f0f2f5}.client-table-odd-row{background-color:#fafafa}.ant-table-pagination.ant-pagination{float:left}.ant-tag{margin-right:0;margin-inline:2px;display:inline-flex;align-items:center;justify-content:space-evenly}.ant-tag:not(.qr-tag){column-gap:4px}#inbound-info-modal .ant-tag{margin-block:2px}.tr-info-table{display:inline-table;margin-block:10px;width:100%}#inbound-info-modal .tr-info-table .ant-tag{margin-block:0;margin-inline:0}.tr-info-row{display:flex;flex-direction:column;row-gap:2px;margin-block:10px}.tr-info-row a{margin-left:6px}.tr-info-row code{padding-inline:8px}.tr-info-tag{max-width:100%;text-wrap:balance;overflow:hidden;overflow-wrap:anywhere}.tr-info-title{display:inline-flex;align-items:center;justify-content:flex-start;column-gap:4px}.ant-tag-blue{background-color:#edf4fa;border-color:#a9c5e7;color:#0e49b5}.ant-tag-green{background-color:#eafff9;border-color:#76ccb4;color:#199270}.ant-tag-purple{background-color:#f2eaf1;border-color:#d5bed2;color:#7a316f}.ant-tag-orange,.ant-alert-warning{background-color:#ffeee1;border-color:#fec093;color:#f37b24}.ant-tag-red,.ant-alert-error{background-color:#ffe9e9;border-color:#ff9e9e;color:#cf3c3c}.ant-input::placeholder{opacity:.5}.ant-input:hover,.ant-input:focus{background-color:#e8f4f2}.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){background-color:#e8f4f2}.delete-icon:hover{color:#e04141}.normal-icon:hover{color:var(--color-primary-100)}.dark::-moz-selection{color:#fff;background-color:var(--color-primary-100)}.dark::selection{color:#fff;background-color:var(--color-primary-100)}.dark .normal-icon:hover{color:#fff}.dark .ant-layout-sider,.dark .ant-drawer-content,.ant-menu-dark,.ant-menu-dark .ant-menu-sub,.dark .ant-card,.dark .ant-table,.dark .ant-collapse-content,.dark .ant-tabs{background-color:var(--dark-color-surface-100);color:var(--dark-color-text-primary)}.dark .ant-card-hoverable:hover,.dark .ant-space-item>.ant-tabs:hover{box-shadow:0 2px 8px #fff0}.dark>.ant-layout,.dark .drawer-handle,.dark .ant-table-thead>tr>th,.dark .ant-table-expanded-row,.dark .ant-table-expanded-row:hover,.dark .ant-table-expanded-row .ant-table-tbody,.dark .ant-calendar{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-table-expanded-row .ant-table-thead>tr:first-child>th{border-radius:0}.dark .ant-calendar,.dark .ant-card-bordered{border-color:var(--dark-color-background)}.dark .ant-table-bordered,.dark .ant-table-bordered.ant-table-empty .ant-table-placeholder,.dark .ant-table-bordered .ant-table-body>table,.dark .ant-table-bordered .ant-table-fixed-left table,.dark .ant-table-bordered .ant-table-fixed-right table,.dark .ant-table-bordered .ant-table-header>table,.dark .ant-table-bordered .ant-table-thead>tr:not(:last-child)>th,.dark .ant-table-bordered .ant-table-tbody>tr>td,.dark .ant-table-bordered .ant-table-thead>tr>th{border-color:var(--dark-color-surface-400)}.dark .ant-table-tbody>tr>td,.dark .ant-table-thead>tr>th,.dark .ant-card-head,.dark .ant-modal-header,.dark .ant-collapse>.ant-collapse-item,.dark .ant-tabs-bar,.dark .ant-list-split .ant-list-item,.dark .ant-popover-title,.dark .ant-calendar-header,.dark .ant-calendar-input-wrap{border-bottom-color:var(--dark-color-surface-400)}.dark .ant-modal-footer,.dark .ant-collapse-content,.dark .ant-calendar-footer,.dark .ant-divider-horizontal.ant-divider-with-text-left:before,.dark .ant-divider-horizontal.ant-divider-with-text-left:after,.dark .ant-divider-horizontal.ant-divider-with-text-center:before,.dark .ant-divider-horizontal.ant-divider-with-text-center:after{border-top-color:var(--dark-color-surface-300)}.ant-divider-horizontal.ant-divider-with-text-left:before{width:10%}.dark .ant-progress-text,.dark .ant-card-head,.dark .ant-form,.dark .ant-collapse>.ant-collapse-item>.ant-collapse-header,.dark .ant-modal-close-x,.dark .ant-form .anticon,.dark .ant-tabs-tab-arrow-show:not(.ant-tabs-tab-btn-disabled),.dark .anticon-close,.dark .ant-list-item-meta-title,.dark .ant-select-selection i,.dark .ant-modal-confirm-title,.dark .ant-modal-confirm-content,.dark .ant-popover-message,.dark .ant-modal,.dark .ant-divider-inner-text,.dark .ant-popover-title,.dark .ant-popover-inner-content,.dark h2,.dark .ant-modal-title,.dark .ant-form-item-label>label,.dark .ant-checkbox-wrapper,.dark .ant-form-item,.dark .ant-calendar-footer .ant-calendar-today-btn,.dark .ant-calendar-footer .ant-calendar-time-picker-btn,.dark .ant-calendar-day-select,.dark .ant-calendar-month-select,.dark .ant-calendar-year-select,.dark .ant-calendar-date,.dark .ant-calendar-year-panel-year,.dark .ant-calendar-month-panel-month,.dark .ant-calendar-decade-panel-decade{color:var(--dark-color-text-primary)}.dark .ant-pagination-options-size-changer .ant-select-arrow .anticon.anticon-down.ant-select-arrow-icon{color:rgb(255 255 255 / 35%)}.dark .ant-pagination-item a,.dark .ant-pagination-next a,.dark .ant-pagination-prev a{color:var(--dark-color-text-primary)}.dark .ant-pagination-item:focus a,.dark .ant-pagination-item:hover a,.dark .ant-pagination-item-active a,.dark .ant-pagination-next:hover .ant-pagination-item-link{color:var(--color-primary-100)}.dark .ant-pagination-item-active{background-color:#fff0}.dark .ant-list-item-meta-description{color:rgb(255 255 255 / .45)}.dark .ant-pagination-disabled i,.dark .ant-tabs-tab-btn-disabled{color:rgb(255 255 255 / .25)}.dark .ant-input,.dark .ant-input-group-addon,.dark .ant-collapse,.dark .ant-select-selection,.dark .ant-input-number,.dark .ant-input-number-handler-wrap,.dark .ant-table-placeholder,.dark .ant-empty-normal,.dark .ant-select-dropdown,.dark .ant-select-dropdown li,.dark .ant-select-dropdown-menu-item,.dark .client-table-header,.dark .ant-select-selection--multiple .ant-select-selection__choice{background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.dark .ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected:not(.ant-dropdown-menu-submenu-title:hover){background-color:var(--dark-color-surface-300)}.dark .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected{background-color:var(--dark-color-surface-300)}.dark .ant-calendar-time-picker-inner{background-color:var(--dark-color-background)}.dark .ant-select-selection:hover,.dark .ant-calendar-picker-clear,.dark .ant-input-number:hover,.dark .ant-input-number:focus,.dark .ant-input:hover,.dark .ant-input:focus{background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.dark .ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){border-color:var(--color-primary-100);background-color:rgb(0 135 113 / .3)}.dark .ant-btn:not(.ant-btn-primary):not(.ant-btn-danger){color:var(--dark-color-text-primary);background-color:rgb(10 117 87 / 30%);border:1px solid var(--color-primary-100)}.dark .ant-radio-button-wrapper,.dark .ant-radio-button-wrapper:before{color:var(--dark-color-text-primary);background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){background-color:#e8f4f2}.dark .ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.dark .ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){color:#fff;background-color:rgb(10 117 87 / 50%);border-color:var(--color-primary-100)}.dark .ant-btn-primary[disabled],.dark .ant-btn-danger[disabled],.dark .ant-calendar-ok-btn-disabled{color:rgb(255 255 255 / 35%);background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300)}.dark .ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.dark .client-table-odd-row{background-color:var(--dark-color-table-hover)}.dark .ant-table-row-expand-icon{color:#fff;background-color:#fff0;border-color:rgb(255 255 255 / 20%)}.dark .ant-table-row-expand-icon:hover{color:var(--color-primary-100);background-color:#fff0;border-color:var(--color-primary-100)}.dark .ant-switch:not(.ant-switch-checked),.dark .ant-progress-line .ant-progress-inner{background-color:var(--dark-color-surface-500)}.dark .ant-progress-circle-trail{stroke:var(--dark-color-stroke)!important}.dark .ant-popover-inner{background-color:var(--dark-color-surface-500)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-500)}@media (max-width:768px){.dark .ant-popover-inner{background-color:var(--dark-color-surface-200)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-200)}}.ant-dropdown-menu-dark .ant-dropdown-menu-item:hover,.dark .ant-select-dropdown-menu-item-selected,.dark .ant-calendar-time-picker-select-option-selected{background-color:var(--dark-color-surface-600)}.ant-menu-dark .ant-menu-item:hover,.ant-menu-dark .ant-menu-submenu-title:hover{background-color:var(--dark-color-surface-300)}.dark .ant-menu-item:active,.dark .ant-menu-submenu-title:active{color:#fff;background-color:var(--dark-color-surface-300)}.dark .ant-alert-message{color:rgb(255 255 255 / .85)}.dark .ant-tag{color:var(--dark-color-tag-color);background-color:var(--dark-color-tag-bg);border-color:var(--dark-color-tag-border)}.dark .ant-tag-blue{background-color:var(--dark-color-tag-blue-bg);border-color:var(--dark-color-tag-blue-border);color:var(--dark-color-tag-blue-color)}.dark .ant-tag-red,.dark .ant-alert-error{background-color:var(--dark-color-tag-red-bg);border-color:var(--dark-color-tag-red-border);color:var(--dark-color-tag-red-color)}.dark .ant-tag-orange,.dark .ant-alert-warning{background-color:var(--dark-color-tag-orange-bg);border-color:var(--dark-color-tag-orange-border);color:var(--dark-color-tag-orange-color)}.dark .ant-tag-green{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border));color:var(--dark-color-tag-green-color)}.dark .ant-tag-purple{background-color:var(--dark-color-tag-purple-bg);border-color:var(--dark-color-tag-purple-border);color:var(--dark-color-tag-purple-color)}.dark .ant-modal-content,.dark .ant-modal-header{background-color:var(--dark-color-surface-700)}.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date{color:var(--dark-color-surface-300)}.dark .ant-calendar-selected-day .ant-calendar-date{background-color:var(--color-primary-100)!important;color:#fff}.dark .ant-calendar-date:hover,.dark .ant-calendar-time-picker-select li:hover{background-color:var(--dark-color-surface-600);color:#fff}.dark .ant-calendar-header a:hover,.dark .ant-calendar-header a:hover::before,.dark .ant-calendar-header a:hover::after{border-color:#fff}.dark .ant-calendar-time-picker-select{border-right-color:var(--dark-color-surface-300)}.has-warning .ant-select-selection,.has-warning .ant-select-selection:hover,.has-warning .ant-input,.has-warning .ant-input:hover{background-color:#ffeee1;border-color:#fec093}.has-warning .ant-input::placeholder{color:#f37b24}.has-warning .ant-input:not([disabled]):hover{border-color:#fec093}.dark .has-warning .ant-select-selection,.dark .has-warning .ant-select-selection:hover,.dark .has-warning .ant-input,.dark .has-warning .ant-input:hover{border-color:#784e1d;background:#312313}.dark .has-warning .ant-input::placeholder{color:rgb(255 160 49 / 70%)}.dark .has-warning .anticon{color:#ffa031}.dark .has-success .anticon{color:var(--color-primary-100);animation-name:diffZoomIn1!important}.dark .anticon-close-circle{color:#e04141}.dark .ant-spin-nested-loading>div>.ant-spin .ant-spin-text{text-shadow:0 1px 2px #0007}.dark .ant-spin{color:#fff}.dark .ant-spin-dot-item{background-color:#fff}.ant-checkbox-wrapper,.ant-input-group-addon,.ant-tabs-tab,.ant-input::placeholder,.ant-collapse-header,.ant-menu,.ant-radio-button-wrapper{-webkit-user-select:none;user-select:none}.ant-calendar-date,.ant-calendar-year-panel-year,.ant-calendar-decade-panel-decade,.ant-calendar-month-panel-month{border-radius:4px}.ant-checkbox-inner,.ant-checkbox-checked:after,.ant-table-row-expand-icon{border-radius:6px}.ant-calendar-date:hover{background-color:#e8f4f2}.ant-calendar-date:active{background-color:#e8f4f2;color:rgb(0 0 0 / .65)}.ant-calendar-today .ant-calendar-date{color:var(--color-primary-100);font-weight:400;border-color:var(--color-primary-100)}.dark .ant-calendar-today .ant-calendar-date{color:#fff;border-color:var(--color-primary-100)}.ant-calendar-selected-day .ant-calendar-date{background:var(--color-primary-100);color:#fff}li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(0 0 0 / .25)}.dark li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(255 255 255 / .3)}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:rgb(0 0 0 / .87)}.dark.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:#fff}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected .ant-select-selected-icon,.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected:hover .ant-select-selected-icon{color:var(--color-primary-100)}.ant-select-selection:hover,.ant-input-number-focused,.ant-input-number:hover{background-color:#e8f4f2}.dark .ant-input-number-handler:active{background-color:var(--color-primary-100)}.dark .ant-input-number-handler:hover .ant-input-number-handler-down-inner,.dark .ant-input-number-handler:hover .ant-input-number-handler-up-inner{color:#fff}.dark .ant-input-number-handler-down{border-top:1px solid rgb(217 217 217 / .3)}.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-century-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-decade-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-month-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-year-select .dark .ant-calendar-month-panel-header .ant-calendar-month-panel-century-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-decade-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-month-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-year-select{color:rgb(255 255 255 / .85)}.dark .ant-calendar-year-panel-header{border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel-last-decade-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-next-decade-cell .ant-calendar-year-panel-year{color:rgb(255 255 255 / .35)}.dark .ant-divider:not(.ant-divider-with-text-center,.ant-divider-with-text-left,.ant-divider-with-text-right),.ant-dropdown-menu-dark,.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-200)}.dark .ant-calendar-header a:hover{color:#fff}.dark .ant-calendar-month-panel-header{background-color:var(--dark-color-background);border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel,.dark .ant-calendar table{background-color:var(--dark-color-background)}.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade:hover{color:#fff;background-color:var(--color-primary-100)!important}.dark .ant-calendar-last-month-cell .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date:hover,.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-next-month-btn-day .ant-calendar-date:hover{color:rgb(255 255 255 / 25%);background:#fff0;border-color:#fff0}.dark .ant-calendar-today .ant-calendar-date:hover{color:#fff;border-color:var(--color-primary-100);background-color:var(--color-primary-100)}.dark .ant-calendar-decade-panel-last-century-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-next-century-cell .ant-calendar-decade-panel-decade{color:rgb(255 255 255 / 25%)}.dark .ant-calendar-decade-panel-header{border-bottom:1px solid var(--dark-color-surface-200);background-color:var(--dark-color-background)}.dark .ant-checkbox-inner{background-color:rgb(0 135 113 / .3);border-color:rgb(0 135 113 / .3)}.dark .ant-checkbox-checked .ant-checkbox-inner{background-color:var(--color-primary-100);border-color:var(--color-primary-100)}.dark .ant-calendar-input{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-calendar-input::placeholder{color:rgb(255 255 255 / .25)}.ant-input-group.ant-input-group-compact-addon:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact-wrap:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact>.ant-input:not(:first-child):not(:last-child),.ant-input-number-handler,.ant-input-number-handler-wrap{border-radius:0}.ant-input-number{overflow:clip}.ant-modal-body,.ant-collapse-content>.ant-collapse-content-box{overflow-x:auto}.ant-modal-body{overflow-y:hidden}.ant-calendar-year-panel-year:hover,.ant-calendar-decade-panel-decade:hover,.ant-calendar-month-panel-month:hover,.ant-dropdown-menu-item:hover,.ant-dropdown-menu-submenu-title:hover,.ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled),.ant-table-tbody>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td{background-color:#e8f4f2}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.ant-select-dropdown,.ant-popover-inner{overflow-x:hidden}.ant-popover-inner-content{max-height:450px;overflow-y:auto}@media (max-height:900px){.ant-popover-inner-content{max-height:400px}}@media (max-height:768px){.ant-popover-inner-content{max-height:300px}}@media (max-width:768px){.ant-popover-inner-content{max-height:300px}}.qr-modal{display:flex;align-items:flex-end;gap:10px;flex-direction:column;flex-wrap:wrap;row-gap:24px}.qr-box{width:220px}.qr-cv{width:100%;height:100%}.dark .qr-cv{filter:invert(1)}.qr-bg{background-color:#fff;display:flex;justify-content:center;align-content:center;padding:.8rem;border-radius:1rem;border:solid 1px #e8e8e8;height:220px;width:220px;transition:all .1s}.qr-bg:hover{border-color:#76ccb4;background-color:#eafff9}.qr-bg:hover:active{border-color:#76ccb4;background-color:rgb(197 241 228 / 70%)}.dark .qr-bg{background-color:var(--dark-color-surface-700);border-color:var(--dark-color-surface-300)}.dark .qr-bg:hover{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border))}.dark .qr-bg:hover:active{background-color:#17322e}@property --tr-rotate{syntax:'';initial-value:45deg;inherits:false}.qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#76ccb4,transparent,#d5bed2);display:flex;justify-content:center;align-content:center;padding:1px;border-radius:1rem;height:220px;width:220px}.dark .qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#195141,transparent,#5a2969)}.qr-bg-sub:hover{animation:tr-rotate-gradient 3.5s linear infinite}@keyframes tr-rotate-gradient{from{--tr-rotate:45deg}to{--tr-rotate:405deg}}.qr-bg-sub-inner{background-color:#fff;padding:.8rem;border-radius:1rem;transition:all .1s}.qr-bg-sub-inner:hover{background-color:rgb(255 255 255 / 60%);backdrop-filter:blur(25px)}.qr-bg-sub-inner:hover:active{background-color:rgb(255 255 255 / 30%)}.dark .qr-bg-sub-inner{background-color:rgb(var(--dark-color-surface-700-rgb))}.dark .qr-bg-sub-inner:hover{background-color:rgba(var(--dark-color-surface-700-rgb),.5);backdrop-filter:blur(25px)}.dark .qr-bg-sub-inner:hover:active{background-color:rgba(var(--dark-color-surface-700-rgb),.2)}.qr-tag{text-align:center;margin-bottom:10px;width:100%;overflow:hidden;margin-inline:0}@media (min-width:769px){.qr-modal{flex-direction:row;max-width:680px}}.tr-marquee{justify-content:flex-start}.tr-marquee span{padding-right:25%;white-space:nowrap;transform-origin:center}@keyframes move-ltr{0%{transform:translateX(0)}100%{transform:translateX(-100%)}}.ant-input-group-addon:not(:first-child):not(:last-child){border-radius:0 1rem 1rem 0}b,strong{font-weight:500}.ant-collapse>.ant-collapse-item>.ant-collapse-header{padding:10px 16px 10px 40px}.dark .ant-message-notice-content{background-color:var(--dark-color-surface-200);border:1px solid var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.ant-btn-danger{background-color:var(--dark-color-btn-danger);border-color:var(--dark-color-btn-danger-border)}.ant-btn-danger:focus,.ant-btn-danger:hover{background-color:var(--dark-color-btn-danger-hover);border-color:var(--dark-color-btn-danger-hover)}.dark .ant-alert-close-icon .anticon-close:hover{color:#fff}.ant-empty-small{margin:4px 0;background-color:transparent!important}.ant-empty-small .ant-empty-image{height:20px}.ant-menu-theme-switch,.ant-menu-theme-switch:hover{background-color:transparent!important;cursor:default!important}.dark .ant-tooltip-inner,.dark .ant-tooltip-arrow:before{background-color:var(--dark-color-tooltip)}.ant-select-sm .ant-select-selection__rendered{margin-left:10px}.ant-collapse{-moz-animation:collfade .3s ease;-webkit-animation:.3s collfade .3s ease;animation:collfade .3s ease}@-webkit-keyframes collfade{0%{transform:scaleY(.8);transform-origin:0 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0 0%;opacity:1}}@keyframes collfade{0%{transform:scaleY(.8);transform-origin:0 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0 0%;opacity:1}}.ant-table-tbody>tr>td{border-color:#f0f0f0}.ant-table-row-expand-icon{vertical-align:middle;margin-inline-end:8px;position:relative;transform:scale(.9411764705882353)}.ant-table-row-collapsed::before{transform:rotate(-180deg);top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform .3s ease-out;content:""}.ant-table-row-collapsed::after{transform:rotate(0deg);top:3px;bottom:3px;inset-inline-start:7px;width:1px;position:absolute;background:currentcolor;transition:transform .3s ease-out;content:""}.ant-table-row-expanded::before{top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform .3s ease-out;content:""}.ant-table-row-expanded::after{top:3px;bottom:3px;inset-inline-start:7px;width:1px;transform:rotate(90deg);position:absolute;background:currentcolor;transition:transform .3s ease-out;content:""}.ant-menu-theme-switch.ant-menu-item .ant-switch:not(.ant-switch-disabled):active:after,.ant-switch:not(.ant-switch-disabled):active:before{width:16px}.dark .ant-select-disabled .ant-select-selection{background:var(--dark-color-surface-100);border-color:var(--dark-color-surface-200);color:rgb(255 255 255 / .25)}.dark .ant-select-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .1)}.dark .ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up-disabled .anticon,.dark .ant-input-number-handler-down:hover.ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up:hover.ant-input-number-handler-up-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down:active.ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up:active.ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .2)}.ant-menu-dark .ant-menu-inline.ant-menu-sub{background:var(--dark-color-surface-100);box-shadow:none}.dark .ant-layout-sider-trigger{background:var(--dark-color-surface-100);color:rgb(255 255 255 / 65%)}.ant-layout-sider{overflow:auto}.dark .ant-back-top-content{background-color:var(--dark-color-back-top)}.dark .ant-back-top-content:hover{background-color:var(--dark-color-back-top-hover)}.ant-calendar-time .ant-calendar-footer .ant-calendar-time-picker-btn{text-transform:capitalize}.ant-calendar{border-color:#fff0;border-width:0}.ant-calendar-time-picker-select li:focus,li.ant-calendar-time-picker-select-option-selected{color:rgb(0 0 0 / .65);font-weight:400;background-color:#e8f4f2}.dark li.ant-calendar-time-picker-select-option-selected{color:var(--dark-color-text-primary);font-weight:400}.dark .ant-calendar-time-picker-select li:focus{color:#fff;font-weight:400;background-color:var(--color-primary-100)}.ant-calendar-time-picker-select li:hover{background:#f5f5f5}.ant-calendar-date{transition:background .3s ease,color .3s ease}li.ant-calendar-time-picker-select-option-selected{margin-block:2px}.ant-calendar-time-picker-select{padding:4px}.ant-calendar-time-picker-select li{height:28px;line-height:28px;border-radius:4px}@media (min-width:769px){.ant-layout-content{margin:24px 16px}}.ant-card-dark h2{color:var(--dark-color-text-primary)}.ant-backup-list-item{gap:10px}.ant-version-list-item{--padding:12px;padding:var(--padding)!important;gap:var(--padding)}.dark .ant-version-list-item svg{color:var(--dark-color-text-primary)}.dark .ant-backup-list-item svg,.dark .ant-badge-status-text,.dark .ant-card-extra{color:var(--dark-color-text-primary)}.dark .ant-card-actions>li{color:rgba(255,255,255,.55)}.dark .ant-radio-inner{background-color:var(--dark-color-surface-100);border-color:var(--dark-color-surface-600)}.dark .ant-radio-checked .ant-radio-inner{border-color:var(--color-primary-100)}.dark .ant-backup-list,.dark .ant-version-list,.dark .ant-card-actions,.dark .ant-card-actions>li:not(:last-child){border-color:var(--dark-color-stroke)}.ant-card-actions{background:transparent}.ip-hidden{-webkit-user-select:none;-moz-user-select:none;user-select:none;filter:blur(10px)}.running-animation .ant-badge-status-dot{animation:runningAnimation 1.2s linear infinite}.running-animation .ant-badge-status-processing:after{border-color:var(--color-primary-100)}@keyframes runningAnimation{0%,50%,100%{transform:scale(1);opacity:1}10%{transform:scale(1.5);opacity:.2}}.mb-10{margin-bottom:10px!important}.mb-12{margin-bottom:12px!important}.mt-5{margin-top:5px!important}.mr-8{margin-right:8px!important}.ml-10{margin-left:10px!important}.mr-05{margin-right:.5rem!important}.fs-1rem{font-size:1rem!important}.w-100{width:100%!important}.w-70{width:70px!important}.w-95{width:95px!important}.text-center{text-align:center!important}.cursor-pointer{cursor:pointer!important}.float-right{float:right!important}.va-middle{vertical-align:middle!important}.d-flex{display:flex!important}.justify-end{justify-content:flex-end!important}.log-container{height:auto;max-height:500px;overflow:auto;margin-top:.5rem}.max-w-400{max-width:400px;display:inline-block}.card-placeholder{text-align:center;padding:30px 0;margin-top:10px;background:transparent;border:none}.ant-space.jc-center{justify-content:center}#app.login-app{overflow:hidden;margin:0!important;padding:0!important;min-height:100vh;width:100vw}#app.login-app *{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#app.login-app h1{text-align:center;height:110px}#app.login-app .ant-layout-content{margin:0!important;padding:0!important;width:100vw;max-width:100vw}#app.login-app.ant-layout,#app.login-app .ant-layout{margin:0!important;padding:0!important;width:100vw;max-width:100vw}.min-h-0{min-height:0!important}.min-h-100vh{min-height:100vh!important}.h-100{height:100%!important}.h-50px{height:50px!important}.overflow-auto{overflow:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-hidden-auto{overflow:hidden auto!important}.mt-1rem{margin-top:1rem!important}.my-3rem{margin-top:3rem!important;margin-bottom:3rem!important}#app.login-app #login{animation:charge .5s both;background-color:#fff;border-radius:2rem;padding:4rem 3rem;transition:all .3s;user-select:none;-webkit-user-select:none;-moz-user-select:none}#app.login-app #login:hover{box-shadow:0 2px 8px rgba(0,0,0,.09)}@keyframes charge{from{transform:translateY(5rem);opacity:0}to{transform:translateY(0);opacity:1}}#app.login-app .under{background-color:#c7ebe2;z-index:0}#app.login-app.dark .under{background-color:var(--dark-color-login-wave)}#app.login-app.dark #login{background-color:var(--dark-color-surface-100)}#app.login-app.dark h1{color:rgba(255,255,255)}#app.login-app #login .ant-form-item-children .ant-btn,#app.login-app #login .ant-input{height:50px;border-radius:30px}#app.login-app #login .ant-input-group-addon{border-radius:0 30px 30px 0;width:50px;font-size:18px}#app.login-app #login .ant-input-affix-wrapper .ant-input-prefix{left:23px}#app.login-app #login .ant-input-affix-wrapper .ant-input:not(:first-child){padding-left:50px}#app.login-app .centered{display:flex;text-align:center;align-items:center;justify-content:center;width:100%}#app.login-app .title{font-size:2rem;margin-block-end:2rem}#app.login-app .title b{font-weight:bold!important}.ant-btn-primary-login{width:100%}.ant-btn-primary-login:focus,.ant-btn-primary-login:hover{color:#fff;background-color:#006655;border-color:#006655;background-image:linear-gradient(270deg,rgba(123,199,77,0) 30%,#009980,rgba(123,199,77,0) 100%);background-repeat:no-repeat;animation:ma-bg-move ease-in-out 5s infinite;background-position-x:-500px;width:95%;animation-delay:-.5s;box-shadow:0 2px 0 rgba(0,0,0,.045)}.ant-btn-primary-login.active,.ant-btn-primary-login:active{color:#fff;background-color:#006655;border-color:#006655}.wave-btn-bg{position:relative;border-radius:25px;width:100%;transition:all .3s cubic-bezier(.645,.045,.355,1)}.dark .wave-btn-bg{color:#fff;position:relative;background-color:#0a7557;border:2px double transparent;background-origin:border-box;background-clip:padding-box,border-box;background-size:300%;width:100%;z-index:1}.dark .wave-btn-bg:hover{animation:wave-btn-tara 4s ease infinite}.dark .wave-btn-bg-cl{background-image:linear-gradient(rgba(13,14,33,0),rgba(13,14,33,0)),radial-gradient(circle at left top,#006655,#009980,#006655)!important;border-radius:3em}.dark .wave-btn-bg-cl:hover{width:95%}.dark .wave-btn-bg-cl:before{position:absolute;content:"";top:-5px;left:-5px;bottom:-5px;right:-5px;z-index:-1;background:inherit;background-size:inherit;border-radius:4em;opacity:0;transition:.5s}.dark .wave-btn-bg-cl:hover::before{opacity:1;filter:blur(20px);animation:wave-btn-tara 8s linear infinite}@keyframes wave-btn-tara{to{background-position:300%}}.waves-header{position:fixed;top:0;left:0;right:0;width:100%;text-align:center;background-color:#dbf5ed;color:white;z-index:-1}.dark .waves-header{background-color:var(--dark-color-login-background)}.waves-inner-header{height:50vh;width:100%;margin:0;padding:0}.waves{position:relative;width:100%;height:15vh;margin-bottom:-8px;min-height:100px;max-height:150px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.dark .parallax>use{fill:var(--dark-color-login-wave)}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:4s;opacity:.2}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:7s;opacity:.4}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:10s;opacity:.6}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:13s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}100%{transform:translate3d(85px,0,0)}}@media (max-width:768px){#app.login-app .waves{height:40px;min-height:40px}}#app.login-app .words-wrapper{width:100%;display:inline-block;position:relative;text-align:center}#app.login-app .words-wrapper b{width:100%;display:inline-block;position:absolute;left:0;top:0}#app.login-app .words-wrapper b.is-visible{position:relative}#app.login-app .headline.zoom .words-wrapper{-webkit-perspective:300px;-moz-perspective:300px;perspective:300px}#app.login-app .headline{display:flex;justify-content:center;align-items:center}#app.login-app .headline.zoom b{opacity:0}#app.login-app .headline.zoom b.is-visible{opacity:1;-webkit-animation:zoom-in .8s;-moz-animation:zoom-in .8s;animation:cubic-bezier(.215,.61,.355,1) zoom-in .8s}#app.login-app .headline.zoom b.is-hidden{-webkit-animation:zoom-out .8s;-moz-animation:zoom-out .8s;animation:cubic-bezier(.215,.61,.355,1) zoom-out .4s}@-webkit-keyframes zoom-in{0%{opacity:0;-webkit-transform:translateZ(100px)}100%{opacity:1;-webkit-transform:translateZ(0)}}@-moz-keyframes zoom-in{0%{opacity:0;-moz-transform:translateZ(100px)}100%{opacity:1;-moz-transform:translateZ(0)}}@keyframes zoom-in{0%{opacity:0;-webkit-transform:translateZ(100px);-moz-transform:translateZ(100px);-ms-transform:translateZ(100px);-o-transform:translateZ(100px);transform:translateZ(100px)}100%{opacity:1;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}}.inbounds-page .ant-table:not(.ant-table-expanded-row .ant-table){outline:1px solid #f0f0f0;outline-offset:-1px;border-radius:1rem;overflow-x:hidden}.inbounds-page.dark .ant-table:not(.ant-table-expanded-row .ant-table){outline-color:var(--dark-color-table-ring)}.inbounds-page .ant-table .ant-table-content .ant-table-scroll .ant-table-body{overflow-y:hidden}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper{margin:-10px 22px!important}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper .ant-table{border-bottom-left-radius:1rem;border-bottom-right-radius:1rem}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child tr:last-child td{border-bottom-color:transparent}.inbounds-page .ant-table .ant-table-tbody tr:last-child.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody>tr:last-child>td:first-child{border-bottom-left-radius:6px}.inbounds-page .ant-table .ant-table-tbody tr:last-child.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody>tr:last-child>td:last-child{border-bottom-right-radius:6px}@media (max-width:768px){.inbounds-page .ant-card-body{padding:.5rem}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper{margin:-10px 2px!important}}.inbounds-page.dark .ant-switch-small:not(.ant-switch-checked){background-color:var(--dark-color-surface-100)!important}.inbounds-page .ant-custom-popover-title{display:flex;align-items:center;gap:10px;margin:5px 0}.inbounds-page .ant-col-sm-24{margin:.5rem -2rem .5rem 2rem}.inbounds-page tr.hideExpandIcon .ant-table-row-expand-icon{display:none}.inbounds-page .infinite-tag{padding:0 5px;border-radius:2rem;min-width:50px;min-height:22px}.inbounds-page .infinite-bar .ant-progress-inner .ant-progress-bg{background-color:#F2EAF1;border:#D5BED2 solid 1px}.inbounds-page.dark .infinite-bar .ant-progress-inner .ant-progress-bg{background-color:#7a316f!important;border:#7a316f solid 1px}.inbounds-page .ant-collapse{margin:5px 0}.inbounds-page .info-large-tag{max-width:200px;overflow:hidden}.inbounds-page .client-comment{font-size:12px;opacity:.75;cursor:help}.inbounds-page .client-email{font-weight:500}.inbounds-page .client-popup-item{display:flex;align-items:center;gap:5px}.inbounds-page .online-animation .ant-badge-status-dot{animation:onlineAnimation 1.2s linear infinite}@keyframes onlineAnimation{0%,50%,100%{transform:scale(1);opacity:1}10%{transform:scale(1.5);opacity:.2}}.inbounds-page .tr-table-box{display:flex;gap:4px;justify-content:center;align-items:center}.inbounds-page .tr-table-rt{flex-basis:70px;min-width:70px;text-align:end}.inbounds-page .tr-table-lt{flex-basis:70px;min-width:70px;text-align:start}.inbounds-page .tr-table-bar{flex-basis:160px;min-width:60px}.inbounds-page .tr-infinity-ch{font-size:14pt;max-height:24px;display:inline-flex;align-items:center}.inbounds-page .ant-table-expanded-row .ant-table .ant-table-body{overflow-x:hidden}.inbounds-page .ant-table-expanded-row .ant-table-tbody>tr>td{padding:10px 2px}.inbounds-page .ant-table-expanded-row .ant-table-thead>tr>th{padding:12px 2px}@-webkit-keyframes zoom-out{0%{opacity:1;-webkit-transform:translateZ(0)}100%{opacity:0;-webkit-transform:translateZ(-100px)}}@-moz-keyframes zoom-out{0%{opacity:1;-moz-transform:translateZ(0)}100%{opacity:0;-moz-transform:translateZ(-100px)}}@keyframes zoom-out{0%{opacity:1;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}100%{opacity:0;-webkit-transform:translateZ(-100px);-moz-transform:translateZ(-100px);-ms-transform:translateZ(-100px);-o-transform:translateZ(-100px);transform:translateZ(-100px)}}.setting-section{position:absolute;top:0;right:0;padding:22px}.ant-space-item .ant-switch{margin:2px 0 4px}@media (min-width:769px){.settings-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.settings-page .ant-tabs-nav .ant-tabs-tab{margin:0;padding:12px .5rem}}.settings-page .ant-tabs-bar{margin:0}.settings-page .ant-list-item{display:block}.settings-page .alert-msg{color:rgb(194,117,18);font-weight:normal;font-size:16px;padding:.5rem 1rem;text-align:center;background:rgb(255 145 0 / 15%);margin:1.5rem 2.5rem 0;border-radius:.5rem;transition:all .5s;animation:settings-signal 3s cubic-bezier(.18,.89,.32,1.28) infinite}.settings-page .alert-msg:hover{cursor:default;transition-duration:.3s;animation:settings-signal .9s ease infinite}@keyframes settings-signal{0%{box-shadow:0 0 0 0 rgba(194,118,18,.5)}50%{box-shadow:0 0 0 6px rgba(0,0,0,0)}100%{box-shadow:0 0 0 6px rgba(0,0,0,0)}}.settings-page .alert-msg>i{color:inherit;font-size:24px}.settings-page.dark .ant-input-password-icon{color:var(--dark-color-text-primary)}.settings-page .ant-collapse-content-box .ant-alert{margin-block-end:12px}@media (min-width:769px){.xray-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.xray-page .ant-tabs-nav .ant-tabs-tab{margin:0;padding:12px .5rem}.xray-page .ant-table-thead>tr>th,.xray-page .ant-table-tbody>tr>td{padding:10px 0}}.xray-page .ant-tabs-bar{margin:0}.xray-page .ant-list-item{display:block}.xray-page .ant-list-item>li{padding:10px 20px!important}.xray-page .ant-collapse-content-box .ant-alert{margin-block-end:12px}#app.login-app.dark #login input.ant-input:-webkit-autofill,#app.login-app.dark #login input.ant-input:-webkit-autofill:hover,#app.login-app.dark #login input.ant-input:-webkit-autofill:focus,#app.login-app.dark #login .ant-input-password input:-webkit-autofill,#app.login-app.dark #login .ant-input-password input:-webkit-autofill:hover,#app.login-app.dark #login .ant-input-password input:-webkit-autofill:focus{-webkit-text-fill-color:var(--login-input-color,#d6dce6)!important;caret-color:var(--login-input-color,#d6dce6)!important;-webkit-box-shadow:0 0 0 1000px var(--login-input-bg,#1d2433) inset!important;box-shadow:0 0 0 1000px var(--login-input-bg,#1d2433) inset!important;transition:background-color 9999s ease-in-out 0s!important}#app.login-app.dark #login input.ant-input:-moz-autofill,#app.login-app.dark #login .ant-input-password input:-moz-autofill{-moz-text-fill-color:var(--login-input-color,#d6dce6)!important;caret-color:var(--login-input-color,#d6dce6)!important;box-shadow:0 0 0 1000px var(--login-input-bg,#1d2433) inset!important}#app.login-app.dark #login{--login-input-bg:var(--dark-color-surface-200);--login-input-color:var(--dark-color-text-primary)} \ No newline at end of file diff --git a/web/html/inbounds.html b/web/html/inbounds.html index 58a4e5a5..54535e46 100644 --- a/web/html/inbounds.html +++ b/web/html/inbounds.html @@ -1,150 +1,8 @@ {{ template "page/head_start" .}} - {{ template "page/head_end" .}} {{ template "page/body_start" .}} - + diff --git a/web/html/index.html b/web/html/index.html index 5d5c3b1d..6f691876 100644 --- a/web/html/index.html +++ b/web/html/index.html @@ -1,73 +1,4 @@ {{ template "page/head_start" .}} - {{ template "page/head_end" .}} {{ template "page/body_start" .}} @@ -77,7 +8,7 @@ - - + - 10 20 @@ -410,7 +339,7 @@ 100 500 - Debug Info @@ -423,11 +352,11 @@ SysLog - + -
+
- + - 10 20 @@ -465,11 +394,11 @@ Blocked Proxy - + -
+
- + diff --git a/web/html/login.html b/web/html/login.html index 968aa0bc..b561b732 100644 --- a/web/html/login.html +++ b/web/html/login.html @@ -1,456 +1,10 @@ {{ template "page/head_start" .}} - {{ template "page/head_end" .}} {{ template "page/body_start" .}} - + - +
- - + + @@ -482,7 +35,7 @@ {{ i18n "pages.settings.language" }} - @@ -511,26 +64,24 @@ - + - + - + -
+
@@ -423,6 +428,36 @@ + + + +
+ +
+
{{template "page/body_scripts" .}} {{template "component/aSidebar" .}} @@ -430,6 +465,190 @@ {{template "component/aCustomStatistic" .}} {{template "modals/textModal"}} {{ template "page/body_end" .}} \ No newline at end of file diff --git a/web/html/modals/inbound_info_modal.html b/web/html/modals/inbound_info_modal.html index 8b825ca8..5112ec1c 100644 --- a/web/html/modals/inbound_info_modal.html +++ b/web/html/modals/inbound_info_modal.html @@ -180,9 +180,9 @@ {{ i18n "status" }} - {{ i18n "enabled" }} - {{ i18n "disabled" }} - {{ i18n "depleted" }} + {{ i18n "enabled" }} + {{ i18n "disabled" }} + {{ i18n "depleted" }} @@ -587,6 +587,14 @@ } return infoModal.dbInbound.isEnable; }, + get isDepleted() { + const stats = this.infoModal.clientStats; + if (!stats) return false; + const now = new Date().getTime(); + const expired = stats.expiryTime > 0 && now >= stats.expiryTime; + const exhausted = stats.total > 0 && (stats.up + stats.down) >= stats.total; + return expired || exhausted; + }, }, methods: { copy(content) { diff --git a/web/service/inbound.go b/web/service/inbound.go index d19668af..4abc88c3 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -1837,8 +1837,14 @@ func (s *InboundService) DelDepletedClients(id int) (err error) { whereText += "= ?" } + // Only consider truly depleted clients: expired OR traffic exhausted + now := time.Now().Unix() * 1000 depletedClients := []xray.ClientTraffic{} - err = db.Model(xray.ClientTraffic{}).Where(whereText+" and enable = ?", id, false).Select("inbound_id, GROUP_CONCAT(email) as email").Group("inbound_id").Find(&depletedClients).Error + err = db.Model(xray.ClientTraffic{}). + Where(whereText+" and ((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?))", id, now). + Select("inbound_id, GROUP_CONCAT(email) as email"). + Group("inbound_id"). + Find(&depletedClients).Error if err != nil { return err } @@ -1889,7 +1895,8 @@ func (s *InboundService) DelDepletedClients(id int) (err error) { } } - err = tx.Where(whereText+" and enable = ?", id, false).Delete(xray.ClientTraffic{}).Error + // Delete stats only for truly depleted clients + err = tx.Where(whereText+" and ((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?))", id, now).Delete(xray.ClientTraffic{}).Error if err != nil { return err } From bc274d1e1fc773f877b027e9f04d15faf8881ca5 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Tue, 16 Sep 2025 18:57:27 +0200 Subject: [PATCH 19/44] Reality: placeholder for min, max --- web/html/form/reality_settings.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/html/form/reality_settings.html b/web/html/form/reality_settings.html index 8758dae1..218ba86d 100644 --- a/web/html/form/reality_settings.html +++ b/web/html/form/reality_settings.html @@ -22,10 +22,10 @@ - + - + @@ -130,7 +130,8 @@ - [[ status.xray.version != 'Unknown' ? `v${status.xray.version}` : '{{ i18n "pages.index.xraySwitch" }}' ]] + [[ status.xray.version != 'Unknown' ? `v${status.xray.version}` : '{{ i18n + "pages.index.xraySwitch" }}' ]] @@ -175,7 +176,8 @@
- Xray: [[ TimeFormatter.formatSecond(status.appStats.uptime) ]] + Xray: [[ TimeFormatter.formatSecond(status.appStats.uptime) + ]] OS: [[ TimeFormatter.formatSecond(status.uptime) ]] @@ -193,7 +195,8 @@ - {{ i18n "pages.index.memory" }}: [[ SizeFormatter.sizeFormat(status.appStats.mem) ]] + {{ i18n "pages.index.memory" }}: [[ + SizeFormatter.sizeFormat(status.appStats.mem) ]] {{ i18n "pages.index.threads" }}: [[ status.appStats.threads ]] @@ -201,7 +204,8 @@ - + @@ -211,7 +215,8 @@ - + @@ -227,14 +232,16 @@ - + - + @@ -250,7 +257,8 @@ - + @@ -297,55 +305,54 @@ - + - - + + [[ version ]] - + - - + + [[ file ]] - + -
{{ i18n "pages.index.geofilesUpdateAll" }}
+
{{ i18n + "pages.index.geofilesUpdateAll" }}
- + - + - + 10 20 50 100 500 - + Debug Info Notice @@ -358,31 +365,25 @@ SysLog - + -
+
- + - + - + 10 20 50 @@ -400,24 +401,21 @@ Proxy - + -
+
- - + + - + @@ -429,33 +427,25 @@ - +
- + +
Timeframe: [[ cpuHistoryModal.bucket ]] sec per point (total [[ cpuHistoryLong.length ]] points)
@@ -543,7 +533,7 @@ const last = this.pointsArr[this.pointsArr.length - 1] const line = this.points // Close to bottom to create an area fill - return `M ${first[0]},${this.paddingTop + this.drawHeight} L ${line.replace(/ /g,' L ')} L ${last[0]},${this.paddingTop + this.drawHeight} Z` + return `M ${first[0]},${this.paddingTop + this.drawHeight} L ${line.replace(/ /g, ' L ')} L ${last[0]},${this.paddingTop + this.drawHeight} Z` }, gridLines() { if (!this.showGrid) return [] @@ -609,7 +599,8 @@ const labels = this.labelsSlice const idx = this.hoverIdx if (idx < 0 || idx >= this.dataSlice.length) return '' - const val = Math.max(0, Math.min(100, Number(this.dataSlice[idx] || 0))) + const raw = Math.max(0, Math.min(100, Number(this.dataSlice[idx] || 0))) + const val = Number.isFinite(raw) ? raw.toFixed(2) : raw const lab = labels[idx] != null ? labels[idx] : '' return `${val}%${lab ? ' • ' + lab : ''}` }, @@ -649,195 +640,196 @@ `, }) - class CurTotal { - constructor(current, total) { - this.current = current; - this.total = total; - } + class CurTotal { - get percent() { - if (this.total === 0) { - return 0; - } - return NumberFormatter.toFixed(this.current / this.total * 100, 2); - } - - get color() { - const percent = this.percent; - if (percent < 80) { - return '#008771'; // Green - } else if (percent < 90) { - return "#f37b24"; // Orange - } else { - return "#cf3c3c"; // Red - } - } + constructor(current, total) { + this.current = current; + this.total = total; } - class Status { - constructor(data) { - this.cpu = new CurTotal(0, 0); - this.cpuCores = 0; - this.logicalPro = 0; - this.cpuSpeedMhz = 0; - this.disk = new CurTotal(0, 0); - this.loads = [0, 0, 0]; - this.mem = new CurTotal(0, 0); - this.netIO = { up: 0, down: 0 }; - this.netTraffic = { sent: 0, recv: 0 }; - this.publicIP = { ipv4: 0, ipv6: 0 }; - this.swap = new CurTotal(0, 0); - this.tcpCount = 0; - this.udpCount = 0; - this.uptime = 0; - this.appUptime = 0; - this.appStats = {threads: 0, mem: 0, uptime: 0}; - - this.xray = { state: 'stop', stateMsg: "", errorMsg: "", version: "", color: "" }; - - if (data == null) { - return; - } - - this.cpu = new CurTotal(data.cpu, 100); - this.cpuCores = data.cpuCores; - this.logicalPro = data.logicalPro; - this.cpuSpeedMhz = data.cpuSpeedMhz; - this.disk = new CurTotal(data.disk.current, data.disk.total); - this.loads = data.loads.map(load => NumberFormatter.toFixed(load, 2)); - this.mem = new CurTotal(data.mem.current, data.mem.total); - this.netIO = data.netIO; - this.netTraffic = data.netTraffic; - this.publicIP = data.publicIP; - this.swap = new CurTotal(data.swap.current, data.swap.total); - this.tcpCount = data.tcpCount; - this.udpCount = data.udpCount; - this.uptime = data.uptime; - this.appUptime = data.appUptime; - this.appStats = data.appStats; - this.xray = data.xray; - switch (this.xray.state) { - case 'running': - this.xray.color = "green"; - this.xray.stateMsg = '{{ i18n "pages.index.xrayStatusRunning" }}'; - break; - case 'stop': - this.xray.color = "orange"; - this.xray.stateMsg = '{{ i18n "pages.index.xrayStatusStop" }}'; - break; - case 'error': - this.xray.color = "red"; - this.xray.stateMsg ='{{ i18n "pages.index.xrayStatusError" }}'; - break; - default: - this.xray.color = "gray"; - this.xray.stateMsg = '{{ i18n "pages.index.xrayStatusUnknown" }}'; - break; - } - } + get percent() { + if (this.total === 0) { + return 0; + } + return NumberFormatter.toFixed(this.current / this.total * 100, 2); } - const versionModal = { - visible: false, - versions: [], - show(versions) { - this.visible = true; - this.versions = versions; - }, - hide() { - this.visible = false; - }, - }; + get color() { + const percent = this.percent; + if (percent < 80) { + return '#008771'; // Green + } else if (percent < 90) { + return "#f37b24"; // Orange + } else { + return "#cf3c3c"; // Red + } + } + } - const logModal = { - visible: false, - logs: [], - rows: 20, - level: 'info', - syslog: false, - loading: false, - show(logs) { - this.visible = true; - this.logs = logs; - this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record..."; - }, - formatLogs(logs) { - let formattedLogs = ''; - const levels = ["DEBUG","INFO","NOTICE","WARNING","ERROR"]; - const levelColors = ["#3c89e8","#008771","#008771","#f37b24","#e04141","#bcbcbc"]; + class Status { + constructor(data) { + this.cpu = new CurTotal(0, 0); + this.cpuCores = 0; + this.logicalPro = 0; + this.cpuSpeedMhz = 0; + this.disk = new CurTotal(0, 0); + this.loads = [0, 0, 0]; + this.mem = new CurTotal(0, 0); + this.netIO = { up: 0, down: 0 }; + this.netTraffic = { sent: 0, recv: 0 }; + this.publicIP = { ipv4: 0, ipv6: 0 }; + this.swap = new CurTotal(0, 0); + this.tcpCount = 0; + this.udpCount = 0; + this.uptime = 0; + this.appUptime = 0; + this.appStats = { threads: 0, mem: 0, uptime: 0 }; - logs.forEach((log, index) => { - let [data, message] = log.split(" - ",2); - const parts = data.split(" ") - if(index>0) formattedLogs += '
'; + this.xray = { state: 'stop', stateMsg: "", errorMsg: "", version: "", color: "" }; - if (parts.length === 3) { - const d = parts[0]; - const t = parts[1]; - const level = parts[2]; - const levelIndex = levels.indexOf(level,levels) || 5; + if (data == null) { + return; + } - //formattedLogs += `${index + 1}.`; - formattedLogs += `${d} ${t} `; - formattedLogs += `${level}`; - } else { - const levelIndex = levels.indexOf(data,levels) || 5; - formattedLogs += `${data}`; - } + this.cpu = new CurTotal(data.cpu, 100); + this.cpuCores = data.cpuCores; + this.logicalPro = data.logicalPro; + this.cpuSpeedMhz = data.cpuSpeedMhz; + this.disk = new CurTotal(data.disk.current, data.disk.total); + this.loads = data.loads.map(load => NumberFormatter.toFixed(load, 2)); + this.mem = new CurTotal(data.mem.current, data.mem.total); + this.netIO = data.netIO; + this.netTraffic = data.netTraffic; + this.publicIP = data.publicIP; + this.swap = new CurTotal(data.swap.current, data.swap.total); + this.tcpCount = data.tcpCount; + this.udpCount = data.udpCount; + this.uptime = data.uptime; + this.appUptime = data.appUptime; + this.appStats = data.appStats; + this.xray = data.xray; + switch (this.xray.state) { + case 'running': + this.xray.color = "green"; + this.xray.stateMsg = '{{ i18n "pages.index.xrayStatusRunning" }}'; + break; + case 'stop': + this.xray.color = "orange"; + this.xray.stateMsg = '{{ i18n "pages.index.xrayStatusStop" }}'; + break; + case 'error': + this.xray.color = "red"; + this.xray.stateMsg = '{{ i18n "pages.index.xrayStatusError" }}'; + break; + default: + this.xray.color = "gray"; + this.xray.stateMsg = '{{ i18n "pages.index.xrayStatusUnknown" }}'; + break; + } + } + } - if(message){ - if(message.startsWith("XRAY:")) - message = "XRAY: " + message.substring(5); - else - message = "X-UI: " + message; - } + const versionModal = { + visible: false, + versions: [], + show(versions) { + this.visible = true; + this.versions = versions; + }, + hide() { + this.visible = false; + }, + }; - formattedLogs += message ? ' - ' + message : ''; - }); + const logModal = { + visible: false, + logs: [], + rows: 20, + level: 'info', + syslog: false, + loading: false, + show(logs) { + this.visible = true; + this.logs = logs; + this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record..."; + }, + formatLogs(logs) { + let formattedLogs = ''; + const levels = ["DEBUG", "INFO", "NOTICE", "WARNING", "ERROR"]; + const levelColors = ["#3c89e8", "#008771", "#008771", "#f37b24", "#e04141", "#bcbcbc"]; - return formattedLogs; - }, - hide() { - this.visible = false; - }, - }; + logs.forEach((log, index) => { + let [data, message] = log.split(" - ", 2); + const parts = data.split(" ") + if (index > 0) formattedLogs += '
'; - const xraylogModal = { - visible: false, - logs: [], - rows: 20, - showDirect: true, - showBlocked: true, - showProxy: true, - loading: false, - show(logs) { - this.visible = true; - this.logs = logs; - this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record..."; - }, - formatLogs(logs) { - let formattedLogs = ''; + if (parts.length === 3) { + const d = parts[0]; + const t = parts[1]; + const level = parts[2]; + const levelIndex = levels.indexOf(level, levels) || 5; - logs.forEach((log, index) => { - if(index > 0) formattedLogs += '
'; + //formattedLogs += `${index + 1}.`; + formattedLogs += `${d} ${t} `; + formattedLogs += `${level}`; + } else { + const levelIndex = levels.indexOf(data, levels) || 5; + formattedLogs += `${data}`; + } - const parts = log.split(' '); + if (message) { + if (message.startsWith("XRAY:")) + message = "XRAY: " + message.substring(5); + else + message = "X-UI: " + message; + } - if(parts.length === 10) { - const dateTime = `${parts[0]} ${parts[1]}`; - const from = `${parts[3]}`; - const to = `${parts[5].replace(/^\/+/, "")}`; + formattedLogs += message ? ' - ' + message : ''; + }); - let outboundColor = ''; - if (parts[9] === "b") { - outboundColor = ' style="color: #e04141;"'; //red for blocked - } - else if (parts[9] === "p") { - outboundColor = ' style="color: #3c89e8;"'; //blue for proxies - } + return formattedLogs; + }, + hide() { + this.visible = false; + }, + }; - formattedLogs += ` + const xraylogModal = { + visible: false, + logs: [], + rows: 20, + showDirect: true, + showBlocked: true, + showProxy: true, + loading: false, + show(logs) { + this.visible = true; + this.logs = logs; + this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record..."; + }, + formatLogs(logs) { + let formattedLogs = ''; + + logs.forEach((log, index) => { + if (index > 0) formattedLogs += '
'; + + const parts = log.split(' '); + + if (parts.length === 10) { + const dateTime = `${parts[0]} ${parts[1]}`; + const from = `${parts[3]}`; + const to = `${parts[5].replace(/^\/+/, "")}`; + + let outboundColor = ''; + if (parts[9] === "b") { + outboundColor = ' style="color: #e04141;"'; //red for blocked + } + else if (parts[9] === "p") { + outboundColor = ' style="color: #3c89e8;"'; //blue for proxies + } + + formattedLogs += ` ${dateTime} ${parts[2]} ${from} @@ -845,261 +837,260 @@ ${dateTime} ${to} ${parts.slice(6, 9).join(' ')} `; - } else { - formattedLogs += `${log}`; - } - }); + } else { + formattedLogs += `${log}`; + } + }); - return formattedLogs; - }, - hide() { - this.visible = false; - }, - }; + return formattedLogs; + }, + hide() { + this.visible = false; + }, + }; - const backupModal = { - visible: false, - show() { - this.visible = true; - }, - hide() { - this.visible = false; - }, - }; + const backupModal = { + visible: false, + show() { + this.visible = true; + }, + hide() { + this.visible = false; + }, + }; - const app = new Vue({ - delimiters: ['[[', ']]'], - el: '#app', - mixins: [MediaQueryMixin], - data: { - themeSwitcher, - loadingStates: { - fetched: false, - spinning: false - }, - status: new Status(), - cpuHistory: [], // keep last N cpu utilization points (0..100) - cpuHistoryLong: [], // long-range history for modal (values) - cpuHistoryLabels: [], // formatted timestamps matching long history - cpuHistoryModal: { visible: false, minutes: 60 }, - versionModal, - logModal, - xraylogModal, - backupModal, - loadingTip: '{{ i18n "loading"}}', - showAlert: false, - showIp: false, - ipLimitEnable: false, - }, - methods: { - loading(spinning, tip = '{{ i18n "loading"}}') { - this.loadingStates.spinning = spinning; - this.loadingTip = tip; - }, - async getStatus() { - try { - const msg = await HttpUtil.get('/panel/api/server/status'); - if (msg.success) { - if (!this.loadingStates.fetched) { - this.loadingStates.fetched = true; - } - - this.setStatus(msg.obj, true); - } - } catch (e) { - console.error("Failed to get status:", e); - } - }, - setStatus(data) { - this.status = new Status(data); - // Push CPU percent into history (clamped 0..100) - const v = Math.max(0, Math.min(100, Number(data?.cpu ?? 0))) - this.cpuHistory.push(v) - const maxPoints = this.isMobile ? 60 : 120 - if (this.cpuHistory.length > maxPoints) { - this.cpuHistory.splice(0, this.cpuHistory.length - maxPoints) - } - }, - openCpuHistory() { - this.cpuHistoryModal.visible = true - this.loadCpuHistory() + const app = new Vue({ + delimiters: ['[[', ']]'], + el: '#app', + mixins: [MediaQueryMixin], + data: { + themeSwitcher, + loadingStates: { + fetched: false, + spinning: false }, - async loadCpuHistory() { - const mins = this.cpuHistoryModal.minutes || 60 + status: new Status(), + cpuHistory: [], // small live widget history + cpuHistoryLong: [], // aggregated points from backend + cpuHistoryLabels: [], + cpuHistoryModal: { visible: false, bucket: 2 }, + versionModal, + logModal, + xraylogModal, + backupModal, + loadingTip: '{{ i18n "loading"}}', + showAlert: false, + showIp: false, + ipLimitEnable: false, + }, + methods: { + loading(spinning, tip = '{{ i18n "loading"}}') { + this.loadingStates.spinning = spinning; + this.loadingTip = tip; + }, + async getStatus() { try { - const msg = await HttpUtil.get(`/panel/api/server/cpuHistory?q=${mins}`) - if (msg.success && Array.isArray(msg.obj)) { - // msg.obj is array of {t, cpu} - const arr = msg.obj.map(p => Math.max(0, Math.min(100, Number(p.cpu || 0)))) - const labels = msg.obj.map(p => { - const t = p.t - let d - if (typeof t === 'number') { - // Heuristic: if seconds, convert to ms - d = new Date(t < 1e12 ? t * 1000 : t) - } else { - d = new Date(t) - } - if (isNaN(d.getTime())) return '' - const hh = String(d.getHours()).padStart(2, '0') - const mm = String(d.getMinutes()).padStart(2, '0') - return `${hh}:${mm}` - }) - this.cpuHistoryLong = arr - this.cpuHistoryLabels = labels + const msg = await HttpUtil.get('/panel/api/server/status'); + if (msg.success) { + if (!this.loadingStates.fetched) { + this.loadingStates.fetched = true; + } + + this.setStatus(msg.obj, true); } } catch (e) { - console.error('Failed to load CPU history', e) + console.error("Failed to get status:", e); } }, - async openSelectV2rayVersion() { - this.loading(true); - const msg = await HttpUtil.get('/panel/api/server/getXrayVersion'); - this.loading(false); - if (!msg.success) { - return; - } - versionModal.show(msg.obj); - }, - switchV2rayVersion(version) { - this.$confirm({ - title: '{{ i18n "pages.index.xraySwitchVersionDialog"}}', - content: '{{ i18n "pages.index.xraySwitchVersionDialogDesc"}}'.replace('#version#', version), - okText: '{{ i18n "confirm"}}', - class: themeSwitcher.currentTheme, - cancelText: '{{ i18n "cancel"}}', - onOk: async () => { - versionModal.hide(); - this.loading(true, '{{ i18n "pages.index.dontRefresh"}}'); - await HttpUtil.post(`/panel/api/server/installXray/${version}`); - this.loading(false); - }, - }); - }, - updateGeofile(fileName) { - const isSingleFile = !!fileName; - this.$confirm({ - title: '{{ i18n "pages.index.geofileUpdateDialog" }}', - content: isSingleFile - ? '{{ i18n "pages.index.geofileUpdateDialogDesc" }}'.replace("#filename#", fileName) - : '{{ i18n "pages.index.geofilesUpdateDialogDesc" }}', - okText: '{{ i18n "confirm"}}', - class: themeSwitcher.currentTheme, - cancelText: '{{ i18n "cancel"}}', - onOk: async () => { - versionModal.hide(); - this.loading(true, '{{ i18n "pages.index.dontRefresh"}}'); - const url = isSingleFile - ? `/panel/api/server/updateGeofile/${fileName}` - : `/panel/api/server/updateGeofile`; - await HttpUtil.post(url); - this.loading(false); - }, - }); - }, - async stopXrayService() { - this.loading(true); - const msg = await HttpUtil.post('/panel/api/server/stopXrayService'); - this.loading(false); - if (!msg.success) { - return; - } - }, - async restartXrayService() { - this.loading(true); - const msg = await HttpUtil.post('/panel/api/server/restartXrayService'); - this.loading(false); - if (!msg.success) { - return; - } - }, - async openLogs(){ - logModal.loading = true; - const msg = await HttpUtil.post('/panel/api/server/logs/'+logModal.rows,{level: logModal.level, syslog: logModal.syslog}); - if (!msg.success) { - return; - } - logModal.show(msg.obj); - await PromiseUtil.sleep(500); - logModal.loading = false; - }, - async openXrayLogs(){ - xraylogModal.loading = true; - const msg = await HttpUtil.post('/panel/api/server/xraylogs/'+xraylogModal.rows,{filter: xraylogModal.filter, showDirect: xraylogModal.showDirect, showBlocked: xraylogModal.showBlocked, showProxy: xraylogModal.showProxy}); - if (!msg.success) { - return; - } - xraylogModal.show(msg.obj); - await PromiseUtil.sleep(500); - xraylogModal.loading = false; - }, - async openConfig() { - this.loading(true); - const msg = await HttpUtil.get('/panel/api/server/getConfigJson'); - this.loading(false); - if (!msg.success) { - return; - } - txtModal.show('config.json', JSON.stringify(msg.obj, null, 2), 'config.json'); - }, - openBackup() { - backupModal.show(); - }, - exportDatabase() { - window.location = basePath + 'panel/api/server/getDb'; - }, - importDatabase() { - const fileInput = document.createElement('input'); - fileInput.type = 'file'; - fileInput.accept = '.db'; - fileInput.addEventListener('change', async (event) => { - const dbFile = event.target.files[0]; - if (dbFile) { - const formData = new FormData(); - formData.append('db', dbFile); - backupModal.hide(); - this.loading(true); - const uploadMsg = await HttpUtil.post('/panel/api/server/importDB', formData, { - headers: { - 'Content-Type': 'multipart/form-data', - } - }); - this.loading(false); - if (!uploadMsg.success) { - return; - } - this.loading(true); - const restartMsg = await HttpUtil.post("/panel/setting/restartPanel"); - this.loading(false); - if (restartMsg.success) { - this.loading(true); - await PromiseUtil.sleep(5000); - location.reload(); - } - } - }); - fileInput.click(); - }, - }, - async mounted() { - if (window.location.protocol !== "https:") { - this.showAlert = true; + setStatus(data) { + this.status = new Status(data); + // Push CPU percent into history (clamped 0..100) + const v = Math.max(0, Math.min(100, Number(data?.cpu ?? 0))) + this.cpuHistory.push(v) + const maxPoints = this.isMobile ? 60 : 120 + if (this.cpuHistory.length > maxPoints) { + this.cpuHistory.splice(0, this.cpuHistory.length - maxPoints) + } + // If modal open, refresh current bucketed data + if (this.cpuHistoryModal.visible) { + this.fetchCpuHistoryBucket() + } + }, + openCpuHistory() { + this.cpuHistoryModal.visible = true + this.fetchCpuHistoryBucket() + }, + async fetchCpuHistoryBucket() { + const bucket = this.cpuHistoryModal.bucket || 2 + try { + const msg = await HttpUtil.get(`/panel/api/server/cpuHistory/${bucket}`) + if (msg.success && Array.isArray(msg.obj)) { + const vals = [] + const labels = [] + for (const p of msg.obj) { + const d = new Date(p.t * 1000) + const hh = String(d.getHours()).padStart(2,'0') + const mm = String(d.getMinutes()).padStart(2,'0') + const ss = String(d.getSeconds()).padStart(2,'0') + labels.push(bucket>=60 ? `${hh}:${mm}` : `${hh}:${mm}:${ss}`) + vals.push(Math.max(0, Math.min(100, p.cpu))) } + this.cpuHistoryLabels = labels + this.cpuHistoryLong = vals + } + } catch(e) { + console.error('Failed to fetch bucketed cpu history', e) + } + }, + async openSelectV2rayVersion() { + this.loading(true); + const msg = await HttpUtil.get('/panel/api/server/getXrayVersion'); + this.loading(false); + if (!msg.success) { + return; + } + versionModal.show(msg.obj); + }, + switchV2rayVersion(version) { + this.$confirm({ + title: '{{ i18n "pages.index.xraySwitchVersionDialog"}}', + content: '{{ i18n "pages.index.xraySwitchVersionDialogDesc"}}'.replace('#version#', version), + okText: '{{ i18n "confirm"}}', + class: themeSwitcher.currentTheme, + cancelText: '{{ i18n "cancel"}}', + onOk: async () => { + versionModal.hide(); + this.loading(true, '{{ i18n "pages.index.dontRefresh"}}'); + await HttpUtil.post(`/panel/api/server/installXray/${version}`); + this.loading(false); + }, + }); + }, + updateGeofile(fileName) { + const isSingleFile = !!fileName; + this.$confirm({ + title: '{{ i18n "pages.index.geofileUpdateDialog" }}', + content: isSingleFile + ? '{{ i18n "pages.index.geofileUpdateDialogDesc" }}'.replace("#filename#", fileName) + : '{{ i18n "pages.index.geofilesUpdateDialogDesc" }}', + okText: '{{ i18n "confirm"}}', + class: themeSwitcher.currentTheme, + cancelText: '{{ i18n "cancel"}}', + onOk: async () => { + versionModal.hide(); + this.loading(true, '{{ i18n "pages.index.dontRefresh"}}'); + const url = isSingleFile + ? `/panel/api/server/updateGeofile/${fileName}` + : `/panel/api/server/updateGeofile`; + await HttpUtil.post(url); + this.loading(false); + }, + }); + }, + async stopXrayService() { + this.loading(true); + const msg = await HttpUtil.post('/panel/api/server/stopXrayService'); + this.loading(false); + if (!msg.success) { + return; + } + }, + async restartXrayService() { + this.loading(true); + const msg = await HttpUtil.post('/panel/api/server/restartXrayService'); + this.loading(false); + if (!msg.success) { + return; + } + }, + async openLogs() { + logModal.loading = true; + const msg = await HttpUtil.post('/panel/api/server/logs/' + logModal.rows, { level: logModal.level, syslog: logModal.syslog }); + if (!msg.success) { + return; + } + logModal.show(msg.obj); + await PromiseUtil.sleep(500); + logModal.loading = false; + }, + async openXrayLogs() { + xraylogModal.loading = true; + const msg = await HttpUtil.post('/panel/api/server/xraylogs/' + xraylogModal.rows, { filter: xraylogModal.filter, showDirect: xraylogModal.showDirect, showBlocked: xraylogModal.showBlocked, showProxy: xraylogModal.showProxy }); + if (!msg.success) { + return; + } + xraylogModal.show(msg.obj); + await PromiseUtil.sleep(500); + xraylogModal.loading = false; + }, + async openConfig() { + this.loading(true); + const msg = await HttpUtil.get('/panel/api/server/getConfigJson'); + this.loading(false); + if (!msg.success) { + return; + } + txtModal.show('config.json', JSON.stringify(msg.obj, null, 2), 'config.json'); + }, + openBackup() { + backupModal.show(); + }, + exportDatabase() { + window.location = basePath + 'panel/api/server/getDb'; + }, + importDatabase() { + const fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = '.db'; + fileInput.addEventListener('change', async (event) => { + const dbFile = event.target.files[0]; + if (dbFile) { + const formData = new FormData(); + formData.append('db', dbFile); + backupModal.hide(); + this.loading(true); + const uploadMsg = await HttpUtil.post('/panel/api/server/importDB', formData, { + headers: { + 'Content-Type': 'multipart/form-data', + } + }); + this.loading(false); + if (!uploadMsg.success) { + return; + } + this.loading(true); + const restartMsg = await HttpUtil.post("/panel/setting/restartPanel"); + this.loading(false); + if (restartMsg.success) { + this.loading(true); + await PromiseUtil.sleep(5000); + location.reload(); + } + } + }); + fileInput.click(); + }, + }, + computed: {}, + async mounted() { + if (window.location.protocol !== "https:") { + this.showAlert = true; + } - const msg = await HttpUtil.post('/panel/setting/defaultSettings'); - if (msg.success) { - this.ipLimitEnable = msg.obj.ipLimitEnable; - } + const msg = await HttpUtil.post('/panel/setting/defaultSettings'); + if (msg.success) { + this.ipLimitEnable = msg.obj.ipLimitEnable; + } - while (true) { - try { - await this.getStatus(); - } catch (e) { - console.error(e); - } - await PromiseUtil.sleep(2000); - } - }, - }); + while (true) { + try { + await this.getStatus(); + } catch (e) { + console.error(e); + } + await PromiseUtil.sleep(2000); + } + }, + }); {{ template "page/body_end" .}} \ No newline at end of file diff --git a/web/service/server.go b/web/service/server.go index de6cc7f5..f0ad3265 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -94,22 +94,81 @@ type Release struct { } type ServerService struct { - xrayService XrayService - inboundService InboundService - cachedIPv4 string - cachedIPv6 string - noIPv6 bool - // CPU utilization smoothing state - mu sync.Mutex - lastCPUTimes cpu.TimesStat - hasLastCPUSample bool - emaCPU float64 - // CPU history buffer (in-memory, protected by mu) - cpuHistory []CPUSample - cpuCapacity int + xrayService XrayService + inboundService InboundService + cachedIPv4 string + cachedIPv6 string + noIPv6 bool + mu sync.Mutex + lastCPUTimes cpu.TimesStat + hasLastCPUSample bool + emaCPU float64 + cpuHistory []CPUSample + cachedCpuSpeedMhz float64 + lastCpuInfoAttempt time.Time } -// CPUSample represents a single CPU utilization sample with timestamp +// AggregateCpuHistory returns up to maxPoints averaged buckets of size bucketSeconds over recent data. +func (s *ServerService) AggregateCpuHistory(bucketSeconds int, maxPoints int) []map[string]any { + if bucketSeconds <= 0 || maxPoints <= 0 { + return nil + } + cutoff := time.Now().Add(-time.Duration(bucketSeconds*maxPoints) * time.Second).Unix() + s.mu.Lock() + // find start index (history sorted ascending) + hist := s.cpuHistory + // binary-ish scan (simple linear from end since size capped ~10800 is fine) + startIdx := 0 + for i := len(hist) - 1; i >= 0; i-- { + if hist[i].T < cutoff { + startIdx = i + 1 + break + } + } + if startIdx >= len(hist) { + s.mu.Unlock() + return []map[string]any{} + } + slice := hist[startIdx:] + // copy for unlock + tmp := make([]CPUSample, len(slice)) + copy(tmp, slice) + s.mu.Unlock() + if len(tmp) == 0 { + return []map[string]any{} + } + var out []map[string]any + var acc []float64 + bSize := int64(bucketSeconds) + curBucket := (tmp[0].T / bSize) * bSize + flush := func(ts int64) { + if len(acc) == 0 { + return + } + sum := 0.0 + for _, v := range acc { + sum += v + } + avg := sum / float64(len(acc)) + out = append(out, map[string]any{"t": ts, "cpu": avg}) + acc = acc[:0] + } + for _, p := range tmp { + b := (p.T / bSize) * bSize + if b != curBucket { + flush(curBucket) + curBucket = b + } + acc = append(acc, p.Cpu) + } + flush(curBucket) + if len(out) > maxPoints { + out = out[len(out)-maxPoints:] + } + return out +} + +// CPUSample single CPU utilization sample type CPUSample struct { T int64 `json:"t"` // unix seconds Cpu float64 `json:"cpu"` // percent 0..100 @@ -168,13 +227,30 @@ func (s *ServerService) GetStatus(lastStatus *Status) *Status { status.LogicalPro = runtime.NumCPU() - cpuInfos, err := cpu.Info() - if err != nil { - logger.Warning("get cpu info failed:", err) - } else if len(cpuInfos) > 0 { - status.CpuSpeedMhz = cpuInfos[0].Mhz - } else { - logger.Warning("could not find cpu info") + if status.CpuSpeedMhz = s.cachedCpuSpeedMhz; s.cachedCpuSpeedMhz == 0 && time.Since(s.lastCpuInfoAttempt) > 5*time.Minute { + s.lastCpuInfoAttempt = time.Now() + done := make(chan struct{}) + go func() { + defer close(done) + cpuInfos, err := cpu.Info() + if err != nil { + logger.Warning("get cpu info failed:", err) + return + } + if len(cpuInfos) > 0 { + s.cachedCpuSpeedMhz = cpuInfos[0].Mhz + status.CpuSpeedMhz = s.cachedCpuSpeedMhz + } else { + logger.Warning("could not find cpu info") + } + }() + select { + case <-done: + case <-time.After(1500 * time.Millisecond): + logger.Warning("cpu info query timed out; will retry later") + } + } else if s.cachedCpuSpeedMhz != 0 { + status.CpuSpeedMhz = s.cachedCpuSpeedMhz } // Uptime @@ -322,55 +398,21 @@ func (s *ServerService) GetStatus(lastStatus *Status) *Status { return status } -// AppendCpuSample appends a CPU sample into the in-memory history with capacity trimming. func (s *ServerService) AppendCpuSample(t time.Time, v float64) { + const capacity = 9000 // ~5 hours @ 2s interval s.mu.Lock() defer s.mu.Unlock() - if s.cpuCapacity == 0 { - s.cpuCapacity = 10800 // ~6 hours at 2s per sample - } p := CPUSample{T: t.Unix(), Cpu: v} - s.cpuHistory = append(s.cpuHistory, p) - if len(s.cpuHistory) > s.cpuCapacity { - drop := len(s.cpuHistory) - s.cpuCapacity - s.cpuHistory = s.cpuHistory[drop:] + if n := len(s.cpuHistory); n > 0 && s.cpuHistory[n-1].T == p.T { + s.cpuHistory[n-1] = p + } else { + s.cpuHistory = append(s.cpuHistory, p) + } + if len(s.cpuHistory) > capacity { + s.cpuHistory = s.cpuHistory[len(s.cpuHistory)-capacity:] } } -// GetCpuHistory returns samples from the last 'mins' minutes (bounded 1..360). -func (s *ServerService) GetCpuHistory(mins int) []CPUSample { - if mins < 1 { - mins = 1 - } - if mins > 360 { - mins = 360 - } - cutoff := time.Now().Add(-time.Duration(mins) * time.Minute).Unix() - s.mu.Lock() - defer s.mu.Unlock() - if len(s.cpuHistory) == 0 { - return nil - } - // find first index >= cutoff (linear scan from end is fine for these sizes) - i := len(s.cpuHistory) - 1 - for ; i >= 0; i-- { - if s.cpuHistory[i].T < cutoff { - i++ - break - } - } - if i < 0 { - i = 0 - } - // copy to avoid exposing internal slice - out := make([]CPUSample, len(s.cpuHistory)-i) - copy(out, s.cpuHistory[i:]) - return out -} - -// sampleCPUUtilization returns a smoothed total CPU utilization percentage across all logical processors. -// It computes utilization from CPU time deltas (non-blocking) and applies an exponential moving average -// to reduce spikes similar to Task Manager's smoothing. func (s *ServerService) sampleCPUUtilization() (float64, error) { // Prefer native Windows API to avoid external deps for CPU percent if runtime.GOOS == "windows" { From 299572a4c23f9ea70c5008c86ec6ee1c02012f99 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Wed, 17 Sep 2025 01:29:22 +0200 Subject: [PATCH 21/44] API: subid to getClientTraffics /getClientTraffics/:email /getClientTrafficsById/:id --- web/service/inbound.go | 3 ++- xray/client_traffic.go | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/web/service/inbound.go b/web/service/inbound.go index 4abc88c3..b0aed169 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -1951,8 +1951,8 @@ func (s *InboundService) GetClientTrafficByEmail(email string) (traffic *xray.Cl return nil, err } if t != nil && client != nil { - // Ensure enable mirrors the client's current enable flag in settings t.Enable = client.Enable + t.SubId = client.SubID return t, nil } return nil, nil @@ -1993,6 +1993,7 @@ func (s *InboundService) GetClientTrafficByID(id string) ([]xray.ClientTraffic, for i := range traffics { if ct, client, e := s.GetClientByEmail(traffics[i].Email); e == nil && ct != nil && client != nil { traffics[i].Enable = client.Enable + traffics[i].SubId = client.SubID } } return traffics, err diff --git a/xray/client_traffic.go b/xray/client_traffic.go index fe527d55..84c509ac 100644 --- a/xray/client_traffic.go +++ b/xray/client_traffic.go @@ -5,6 +5,7 @@ type ClientTraffic struct { InboundId int `json:"inboundId" form:"inboundId"` Enable bool `json:"enable" form:"enable"` Email string `json:"email" form:"email" gorm:"unique"` + SubId string `json:"subId" form:"subId" gorm:"-"` Up int64 `json:"up" form:"up"` Down int64 `json:"down" form:"down"` AllTime int64 `json:"allTime" form:"allTime"` From 2eb8abf61e6aae94ef3cefae33c2a08595cc5fce Mon Sep 17 00:00:00 2001 From: fgsfds <4870330+fgsfds@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:19:55 +0500 Subject: [PATCH 22/44] Improved xray logs display handling (#3475) * improved xray logs handling * fix download Xray Logs * Update index.html --- web/html/index.html | 125 ++++++++++++++++++++++++++---------------- web/service/server.go | 73 ++++++++++++++++++------ 2 files changed, 135 insertions(+), 63 deletions(-) diff --git a/web/html/index.html b/web/html/index.html index 819d6df2..4ddf26b5 100644 --- a/web/html/index.html +++ b/web/html/index.html @@ -365,8 +365,7 @@ SysLog - +
@@ -401,8 +400,7 @@ Proxy - +
@@ -796,59 +794,74 @@ }; const xraylogModal = { - visible: false, - logs: [], - rows: 20, - showDirect: true, - showBlocked: true, - showProxy: true, - loading: false, - show(logs) { - this.visible = true; - this.logs = logs; - this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record..."; - }, - formatLogs(logs) { - let formattedLogs = ''; + visible: false, + logs: [], + rows: 20, + showDirect: true, + showBlocked: true, + showProxy: true, + loading: false, + show(logs) { + this.visible = true; + this.logs = logs; + this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record..."; + }, + formatLogs(logs) { + let formattedLogs = ` + - const parts = log.split(' '); - - if (parts.length === 10) { - const dateTime = `${parts[0]} ${parts[1]}`; - const from = `${parts[3]}`; - const to = `${parts[5].replace(/^\/+/, "")}`; + + + + + + + + + +`; + logs.reverse().forEach((log, index) => { let outboundColor = ''; - if (parts[9] === "b") { + if (log.Event === 1) { outboundColor = ' style="color: #e04141;"'; //red for blocked } - else if (parts[9] === "p") { + else if (log.Event === 2) { outboundColor = ' style="color: #3c89e8;"'; //blue for proxies } - formattedLogs += ` -${dateTime} - ${parts[2]} - ${from} - ${parts[4]} - ${to} - ${parts.slice(6, 9).join(' ')} -`; - } else { - formattedLogs += `${log}`; - } - }); + let text = ``; + if (log.Email !== "") { + text = ``; + } - return formattedLogs; - }, - hide() { - this.visible = false; - }, - }; + formattedLogs += ` + + + + + + + ${text} + +`; + }); + return formattedLogs += "
DateFromToInboundOutboundEmail
${log.Email}
${new Date(log.DateTime).toLocaleString()}${log.FromAddress}${log.ToAddress}${log.Inbound}${log.Outbound}
"; + }, + hide() { + this.visible = false; + }, + }; const backupModal = { visible: false, show() { @@ -1023,6 +1036,25 @@ ${dateTime} await PromiseUtil.sleep(500); xraylogModal.loading = false; }, + downloadXrayLogs() { + if (!Array.isArray(this.xraylogModal.logs) || this.xraylogModal.logs.length === 0) { + FileManager.downloadTextFile('', 'x-ui.log'); + return; + } + const lines = this.xraylogModal.logs.map(l => { + try { + const dt = l.DateTime ? new Date(l.DateTime) : null; + const dateStr = dt && !isNaN(dt.getTime()) ? dt.toISOString() : ''; + const eventMap = { 0: 'DIRECT', 1: 'BLOCKED', 2: 'PROXY' }; + const eventText = eventMap[l.Event] || String(l.Event ?? ''); + const emailPart = l.Email ? ` Email=${l.Email}` : ''; + return `${dateStr} FROM=${l.FromAddress || ''} TO=${l.ToAddress || ''} INBOUND=${l.Inbound || ''} OUTBOUND=${l.Outbound || ''}${emailPart} EVENT=${eventText}`.trim(); + } catch (e) { + return JSON.stringify(l); + } + }).join('\n'); + FileManager.downloadTextFile(lines, 'x-ui.log'); + }, async openConfig() { this.loading(true); const msg = await HttpUtil.get('/panel/api/server/getConfigJson'); @@ -1071,7 +1103,6 @@ ${dateTime} fileInput.click(); }, }, - computed: {}, async mounted() { if (window.location.protocol !== "https:") { this.showAlert = true; diff --git a/web/service/server.go b/web/service/server.go index f0ad3265..670e622e 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -174,6 +174,16 @@ type CPUSample struct { Cpu float64 `json:"cpu"` // percent 0..100 } +type LogEntry struct { + DateTime time.Time + FromAddress string + ToAddress string + Inbound string + Outbound string + Email string + Event int +} + func getPublicIP(url string) string { client := &http.Client{ Timeout: 3 * time.Second, @@ -704,19 +714,25 @@ func (s *ServerService) GetXrayLogs( showBlocked string, showProxy string, freedoms []string, - blackholes []string) []string { + blackholes []string) []LogEntry { + + const ( + Direct = iota + Blocked + Proxied + ) countInt, _ := strconv.Atoi(count) - var lines []string + var entries []LogEntry pathToAccessLog, err := xray.GetAccessLogPath() if err != nil { - return lines + return nil } file, err := os.Open(pathToAccessLog) if err != nil { - return lines + return nil } defer file.Close() @@ -735,37 +751,62 @@ func (s *ServerService) GetXrayLogs( continue } - //adding suffixes to further distinguish entries by outbound - if hasSuffix(line, freedoms) { + var entry LogEntry + parts := strings.Fields(line) + + for i, part := range parts { + + if i == 0 { + dateTime, err := time.Parse("2006/01/02 15:04:05.999999", parts[0]+" "+parts[1]) + if err != nil { + continue + } + entry.DateTime = dateTime + } + + if part == "from" { + entry.FromAddress = parts[i+1] + } else if part == "accepted" { + entry.ToAddress = parts[i+1] + } else if strings.HasPrefix(part, "[") { + entry.Inbound = part[1:] + } else if strings.HasSuffix(part, "]") { + entry.Outbound = part[:len(part)-1] + } else if part == "email:" { + entry.Email = parts[i+1] + } + } + + if logEntryContains(line, freedoms) { if showDirect == "false" { continue } - line = line + " f" - } else if hasSuffix(line, blackholes) { + entry.Event = Direct + } else if logEntryContains(line, blackholes) { if showBlocked == "false" { continue } - line = line + " b" + entry.Event = Blocked } else { if showProxy == "false" { continue } - line = line + " p" + entry.Event = Proxied } - lines = append(lines, line) + entries = append(entries, entry) } - if len(lines) > countInt { - lines = lines[len(lines)-countInt:] + if len(entries) > countInt { + entries = entries[len(entries)-countInt:] } - return lines + return entries } -func hasSuffix(line string, suffixes []string) bool { +func logEntryContains(line string, suffixes []string) bool { for _, sfx := range suffixes { - if strings.HasSuffix(line, sfx+"]") { + if strings.Contains(line, sfx+"]") { return true } } From d7efc2aef9b51c6f18f51f41e30f8dba4b573e93 Mon Sep 17 00:00:00 2001 From: Tara Rostami <132676256+TaraRostami@users.noreply.github.com> Date: Wed, 17 Sep 2025 06:47:01 -0500 Subject: [PATCH 23/44] Minor Fixes (#3483) * Minor Fixes * Minor Fixes 2 --------- Co-authored-by: Sanaei --- web/assets/css/custom.min.css | 2 +- web/html/index.html | 26 ++++++------ web/html/login.html | 79 ++++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 16 deletions(-) diff --git a/web/assets/css/custom.min.css b/web/assets/css/custom.min.css index cb5f1238..04f31327 100644 --- a/web/assets/css/custom.min.css +++ b/web/assets/css/custom.min.css @@ -1 +1 @@ -:root{--color-primary-100:#008771;--dark-color-background:#0a1222;--dark-color-surface-100:#151f31;--dark-color-surface-200:#222d42;--dark-color-surface-300:#2c3950;--dark-color-surface-400:rgba(65, 85, 119, 0.5);--dark-color-surface-500:#2c3950;--dark-color-surface-600:#313f5a;--dark-color-surface-700:#111929;--dark-color-surface-700-rgb:17, 25, 41;--dark-color-table-hover:rgba(44, 57, 80, 0.2);--dark-color-text-primary:rgba(255, 255, 255, 0.75);--dark-color-stroke:#2c3950;--dark-color-btn-danger:#cd3838;--dark-color-btn-danger-border:transparent;--dark-color-btn-danger-hover:#e94b4b;--dark-color-tag-bg:rgba(255, 255, 255, 0.05);--dark-color-tag-border:rgba(255, 255, 255, 0.15);--dark-color-tag-color:rgba(255, 255, 255, 0.75);--dark-color-tag-green-bg:17, 36, 33;--dark-color-tag-green-border:25, 81, 65;--dark-color-tag-green-color:#3ad3ba;--dark-color-tag-purple-bg:#201425;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d988cd;--dark-color-tag-red-bg:#291515;--dark-color-tag-red-border:#5c2626;--dark-color-tag-red-color:#e04141;--dark-color-tag-orange-bg:#312313;--dark-color-tag-orange-border:#593914;--dark-color-tag-orange-color:#ffa031;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#1348ab;--dark-color-tag-blue-color:#529fff;--dark-color-codemirror-line-hover:rgba(0, 135, 113, 0.2);--dark-color-codemirror-line-selection:rgba(0, 135, 113, 0.3);--dark-color-login-background:var(--dark-color-background);--dark-color-login-wave:var(--dark-color-surface-200);--dark-color-tooltip:rgba(61, 76, 104, 0.9);--dark-color-back-top:rgba(61, 76, 104, 0.9);--dark-color-back-top-hover:rgba(61, 76, 104, 1);--dark-color-scrollbar:#313f5a;--dark-color-scrollbar-webkit:#7484a0;--dark-color-scrollbar-webkit-hover:#90a4c7;--dark-color-table-ring:rgb(38 52 77);--dark-color-spin-container:#151f31}html[data-theme-animations='off']{.ant-menu,.ant-layout-sider,.ant-card,.ant-tag,.ant-progress-circle>*,.ant-input,.ant-table-row-expand-icon,.ant-switch,.ant-table-thead>tr>th,.ant-select-selection,.ant-btn,.ant-input-number,.ant-input-group-addon,.ant-checkbox-inner,.ant-progress-bg,.ant-progress-success-bg,.ant-radio-button-wrapper:not(:first-child):before,.ant-radio-button-wrapper,#login,.cm-s-xq.CodeMirror{transition:border 0s,background 0s!important}.ant-menu.ant-menu-inline .ant-menu-item:not(.ant-menu-sub .ant-menu-item),.ant-layout-sider-trigger,.ant-alert-close-icon .anticon-close,.ant-tabs-nav .ant-tabs-tab,.ant-input-number-input,.ant-collapse>.ant-collapse-item>.ant-collapse-header,.Line-Hover,.ant-menu-theme-switch,.ant-menu-submenu-title{transition:color 0s!important}.wave-btn-bg{transition:width 0s!important}}html[data-theme='ultra-dark']{--dark-color-background:#21242a;--dark-color-surface-100:#0c0e12;--dark-color-surface-200:#222327;--dark-color-surface-300:#32353b;--dark-color-surface-400:rgba(255, 255, 255, 0.1);--dark-color-surface-500:#3b404b;--dark-color-surface-600:#505663;--dark-color-surface-700:#101113;--dark-color-surface-700-rgb:16, 17, 19;--dark-color-table-hover:rgba(89, 89, 89, 0.15);--dark-color-text-primary:rgb(255 255 255 / 85%);--dark-color-stroke:#202025;--dark-color-tag-green-bg:17, 36, 33;--dark-color-tag-green-border:29, 95, 77;--dark-color-tag-green-color:#59cbac;--dark-color-tag-purple-bg:#241121;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d686ca;--dark-color-tag-red-bg:#2a1215;--dark-color-tag-red-border:#58181c;--dark-color-tag-red-color:#e84749;--dark-color-tag-orange-bg:#2b1d11;--dark-color-tag-orange-border:#593815;--dark-color-tag-orange-color:#e89a3c;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#0f367e;--dark-color-tag-blue-color:#3c89e8;--dark-color-codemirror-line-hover:rgba(82, 84, 94, 0.2);--dark-color-codemirror-line-selection:rgba(82, 84, 94, 0.3);--dark-color-login-background:#0a2227;--dark-color-login-wave:#0f2d32;--dark-color-tooltip:rgba(88, 93, 100, 0.9);--dark-color-back-top:rgba(88, 93, 100, 0.9);--dark-color-back-top-hover:rgba(88, 93, 100, 1);--dark-color-scrollbar:rgb(107,107,107);--dark-color-scrollbar-webkit:#9f9f9f;--dark-color-scrollbar-webkit-hover:#d1d1d1;--dark-color-table-ring:rgb(37 39 42);--dark-color-spin-container:#1d1d1d;.ant-dropdown-menu-dark,.dark .ant-dropdown-menu{background-color:var(--dark-color-surface-500)}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.dark .waves-header{background-color:#0a2227}.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-600)}}html,body{height:100vh;width:100vw;margin:0;padding:0;overflow:hidden}body{color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;background-color:#fff;font-feature-settings:"tnum"}html{--antd-wave-shadow-color:var(--color-primary-100);line-height:1.15;text-size-adjust:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-moz-tap-highlight-color:#fff0;-webkit-tap-highlight-color:#fff0}@supports (scrollbar-width:auto) and (not selector(::-webkit-scrollbar)){:not(.dark){scrollbar-color:#9a9a9a #fff0;scrollbar-width:thin}.dark *{scrollbar-color:var(--dark-color-scrollbar) #fff0;scrollbar-width:thin}}::-webkit-scrollbar{width:10px;height:10px;background-color:#fff0}::-webkit-scrollbar-track{background-color:#fff0;margin-block:.5em}.ant-modal-wrap::-webkit-scrollbar-track{background-color:#fff;margin-block:0}::-webkit-scrollbar-thumb{border-radius:9999px;background-color:#9a9a9a;border:2px solid #fff0;background-clip:content-box}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background-color:#828282}.dark .ant-modal-wrap::-webkit-scrollbar-track{background-color:var(--dark-color-background)}.dark::-webkit-scrollbar-thumb{background-color:var(--dark-color-scrollbar-webkit)}.dark::-webkit-scrollbar-thumb:hover,.dark::-webkit-scrollbar-thumb:active{background-color:var(--dark-color-scrollbar-webkit-hover)}::-moz-selection{color:var(--color-primary-100);background-color:#cfe8e4}::selection{color:var(--color-primary-100);background-color:#cfe8e4}#app{height:100%;position:fixed;top:0;left:0;right:0;bottom:0;margin:0;padding:0;overflow:auto}.ant-layout,.ant-layout *{box-sizing:border-box}.ant-spin-container:after{border-radius:1.5rem}.dark .ant-spin-container:after{background:var(--dark-color-spin-container)}style attribute{text-align:center}.ant-table-thead>tr>th{padding:12px 8px}.ant-table-tbody>tr>td{padding:10px 8px}.ant-table-thead>tr>th{color:rgb(0 0 0 / .85);font-weight:500;text-align:left;border-bottom:1px solid #e8e8e8;transition:background 0.3s ease}.ant-table table{border-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:first-child{border-bottom-left-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:last-child{border-bottom-right-radius:1rem}.ant-table{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;font-feature-settings:"tnum";position:relative;clear:both}.ant-table .ant-table-body:not(.ant-table-expanded-row .ant-table-body){overflow-x:auto!important}.ant-card-hoverable{cursor:auto;cursor:pointer}.ant-card{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;position:relative;background-color:#fff;border-radius:2px;transition:all 0.3s}.ant-space{width:100%}.ant-layout-sider-zero-width-trigger{display:none}@media (max-width:768px){.ant-layout-sider{display:none}.ant-card,.ant-alert-error{margin:.5rem}.ant-tabs{margin:.5rem;padding:.5rem}.ant-modal-body{padding:20px}.ant-form-item-label{line-height:1.5;padding:8px 0 0}:not(.dark)::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}.dark::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}}.ant-layout-content{min-height:auto}.ant-card,.ant-tabs{border-radius:1.5rem}.ant-card-hoverable{cursor:auto}.ant-card+.ant-card{margin-top:20px}.drawer-handle{position:absolute;top:72px;width:41px;height:40px;cursor:pointer;z-index:0;text-align:center;line-height:40px;font-size:16px;display:flex;justify-content:center;align-items:center;background-color:#fff;right:-40px;box-shadow:2px 0 8px rgb(0 0 0 / .15);border-radius:0 4px 4px 0}.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{background-color:#006655!important;background-image:linear-gradient(270deg,#fff0 30%,#009980,#fff0 100%);background-repeat:no-repeat;animation:ma-bg-move linear 6.6s infinite;color:#fff;border-radius:.5rem}.ant-layout-sider-collapsed .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{border-radius:0}.ant-menu-item-active,.ant-menu-item:hover,.ant-menu-submenu-title:hover,.ant-menu-item:active,.ant-menu-submenu-title:active{color:var(--color-primary-100);background-color:#e8f4f2}.ant-menu-inline .ant-menu-item,.ant-menu-inline .ant-menu-submenu-title{border-radius:.5rem}.ant-menu-inline .ant-menu-item:after,.ant-menu{border-right-width:0}.ant-layout-sider-children,.ant-pagination ul{padding:.5rem}.ant-layout-sider-collapsed .ant-layout-sider-children{padding:.5rem 0}.ant-dropdown-menu,.ant-select-dropdown-menu{padding:.5rem}.ant-dropdown-menu-item,.ant-dropdown-menu-item:hover,.ant-select-dropdown-menu-item,.ant-select-dropdown-menu-item:hover,.ant-select-selection--multiple .ant-select-selection__choice{border-radius:.5rem}.ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item,.ant-select-dropdown--single .ant-select-dropdown-menu .ant-select-dropdown-menu-item-selected{margin-block:2px}@media (min-width:769px){.drawer-handle{display:none}.ant-tabs{padding:2rem}}.fade-in-enter,.fade-in-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.fade-in-enter-active,.fade-in-leave-active{-webkit-transition:all 0.3s cubic-bezier(.55,0,.1,1);transition:all 0.3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter-active,.zoom-in-center-leave-active{-webkit-transition:all 0.3s cubic-bezier(.55,0,.1,1);transition:all 0.3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter,.zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.zoom-in-top-enter-active,.zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.zoom-in-top-enter,.zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-bottom-enter-active,.zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.zoom-in-bottom-enter,.zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-left-enter-active,.zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.zoom-in-left-enter,.zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.list-enter-active,.list-leave-active{-webkit-transition:all 0.3s;transition:all 0.3s}.list-enter,.list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.ant-tooltip-inner{min-height:0;padding-inline:1rem}.ant-list-item-meta-title{font-size:14px}.ant-progress-inner{background-color:#ebeef5}.deactive-client .ant-collapse-header{color:#ffffff!important;background-color:#ff7f7f}.ant-table-expand-icon-th,.ant-table-row-expand-icon-cell{width:30px;min-width:30px}.ant-tabs{background-color:#fff}.ant-form-item{margin-bottom:0}.ant-setting-textarea{margin-top:1.5rem}.client-table-header{background-color:#f0f2f5}.client-table-odd-row{background-color:#fafafa}.ant-table-pagination.ant-pagination{float:left}.ant-tag{margin-right:0;margin-inline:2px;display:inline-flex;align-items:center;justify-content:space-evenly}.ant-tag:not(.qr-tag){column-gap:4px}#inbound-info-modal .ant-tag{margin-block:2px}.tr-info-table{display:inline-table;margin-block:10px;width:100%}#inbound-info-modal .tr-info-table .ant-tag{margin-block:0;margin-inline:0}.tr-info-row{display:flex;flex-direction:column;row-gap:2px;margin-block:10px}.tr-info-row a{margin-left:6px}.tr-info-row code{padding-inline:8px}.tr-info-tag{max-width:100%;text-wrap:balance;overflow:hidden;overflow-wrap:anywhere}.tr-info-title{display:inline-flex;align-items:center;justify-content:flex-start;column-gap:4px}.ant-tag-blue{background-color:#edf4fa;border-color:#a9c5e7;color:#0e49b5}.ant-tag-green{background-color:#eafff9;border-color:#76ccb4;color:#199270}.ant-tag-purple{background-color:#f2eaf1;border-color:#d5bed2;color:#7a316f}.ant-tag-orange,.ant-alert-warning{background-color:#ffeee1;border-color:#fec093;color:#f37b24}.ant-tag-red,.ant-alert-error{background-color:#ffe9e9;border-color:#ff9e9e;color:#cf3c3c}.ant-input::placeholder{opacity:.5}.ant-input:hover,.ant-input:focus{background-color:#e8f4f2}.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){background-color:#e8f4f2}.delete-icon:hover{color:#e04141}.normal-icon:hover{color:var(--color-primary-100)}.dark ::-moz-selection{color:#fff;background-color:var(--color-primary-100)}.dark ::selection{color:#fff;background-color:var(--color-primary-100)}.dark .normal-icon:hover{color:#fff}.dark .ant-layout-sider,.dark .ant-drawer-content,.ant-menu-dark,.ant-menu-dark .ant-menu-sub,.dark .ant-card,.dark .ant-table,.dark .ant-collapse-content,.dark .ant-tabs{background-color:var(--dark-color-surface-100);color:var(--dark-color-text-primary)}.dark .ant-card-hoverable:hover,.dark .ant-space-item>.ant-tabs:hover{box-shadow:0 2px 8px #fff0}.dark>.ant-layout,.dark .drawer-handle,.dark .ant-table-thead>tr>th,.dark .ant-table-expanded-row,.dark .ant-table-expanded-row:hover,.dark .ant-table-expanded-row .ant-table-tbody,.dark .ant-calendar{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-table-expanded-row .ant-table-thead>tr:first-child>th{border-radius:0}.dark .ant-calendar,.dark .ant-card-bordered{border-color:var(--dark-color-background)}.dark .ant-table-bordered,.dark .ant-table-bordered.ant-table-empty .ant-table-placeholder,.dark .ant-table-bordered .ant-table-body>table,.dark .ant-table-bordered .ant-table-fixed-left table,.dark .ant-table-bordered .ant-table-fixed-right table,.dark .ant-table-bordered .ant-table-header>table,.dark .ant-table-bordered .ant-table-thead>tr:not(:last-child)>th,.dark .ant-table-bordered .ant-table-tbody>tr>td,.dark .ant-table-bordered .ant-table-thead>tr>th{border-color:var(--dark-color-surface-400)}.dark .ant-table-tbody>tr>td,.dark .ant-table-thead>tr>th,.dark .ant-card-head,.dark .ant-modal-header,.dark .ant-collapse>.ant-collapse-item,.dark .ant-tabs-bar,.dark .ant-list-split .ant-list-item,.dark .ant-popover-title,.dark .ant-calendar-header,.dark .ant-calendar-input-wrap{border-bottom-color:var(--dark-color-surface-400)}.dark .ant-modal-footer,.dark .ant-collapse-content,.dark .ant-calendar-footer,.dark .ant-divider-horizontal.ant-divider-with-text-left:before,.dark .ant-divider-horizontal.ant-divider-with-text-left:after,.dark .ant-divider-horizontal.ant-divider-with-text-center:before,.dark .ant-divider-horizontal.ant-divider-with-text-center:after{border-top-color:var(--dark-color-surface-300)}.ant-divider-horizontal.ant-divider-with-text-left:before{width:10%}.dark .ant-progress-text,.dark .ant-card-head,.dark .ant-form,.dark .ant-collapse>.ant-collapse-item>.ant-collapse-header,.dark .ant-modal-close-x,.dark .ant-form .anticon,.dark .ant-tabs-tab-arrow-show:not(.ant-tabs-tab-btn-disabled),.dark .anticon-close,.dark .ant-list-item-meta-title,.dark .ant-select-selection i,.dark .ant-modal-confirm-title,.dark .ant-modal-confirm-content,.dark .ant-popover-message,.dark .ant-modal,.dark .ant-divider-inner-text,.dark .ant-popover-title,.dark .ant-popover-inner-content,.dark h2,.dark .ant-modal-title,.dark .ant-form-item-label>label,.dark .ant-checkbox-wrapper,.dark .ant-form-item,.dark .ant-calendar-footer .ant-calendar-today-btn,.dark .ant-calendar-footer .ant-calendar-time-picker-btn,.dark .ant-calendar-day-select,.dark .ant-calendar-month-select,.dark .ant-calendar-year-select,.dark .ant-calendar-date,.dark .ant-calendar-year-panel-year,.dark .ant-calendar-month-panel-month,.dark .ant-calendar-decade-panel-decade{color:var(--dark-color-text-primary)}.dark .ant-pagination-options-size-changer .ant-select-arrow .anticon.anticon-down.ant-select-arrow-icon{color:rgb(255 255 255 / 35%)}.dark .ant-pagination-item a,.dark .ant-pagination-next a,.dark .ant-pagination-prev a{color:var(--dark-color-text-primary)}.dark .ant-pagination-item:focus a,.dark .ant-pagination-item:hover a,.dark .ant-pagination-item-active a,.dark .ant-pagination-next:hover .ant-pagination-item-link{color:var(--color-primary-100)}.dark .ant-pagination-item-active{background-color:#fff0}.dark .ant-list-item-meta-description{color:rgb(255 255 255 / .45)}.dark .ant-pagination-disabled i,.dark .ant-tabs-tab-btn-disabled{color:rgb(255 255 255 / .25)}.dark .ant-input,.dark .ant-input-group-addon,.dark .ant-collapse,.dark .ant-select-selection,.dark .ant-input-number,.dark .ant-input-number-handler-wrap,.dark .ant-table-placeholder,.dark .ant-empty-normal,.dark .ant-select-dropdown,.dark .ant-select-dropdown li,.dark .ant-select-dropdown-menu-item,.dark .client-table-header,.dark .ant-select-selection--multiple .ant-select-selection__choice{background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.dark .ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected :not(.ant-dropdown-menu-submenu-title:hover){background-color:var(--dark-color-surface-300)}.dark .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected{background-color:var(--dark-color-surface-300)}.dark .ant-calendar-time-picker-inner{background-color:var(--dark-color-background)}.dark .ant-select-selection:hover,.dark .ant-calendar-picker-clear,.dark .ant-input-number:hover,.dark .ant-input-number:focus,.dark .ant-input:hover,.dark .ant-input:focus{background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.dark .ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){border-color:var(--color-primary-100);background-color:rgb(0 135 113 / .3)}.dark .ant-btn:not(.ant-btn-primary):not(.ant-btn-danger){color:var(--dark-color-text-primary);background-color:rgb(10 117 87 / 30%);border:1px solid var(--color-primary-100)}.dark .ant-radio-button-wrapper,.dark .ant-radio-button-wrapper:before{color:var(--dark-color-text-primary);background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){background-color:#e8f4f2}.dark .ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.dark .ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){color:#fff;background-color:rgb(10 117 87 / 50%);border-color:var(--color-primary-100)}.dark .ant-btn-primary[disabled],.dark .ant-btn-danger[disabled],.dark .ant-calendar-ok-btn-disabled{color:rgb(255 255 255 / 35%);background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300)}.dark .ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.dark .client-table-odd-row{background-color:var(--dark-color-table-hover)}.dark .ant-table-row-expand-icon{color:#fff;background-color:#fff0;border-color:rgb(255 255 255 / 20%)}.dark .ant-table-row-expand-icon:hover{color:var(--color-primary-100);background-color:#fff0;border-color:var(--color-primary-100)}.dark .ant-switch:not(.ant-switch-checked),.dark .ant-progress-line .ant-progress-inner{background-color:var(--dark-color-surface-500)}.dark .ant-progress-circle-trail{stroke:var(--dark-color-stroke)!important}.dark .ant-popover-inner{background-color:var(--dark-color-surface-500)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-500)}@media (max-width:768px){.dark .ant-popover-inner{background-color:var(--dark-color-surface-200)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-200)}}.ant-dropdown-menu-dark .ant-dropdown-menu-item:hover,.dark .ant-select-dropdown-menu-item-selected,.dark .ant-calendar-time-picker-select-option-selected{background-color:var(--dark-color-surface-600)}.ant-menu-dark .ant-menu-item:hover,.ant-menu-dark .ant-menu-submenu-title:hover{background-color:var(--dark-color-surface-300)}.dark .ant-menu-item:active,.dark .ant-menu-submenu-title:active{color:#fff;background-color:var(--dark-color-surface-300)}.dark .ant-alert-message{color:rgb(255 255 255 / .85)}.dark .ant-tag{color:var(--dark-color-tag-color);background-color:var(--dark-color-tag-bg);border-color:var(--dark-color-tag-border)}.dark .ant-tag-blue{background-color:var(--dark-color-tag-blue-bg);border-color:var(--dark-color-tag-blue-border);color:var(--dark-color-tag-blue-color)}.dark .ant-tag-red,.dark .ant-alert-error{background-color:var(--dark-color-tag-red-bg);border-color:var(--dark-color-tag-red-border);color:var(--dark-color-tag-red-color)}.dark .ant-tag-orange,.dark .ant-alert-warning{background-color:var(--dark-color-tag-orange-bg);border-color:var(--dark-color-tag-orange-border);color:var(--dark-color-tag-orange-color)}.dark .ant-tag-green{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border));color:var(--dark-color-tag-green-color)}.dark .ant-tag-purple{background-color:var(--dark-color-tag-purple-bg);border-color:var(--dark-color-tag-purple-border);color:var(--dark-color-tag-purple-color)}.dark .ant-modal-content,.dark .ant-modal-header{background-color:var(--dark-color-surface-700)}.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date{color:var(--dark-color-surface-300)}.dark .ant-calendar-selected-day .ant-calendar-date{background-color:var(--color-primary-100)!important;color:#fff}.dark .ant-calendar-date:hover,.dark .ant-calendar-time-picker-select li:hover{background-color:var(--dark-color-surface-600);color:#fff}.dark .ant-calendar-header a:hover,.dark .ant-calendar-header a:hover::before,.dark .ant-calendar-header a:hover::after{border-color:#fff}.dark .ant-calendar-time-picker-select{border-right-color:var(--dark-color-surface-300)}.has-warning .ant-select-selection,.has-warning .ant-select-selection:hover,.has-warning .ant-input,.has-warning .ant-input:hover{background-color:#ffeee1;border-color:#fec093}.has-warning .ant-input::placeholder{color:#f37b24}.has-warning .ant-input:not([disabled]):hover{border-color:#fec093}.dark .has-warning .ant-select-selection,.dark .has-warning .ant-select-selection:hover,.dark .has-warning .ant-input,.dark .has-warning .ant-input:hover{border-color:#784e1d;background:#312313}.dark .has-warning .ant-input::placeholder{color:rgb(255 160 49 / 70%)}.dark .has-warning .anticon{color:#ffa031}.dark .has-success .anticon{color:var(--color-primary-100);animation-name:diffZoomIn1!important}.dark .anticon-close-circle{color:#e04141}.dark .ant-spin-nested-loading>div>.ant-spin .ant-spin-text{text-shadow:0 1px 2px #0007}.dark .ant-spin{color:#fff}.dark .ant-spin-dot-item{background-color:#fff}.ant-checkbox-wrapper,.ant-input-group-addon,.ant-tabs-tab,.ant-input::placeholder,.ant-collapse-header,.ant-menu,.ant-radio-button-wrapper{-webkit-user-select:none;user-select:none}.ant-calendar-date,.ant-calendar-year-panel-year,.ant-calendar-decade-panel-decade,.ant-calendar-month-panel-month{border-radius:4px}.ant-checkbox-inner,.ant-checkbox-checked:after,.ant-table-row-expand-icon{border-radius:6px}.ant-calendar-date:hover{background-color:#e8f4f2}.ant-calendar-date:active{background-color:#e8f4f2;color:rgb(0 0 0 / .65)}.ant-calendar-today .ant-calendar-date{color:var(--color-primary-100);font-weight:400;border-color:var(--color-primary-100)}.dark .ant-calendar-today .ant-calendar-date{color:#fff;border-color:var(--color-primary-100)}.ant-calendar-selected-day .ant-calendar-date{background:var(--color-primary-100);color:#fff}li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(0 0 0 / .25)}.dark li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(255 255 255 / .3)}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:rgb(0 0 0 / .87)}.dark.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:#fff}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected .ant-select-selected-icon,.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected:hover .ant-select-selected-icon{color:var(--color-primary-100)}.ant-select-selection:hover,.ant-input-number-focused,.ant-input-number:hover{background-color:#e8f4f2}.dark .ant-input-number-handler:active{background-color:var(--color-primary-100)}.dark .ant-input-number-handler:hover .ant-input-number-handler-down-inner,.dark .ant-input-number-handler:hover .ant-input-number-handler-up-inner{color:#fff}.dark .ant-input-number-handler-down{border-top:1px solid rgb(217 217 217 / .3)}.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-century-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-decade-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-month-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-year-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-century-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-decade-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-month-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-year-select{color:rgb(255 255 255 / .85)}.dark .ant-calendar-year-panel-header{border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel-last-decade-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-next-decade-cell .ant-calendar-year-panel-year{color:rgb(255 255 255 / .35)}.dark .ant-divider:not(.ant-divider-with-text-center,.ant-divider-with-text-left,.ant-divider-with-text-right),.ant-dropdown-menu-dark,.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-200)}.dark .ant-calendar-header a:hover{color:#fff}.dark .ant-calendar-month-panel-header{background-color:var(--dark-color-background);border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel,.dark .ant-calendar table{background-color:var(--dark-color-background)}.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade:hover{color:#fff;background-color:var(--color-primary-100)!important}.dark .ant-calendar-last-month-cell .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date:hover,.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-next-month-btn-day .ant-calendar-date:hover{color:rgb(255 255 255 / 25%);background:#fff0;border-color:#fff0}.dark .ant-calendar-today .ant-calendar-date:hover{color:#fff;border-color:var(--color-primary-100);background-color:var(--color-primary-100)}.dark .ant-calendar-decade-panel-last-century-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-next-century-cell .ant-calendar-decade-panel-decade{color:rgb(255 255 255 / 25%)}.dark .ant-calendar-decade-panel-header{border-bottom:1px solid var(--dark-color-surface-200);background-color:var(--dark-color-background)}.dark .ant-checkbox-inner{background-color:rgb(0 135 113 / .3);border-color:rgb(0 135 113 / .3)}.dark .ant-checkbox-checked .ant-checkbox-inner{background-color:var(--color-primary-100);border-color:var(--color-primary-100)}.dark .ant-calendar-input{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-calendar-input::placeholder{color:rgb(255 255 255 / .25)}.ant-input-group.ant-input-group-compact-addon:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact-wrap:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact>.ant-input:not(:first-child):not(:last-child),.ant-input-number-handler,.ant-input-number-handler-wrap{border-radius:0}.ant-input-number{overflow:clip}.ant-modal-body,.ant-collapse-content>.ant-collapse-content-box{overflow-x:auto}.ant-modal-body{overflow-y:hidden}.ant-calendar-year-panel-year:hover,.ant-calendar-decade-panel-decade:hover,.ant-calendar-month-panel-month:hover,.ant-dropdown-menu-item:hover,.ant-dropdown-menu-submenu-title:hover,.ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled),.ant-table-tbody>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td{background-color:#e8f4f2}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.ant-select-dropdown,.ant-popover-inner{overflow-x:hidden}.ant-popover-inner-content{max-height:450px;overflow-y:auto}@media (max-height:900px){.ant-popover-inner-content{max-height:400px}}@media (max-height:768px){.ant-popover-inner-content{max-height:300px}}@media (max-width:768px){.ant-popover-inner-content{max-height:300px}}.qr-modal{display:flex;align-items:flex-end;gap:10px;flex-direction:column;flex-wrap:wrap;row-gap:24px}.qr-box{width:220px}.qr-cv{width:100%;height:100%}.dark .qr-cv{filter:invert(1)}.qr-bg{background-color:#fff;display:flex;justify-content:center;align-content:center;padding:.8rem;border-radius:1rem;border:solid 1px #e8e8e8;height:220px;width:220px;transition:all 0.1s}.qr-bg:hover{border-color:#76ccb4;background-color:#eafff9}.qr-bg:hover:active{border-color:#76ccb4;background-color:rgb(197 241 228 / 70%)}.dark .qr-bg{background-color:var(--dark-color-surface-700);border-color:var(--dark-color-surface-300)}.dark .qr-bg:hover{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border))}.dark .qr-bg:hover:active{background-color:#17322e}@property --tr-rotate{syntax:'';initial-value:45deg;inherits:false}.qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#76ccb4,transparent,#d5bed2);display:flex;justify-content:center;align-content:center;padding:1px;border-radius:1rem;height:220px;width:220px}.dark .qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#195141,transparent,#5a2969)}.qr-bg-sub:hover{animation:tr-rotate-gradient 3.5s linear infinite}@keyframes tr-rotate-gradient{from{--tr-rotate:45deg}to{--tr-rotate:405deg}}.qr-bg-sub-inner{background-color:#fff;padding:.8rem;border-radius:1rem;transition:all 0.1s}.qr-bg-sub-inner:hover{background-color:rgb(255 255 255 / 60%);backdrop-filter:blur(25px)}.qr-bg-sub-inner:hover:active{background-color:rgb(255 255 255 / 30%)}.dark .qr-bg-sub-inner{background-color:rgb(var(--dark-color-surface-700-rgb))}.dark .qr-bg-sub-inner:hover{background-color:rgba(var(--dark-color-surface-700-rgb),.5);backdrop-filter:blur(25px)}.dark .qr-bg-sub-inner:hover:active{background-color:rgba(var(--dark-color-surface-700-rgb),.2)}.qr-tag{text-align:center;margin-bottom:10px;width:100%;overflow:hidden;margin-inline:0}@media (min-width:769px){.qr-modal{flex-direction:row;max-width:680px}}.tr-marquee{justify-content:flex-start}.tr-marquee span{padding-right:25%;white-space:nowrap;transform-origin:center}@keyframes move-ltr{0%{transform:translateX(0)}100%{transform:translateX(-100%)}}.ant-input-group-addon:not(:first-child):not(:last-child){border-radius:0rem 1rem 1rem 0rem}b,strong{font-weight:500}.ant-collapse>.ant-collapse-item>.ant-collapse-header{padding:10px 16px 10px 40px}.dark .ant-message-notice-content{background-color:var(--dark-color-surface-200);border:1px solid var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.ant-btn-danger{background-color:var(--dark-color-btn-danger);border-color:var(--dark-color-btn-danger-border)}.ant-btn-danger:focus,.ant-btn-danger:hover{background-color:var(--dark-color-btn-danger-hover);border-color:var(--dark-color-btn-danger-hover)}.dark .ant-alert-close-icon .anticon-close:hover{color:#fff}.ant-empty-small{margin:4px 0;background-color:transparent!important}.ant-empty-small .ant-empty-image{height:20px}.ant-menu-theme-switch,.ant-menu-theme-switch:hover{background-color:transparent!important;cursor:default!important}.dark .ant-tooltip-inner,.dark .ant-tooltip-arrow:before{background-color:var(--dark-color-tooltip)}.ant-select-sm .ant-select-selection__rendered{margin-left:10px}.ant-collapse{-moz-animation:collfade 0.3s ease;-webkit-animation:0.3s collfade 0.3s ease;animation:collfade 0.3s ease}@-webkit-keyframes collfade{0%{transform:scaleY(.8);transform-origin:0% 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0% 0%;opacity:1}}@keyframes collfade{0%{transform:scaleY(.8);transform-origin:0% 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0% 0%;opacity:1}}.ant-table-tbody>tr>td{border-color:#f0f0f0}.ant-table-row-expand-icon{vertical-align:middle;margin-inline-end:8px;position:relative;transform:scale(.9411764705882353)}.ant-table-row-collapsed::before{transform:rotate(-180deg);top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-collapsed::after{transform:rotate(0deg);top:3px;bottom:3px;inset-inline-start:7px;width:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-expanded::before{top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-expanded::after{top:3px;bottom:3px;inset-inline-start:7px;width:1px;transform:rotate(90deg);position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-menu-theme-switch.ant-menu-item .ant-switch:not(.ant-switch-disabled):active:after,.ant-switch:not(.ant-switch-disabled):active:before{width:16px}.dark .ant-select-disabled .ant-select-selection{background:var(--dark-color-surface-100);border-color:var(--dark-color-surface-200);color:rgb(255 255 255 / .25)}.dark .ant-select-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .1)}.dark .ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up-disabled .anticon,.dark .ant-input-number-handler-down:hover.ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up:hover.ant-input-number-handler-up-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down:active.ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up:active.ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .2)}.ant-menu-dark .ant-menu-inline.ant-menu-sub{background:var(--dark-color-surface-100);box-shadow:none}.dark .ant-layout-sider-trigger{background:var(--dark-color-surface-100);color:rgb(255 255 255 / 65%)}.ant-layout-sider{overflow:auto}.dark .ant-back-top-content{background-color:var(--dark-color-back-top)}.dark .ant-back-top-content:hover{background-color:var(--dark-color-back-top-hover)}.ant-calendar-time .ant-calendar-footer .ant-calendar-time-picker-btn{text-transform:capitalize}.ant-calendar{border-color:#fff0;border-width:0}.ant-calendar-time-picker-select li:focus,li.ant-calendar-time-picker-select-option-selected{color:rgb(0 0 0 / .65);font-weight:400;background-color:#e8f4f2}.dark li.ant-calendar-time-picker-select-option-selected{color:var(--dark-color-text-primary);font-weight:400}.dark .ant-calendar-time-picker-select li:focus{color:#fff;font-weight:400;background-color:var(--color-primary-100)}.ant-calendar-time-picker-select li:hover{background:#f5f5f5}.ant-calendar-date{transition:background .3s ease,color .3s ease}li.ant-calendar-time-picker-select-option-selected{margin-block:2px}.ant-calendar-time-picker-select{padding:4px}.ant-calendar-time-picker-select li{height:28px;line-height:28px;border-radius:4px}@media (min-width:769px){.index-page .ant-layout-content{margin:24px 16px}}.index-page .ant-card-dark h2{color:var(--dark-color-text-primary)}.index-page~div .ant-backup-list-item{gap:10px}.index-page~div .ant-version-list-item{--padding:12px;padding:var(--padding)!important;gap:var(--padding)}.index-page.dark~div .ant-version-list-item svg{color:var(--dark-color-text-primary)}.index-page.dark~div .ant-backup-list-item svg,.index-page.dark .ant-badge-status-text,.index-page.dark .ant-card-extra{color:var(--dark-color-text-primary)}.index-page.dark .ant-card-actions>li{color:rgb(255 255 255 / .55)}.index-page.dark~div .ant-radio-inner{background-color:var(--dark-color-surface-100);border-color:var(--dark-color-surface-600)}.index-page.dark~div .ant-radio-checked .ant-radio-inner{border-color:var(--color-primary-100)}.index-page.dark~div .ant-backup-list,.index-page.dark~div .ant-version-list,.index-page.dark .ant-card-actions,.index-page.dark .ant-card-actions>li:not(:last-child){border-color:var(--dark-color-stroke)}.index-page .ant-card-actions{background:#fff0}.index-page .ip-hidden{-webkit-user-select:none;-moz-user-select:none;user-select:none;filter:blur(10px)}.index-page .xray-running-animation .ant-badge-status-dot,.index-page .xray-processing-animation .ant-badge-status-dot{animation:runningAnimation 1.2s linear infinite}.index-page .xray-running-animation .ant-badge-status-processing:after{border-color:var(--color-primary-100)}.index-page .xray-stop-animation .ant-badge-status-processing:after{border-color:#fa8c16}.index-page .xray-error-animation .ant-badge-status-processing:after{border-color:#f5222d}@keyframes runningAnimation{0%,50%,100%{transform:scale(1);opacity:1}10%{transform:scale(1.5);opacity:.2}}.index-page .card-placeholder{text-align:center;padding:30px 0;margin-top:10px;background:#fff0;border:none}.index-page~div .log-container{height:auto;max-height:500px;overflow:auto;margin-top:.5rem}#app.login-app *{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#app.login-app h1{text-align:center;height:110px}#app.login-app .ant-form-item-children .ant-btn,#app.login-app .ant-input{height:50px;border-radius:30px}#app.login-app .ant-input-group-addon{border-radius:0 30px 30px 0;width:50px;font-size:18px}#app.login-app .ant-input-affix-wrapper .ant-input-prefix{left:23px}#app.login-app .ant-input-affix-wrapper .ant-input:not(:first-child){padding-left:50px}#app.login-app .centered{display:flex;text-align:center;align-items:center;justify-content:center;width:100%}#app.login-app .title{font-size:2rem;margin-block-end:2rem}#app.login-app .title b{font-weight:bold!important}#app.login-app{overflow:hidden}#app.login-app #login{animation:charge 0.5s both;background-color:#fff;border-radius:2rem;padding:4rem 3rem;transition:all 0.3s;user-select:none;-webkit-user-select:none;-moz-user-select:none}#app.login-app #login:hover{box-shadow:0 2px 8px rgb(0 0 0 / .09)}@keyframes charge{from{transform:translateY(5rem);opacity:0}to{transform:translateY(0);opacity:1}}#app.login-app .under{background-color:#c7ebe2;z-index:0}#app.login-app.dark .under{background-color:var(--dark-color-login-wave)}#app.login-app.dark #login{background-color:var(--dark-color-surface-100)}#app.login-app.dark h1{color:#fff}#app.login-app .ant-btn-primary-login{width:100%}#app.login-app .ant-btn-primary-login:focus,#app.login-app .ant-btn-primary-login:hover{color:#fff;background-color:#065;border-color:#065;background-image:linear-gradient(270deg,#fff0 30%,#009980,#fff0 100%);background-repeat:no-repeat;animation:ma-bg-move ease-in-out 5s infinite;background-position-x:-500px;width:95%;animation-delay:-0.5s;box-shadow:0 2px 0 rgb(0 0 0 / .045)}#app.login-app .ant-btn-primary-login.active,#app.login-app .ant-btn-primary-login:active{color:#fff;background-color:#065;border-color:#065}@keyframes ma-bg-move{0%{background-position:-500px 0}50%{background-position:1000px 0}100%{background-position:1000px 0}}#app.login-app .wave-btn-bg{position:relative;border-radius:25px;width:100%;transition:all 0.3s cubic-bezier(.645,.045,.355,1)}#app.login-app.dark .wave-btn-bg{color:#fff;position:relative;background-color:#0a7557;border:2px double #fff0;background-origin:border-box;background-clip:padding-box,border-box;background-size:300%;width:100%;z-index:1}#app.login-app.dark .wave-btn-bg:hover{animation:wave-btn-tara 4s ease infinite}#app.login-app.dark .wave-btn-bg-cl{background-image:linear-gradient(#fff0,#fff0),radial-gradient(circle at left top,#006655,#009980,#006655)!important;border-radius:3em}#app.login-app.dark .wave-btn-bg-cl:hover{width:95%}#app.login-app.dark .wave-btn-bg-cl:before{position:absolute;content:"";top:-5px;left:-5px;bottom:-5px;right:-5px;z-index:-1;background:inherit;background-size:inherit;border-radius:4em;opacity:0;transition:0.5s}#app.login-app.dark .wave-btn-bg-cl:hover::before{opacity:1;filter:blur(20px);animation:wave-btn-tara 8s linear infinite}@keyframes wave-btn-tara{to{background-position:300%}}#app.login-app.dark .ant-btn-primary-login{font-size:14px;color:#fff;text-align:center;background-image:linear-gradient(rgb(13 14 33 / .45),rgb(13 14 33 / .35));border-radius:2rem;border:none;outline:none;background-color:#fff0;height:46px;position:relative;white-space:nowrap;cursor:pointer;touch-action:manipulation;padding:0 15px;width:100%;animation:none;background-position-x:0;box-shadow:none}#app.login-app .waves-header{position:fixed;width:100%;text-align:center;background-color:#dbf5ed;color:#fff;z-index:-1}#app.login-app.dark .waves-header{background-color:var(--dark-color-login-background)}#app.login-app .waves-inner-header{height:50vh;width:100%;margin:0;padding:0}#app.login-app .waves{position:relative;width:100%;height:15vh;margin-bottom:-8px;min-height:100px;max-height:150px}#app.login-app .parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}#app.login-app.dark .parallax>use{fill:var(--dark-color-login-wave)}#app.login-app .parallax>use:nth-child(1){animation-delay:-2s;animation-duration:4s;opacity:.2}#app.login-app .parallax>use:nth-child(2){animation-delay:-3s;animation-duration:7s;opacity:.4}#app.login-app .parallax>use:nth-child(3){animation-delay:-4s;animation-duration:10s;opacity:.6}#app.login-app .parallax>use:nth-child(4){animation-delay:-5s;animation-duration:13s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}100%{transform:translate3d(85px,0,0)}}@media (max-width:768px){#app.login-app .waves{height:40px;min-height:40px}}#app.login-app .words-wrapper{width:100%;display:inline-block;position:relative;text-align:center}#app.login-app .words-wrapper b{width:100%;display:inline-block;position:absolute;left:0;top:0}#app.login-app .words-wrapper b.is-visible{position:relative}#app.login-app .headline.zoom .words-wrapper{-webkit-perspective:300px;-moz-perspective:300px;perspective:300px}#app.login-app .headline{display:flex;justify-content:center;align-items:center}#app.login-app .headline.zoom b{opacity:0}#app.login-app .headline.zoom b.is-visible{opacity:1;-webkit-animation:zoom-in 0.8s;-moz-animation:zoom-in 0.8s;animation:cubic-bezier(.215,.61,.355,1) zoom-in 0.8s}#app.login-app .headline.zoom b.is-hidden{-webkit-animation:zoom-out 0.8s;-moz-animation:zoom-out 0.8s;animation:cubic-bezier(.215,.61,.355,1) zoom-out 0.4s}@-webkit-keyframes zoom-in{0%{opacity:0;-webkit-transform:translateZ(100px)}100%{opacity:1;-webkit-transform:translateZ(0)}}@-moz-keyframes zoom-in{0%{opacity:0;-moz-transform:translateZ(100px)}100%{opacity:1;-moz-transform:translateZ(0)}}@keyframes zoom-in{0%{opacity:0;-webkit-transform:translateZ(100px);-moz-transform:translateZ(100px);-ms-transform:translateZ(100px);-o-transform:translateZ(100px);transform:translateZ(100px)}100%{opacity:1;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}}@-webkit-keyframes zoom-out{0%{opacity:1;-webkit-transform:translateZ(0)}100%{opacity:0;-webkit-transform:translateZ(-100px)}}@-moz-keyframes zoom-out{0%{opacity:1;-moz-transform:translateZ(0)}100%{opacity:0;-moz-transform:translateZ(-100px)}}@keyframes zoom-out{0%{opacity:1;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}100%{opacity:0;-webkit-transform:translateZ(-100px);-moz-transform:translateZ(-100px);-ms-transform:translateZ(-100px);-o-transform:translateZ(-100px);transform:translateZ(-100px)}}#app.login-app .setting-section{position:absolute;top:0;right:0;padding:22px}#app.login-app .ant-space-item .ant-switch{margin:2px 0 4px}.inbounds-page .ant-table:not(.ant-table-expanded-row .ant-table){outline:1px solid #f0f0f0;outline-offset:-1px;border-radius:1rem;overflow-x:hidden}.inbounds-page.dark .ant-table:not(.ant-table-expanded-row .ant-table){outline-color:var(--dark-color-table-ring)}.inbounds-page .ant-table .ant-table-content .ant-table-scroll .ant-table-body{overflow-y:hidden}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper{margin:-10px 22px!important}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper .ant-table{border-bottom-left-radius:1rem;border-bottom-right-radius:1rem}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child tr:last-child td{border-bottom-color:#fff0}.inbounds-page .ant-table .ant-table-tbody tr:last-child.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody>tr:last-child>td:first-child{border-bottom-left-radius:6px}.inbounds-page .ant-table .ant-table-tbody tr:last-child.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody>tr:last-child>td:last-child{border-bottom-right-radius:6px}@media (min-width:769px){.inbounds-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.inbounds-page .ant-card-body{padding:.5rem}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper{margin:-10px 2px!important}}.inbounds-page.dark .ant-switch-small:not(.ant-switch-checked){background-color:var(--dark-color-surface-100)!important}.inbounds-page .ant-custom-popover-title{display:flex;align-items:center;gap:10px;margin:5px 0}.inbounds-page .ant-col-sm-24{margin:.5rem -2rem .5rem 2rem}.inbounds-page tr.hideExpandIcon .ant-table-row-expand-icon{display:none}.inbounds-page .infinite-tag,.inbounds-page~div .infinite-tag{padding:0 5px;border-radius:2rem;min-width:50px;min-height:22px}.inbounds-page .infinite-bar .ant-progress-inner .ant-progress-bg{background-color:#F2EAF1;border:#D5BED2 solid 1px}.inbounds-page.dark .infinite-bar .ant-progress-inner .ant-progress-bg{background-color:#7a316f!important;border:#7a316f solid 1px}.inbounds-page~div .ant-collapse{margin:5px 0}.inbounds-page .info-large-tag,.inbounds-page~div .info-large-tag{max-width:200px;overflow:hidden}.inbounds-page .client-comment{font-size:12px;opacity:.75;cursor:help}.inbounds-page .client-email{font-weight:500}.inbounds-page .client-popup-item{display:flex;align-items:center;gap:5px}.inbounds-page .online-animation .ant-badge-status-dot{animation:onlineAnimation 1.2s linear infinite}@keyframes onlineAnimation{0%,50%,100%{transform:scale(1);opacity:1}10%{transform:scale(1.5);opacity:.2}}.inbounds-page .tr-table-box{display:flex;gap:4px;justify-content:center;align-items:center}.inbounds-page .tr-table-rt{flex-basis:70px;min-width:70px;text-align:end}.inbounds-page .tr-table-lt{flex-basis:70px;min-width:70px;text-align:start}.inbounds-page .tr-table-bar{flex-basis:160px;min-width:60px}.inbounds-page .tr-infinity-ch{font-size:14pt;max-height:24px;display:inline-flex;align-items:center}.inbounds-page .ant-table-expanded-row .ant-table .ant-table-body{overflow-x:hidden}.inbounds-page .ant-table-expanded-row .ant-table-tbody>tr>td{padding:10px 2px}.inbounds-page .ant-table-expanded-row .ant-table-thead>tr>th{padding:12px 2px}@media (min-width:769px){.settings-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.settings-page .ant-tabs-nav .ant-tabs-tab{margin:0;padding:12px .5rem}}.settings-page .ant-tabs-bar{margin:0}.settings-page .ant-list-item{display:block}.settings-page .alert-msg{color:#c27512;font-weight:400;font-size:16px;padding:.5rem 1rem;text-align:center;background:rgb(255 145 0 / 15%);margin:1.5rem 2.5rem 0rem;border-radius:.5rem;transition:all 0.5s;animation:settings-page-signal 3s cubic-bezier(.18,.89,.32,1.28) infinite}.settings-page .alert-msg:hover{cursor:default;transition-duration:.3s;animation:settings-page-signal 0.9s ease infinite}@keyframes settings-page-signal{0%{box-shadow:0 0 0 0 rgb(194 118 18 / .5)}50%{box-shadow:0 0 0 6px #fff0}100%{box-shadow:0 0 0 6px #fff0}}.settings-page .alert-msg>i{color:inherit;font-size:24px}.settings-page.dark .ant-input-password-icon{color:var(--dark-color-text-primary)}.settings-page .ant-collapse-content-box .ant-alert{margin-block-end:12px}@media (min-width:769px){.xray-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.xray-page .ant-tabs-nav .ant-tabs-tab{margin:0;padding:12px .5rem}.xray-page .ant-table-thead>tr>th,.xray-page .ant-table-tbody>tr>td{padding:10px 0}}.xray-page .ant-tabs-bar{margin:0}.xray-page .ant-list-item{display:block}.xray-page .ant-list-item>li{padding:10px 20px!important}.xray-page .ant-collapse-content-box .ant-alert{margin-block-end:12px}#app.login-app.dark #login input.ant-input:-webkit-autofill,#app.login-app.dark #login input.ant-input:-webkit-autofill:hover,#app.login-app.dark #login input.ant-input:-webkit-autofill:focus,#app.login-app.dark #login .ant-input-password input:-webkit-autofill,#app.login-app.dark #login .ant-input-password input:-webkit-autofill:hover,#app.login-app.dark #login .ant-input-password input:-webkit-autofill:focus{-webkit-text-fill-color:var(--login-input-color,#d6dce6);caret-color:var(--login-input-color,#d6dce6);-webkit-box-shadow:0 0 0 1000px var(--login-input-bg,#1d2433) inset;box-shadow:0 0 0 1000px var(--login-input-bg,#1d2433) inset;transition:background-color 9999s ease-in-out 0s}#app.login-app.dark #login input.ant-input:-moz-autofill,#app.login-app.dark #login .ant-input-password input:-moz-autofill{-moz-text-fill-color:var(--login-input-color,#d6dce6);caret-color:var(--login-input-color,#d6dce6);box-shadow:0 0 0 1000px var(--login-input-bg,#1d2433) inset}#app.login-app.dark #login{--login-input-bg:var(--dark-color-surface-200);--login-input-color:var(--dark-color-text-primary)}.dark .ant-descriptions-bordered .ant-descriptions-item-label{background-color:var(--dark-color-background)}.dark .ant-descriptions-bordered .ant-descriptions-view,.dark .ant-descriptions-bordered .ant-descriptions-row,.dark .ant-descriptions-bordered .ant-descriptions-item-label,.dark .ant-list-bordered{border-color:var(--dark-color-surface-400)}.dark .ant-descriptions-bordered .ant-descriptions-item-label,.dark .ant-descriptions-bordered .ant-descriptions-item-content{color:var(--dark-color-text-primary)}.dark .ant-dropdown-menu{background-color:var(--dark-color-surface-200)}.dark .ant-dropdown-menu .ant-dropdown-menu-item{color:hsl(0 0% 100% / .65)}.dark .ant-dropdown-menu .ant-dropdown-menu-item:hover{background-color:var(--dark-color-surface-600)}.subscription-page .ant-list.ant-list-split.ant-list-bordered{overflow:hidden}.subscription-page .ant-list.ant-list-split.ant-list-bordered .ant-list-item{overflow-x:auto}.subscription-page .ant-btn.ant-btn-primary.ant-btn-lg.ant-dropdown-trigger{border-radius:4rem;padding:0 20px}.subscription-page .subscription-card{margin:2rem 0}.mb-10{margin-bottom:10px}.mb-12{margin-bottom:12px}.mt-5{margin-top:5px}.mr-8{margin-right:8px}.ml-10{margin-left:10px}.mr-05{margin-right:.5rem}.fs-1rem{font-size:1rem}.w-100{width:100%}.w-70{width:70px}.w-95{width:95px}.text-center{text-align:center}.cursor-pointer{cursor:pointer}.float-right{float:right}.va-middle{vertical-align:middle}.d-flex{display:flex}.justify-end{justify-content:flex-end}.max-w-400{max-width:400px;display:inline-block}.ant-space.jc-center{justify-content:center}.min-h-0{min-height:0}.min-h-100vh{min-height:100vh}.h-100{height:100%}.h-50px{height:50px}.overflow-auto{overflow:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-hidden-auto{overflow:hidden auto}.mt-1rem{margin-top:1rem}.my-3rem{margin-top:3rem;margin-bottom:3rem} \ No newline at end of file +:root{--color-primary-100:#008771;--dark-color-background:#0a1222;--dark-color-surface-100:#151f31;--dark-color-surface-200:#222d42;--dark-color-surface-300:#2c3950;--dark-color-surface-400:rgba(65, 85, 119, 0.5);--dark-color-surface-500:#2c3950;--dark-color-surface-600:#313f5a;--dark-color-surface-700:#111929;--dark-color-surface-700-rgb:17, 25, 41;--dark-color-table-hover:rgba(44, 57, 80, 0.2);--dark-color-text-primary:rgba(255, 255, 255, 0.75);--dark-color-stroke:#2c3950;--dark-color-btn-danger:#cd3838;--dark-color-btn-danger-border:transparent;--dark-color-btn-danger-hover:#e94b4b;--dark-color-tag-bg:rgba(255, 255, 255, 0.05);--dark-color-tag-border:rgba(255, 255, 255, 0.15);--dark-color-tag-color:rgba(255, 255, 255, 0.75);--dark-color-tag-green-bg:17, 36, 33;--dark-color-tag-green-border:25, 81, 65;--dark-color-tag-green-color:#3ad3ba;--dark-color-tag-purple-bg:#201425;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d988cd;--dark-color-tag-red-bg:#291515;--dark-color-tag-red-border:#5c2626;--dark-color-tag-red-color:#e04141;--dark-color-tag-orange-bg:#312313;--dark-color-tag-orange-border:#593914;--dark-color-tag-orange-color:#ffa031;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#1348ab;--dark-color-tag-blue-color:#529fff;--dark-color-codemirror-line-hover:rgba(0, 135, 113, 0.2);--dark-color-codemirror-line-selection:rgba(0, 135, 113, 0.3);--dark-color-login-background:var(--dark-color-background);--dark-color-login-wave:var(--dark-color-surface-200);--dark-color-tooltip:rgba(61, 76, 104, 0.9);--dark-color-back-top:rgba(61, 76, 104, 0.9);--dark-color-back-top-hover:rgba(61, 76, 104, 1);--dark-color-scrollbar:#313f5a;--dark-color-scrollbar-webkit:#7484a0;--dark-color-scrollbar-webkit-hover:#90a4c7;--dark-color-table-ring:rgb(38 52 77);--dark-color-spin-container:#151f31}html[data-theme-animations='off']{.ant-menu,.ant-layout-sider,.ant-card,.ant-tag,.ant-progress-circle>*,.ant-input,.ant-table-row-expand-icon,.ant-switch,.ant-table-thead>tr>th,.ant-select-selection,.ant-btn,.ant-input-number,.ant-input-group-addon,.ant-checkbox-inner,.ant-progress-bg,.ant-progress-success-bg,.ant-radio-button-wrapper:not(:first-child):before,.ant-radio-button-wrapper,#login,.cm-s-xq.CodeMirror{transition:border 0s,background 0s!important}.ant-menu.ant-menu-inline .ant-menu-item:not(.ant-menu-sub .ant-menu-item),.ant-layout-sider-trigger,.ant-alert-close-icon .anticon-close,.ant-tabs-nav .ant-tabs-tab,.ant-input-number-input,.ant-collapse>.ant-collapse-item>.ant-collapse-header,.Line-Hover,.ant-menu-theme-switch,.ant-menu-submenu-title{transition:color 0s!important}.wave-btn-bg{transition:width 0s!important}}html[data-theme='ultra-dark']{--dark-color-background:#21242a;--dark-color-surface-100:#0c0e12;--dark-color-surface-200:#222327;--dark-color-surface-300:#32353b;--dark-color-surface-400:rgba(255, 255, 255, 0.1);--dark-color-surface-500:#3b404b;--dark-color-surface-600:#505663;--dark-color-surface-700:#101113;--dark-color-surface-700-rgb:16, 17, 19;--dark-color-table-hover:rgba(89, 89, 89, 0.15);--dark-color-text-primary:rgb(255 255 255 / 85%);--dark-color-stroke:#202025;--dark-color-tag-green-bg:17, 36, 33;--dark-color-tag-green-border:29, 95, 77;--dark-color-tag-green-color:#59cbac;--dark-color-tag-purple-bg:#241121;--dark-color-tag-purple-border:#5a2969;--dark-color-tag-purple-color:#d686ca;--dark-color-tag-red-bg:#2a1215;--dark-color-tag-red-border:#58181c;--dark-color-tag-red-color:#e84749;--dark-color-tag-orange-bg:#2b1d11;--dark-color-tag-orange-border:#593815;--dark-color-tag-orange-color:#e89a3c;--dark-color-tag-blue-bg:#111a2c;--dark-color-tag-blue-border:#0f367e;--dark-color-tag-blue-color:#3c89e8;--dark-color-codemirror-line-hover:rgba(82, 84, 94, 0.2);--dark-color-codemirror-line-selection:rgba(82, 84, 94, 0.3);--dark-color-login-background:#0a2227;--dark-color-login-wave:#0f2d32;--dark-color-tooltip:rgba(88, 93, 100, 0.9);--dark-color-back-top:rgba(88, 93, 100, 0.9);--dark-color-back-top-hover:rgba(88, 93, 100, 1);--dark-color-scrollbar:rgb(107,107,107);--dark-color-scrollbar-webkit:#9f9f9f;--dark-color-scrollbar-webkit-hover:#d1d1d1;--dark-color-table-ring:rgb(37 39 42);--dark-color-spin-container:#1d1d1d;.ant-dropdown-menu-dark,.dark .ant-dropdown-menu{background-color:var(--dark-color-surface-500)}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.dark .waves-header{background-color:#0a2227}.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-600)}}html,body{height:100vh;width:100vw;margin:0;padding:0;overflow:hidden}body{color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;background-color:#fff;font-feature-settings:"tnum"}html{--antd-wave-shadow-color:var(--color-primary-100);line-height:1.15;text-size-adjust:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-moz-tap-highlight-color:#fff0;-webkit-tap-highlight-color:#fff0}@supports (scrollbar-width:auto) and (not selector(::-webkit-scrollbar)){:not(.dark){scrollbar-color:#9a9a9a #fff0;scrollbar-width:thin}.dark *{scrollbar-color:var(--dark-color-scrollbar) #fff0;scrollbar-width:thin}}::-webkit-scrollbar{width:10px;height:10px;background-color:#fff0}::-webkit-scrollbar-track{background-color:#fff0;margin-block:.5em}.ant-modal-wrap::-webkit-scrollbar-track{background-color:#fff;margin-block:0}::-webkit-scrollbar-thumb{border-radius:9999px;background-color:#9a9a9a;border:2px solid #fff0;background-clip:content-box}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background-color:#828282}.dark .ant-modal-wrap::-webkit-scrollbar-track{background-color:var(--dark-color-background)}.dark::-webkit-scrollbar-thumb{background-color:var(--dark-color-scrollbar-webkit)}.dark::-webkit-scrollbar-thumb:hover,.dark::-webkit-scrollbar-thumb:active{background-color:var(--dark-color-scrollbar-webkit-hover)}::-moz-selection{color:var(--color-primary-100);background-color:#cfe8e4}::selection{color:var(--color-primary-100);background-color:#cfe8e4}#app{height:100%;position:fixed;top:0;left:0;right:0;bottom:0;margin:0;padding:0;overflow:auto}.ant-layout,.ant-layout *{box-sizing:border-box}.ant-spin-container:after{border-radius:1.5rem}.dark .ant-spin-container:after{background:var(--dark-color-spin-container)}style attribute{text-align:center}.ant-table-thead>tr>th{padding:12px 8px}.ant-table-tbody>tr>td{padding:10px 8px}.ant-table-thead>tr>th{color:rgb(0 0 0 / .85);font-weight:500;text-align:left;border-bottom:1px solid #e8e8e8;transition:background 0.3s ease}.ant-table table{border-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:first-child{border-bottom-left-radius:1rem}.ant-table-bordered .ant-table-tbody:not(.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody)>tr:last-child>td:last-child{border-bottom-right-radius:1rem}.ant-table{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;font-feature-settings:"tnum";position:relative;clear:both}.ant-table .ant-table-body:not(.ant-table-expanded-row .ant-table-body){overflow-x:auto!important}.ant-card-hoverable{cursor:auto;cursor:pointer}.ant-card{box-sizing:border-box;margin:0;padding:0;color:rgb(0 0 0 / .65);font-size:14px;font-variant:tabular-nums;line-height:1.5;list-style:none;position:relative;background-color:#fff;border-radius:2px;transition:all 0.3s}.ant-space{width:100%}.ant-layout-sider-zero-width-trigger{display:none}@media (max-width:768px){.ant-layout-sider{display:none}.ant-card,.ant-alert-error{margin:.5rem}.ant-tabs{margin:.5rem;padding:.5rem}.ant-modal-body{padding:20px}.ant-form-item-label{line-height:1.5;padding:8px 0 0}:not(.dark)::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}.dark::-webkit-scrollbar{width:8px;height:8px;background-color:#fff0}}.ant-layout-content{min-height:auto}.ant-card,.ant-tabs{border-radius:1.5rem}.ant-card-hoverable{cursor:auto}.ant-card+.ant-card{margin-top:20px}.drawer-handle{position:absolute;top:72px;width:41px;height:40px;cursor:pointer;z-index:0;text-align:center;line-height:40px;font-size:16px;display:flex;justify-content:center;align-items:center;background-color:#fff;right:-40px;box-shadow:2px 0 8px rgb(0 0 0 / .15);border-radius:0 4px 4px 0}.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{background-color:#006655!important;background-image:linear-gradient(270deg,#fff0 30%,#009980,#fff0 100%);background-repeat:no-repeat;animation:ma-bg-move linear 6.6s infinite;color:#fff;border-radius:.5rem}.ant-layout-sider-collapsed .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected{border-radius:0}.ant-menu-item-active,.ant-menu-item:hover,.ant-menu-submenu-title:hover,.ant-menu-item:active,.ant-menu-submenu-title:active{color:var(--color-primary-100);background-color:#e8f4f2}.ant-menu-inline .ant-menu-item,.ant-menu-inline .ant-menu-submenu-title{border-radius:.5rem}.ant-menu-inline .ant-menu-item:after,.ant-menu{border-right-width:0}.ant-layout-sider-children,.ant-pagination ul{padding:.5rem}.ant-layout-sider-collapsed .ant-layout-sider-children{padding:.5rem 0}.ant-dropdown-menu,.ant-select-dropdown-menu{padding:.5rem}.ant-dropdown-menu-item,.ant-dropdown-menu-item:hover,.ant-select-dropdown-menu-item,.ant-select-dropdown-menu-item:hover,.ant-select-selection--multiple .ant-select-selection__choice{border-radius:.5rem}.ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item,.ant-select-dropdown--single .ant-select-dropdown-menu .ant-select-dropdown-menu-item-selected{margin-block:2px}@media (min-width:769px){.drawer-handle{display:none}.ant-tabs{padding:2rem}}.fade-in-enter,.fade-in-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.fade-in-enter-active,.fade-in-leave-active{-webkit-transition:all 0.3s cubic-bezier(.55,0,.1,1);transition:all 0.3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter-active,.zoom-in-center-leave-active{-webkit-transition:all 0.3s cubic-bezier(.55,0,.1,1);transition:all 0.3s cubic-bezier(.55,0,.1,1)}.zoom-in-center-enter,.zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.zoom-in-top-enter-active,.zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.zoom-in-top-enter,.zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-bottom-enter-active,.zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.zoom-in-bottom-enter,.zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.zoom-in-left-enter-active,.zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1);transition:transform 0.3s cubic-bezier(.23,1,.32,1),opacity 0.3s cubic-bezier(.23,1,.32,1),-webkit-transform 0.3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.zoom-in-left-enter,.zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.list-enter-active,.list-leave-active{-webkit-transition:all 0.3s;transition:all 0.3s}.list-enter,.list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.ant-tooltip-inner{min-height:0;padding-inline:1rem}.ant-list-item-meta-title{font-size:14px}.ant-progress-inner{background-color:#ebeef5}.deactive-client .ant-collapse-header{color:#ffffff!important;background-color:#ff7f7f}.ant-table-expand-icon-th,.ant-table-row-expand-icon-cell{width:30px;min-width:30px}.ant-tabs{background-color:#fff}.ant-form-item{margin-bottom:0}.ant-setting-textarea{margin-top:1.5rem}.client-table-header{background-color:#f0f2f5}.client-table-odd-row{background-color:#fafafa}.ant-table-pagination.ant-pagination{float:left}.ant-tag{margin-right:0;margin-inline:2px;display:inline-flex;align-items:center;justify-content:space-evenly}.ant-tag:not(.qr-tag){column-gap:4px}#inbound-info-modal .ant-tag{margin-block:2px}.tr-info-table{display:inline-table;margin-block:10px;width:100%}#inbound-info-modal .tr-info-table .ant-tag{margin-block:0;margin-inline:0}.tr-info-row{display:flex;flex-direction:column;row-gap:2px;margin-block:10px}.tr-info-row a{margin-left:6px}.tr-info-row code{padding-inline:8px}.tr-info-tag{max-width:100%;text-wrap:balance;overflow:hidden;overflow-wrap:anywhere}.tr-info-title{display:inline-flex;align-items:center;justify-content:flex-start;column-gap:4px}.ant-tag-blue{background-color:#edf4fa;border-color:#a9c5e7;color:#0e49b5}.ant-tag-green{background-color:#eafff9;border-color:#76ccb4;color:#199270}.ant-tag-purple{background-color:#f2eaf1;border-color:#d5bed2;color:#7a316f}.ant-tag-orange,.ant-alert-warning{background-color:#ffeee1;border-color:#fec093;color:#f37b24}.ant-tag-red,.ant-alert-error{background-color:#ffe9e9;border-color:#ff9e9e;color:#cf3c3c}.ant-input::placeholder{opacity:.5}.ant-input:hover,.ant-input:focus{background-color:#e8f4f2}.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){background-color:#e8f4f2}.delete-icon:hover{color:#e04141}.normal-icon:hover{color:var(--color-primary-100)}.dark ::-moz-selection{color:#fff;background-color:var(--color-primary-100)}.dark ::selection{color:#fff;background-color:var(--color-primary-100)}.dark .normal-icon:hover{color:#fff}.dark .ant-layout-sider,.dark .ant-drawer-content,.ant-menu-dark,.ant-menu-dark .ant-menu-sub,.dark .ant-card,.dark .ant-table,.dark .ant-collapse-content,.dark .ant-tabs{background-color:var(--dark-color-surface-100);color:var(--dark-color-text-primary)}.dark .ant-card-hoverable:hover,.dark .ant-space-item>.ant-tabs:hover{box-shadow:0 2px 8px #fff0}.dark>.ant-layout,.dark .drawer-handle,.dark .ant-table-thead>tr>th,.dark .ant-table-expanded-row,.dark .ant-table-expanded-row:hover,.dark .ant-table-expanded-row .ant-table-tbody,.dark .ant-calendar{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-table-expanded-row .ant-table-thead>tr:first-child>th{border-radius:0}.dark .ant-calendar,.dark .ant-card-bordered{border-color:var(--dark-color-background)}.dark .ant-table-bordered,.dark .ant-table-bordered.ant-table-empty .ant-table-placeholder,.dark .ant-table-bordered .ant-table-body>table,.dark .ant-table-bordered .ant-table-fixed-left table,.dark .ant-table-bordered .ant-table-fixed-right table,.dark .ant-table-bordered .ant-table-header>table,.dark .ant-table-bordered .ant-table-thead>tr:not(:last-child)>th,.dark .ant-table-bordered .ant-table-tbody>tr>td,.dark .ant-table-bordered .ant-table-thead>tr>th{border-color:var(--dark-color-surface-400)}.dark .ant-table-tbody>tr>td,.dark .ant-table-thead>tr>th,.dark .ant-card-head,.dark .ant-modal-header,.dark .ant-collapse>.ant-collapse-item,.dark .ant-tabs-bar,.dark .ant-list-split .ant-list-item,.dark .ant-popover-title,.dark .ant-calendar-header,.dark .ant-calendar-input-wrap{border-bottom-color:var(--dark-color-surface-400)}.dark .ant-modal-footer,.dark .ant-collapse-content,.dark .ant-calendar-footer,.dark .ant-divider-horizontal.ant-divider-with-text-left:before,.dark .ant-divider-horizontal.ant-divider-with-text-left:after,.dark .ant-divider-horizontal.ant-divider-with-text-center:before,.dark .ant-divider-horizontal.ant-divider-with-text-center:after{border-top-color:var(--dark-color-surface-300)}.ant-divider-horizontal.ant-divider-with-text-left:before{width:10%}.dark .ant-progress-text,.dark .ant-card-head,.dark .ant-form,.dark .ant-collapse>.ant-collapse-item>.ant-collapse-header,.dark .ant-modal-close-x,.dark .ant-form .anticon,.dark .ant-tabs-tab-arrow-show:not(.ant-tabs-tab-btn-disabled),.dark .anticon-close,.dark .ant-list-item-meta-title,.dark .ant-select-selection i,.dark .ant-modal-confirm-title,.dark .ant-modal-confirm-content,.dark .ant-popover-message,.dark .ant-modal,.dark .ant-divider-inner-text,.dark .ant-popover-title,.dark .ant-popover-inner-content,.dark h2,.dark .ant-modal-title,.dark .ant-form-item-label>label,.dark .ant-checkbox-wrapper,.dark .ant-form-item,.dark .ant-calendar-footer .ant-calendar-today-btn,.dark .ant-calendar-footer .ant-calendar-time-picker-btn,.dark .ant-calendar-day-select,.dark .ant-calendar-month-select,.dark .ant-calendar-year-select,.dark .ant-calendar-date,.dark .ant-calendar-year-panel-year,.dark .ant-calendar-month-panel-month,.dark .ant-calendar-decade-panel-decade{color:var(--dark-color-text-primary)}.dark .ant-pagination-options-size-changer .ant-select-arrow .anticon.anticon-down.ant-select-arrow-icon{color:rgb(255 255 255 / 35%)}.dark .ant-pagination-item a,.dark .ant-pagination-next a,.dark .ant-pagination-prev a{color:var(--dark-color-text-primary)}.dark .ant-pagination-item:focus a,.dark .ant-pagination-item:hover a,.dark .ant-pagination-item-active a,.dark .ant-pagination-next:hover .ant-pagination-item-link{color:var(--color-primary-100)}.dark .ant-pagination-item-active{background-color:#fff0}.dark .ant-list-item-meta-description{color:rgb(255 255 255 / .45)}.dark .ant-pagination-disabled i,.dark .ant-tabs-tab-btn-disabled{color:rgb(255 255 255 / .25)}.dark .ant-input,.dark .ant-input-group-addon,.dark .ant-collapse,.dark .ant-select-selection,.dark .ant-input-number,.dark .ant-input-number-handler-wrap,.dark .ant-table-placeholder,.dark .ant-empty-normal,.dark .ant-select-dropdown,.dark .ant-select-dropdown li,.dark .ant-select-dropdown-menu-item,.dark .client-table-header,.dark .ant-select-selection--multiple .ant-select-selection__choice{background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.dark .ant-select-dropdown--multiple .ant-select-dropdown-menu .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected :not(.ant-dropdown-menu-submenu-title:hover){background-color:var(--dark-color-surface-300)}.dark .ant-select-dropdown-menu-item.ant-select-dropdown-menu-item-selected{background-color:var(--dark-color-surface-300)}.dark .ant-calendar-time-picker-inner{background-color:var(--dark-color-background)}.dark .ant-select-selection:hover,.dark .ant-calendar-picker-clear,.dark .ant-input-number:hover,.dark .ant-input-number:focus,.dark .ant-input:hover,.dark .ant-input:focus{background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.dark .ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){border-color:var(--color-primary-100);background-color:rgb(0 135 113 / .3)}.dark .ant-btn:not(.ant-btn-primary):not(.ant-btn-danger){color:var(--dark-color-text-primary);background-color:rgb(10 117 87 / 30%);border:1px solid var(--color-primary-100)}.dark .ant-radio-button-wrapper,.dark .ant-radio-button-wrapper:before{color:var(--dark-color-text-primary);background-color:rgb(0 135 113 / .3);border-color:var(--color-primary-100)}.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){background-color:#e8f4f2}.dark .ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.dark .ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger){color:#fff;background-color:rgb(10 117 87 / 50%);border-color:var(--color-primary-100)}.dark .ant-btn-primary[disabled],.dark .ant-btn-danger[disabled],.dark .ant-calendar-ok-btn-disabled{color:rgb(255 255 255 / 35%);background-color:var(--dark-color-surface-200);border-color:var(--dark-color-surface-300)}.dark .ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.dark .client-table-odd-row{background-color:var(--dark-color-table-hover)}.dark .ant-table-row-expand-icon{color:#fff;background-color:#fff0;border-color:rgb(255 255 255 / 20%)}.dark .ant-table-row-expand-icon:hover{color:var(--color-primary-100);background-color:#fff0;border-color:var(--color-primary-100)}.dark .ant-switch:not(.ant-switch-checked),.dark .ant-progress-line .ant-progress-inner{background-color:var(--dark-color-surface-500)}.dark .ant-progress-circle-trail{stroke:var(--dark-color-stroke)!important}.dark .ant-popover-inner{background-color:var(--dark-color-surface-500)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-500)}@media (max-width:768px){.dark .ant-popover-inner{background-color:var(--dark-color-surface-200)}.dark>.ant-popover-content>.ant-popover-arrow{border-color:var(--dark-color-surface-200)}}.ant-dropdown-menu-dark .ant-dropdown-menu-item:hover,.dark .ant-select-dropdown-menu-item-selected,.dark .ant-calendar-time-picker-select-option-selected{background-color:var(--dark-color-surface-600)}.ant-menu-dark .ant-menu-item:hover,.ant-menu-dark .ant-menu-submenu-title:hover{background-color:var(--dark-color-surface-300)}.dark .ant-menu-item:active,.dark .ant-menu-submenu-title:active{color:#fff;background-color:var(--dark-color-surface-300)}.dark .ant-alert-message{color:rgb(255 255 255 / .85)}.dark .ant-tag{color:var(--dark-color-tag-color);background-color:var(--dark-color-tag-bg);border-color:var(--dark-color-tag-border)}.dark .ant-tag-blue{background-color:var(--dark-color-tag-blue-bg);border-color:var(--dark-color-tag-blue-border);color:var(--dark-color-tag-blue-color)}.dark .ant-tag-red,.dark .ant-alert-error{background-color:var(--dark-color-tag-red-bg);border-color:var(--dark-color-tag-red-border);color:var(--dark-color-tag-red-color)}.dark .ant-tag-orange,.dark .ant-alert-warning{background-color:var(--dark-color-tag-orange-bg);border-color:var(--dark-color-tag-orange-border);color:var(--dark-color-tag-orange-color)}.dark .ant-tag-green{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border));color:var(--dark-color-tag-green-color)}.dark .ant-tag-purple{background-color:var(--dark-color-tag-purple-bg);border-color:var(--dark-color-tag-purple-border);color:var(--dark-color-tag-purple-color)}.dark .ant-modal-content,.dark .ant-modal-header{background-color:var(--dark-color-surface-700)}.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date{color:var(--dark-color-surface-300)}.dark .ant-calendar-selected-day .ant-calendar-date{background-color:var(--color-primary-100)!important;color:#fff}.dark .ant-calendar-date:hover,.dark .ant-calendar-time-picker-select li:hover{background-color:var(--dark-color-surface-600);color:#fff}.dark .ant-calendar-header a:hover,.dark .ant-calendar-header a:hover::before,.dark .ant-calendar-header a:hover::after{border-color:#fff}.dark .ant-calendar-time-picker-select{border-right-color:var(--dark-color-surface-300)}.has-warning .ant-select-selection,.has-warning .ant-select-selection:hover,.has-warning .ant-input,.has-warning .ant-input:hover{background-color:#ffeee1;border-color:#fec093}.has-warning .ant-input::placeholder{color:#f37b24}.has-warning .ant-input:not([disabled]):hover{border-color:#fec093}.dark .has-warning .ant-select-selection,.dark .has-warning .ant-select-selection:hover,.dark .has-warning .ant-input,.dark .has-warning .ant-input:hover{border-color:#784e1d;background:#312313}.dark .has-warning .ant-input::placeholder{color:rgb(255 160 49 / 70%)}.dark .has-warning .anticon{color:#ffa031}.dark .has-success .anticon{color:var(--color-primary-100);animation-name:diffZoomIn1!important}.dark .anticon-close-circle{color:#e04141}.dark .ant-spin-nested-loading>div>.ant-spin .ant-spin-text{text-shadow:0 1px 2px #0007}.dark .ant-spin{color:#fff}.dark .ant-spin-dot-item{background-color:#fff}.ant-checkbox-wrapper,.ant-input-group-addon,.ant-tabs-tab,.ant-input::placeholder,.ant-collapse-header,.ant-menu,.ant-radio-button-wrapper{-webkit-user-select:none;user-select:none}.ant-calendar-date,.ant-calendar-year-panel-year,.ant-calendar-decade-panel-decade,.ant-calendar-month-panel-month{border-radius:4px}.ant-checkbox-inner,.ant-checkbox-checked:after,.ant-table-row-expand-icon{border-radius:6px}.ant-calendar-date:hover{background-color:#e8f4f2}.ant-calendar-date:active{background-color:#e8f4f2;color:rgb(0 0 0 / .65)}.ant-calendar-today .ant-calendar-date{color:var(--color-primary-100);font-weight:400;border-color:var(--color-primary-100)}.dark .ant-calendar-today .ant-calendar-date{color:#fff;border-color:var(--color-primary-100)}.ant-calendar-selected-day .ant-calendar-date{background:var(--color-primary-100);color:#fff}li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(0 0 0 / .25)}.dark li.ant-select-dropdown-menu-item:empty:after{content:"None";font-weight:400;color:rgb(255 255 255 / .3)}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:rgb(0 0 0 / .87)}.dark.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item:hover .ant-select-selected-icon{color:#fff}.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected .ant-select-selected-icon,.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item-selected:hover .ant-select-selected-icon{color:var(--color-primary-100)}.ant-select-selection:hover,.ant-input-number-focused,.ant-input-number:hover{background-color:#e8f4f2}.dark .ant-input-number-handler:active{background-color:var(--color-primary-100)}.dark .ant-input-number-handler:hover .ant-input-number-handler-down-inner,.dark .ant-input-number-handler:hover .ant-input-number-handler-up-inner{color:#fff}.dark .ant-input-number-handler-down{border-top:1px solid rgb(217 217 217 / .3)}.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-century-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-decade-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-month-select,.dark .ant-calendar-year-panel-header .ant-calendar-year-panel-year-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-century-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-decade-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-month-select,.dark .ant-calendar-month-panel-header .ant-calendar-month-panel-year-select{color:rgb(255 255 255 / .85)}.dark .ant-calendar-year-panel-header{border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel-last-decade-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-next-decade-cell .ant-calendar-year-panel-year{color:rgb(255 255 255 / .35)}.dark .ant-divider:not(.ant-divider-with-text-center,.ant-divider-with-text-left,.ant-divider-with-text-right),.ant-dropdown-menu-dark,.dark .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-decade:hover{background-color:var(--dark-color-surface-200)}.dark .ant-calendar-header a:hover{color:#fff}.dark .ant-calendar-month-panel-header{background-color:var(--dark-color-background);border-bottom:1px solid var(--dark-color-surface-200)}.dark .ant-calendar-year-panel,.dark .ant-calendar table{background-color:var(--dark-color-background)}.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year,.dark .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year:hover,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month,.dark .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month:hover,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-selected-cell .ant-calendar-decade-panel-decade:hover{color:#fff;background-color:var(--color-primary-100)!important}.dark .ant-calendar-last-month-cell .ant-calendar-date,.dark .ant-calendar-last-month-cell .ant-calendar-date:hover,.dark .ant-calendar-next-month-btn-day .ant-calendar-date,.dark .ant-calendar-next-month-btn-day .ant-calendar-date:hover{color:rgb(255 255 255 / 25%);background:#fff0;border-color:#fff0}.dark .ant-calendar-today .ant-calendar-date:hover{color:#fff;border-color:var(--color-primary-100);background-color:var(--color-primary-100)}.dark .ant-calendar-decade-panel-last-century-cell .ant-calendar-decade-panel-decade,.dark .ant-calendar-decade-panel-next-century-cell .ant-calendar-decade-panel-decade{color:rgb(255 255 255 / 25%)}.dark .ant-calendar-decade-panel-header{border-bottom:1px solid var(--dark-color-surface-200);background-color:var(--dark-color-background)}.dark .ant-checkbox-inner{background-color:rgb(0 135 113 / .3);border-color:rgb(0 135 113 / .3)}.dark .ant-checkbox-checked .ant-checkbox-inner{background-color:var(--color-primary-100);border-color:var(--color-primary-100)}.dark .ant-calendar-input{background-color:var(--dark-color-background);color:var(--dark-color-text-primary)}.dark .ant-calendar-input::placeholder{color:rgb(255 255 255 / .25)}.ant-input-group.ant-input-group-compact-addon:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact-wrap:not(:first-child):not(:last-child),.ant-input-group.ant-input-group-compact>.ant-input:not(:first-child):not(:last-child),.ant-input-number-handler,.ant-input-number-handler-wrap{border-radius:0}.ant-input-number{overflow:clip}.ant-modal-body,.ant-collapse-content>.ant-collapse-content-box{overflow-x:auto}.ant-modal-body{overflow-y:hidden}.ant-calendar-year-panel-year:hover,.ant-calendar-decade-panel-decade:hover,.ant-calendar-month-panel-month:hover,.ant-dropdown-menu-item:hover,.ant-dropdown-menu-submenu-title:hover,.ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled),.ant-table-tbody>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td,.ant-table-thead>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td{background-color:#e8f4f2}.dark .ant-dropdown-menu-submenu-title:hover,.dark .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled),.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled){background-color:rgb(0 93 78 / .3)}.ant-select-dropdown,.ant-popover-inner{overflow-x:hidden}.ant-popover-inner-content{max-height:450px;overflow-y:auto}@media (max-height:900px){.ant-popover-inner-content{max-height:400px}}@media (max-height:768px){.ant-popover-inner-content{max-height:300px}}@media (max-width:768px){.ant-popover-inner-content{max-height:300px}}.qr-modal{display:flex;align-items:flex-end;gap:10px;flex-direction:column;flex-wrap:wrap;row-gap:24px}.qr-box{width:220px}.qr-cv{width:100%;height:100%}.dark .qr-cv{filter:invert(1)}.qr-bg{background-color:#fff;display:flex;justify-content:center;align-content:center;padding:.8rem;border-radius:1rem;border:solid 1px #e8e8e8;height:220px;width:220px;transition:all 0.1s}.qr-bg:hover{border-color:#76ccb4;background-color:#eafff9}.qr-bg:hover:active{border-color:#76ccb4;background-color:rgb(197 241 228 / 70%)}.dark .qr-bg{background-color:var(--dark-color-surface-700);border-color:var(--dark-color-surface-300)}.dark .qr-bg:hover{background-color:rgb(var(--dark-color-tag-green-bg));border-color:rgb(var(--dark-color-tag-green-border))}.dark .qr-bg:hover:active{background-color:#17322e}@property --tr-rotate{syntax:'';initial-value:45deg;inherits:false}.qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#76ccb4,transparent,#d5bed2);display:flex;justify-content:center;align-content:center;padding:1px;border-radius:1rem;height:220px;width:220px}.dark .qr-bg-sub{background-image:linear-gradient(var(--tr-rotate),#195141,transparent,#5a2969)}.qr-bg-sub:hover{animation:tr-rotate-gradient 3.5s linear infinite}@keyframes tr-rotate-gradient{from{--tr-rotate:45deg}to{--tr-rotate:405deg}}.qr-bg-sub-inner{background-color:#fff;padding:.8rem;border-radius:1rem;transition:all 0.1s}.qr-bg-sub-inner:hover{background-color:rgb(255 255 255 / 60%);backdrop-filter:blur(25px)}.qr-bg-sub-inner:hover:active{background-color:rgb(255 255 255 / 30%)}.dark .qr-bg-sub-inner{background-color:rgb(var(--dark-color-surface-700-rgb))}.dark .qr-bg-sub-inner:hover{background-color:rgba(var(--dark-color-surface-700-rgb),.5);backdrop-filter:blur(25px)}.dark .qr-bg-sub-inner:hover:active{background-color:rgba(var(--dark-color-surface-700-rgb),.2)}.qr-tag{text-align:center;margin-bottom:10px;width:100%;overflow:hidden;margin-inline:0}@media (min-width:769px){.qr-modal{flex-direction:row;max-width:680px}}.tr-marquee{justify-content:flex-start}.tr-marquee span{padding-right:25%;white-space:nowrap;transform-origin:center}@keyframes move-ltr{0%{transform:translateX(0)}100%{transform:translateX(-100%)}}.ant-input-group-addon:not(:first-child):not(:last-child){border-radius:0rem 1rem 1rem 0rem}b,strong{font-weight:500}.ant-collapse>.ant-collapse-item>.ant-collapse-header{padding:10px 16px 10px 40px}.dark .ant-message-notice-content{background-color:var(--dark-color-surface-200);border:1px solid var(--dark-color-surface-300);color:var(--dark-color-text-primary)}.ant-btn-danger{background-color:var(--dark-color-btn-danger);border-color:var(--dark-color-btn-danger-border)}.ant-btn-danger:focus,.ant-btn-danger:hover{background-color:var(--dark-color-btn-danger-hover);border-color:var(--dark-color-btn-danger-hover)}.dark .ant-alert-close-icon .anticon-close:hover{color:#fff}.ant-empty-small{margin:4px 0;background-color:transparent!important}.ant-empty-small .ant-empty-image{height:20px}.ant-menu-theme-switch,.ant-menu-theme-switch:hover{background-color:transparent!important;cursor:default!important}.dark .ant-tooltip-inner,.dark .ant-tooltip-arrow:before{background-color:var(--dark-color-tooltip)}.ant-select-sm .ant-select-selection__rendered{margin-left:10px}.ant-collapse{-moz-animation:collfade 0.3s ease;-webkit-animation:0.3s collfade 0.3s ease;animation:collfade 0.3s ease}@-webkit-keyframes collfade{0%{transform:scaleY(.8);transform-origin:0% 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0% 0%;opacity:1}}@keyframes collfade{0%{transform:scaleY(.8);transform-origin:0% 0%;opacity:0}100%{transform:scaleY(1);transform-origin:0% 0%;opacity:1}}.ant-table-tbody>tr>td{border-color:#f0f0f0}.ant-table-row-expand-icon{vertical-align:middle;margin-inline-end:8px;position:relative;transform:scale(.9411764705882353)}.ant-table-row-collapsed::before{transform:rotate(-180deg);top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-collapsed::after{transform:rotate(0deg);top:3px;bottom:3px;inset-inline-start:7px;width:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-expanded::before{top:7px;inset-inline-end:3px;inset-inline-start:3px;height:1px;position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-table-row-expanded::after{top:3px;bottom:3px;inset-inline-start:7px;width:1px;transform:rotate(90deg);position:absolute;background:currentcolor;transition:transform 0.3s ease-out;content:""}.ant-menu-theme-switch.ant-menu-item .ant-switch:not(.ant-switch-disabled):active:after,.ant-switch:not(.ant-switch-disabled):active:before{width:16px}.dark .ant-select-disabled .ant-select-selection{background:var(--dark-color-surface-100);border-color:var(--dark-color-surface-200);color:rgb(255 255 255 / .25)}.dark .ant-select-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .1)}.dark .ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up-disabled .anticon,.dark .ant-input-number-handler-down:hover.ant-input-number-handler-down-disabled .anticon,.dark .ant-input-number-handler-up:hover.ant-input-number-handler-up-disabled .anticon{color:rgb(255 255 255 / .25)}.dark .ant-input-number-handler-down:active.ant-input-number-handler-down-disabled,.dark .ant-input-number-handler-up:active.ant-input-number-handler-up-disabled{background-color:rgb(0 0 0 / .2)}.ant-menu-dark .ant-menu-inline.ant-menu-sub{background:var(--dark-color-surface-100);box-shadow:none}.dark .ant-layout-sider-trigger{background:var(--dark-color-surface-100);color:rgb(255 255 255 / 65%)}.ant-layout-sider{overflow:auto}.dark .ant-back-top-content{background-color:var(--dark-color-back-top)}.dark .ant-back-top-content:hover{background-color:var(--dark-color-back-top-hover)}.ant-calendar-time .ant-calendar-footer .ant-calendar-time-picker-btn{text-transform:capitalize}.ant-calendar{border-color:#fff0;border-width:0}.ant-calendar-time-picker-select li:focus,li.ant-calendar-time-picker-select-option-selected{color:rgb(0 0 0 / .65);font-weight:400;background-color:#e8f4f2}.dark li.ant-calendar-time-picker-select-option-selected{color:var(--dark-color-text-primary);font-weight:400}.dark .ant-calendar-time-picker-select li:focus{color:#fff;font-weight:400;background-color:var(--color-primary-100)}.ant-calendar-time-picker-select li:hover{background:#f5f5f5}.ant-calendar-date{transition:background .3s ease,color .3s ease}li.ant-calendar-time-picker-select-option-selected{margin-block:2px}.ant-calendar-time-picker-select{padding:4px}.ant-calendar-time-picker-select li{height:28px;line-height:28px;border-radius:4px}@media (min-width:769px){.index-page .ant-layout-content{margin:24px 16px}}.index-page .ant-card-dark h2{color:var(--dark-color-text-primary)}.index-page~div .ant-backup-list-item{gap:10px}.index-page~div .ant-version-list-item{--padding:12px;padding:var(--padding)!important;gap:var(--padding)}.index-page.dark~div .ant-version-list-item svg{color:var(--dark-color-text-primary)}.index-page.dark~div .ant-backup-list-item svg,.index-page.dark .ant-badge-status-text,.index-page.dark .ant-card-extra{color:var(--dark-color-text-primary)}.index-page.dark .ant-card-actions>li{color:rgb(255 255 255 / .55)}.index-page.dark~div .ant-radio-inner{background-color:var(--dark-color-surface-100);border-color:var(--dark-color-surface-600)}.index-page.dark~div .ant-radio-checked .ant-radio-inner{border-color:var(--color-primary-100)}.index-page.dark~div .ant-backup-list,.index-page.dark~div .ant-version-list,.index-page.dark .ant-card-actions,.index-page.dark .ant-card-actions>li:not(:last-child){border-color:var(--dark-color-stroke)}.index-page .ant-card-actions{background:#fff0}.index-page .ip-hidden{-webkit-user-select:none;-moz-user-select:none;user-select:none;filter:blur(10px)}.index-page .xray-running-animation .ant-badge-status-dot,.index-page .xray-processing-animation .ant-badge-status-dot{animation:runningAnimation 1.2s linear infinite}.index-page .xray-running-animation .ant-badge-status-processing:after{border-color:var(--color-primary-100)}.index-page .xray-stop-animation .ant-badge-status-processing:after{border-color:#fa8c16}.index-page .xray-error-animation .ant-badge-status-processing:after{border-color:#f5222d}@keyframes runningAnimation{0%,50%,100%{transform:scale(1);opacity:1}10%{transform:scale(1.5);opacity:.2}}.index-page .card-placeholder{text-align:center;padding:30px 0;margin-top:10px;background:#fff0;border:none}.index-page~div .log-container{height:auto;max-height:500px;overflow:auto;margin-top:.5rem}#app.login-app *{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#app.login-app h1{text-align:center;height:110px}#app.login-app .ant-form-item-children .ant-btn,#app.login-app .ant-input{height:50px;border-radius:30px}#app.login-app .ant-input-group-addon{border-radius:0 30px 30px 0;width:50px;font-size:18px}#app.login-app .ant-input-affix-wrapper .ant-input-prefix{left:23px}#app.login-app .ant-input-affix-wrapper .ant-input:not(:first-child){padding-left:50px}#app.login-app .centered{display:flex;text-align:center;align-items:center;justify-content:center;width:100%}#app.login-app .title{font-size:2rem;margin-block-end:2rem}#app.login-app .title b{font-weight:bold!important}#app.login-app{overflow:hidden}#app.login-app #login{animation:charge 0.5s both;background-color:#fff;border-radius:2rem;padding:4rem 3rem;transition:all 0.3s;user-select:none;-webkit-user-select:none;-moz-user-select:none}#app.login-app #login:hover{box-shadow:0 2px 8px rgb(0 0 0 / .09)}@keyframes charge{from{transform:translateY(5rem);opacity:0}to{transform:translateY(0);opacity:1}}#app.login-app .under{background-color:#c7ebe2;z-index:0}#app.login-app.dark .under{background-color:var(--dark-color-login-wave)}#app.login-app.dark #login{background-color:var(--dark-color-surface-100)}#app.login-app.dark h1{color:#fff}#app.login-app .ant-btn-primary-login{width:100%}#app.login-app .ant-btn-primary-login:focus,#app.login-app .ant-btn-primary-login:hover{color:#fff;background-color:#065;border-color:#065;background-image:linear-gradient(270deg,#fff0 30%,#009980,#fff0 100%);background-repeat:no-repeat;animation:ma-bg-move ease-in-out 5s infinite;background-position-x:-500px;width:95%;animation-delay:-0.5s;box-shadow:0 2px 0 rgb(0 0 0 / .045)}#app.login-app .ant-btn-primary-login.active,#app.login-app .ant-btn-primary-login:active{color:#fff;background-color:#065;border-color:#065}@keyframes ma-bg-move{0%{background-position:-500px 0}50%{background-position:1000px 0}100%{background-position:1000px 0}}#app.login-app .wave-btn-bg{position:relative;border-radius:25px;width:100%;transition:all 0.3s cubic-bezier(.645,.045,.355,1)}#app.login-app.dark .wave-btn-bg{color:#fff;position:relative;background-color:#0a7557;border:2px double #fff0;background-origin:border-box;background-clip:padding-box,border-box;background-size:300%;width:100%;z-index:1}#app.login-app.dark .wave-btn-bg:hover{animation:wave-btn-tara 4s ease infinite}#app.login-app.dark .wave-btn-bg-cl{background-image:linear-gradient(#fff0,#fff0),radial-gradient(circle at left top,#006655,#009980,#006655)!important;border-radius:3em}#app.login-app.dark .wave-btn-bg-cl:hover{width:95%}#app.login-app.dark .wave-btn-bg-cl:before{position:absolute;content:"";top:-5px;left:-5px;bottom:-5px;right:-5px;z-index:-1;background:inherit;background-size:inherit;border-radius:4em;opacity:0;transition:0.5s}#app.login-app.dark .wave-btn-bg-cl:hover::before{opacity:1;filter:blur(20px);animation:wave-btn-tara 8s linear infinite}@keyframes wave-btn-tara{to{background-position:300%}}#app.login-app.dark .ant-btn-primary-login{font-size:14px;color:#fff;text-align:center;background-image:linear-gradient(rgb(13 14 33 / .45),rgb(13 14 33 / .35));border-radius:2rem;border:none;outline:none;background-color:#fff0;height:46px;position:relative;white-space:nowrap;cursor:pointer;touch-action:manipulation;padding:0 15px;width:100%;animation:none;background-position-x:0;box-shadow:none}#app.login-app .waves-header{position:fixed;width:100%;text-align:center;background-color:#dbf5ed;color:#fff;z-index:-1}#app.login-app.dark .waves-header{background-color:var(--dark-color-login-background)}#app.login-app .waves-inner-header{height:50vh;width:100%;margin:0;padding:0}#app.login-app .waves{position:relative;width:100%;height:15vh;margin-bottom:-8px;min-height:100px;max-height:150px}#app.login-app .parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}#app.login-app.dark .parallax>use{fill:var(--dark-color-login-wave)}#app.login-app .parallax>use:nth-child(1){animation-delay:-2s;animation-duration:4s;opacity:.2}#app.login-app .parallax>use:nth-child(2){animation-delay:-3s;animation-duration:7s;opacity:.4}#app.login-app .parallax>use:nth-child(3){animation-delay:-4s;animation-duration:10s;opacity:.6}#app.login-app .parallax>use:nth-child(4){animation-delay:-5s;animation-duration:13s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}100%{transform:translate3d(85px,0,0)}}@media (max-width:768px){#app.login-app .waves{height:40px;min-height:40px}}#app.login-app .words-wrapper{width:100%;display:inline-block;position:relative;text-align:center}#app.login-app .words-wrapper b{width:100%;display:inline-block;position:absolute;left:0;top:0}#app.login-app .words-wrapper b.is-visible{position:relative}#app.login-app .headline.zoom .words-wrapper{-webkit-perspective:300px;-moz-perspective:300px;perspective:300px}#app.login-app .headline{display:flex;justify-content:center;align-items:center}#app.login-app .headline.zoom b{opacity:0}#app.login-app .headline.zoom b.is-visible{opacity:1;-webkit-animation:zoom-in 0.8s;-moz-animation:zoom-in 0.8s;animation:cubic-bezier(.215,.61,.355,1) zoom-in 0.8s}#app.login-app .headline.zoom b.is-hidden{-webkit-animation:zoom-out 0.8s;-moz-animation:zoom-out 0.8s;animation:cubic-bezier(.215,.61,.355,1) zoom-out 0.4s}@-webkit-keyframes zoom-in{0%{opacity:0;-webkit-transform:translateZ(100px)}100%{opacity:1;-webkit-transform:translateZ(0)}}@-moz-keyframes zoom-in{0%{opacity:0;-moz-transform:translateZ(100px)}100%{opacity:1;-moz-transform:translateZ(0)}}@keyframes zoom-in{0%{opacity:0;-webkit-transform:translateZ(100px);-moz-transform:translateZ(100px);-ms-transform:translateZ(100px);-o-transform:translateZ(100px);transform:translateZ(100px)}100%{opacity:1;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}}@-webkit-keyframes zoom-out{0%{opacity:1;-webkit-transform:translateZ(0)}100%{opacity:0;-webkit-transform:translateZ(-100px)}}@-moz-keyframes zoom-out{0%{opacity:1;-moz-transform:translateZ(0)}100%{opacity:0;-moz-transform:translateZ(-100px)}}@keyframes zoom-out{0%{opacity:1;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}100%{opacity:0;-webkit-transform:translateZ(-100px);-moz-transform:translateZ(-100px);-ms-transform:translateZ(-100px);-o-transform:translateZ(-100px);transform:translateZ(-100px)}}#app.login-app .setting-section{position:absolute;top:0;right:0;padding:22px}#app.login-app .ant-space-item .ant-switch{margin:2px 0 4px}#app.login-app .ant-layout-content{transition:none}.inbounds-page .ant-table:not(.ant-table-expanded-row .ant-table){outline:1px solid #f0f0f0;outline-offset:-1px;border-radius:1rem;overflow-x:hidden}.inbounds-page.dark .ant-table:not(.ant-table-expanded-row .ant-table){outline-color:var(--dark-color-table-ring)}.inbounds-page .ant-table .ant-table-content .ant-table-scroll .ant-table-body{overflow-y:hidden}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper{margin:-10px 22px!important}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper .ant-table{border-bottom-left-radius:1rem;border-bottom-right-radius:1rem}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child tr:last-child td{border-bottom-color:#fff0}.inbounds-page .ant-table .ant-table-tbody tr:last-child.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody>tr:last-child>td:first-child{border-bottom-left-radius:6px}.inbounds-page .ant-table .ant-table-tbody tr:last-child.ant-table-expanded-row .ant-table-wrapper .ant-table-tbody>tr:last-child>td:last-child{border-bottom-right-radius:6px}@media (min-width:769px){.inbounds-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.inbounds-page .ant-card-body{padding:.5rem}.inbounds-page .ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper{margin:-10px 2px!important}}.inbounds-page.dark .ant-switch-small:not(.ant-switch-checked){background-color:var(--dark-color-surface-100)!important}.inbounds-page .ant-custom-popover-title{display:flex;align-items:center;gap:10px;margin:5px 0}.inbounds-page .ant-col-sm-24{margin:.5rem -2rem .5rem 2rem}.inbounds-page tr.hideExpandIcon .ant-table-row-expand-icon{display:none}.inbounds-page .infinite-tag,.inbounds-page~div .infinite-tag{padding:0 5px;border-radius:2rem;min-width:50px;min-height:22px}.inbounds-page .infinite-bar .ant-progress-inner .ant-progress-bg{background-color:#F2EAF1;border:#D5BED2 solid 1px}.inbounds-page.dark .infinite-bar .ant-progress-inner .ant-progress-bg{background-color:#7a316f!important;border:#7a316f solid 1px}.inbounds-page~div .ant-collapse{margin:5px 0}.inbounds-page .info-large-tag,.inbounds-page~div .info-large-tag{max-width:200px;overflow:hidden}.inbounds-page .client-comment{font-size:12px;opacity:.75;cursor:help}.inbounds-page .client-email{font-weight:500}.inbounds-page .client-popup-item{display:flex;align-items:center;gap:5px}.inbounds-page .online-animation .ant-badge-status-dot{animation:onlineAnimation 1.2s linear infinite}@keyframes onlineAnimation{0%,50%,100%{transform:scale(1);opacity:1}10%{transform:scale(1.5);opacity:.2}}.inbounds-page .tr-table-box{display:flex;gap:4px;justify-content:center;align-items:center}.inbounds-page .tr-table-rt{flex-basis:70px;min-width:70px;text-align:end}.inbounds-page .tr-table-lt{flex-basis:70px;min-width:70px;text-align:start}.inbounds-page .tr-table-bar{flex-basis:160px;min-width:60px}.inbounds-page .tr-infinity-ch{font-size:14pt;max-height:24px;display:inline-flex;align-items:center}.inbounds-page .ant-table-expanded-row .ant-table .ant-table-body{overflow-x:hidden}.inbounds-page .ant-table-expanded-row .ant-table-tbody>tr>td{padding:10px 2px}.inbounds-page .ant-table-expanded-row .ant-table-thead>tr>th{padding:12px 2px}.idx-cpu-history-svg{display:block;overflow:unset!important}.dark .idx-cpu-history-svg .cpu-grid-line{stroke:rgb(255 255 255 / .08)}.dark .idx-cpu-history-svg .cpu-grid-h-line{stroke:rgb(255 255 255 / .25)}.dark .idx-cpu-history-svg .cpu-grid-y-text,.dark .idx-cpu-history-svg .cpu-grid-x-text{stroke:rgb(200 200 200 / .8)}.idx-cpu-history-svg .cpu-grid-text{stroke-width:3;paint-order:stroke;stroke:rgb(0 0 0 / .05)}.dark .idx-cpu-history-svg .cpu-grid-text{fill:#fff;stroke:rgb(0 0 0 / .35)}.inbounds-page~div #inbound-modal form textarea.ant-input{margin:4px 0}@media (min-width:769px){.settings-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.settings-page .ant-tabs-nav .ant-tabs-tab{margin:0;padding:12px .5rem}}.settings-page .ant-tabs-bar{margin:0}.settings-page .ant-list-item{display:block}.settings-page .alert-msg{color:#c27512;font-weight:400;font-size:16px;padding:.5rem 1rem;text-align:center;background:rgb(255 145 0 / 15%);margin:1.5rem 2.5rem 0rem;border-radius:.5rem;transition:all 0.5s;animation:settings-page-signal 3s cubic-bezier(.18,.89,.32,1.28) infinite}.settings-page .alert-msg:hover{cursor:default;transition-duration:.3s;animation:settings-page-signal 0.9s ease infinite}@keyframes settings-page-signal{0%{box-shadow:0 0 0 0 rgb(194 118 18 / .5)}50%{box-shadow:0 0 0 6px #fff0}100%{box-shadow:0 0 0 6px #fff0}}.settings-page .alert-msg>i{color:inherit;font-size:24px}.settings-page.dark .ant-input-password-icon{color:var(--dark-color-text-primary)}.settings-page .ant-collapse-content-box .ant-alert{margin-block-end:12px}@media (min-width:769px){.xray-page .ant-layout-content{margin:24px 16px}}@media (max-width:768px){.xray-page .ant-tabs-nav .ant-tabs-tab{margin:0;padding:12px .5rem}.xray-page .ant-table-thead>tr>th,.xray-page .ant-table-tbody>tr>td{padding:10px 0}}.xray-page .ant-tabs-bar{margin:0}.xray-page .ant-list-item{display:block}.xray-page .ant-list-item>li{padding:10px 20px!important}.xray-page .ant-collapse-content-box .ant-alert{margin-block-end:12px}#app.login-app #login input.ant-input:-webkit-autofill{-webkit-box-shadow:0 0 0 100px #f8f8f8 inset;box-shadow:0 0 0 100px #f8f8f8 inset;transition:background-color 9999s ease-in-out 0s,color 9999s ease-in-out 0s;background-clip:text}#app.login-app #login .ant-input-affix-wrapper:hover .ant-input:-webkit-autofill:not(.ant-input-disabled),#app.login-app #login input.ant-input:-webkit-autofill:hover,#app.login-app #login input.ant-input:-webkit-autofill:focus{-webkit-box-shadow:0 0 0 100px #e8f4f2 inset;box-shadow:0 0 0 100px #e8f4f2 inset}#app.login-app.dark #login .ant-input-affix-wrapper:hover .ant-input:-webkit-autofill:not(.ant-input-disabled),#app.login-app.dark #login input.ant-input:-webkit-autofill{-webkit-text-fill-color:var(--dark-color-text-primary);caret-color:var(--dark-color-text-primary);-webkit-box-shadow:0 0 0 1000px var(--dark-color-surface-200) inset;box-shadow:0 0 0 1000px var(--dark-color-surface-200) inset;transition:background-color 9999s ease-in-out 0s,color 9999s ease-in-out 0s}#app.login-app.dark #login .ant-input-affix-wrapper:hover .ant-input:-webkit-autofill:not(.ant-input-disabled),#app.login-app.dark #login input.ant-input:-webkit-autofill:hover,#app.login-app.dark #login input.ant-input:-webkit-autofill:focus{border-color:var(--dark-color-surface-300)}.dark .ant-descriptions-bordered .ant-descriptions-item-label{background-color:var(--dark-color-background)}.dark .ant-descriptions-bordered .ant-descriptions-view,.dark .ant-descriptions-bordered .ant-descriptions-row,.dark .ant-descriptions-bordered .ant-descriptions-item-label,.dark .ant-list-bordered{border-color:var(--dark-color-surface-400)}.dark .ant-descriptions-bordered .ant-descriptions-item-label,.dark .ant-descriptions-bordered .ant-descriptions-item-content{color:var(--dark-color-text-primary)}.dark .ant-dropdown-menu{background-color:var(--dark-color-surface-200)}.dark .ant-dropdown-menu .ant-dropdown-menu-item{color:hsl(0 0% 100% / .65)}.dark .ant-dropdown-menu .ant-dropdown-menu-item:hover{background-color:var(--dark-color-surface-600)}.subscription-page .ant-list.ant-list-split.ant-list-bordered{overflow:hidden}.subscription-page .ant-list.ant-list-split.ant-list-bordered .ant-list-item{overflow-x:auto}.subscription-page .ant-btn.ant-btn-primary.ant-btn-lg.ant-dropdown-trigger{border-radius:4rem;padding:0 20px}.subscription-page .subscription-card{margin:2rem 0}.mb-10{margin-bottom:10px}.mb-12{margin-bottom:12px}.mt-5{margin-top:5px}.mr-8{margin-right:8px}.ml-10{margin-left:10px}.mr-05{margin-right:.5rem}.fs-1rem{font-size:1rem}.w-100{width:100%}.w-70{width:70px}.w-95{width:95px}.text-center{text-align:center}.cursor-pointer{cursor:pointer}.float-right{float:right}.va-middle{vertical-align:middle}.d-flex{display:flex}.justify-end{justify-content:flex-end}.max-w-400{max-width:400px;display:inline-block}.ant-space.jc-center{justify-content:center}.min-h-0{min-height:0}.min-h-100vh{min-height:100vh}.h-100{height:100%}.h-50px{height:50px}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.overflow-y-auto{overflow-y:auto}.overflow-x-auto{overflow-x:auto}.mt-1rem{margin-top:1rem}.my-3rem{margin-top:3rem;margin-bottom:3rem} \ No newline at end of file diff --git a/web/html/index.html b/web/html/index.html index 4ddf26b5..fca0eb87 100644 --- a/web/html/index.html +++ b/web/html/index.html @@ -39,7 +39,7 @@ - + @@ -343,7 +343,7 @@ - 10 20 @@ -351,7 +351,7 @@ 100 500 - Debug Info @@ -381,7 +381,7 @@ - 10 20 @@ -429,7 +429,7 @@ @cancel="() => cpuHistoryModal.visible = false" :class="themeSwitcher.currentTheme" width="900px" footer=""> -
+
@@ -464,7 +464,7 @@ strokeWidth: { type: Number, default: 2 }, maxPoints: { type: Number, default: 120 }, showGrid: { type: Boolean, default: true }, - gridColor: { type: String, default: 'rgba(255,255,255,0.08)' }, + gridColor: { type: String, default: 'rgba(0,0,0,0.1)' }, fillOpacity: { type: Number, default: 0.15 }, showMarker: { type: Boolean, default: true }, markerRadius: { type: Number, default: 2.8 }, @@ -604,7 +604,7 @@ }, }, template: ` - @@ -613,16 +613,16 @@ - + - + - + @@ -630,9 +630,9 @@ - + - + `, diff --git a/web/html/login.html b/web/html/login.html index b561b732..26a6ca86 100644 --- a/web/html/login.html +++ b/web/html/login.html @@ -4,7 +4,7 @@ {{ template "page/body_start" .}} - +
- + - + [[ client.reset + "d" ]] diff --git a/web/html/inbounds.html b/web/html/inbounds.html index 5f17c98b..bea8e8d9 100644 --- a/web/html/inbounds.html +++ b/web/html/inbounds.html @@ -1434,15 +1434,19 @@ clientStats = dbInbound.clientStats ? dbInbound.clientStats.find(stats => stats.email === email) : null; return clientStats ? clientStats['enable'] : true; }, - // Returns true when client's traffic is exhausted or expiry time is passed isClientDepleted(dbInbound, email) { if (!email || !dbInbound || !dbInbound.clientStats) return false; const stats = dbInbound.clientStats.find(s => s.email === email); if (!stats) return false; - const now = new Date().getTime(); - const exhausted = stats.total > 0 && (stats.up + stats.down) >= stats.total; - const expired = stats.expiryTime > 0 && now >= stats.expiryTime; - return exhausted || expired; + const total = stats.total ?? 0; + const used = (stats.up ?? 0) + (stats.down ?? 0); + const hasTotal = total > 0; + const exhausted = hasTotal && used >= total; + const expiryTime = stats.expiryTime ?? 0; + const hasExpiry = expiryTime > 0; + const now = Date.now(); + const expired = hasExpiry && expiryTime <= now; + return expired || exhausted; }, isClientOnline(email) { return this.onlineClients.includes(email); diff --git a/web/html/modals/inbound_info_modal.html b/web/html/modals/inbound_info_modal.html index 55d9919c..25f43506 100644 --- a/web/html/modals/inbound_info_modal.html +++ b/web/html/modals/inbound_info_modal.html @@ -180,9 +180,9 @@ {{ i18n "status" }} - {{ i18n "enabled" }} - {{ i18n "disabled" }} {{ i18n "depleted" }} + {{ i18n "enabled" }} + {{ i18n "disabled" }} @@ -524,7 +524,7 @@ this.dbInbound = new DBInbound(dbInbound); this.clientSettings = this.inbound.clients ? this.inbound.clients[index] : null; this.isExpired = this.inbound.clients ? this.inbound.isExpiry(index) : this.dbInbound.isExpiry; - this.clientStats = this.inbound.clients ? this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) : []; + this.clientStats = this.inbound.clients ? (this.dbInbound.clientStats.find(row => row.email === this.clientSettings.email) || null) : null; if ( [ @@ -588,11 +588,21 @@ return infoModal.dbInbound.isEnable; }, get isDepleted() { - const stats = this.infoModal.clientStats; - if (!stats) return false; - const now = new Date().getTime(); - const expired = stats.expiryTime > 0 && now >= stats.expiryTime; - const exhausted = stats.total > 0 && (stats.up + stats.down) >= stats.total; + const stats = infoModal.clientStats; + const settings = infoModal.clientSettings; + if (!stats || !settings) { + return false; + } + const total = stats.total ?? 0; + const used = (stats.up ?? 0) + (stats.down ?? 0); + const hasTotal = total > 0; + const exhausted = hasTotal && used >= total; + + const expiryTime = settings.expiryTime ?? 0; + const hasExpiry = expiryTime > 0; + const now = Date.now(); + const expired = hasExpiry && now >= expiryTime; + return expired || exhausted; }, }, From e3883fca8708867ef4b1e02aaed2803c58e41f57 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Thu, 18 Sep 2025 20:08:56 +0200 Subject: [PATCH 36/44] donate: nowpayments --- .github/FUNDING.yml | 2 +- README.ar_EG.md | 16 +++++++--------- README.es_ES.md | 15 +++++++-------- README.fa_IR.md | 15 +++++++-------- README.md | 15 +++++++-------- README.ru_RU.md | 15 +++++++-------- README.zh_CN.md | 15 +++++++-------- media/buymeacoffe.png | Bin 6287 -> 0 bytes media/default-yellow.png | Bin 0 -> 4811 bytes media/donation-button-black.svg | 1 + 10 files changed, 44 insertions(+), 50 deletions(-) delete mode 100644 media/buymeacoffe.png create mode 100644 media/default-yellow.png create mode 100644 media/donation-button-black.svg diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index d1b2b391..5f69a4d6 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -11,4 +11,4 @@ issuehunt: # Replace with a single IssueHunt username lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry polar: # Replace with a single Polar username buy_me_a_coffee: mhsanaei -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] +custom: https://nowpayments.io/donation/hsanaei diff --git a/README.ar_EG.md b/README.ar_EG.md index e6a0c69c..5990a829 100644 --- a/README.ar_EG.md +++ b/README.ar_EG.md @@ -41,15 +41,13 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install. **إذا كان هذا المشروع مفيدًا لك، فقد ترغب في إعطائه**:star2: -

- - Image - -

- -- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` -- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A` -- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv` + +Buy Me A Coffee + +
+ + Crypto donation button by NOWPayments + ## النجوم عبر الزمن diff --git a/README.es_ES.md b/README.es_ES.md index 4ce65ca8..61933b14 100644 --- a/README.es_ES.md +++ b/README.es_ES.md @@ -41,15 +41,14 @@ Para documentación completa, visita la [Wiki del proyecto](https://github.com/M **Si este proyecto te es útil, puedes darle una**:star2: -

- - Image - -

+ +Buy Me A Coffee + -- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` -- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A` -- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv` +
+ + Crypto donation button by NOWPayments + ## Estrellas a lo Largo del Tiempo diff --git a/README.fa_IR.md b/README.fa_IR.md index 19790945..4d363eef 100644 --- a/README.fa_IR.md +++ b/README.fa_IR.md @@ -41,15 +41,14 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install. **اگر این پروژه برای شما مفید است، می‌توانید به آن یک**:star2: بدهید -

- - Image - -

+ +Buy Me A Coffee + -- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` -- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A` -- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv` +
+ + Crypto donation button by NOWPayments + ## ستاره‌ها در طول زمان diff --git a/README.md b/README.md index e73859ec..b7ce4854 100644 --- a/README.md +++ b/README.md @@ -41,15 +41,14 @@ For full documentation, please visit the [project Wiki](https://github.com/MHSan **If this project is helpful to you, you may wish to give it a**:star2: -

- - Image - -

+ +Buy Me A Coffee + -- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` -- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A` -- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv` +
+ + Crypto donation button by NOWPayments + ## Stargazers over Time diff --git a/README.ru_RU.md b/README.ru_RU.md index 48713183..3971b70c 100644 --- a/README.ru_RU.md +++ b/README.ru_RU.md @@ -41,15 +41,14 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install. **Если этот проект полезен для вас, вы можете поставить ему**:star2: -

- - Image - -

+ +Buy Me A Coffee + -- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` -- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A` -- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv` +
+ + Crypto donation button by NOWPayments + ## Звезды с течением времени diff --git a/README.zh_CN.md b/README.zh_CN.md index 322a4b78..4abbf087 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -41,15 +41,14 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install. **如果这个项目对您有帮助,您可以给它一个**:star2: -

- - Image - -

+ +Buy Me A Coffee + -- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` -- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A` -- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv` +
+ + Crypto donation button by NOWPayments + ## 随时间变化的星标数 diff --git a/media/buymeacoffe.png b/media/buymeacoffe.png deleted file mode 100644 index 81571db7fac96be649e54b5e22254a4a9979cae0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6287 zcmV;A7;xu_P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&7$iwVK~#8N?Oh3& zTveGpwQs#I=`Ed3cV{OANCJ^9gdhQg5sWyXfG{A8ih~L|g39Q8BW|C{h>XiP;;1+x zAUFaB1tEqYB9xA5x~jVNIpECdn-$R>?!e|p3P*DjK+~or_HfN6mdA=)_()D586SQq6b@eV zow=9vilc_DH*a{j&FOHjBuN`$10i!#5k(v+*htGjO$B1X$ogSB7JqZfIX!l=*M@ZN zmm+Djf3R?95k(w1?)#&qYF%`q^zgeKDS|6E}PCO{~t5# zP6r%rr}=HyOc({(Y!+FncsiLvF2idVQN$>)JDuc8a*yqnS05SMLMhL-JMD0n_z>$4 zV_@qZgm?EL+80JV7(qIb;z61PIk>zYcq;-ZnNWf9=2}#>*27yKKq3-DalN*PeIZZO zROgt9YIoSFjA^X;{v+71Y&8aV^dO#&a*vi1?B>VDA8IJK=qGDFJK#c1YZFfRz*(4g z)!E3VGscq?QN&1$8&Q3gC3xf@X%)0OtRJS$2UsDFB*A1u3iPUh? zg!-X9LG*9##87t-8-M>I26}hleRq5YvzMNV;c(F_7x89{8&O?8H}W1G}j*{APdQ-ltN=-)Zq&3K^ zB#BFMCx?cSpxSDMK#CioXHDedOs*VQc>Tp#`00z0B#Dd4T7)oWqWUUIu<8eo;E{j* z9!|MxDasnEvHQgigm!6ZDr7=`nh8`kH}VNAX8R5o+yO09mGGP@R59tQo!*Rf53EG@ zYuj+$V_!#Eb1gDvS!@4@Ws-2%>~Pr}NawU3OO@w)d;VFQA`TMqOuo;393w%!m}0*s zvT6A2jE3yj!>u1FO)V_V|Xx%RCE}_krRV)_Lq8Py#PTIA9a*O}E*(3J?| zwMaMWy=8`=dxpapX2*K%&Y~zE1T@i4tY|jxpBvoC32!&sCb&y5yR;t9hjt;7P8hNt zPK+&?VqKji+}itApl8!Al+}@>^qUIndiqr)4AfSjtg!~=6Kha5sTO4uYf(zo4bU2h zobsW=%<>1f_h9$S9awYk3UqJUg6WGFpnmq`!i|D`BTeF0xV*S>(utT;-hk7pT5(!+ zD;88v!tAnobPh+*myDXuF5<0`Wq&FveXR9VH2W&>)W8-EqnYq$*G|J(wNueC)Q3G3 z1*hFnIP36W%*m8H;Ki2ZYw+Mlzm1`2AGzy>*XcLOl#l+@Us+-Z>te#CwN%|IHEXGS zNiDS$B?VTZ73c3nE`rH(=HTMHZi1)W&sjA3gE9(5Exs!JQ`@OXW;1wws0TY^gH+X0 z%%>_0rsDX<=H*B;nL8S7fI2)&wNl;mGu{yK^dnnzAV{+ht6TxxJZ&*HNBi;JZBN6^ zh%`(qaP_2*OkQnm$V@ zT%4&QNsNP`duG}{5*c1YRoI(I`jlcB3BIH*iA>tmCz+$g;Rzy#CXxnU+eJ!C*>$eA ziKGFihvj5V-9`(iI(wMqr&zYmv#PSc$)~n?NHQ;dX4H82KTigcC(iv=c~<@On&2tH zNsLG$<4d94rhl}3VRaj$mk&?$Z8Gi3Pp*7F3ISdx&N^zVh^g(`?{~Oamz3GAemPW( zeR-+?m)~OwTXWBHG|iuC5+jB5bb^DGU^0~^QRGwYHe?-MWI1ykUJpD07rePB?ppF0 z*xfE%_r%vtxK9s@q=mvqflR+hdfCLexSJ$hHMoNvOVY3-Z)iOY(@Q4cwvCUYKNZ8m zsy4Iz1$rzE)YL!?_t)Y{c6^N6<;%jUVRS@$-%ub8V1ON+-oNBa~W<=u4M6UrKK zA_q7`6@R?9gW)lPnWc4D!~vE?d5jaOi&n(L`YAC{x$kQ{4($OZpTi+D$*iPsBs5Wk zcT}{P>unznV&hP+xqdXA+$UMpFLPL*3+s;|QC#=~+qj~CvngBTbi$5#Y;Oz8^Ar-M zC;K|Ekr8oz#YFr=^GSHBe+%yKT4T=FKzzD=k(pFq>3H0fZ%xFB-U=*jn2kCL#=6KJ z{EFvj@-{M8Q2VrfL!<}ybiQQz@KCkYQq%*B4f_KJLyGy}KYt6WzV|R}4hL*3JnvJ> z5ooA|ucZ~PiS1}^%;5CeXYtOG-{3gsQ%Da*5RW9_uP!5*(?+Eaq&-q?4Y(lHP^V5} z=U>@8-;ng_fo&$qs-hBH#LhgkW{Mejop(XqEG**Z5_W!#%a6Zjr^SyB$UULSoxuCMeyl=#W0sqD2p_u|GmW@4#sdVQd2u2KAe!(+-(!X&7C)m!}(%_K~_ zrHym_~bC!QqSPh>=$tZuEzWEMO3enl zXwXpsXP&4ZpsIdp#(DTe+d`aFG0ALGr>d+8?o#u4GZjPIDx5yl(Z`D1QodtICSiSe zj|stoj+4rka)2}_`q>-1;`#5DiLfH_H#RNDV?7(pWcl#qQ;h2TaQm}n!qj*Im_ijF zq6$vp0E*OW!(I3`J)dB;Vfs6OGlluj>_~uChC?ggZ?+rL2qEEew&U8VQvtSw# z|I0$$UV(vr4Nk&XgoAe1WGb$=`%&aK@OS-8Kdecp(v+i5V6Bl67A0~cIT6ekq{{~*kv4OJ;rEZ zb#R9vo76>6xtdV&wZasCjmf6NB%jn(O5eb+ohNKQQPd>c#7H1=shnwrx^Ip3o8MBv z%O}n=Nsyv|>`x`FjF#o3hWB>9j62ycQhfPIVHN8&#Awo!7{XMN+KMP5V&0R|N@eAL zwT4PhTToe%IzLtOlS0-=R^xO=6xj>avzui$`pS*3KZSPY-So-ZC?H!Y0_x{lo}+pl zD#n4RFpKzs39RH`2z?O_4#S0M(SGU`vsWV2CzW7=L82Z^*mqEUMUDswppN%Bd3`FZ zUiqvxYeKh-y_9Nz%2L7*JF_%D<26ujs$24RjPp~>oVOdLIBDs`S2=cR3Qr8pt1cg(DO-r@Tt(##c*-sfBHHprfFcTkYSzrcI z%3D<+_^#nWlQ>Nz0UCW}MwR;67M&~aIgbgD2rE_9MA9|1Pg!=91dWh@DpRW6s|0uNdcj;@WY@CR zyXt3|33m6c7de^JWh;(}B{uDkS3(3=C3v9QlyDKg3XuaIYS) zrjf5Mr`J8O(4aZ(;yDWagCvqVPd-c`E5Qy{=Sh*a#e$||L{x=8-Ca>8Du`S&+2MW? zTqM)-OPjCCBpXsf4VV-}fOQGejILQ^~#5$EEJhi&jl&5y6ZL%g>p|GGtP<>z$M=HVbByW_Yrz<)k#rF(d+x${$%Wy`d0*2Ki#=?CH{kIzLRyEOB*G7@B%&dUbgz6Fm|FA zkPqL(7zpN&wC4#iDp=!iwi1!v2nWMs9%Y>#~2~ zpguR459dM!$slNe@+y{N*!7uhx`nH9MJD}dwv_decU!nI`OO^ro^z?`t}q1Z~Cj zlTS6t<{H|I2yMnW6K3EHTB5T_a#K@sT_Y_le;k}NABJC70I^V8mm zGwA)-b8@MF%UG9fg@`hb{`Z6IPt`+Xvy~HAkwr^o>gOINu38?nJnx}kY|o<>pl3|A zu)pCC&!BbT0-Qf*6THdZ!rpy=MBQLN4fp*#ghXc-7F_!-xB^~t_v)>n!Pj7)LZuKv zMAG9qYqd72Wt(S$+f3(cu$4T?i_K+-)B?0fsI@*VVM&ed+PT_LN!hf*_&vK{G813{ z6;9WXPyH=3+u!wWFeH_#Ns-RtWRN;(%~3wn9Ltcc`n(k0ZLT48RF>aJqN}d*Xs1nw5>g3@mX(wgwUfA-JPP4zmxWzy z^E9?s;dwT%Aq()oUF-2{`gajgs|d0S+LvM59_U(QZkMXwXV7oz`g#f9rBX`4XRw}X zpXwpPYXw5KOLwc(4lPZ|LWJmJ*U+zPg+teolAg!trb+mt9ji@09m?(3aa-^gJY{}t z{Oxo2pX+YJ;#;oA-8VgnhR`#Gz54)l{MWggaNR|(BGilx>TL{!zA95QXv)o0LS&n&4kzEEv31S-@^|H^M$kw)Z`YRhZq?-Hd=KQ(jW zNbPsh|B77lnzAyVoqCp;thx~*mDeQDwbdtDYE!+N=#{_T@g%~u6*86%Twtv&KBAa-h(lD09~tB8!M5Vv3-G{?%YM0WGmZ(T7f+;yu z9V`{w8)}zIvTm`eUb?Q%-J94Jtc1+;2i3?TvY_%*A4;v6Olp_PlQp@8L=~~LzWcdp zXOp}xCWT=}t47@V`lFc4=x_}azMnI3T1}7ZFm<4~ux08$5nlCF`;=6vz4E+D+LXW@ z_{hE)<9BC@$k1QvOMV_INN7(8p>%#ZWK{5~!3bx0FpNM=xp@*xv-e<-?-;uwoCaE- zE#e6(PM<|4y)1vE0UUX(b)4m475?SB%pW`C%TiJcI$qb4pL_G3H$%s%ZX%S3X;}yT z)?^WB^nNsw3TmH4Qo*|JXe1RZ;+r<^RYR3${5|)NoO~9vj;wmiQ_7?JIk5zl8A|8Z zghfu3s&do@ogreXtycRa5SlRBuBWn8=2$TMfEfhYtf`CsMH? zl+@9OIklWM9?dy;NMUr#Z!#6NBid&Ygego|x~L{n1dGt)2@UDnQSPBYwUF|w_eE{3 z7$~XK-8)$;L8~g|&U~_{l?7|^sttQj2El9}=k|>YQ8|Uo6HozW@6nzhf^n^-7WVA} z89P1VfZj2Ctgket|42b$vYA8`{=|eu{!=QjF`9n>h!Vn1Jv@B``el5k z28pV_IaSIqo(%86v#(ZRYvod!Dk>|t!^4KT^>QQSuf_7f$FTF&KAxB{PyXxS=_3XC zwY8BhlYwg~OMdp=-7lk?K22Hm-vZ<}pJ#&f3;J_Cqj1-b)#kBBdCebgUxh#RZ8pnv z_jkQwqRo+rf8&z%3-YMzf3?zl@2R$BIu?EQa?F@vV<#kG%cafNrBhiK20}KhT|I~u z|Mmma&6teK@4wajS)c>GGxc^riXv#uQyHutuo%nY^#50=?Q*Lo>0`2C?+322Y+|_M^M>X zk5rVV{m9u=18dnz1ECDIh@%7JPE=il>y^#sFQgh>C6F7Zzsp+0 zUoY}RP42PhGMRq)$MJ-|`=qZ=>zk%;dIj^pjmpZC7D-yfTR>~iYVe}gRG-$DRZBn+rN6u1-~2W8+hJdb>L6g7g5C94RJA0 zQ;DJA;3Hq2dH(adRja3mFG&o=x&qa2@i0jdMH~)LNlPbGAvO?RpLXIZZDQ!p*}gjc zf-S?rq0>p$r=+aj@={}Bm7y0=#NmQ0sIQ_FKJqUf8hR)k9X#_}Gv3`Nj#5uY`QN28 z*(GFZ{gJ$5RK(v7^dvvonE&6UGr6DMHvOCxW{2S?@PFl2BdmBj7D503002ovPDHLk FV1l(aIs5&XBS1lqIrn*|J1g8iTRK*w<_k#!hwze)}5A(^PS-E6x71)3Z1h)v_p)c<8*Ri&rNrKg4J`68m1eN zuC-(D4z!l@bf98PO>}lz!m#R^J1t^JhWaUK0$2gbzy{Jnqb8zMU`2%BvO?i?juRfx zyx&=Hph4~xsayU$HEDju|G>7q&nEqMvcGI@^KlOFd`K&6w}&BG5$odt>g*{Mn|tAq zuUDAK%T2xoJTM8F(+dt#+#oN*-4A>$@^ja_A6erjB7WZ{qzc3$Yc)xnwJYJA6fK_e zr;rTM=;5sPhffWf^Ke6%vj$=m4TShw`TfSyGQ>*pP zT@f-Hw4^2cE#`uqO1iWO@SyiR6 z@vpU930}hLXPqoh{sq{;upYgBBXJDf8P-u6%5wRO`Qai+IcjCa>~Hy*Gs^l3f-N)M z(U^Q&QwIMh2!(0OmcRsY2@Jkbx6mV2AT|4F-l&X0$qx-vk?Ii!J*P{#S<;+Ve2sz3 z-;bd|7<7)i6U-InlRL~_4;Pocp2=|R5v2j!k*ybU^=!Q(FexCv(EZpjPu2`;bae3} z2$!O-_`d&)Z$%<$U`t*w@^0N$DF#zOxFcO*>#SSam$jCxt>~~ zUV}nixc#FWAO0$V>~WVSRY5Rrn6;_01nTYg4;LT4?J-uT1oho8>mQNFBNN7p&je7e zc9i#u$k#;siL3DJ%%pJjHk)siBle-aha#?X zxUQO#IxgN4nOJgkqT}_}y4G-H_}PyjK-nf_!pF}b`{!a)l>)$-71R?$h>wfI5 zL}j8pbnBIxFC{Jm;oo$`pAhstxn{V)dLpoLHhjSBL4o)a$mw*7%&Vu14j(Rei7|YF zPs3=xVv$yR1wu+UcKInhoIzkc|1`MkK_)nTD-+YV#_($-ojP@o9)T-Pe%WItZ?YVp z-hMb(R`pt-qPufZd3W13KQ8YuL}wB(DvyS_+M2)U^Vk$dwoY;`G!FO+uUCgQuXm#H zR}Bp!!+k(!vrZ?LHX4=eBH{r%Q$!~QJKXd^@SLRE=PAcLs>$O7>0%WbnYn4M0YyEo zA$_yk45xQ#rmwQV3uyA$)S#P}lD}PuGekL&pdhzTZ+Zr~KL$5=oK^h6PC=Q&cveVj zwOGxCdgt`x98HCfPW6J7CbRHN=R9Cikk0}TaDnr- zeYY>|{}8@vbVG0VOQACNd+&mEBVDTrLLX3#x3J6p=HuDz{ki7!^_1(VQMkRNePQ;! zL(qerX9AxLk?s|Gj&ftKk_o9z0ko#y#~ff(S_Zm(EV2h635ID3PY)#eC$=^ivqXj` zKAd^mc3c%f;y{F(H>%t%>~RAg1Z7mWR}K7rLVw+**ch*md+rUCBx)G!=UAdo3%VMh zO@Cn~DEyjq_@h6}do9s={3r~Bb2OI^IB)i#H7=EINY(;msBu)np=lOl4Tv7MMWDa< zcs)OC=ICosIx;QA=2kBYXZW((-1iX^4U8P^6h-a|Qf#2`qHpit3@&L*`MEAm25nZZ zmA}EY8Lj#xE4Nv-HHEyun+Z@h9OMkLDTNF&o{4&8%L5r<)!;;ak=v5D&o0yyebppI zCs*h@e9F4Q%C0OhMNq^Nx?`49mwO$usG$$Ke*Y_@Lw0(d@)8nsU{U(W(6jalshmK~ z_g+TG9s*Y2+SBs=dvd5o6NXOit

S71G_&7jPUgJ>e|F+uB1dk>&X);VcIhO>(Bf z7}KL8sqi#mm8XQkHKpR5?kB2J-cd<=a2X#XwB>=9b)^6i|b+4{%j9hkf#mMaMn6SWlJ)5kn9* z??*GgdaY6x3jOwgAH{^<*H(r#Fn3Fx#H(I_J*hJhIt6y+gp7Z26%Tu(b2mIambdUW zpYO(PO!xNrU0cAppsmUgZA+!~p<}}N73r-7qvbvqWj|H2TUG)}t4G4RqjBmyw_1fb*if3|F+um7x|J_zba_iiwLoh%CyC{Tx%!?SsUpGsz`Q+$ zfMZ#n*%MYQJn$t1S!GFD13?y(qfl5V(rUxH_H|3qR_4a*Z_08T3UN9J*;YL!;;>m>f3)CP_|6URIvP(NL)v5HWyg_pXZP5@IQF9BiZk409 z6Nn>weav-p)a{?U#`V_W%4Gng73^NhMvr`$zjT1s%tNq;zZ?sIYraS(0RPhSLQ@34 z)X4z#G-HzMPoKMyryxNy68X=r*6<@TkMo&{I%iDJIR8GH@ga_hbmW#oyi5#d!l~UOyV^8742^f}gm6ryAT$ z5|9=}Jzqhj*8KtcD%g2_{-H~Lx*cMJ`y2wLgw{FbESNZPGR8JSGJM9o9vAq6EE?He z>An3rCf7Ge0yiQ|^NNq&xVKz2L{a}areA9pD}69+oLe+n5fNxkDn3*=cG5L1VrbX^ zo)tKti?M{t&rPJ=Ov@@rw|d*ctk zHrKe>8LHWmp&&8({`Zy|dK_l+1`S&ig76UkC%yo2ty1v3C)jF`%GttuqNzmYI~<(5 z@g7acuDvWuJ+bHh)ilW-8Q-}yotGa%iFxdC?|$E+potY`5{+>vV_orAxBYrO z8xyI4bPDSSUOTzQuO*P-OeRzzaL0P?x(38Mi&^sbOH{uz;)1GK`qy+vWPCBX#GD`U zwGwK9b*D`x3e}?O&>%w1^Gt>m$@))RY4NwDy`zY8o;IH?viS!}Ct3D{D3@^dY*4G2 zGKJVaLVmZ$X9K}M+6&Va)BT_u5-Ea(w2gn@9ftEonQyGxJq5xBHS3bPQ`I1;xBuOA zv4(Io6b=NWz1vpDw&Vxx$d7jie;|knYsbas8f)&S=2$KiB4%9DBg((#r)?usn+(2k8`Afj zT#{PsY01wC0nmX#T)#$JqXK$|SafCL15S0U#%?;19gTr}`sDPguG|9Xx2OgoGjc{w zLIQCOqPOw*;T>k=*Zm}w9jM#1z`HTVao%>Plsg5YA@4s|bZ?P>_PW(Tu&0U02M4D7 z;he-cUo$3_dwz{}=y+8&SnXbj7>whcKGE&W9I`}S!CPc!O5;Vd(^~j19h{}+dLUFe z1H?Wmpo=#j5b6eY(U?$jl>}U0A_1+apV(FPa119Ik0+{CF+7e-w`~^+*PfaObAF=L zLgn_oy0?IO2@tt5n;Oo{KW5B`A_&Y*47LbL4ZEU?QPGs^$#S5Ba&msMd%o2v-#eB8 z{+kJe4FZ4j9+Eu7Zd*z)`C?^Mufy!*Iev`ifoBpPu4s|hn#J5wJ2tMuRhB@%9Sbe4 zr=@J+@U7#P33#FsqVITjT{T-NP4q82%F>)`AfcahDCVk$Cu}juTl)_umN*W3I%4~e z&`H=mZAXAi2H`@+{M32ND07jiqVGq8eM>gaAQICX4d$4KGCGx1aomA4>P4=lk2D$Q zI7pcZ4+Bq|7?RT}jh7O~3&1~zs6IR}n-vr=tk{Q2KdN5xNkV6;gjPnakaX}%!_ z$spz=UZJrSmd%^LeH)f)bPKO9dv{FFd{onaYn-NEFuhCtbSe|O7Y;3FnLlM$uGltr zF#gxftdnDwwwjM`cg_IyIZ-WuTPh!Rog?(PRC@;67gu62&&+F>1`l?AU(v&eLV`gu<$w`iN@x_f=>1Uh{E9r#D`&7~=^m_!_V6FRKQ3X9hE+ z6zr$UlpCF(nhUDkb$;+2 zCxYAyn)i6_kRr*G7d!Hd(9&to=%?<-NO^+89D*RMODPF+lN-iBeokyWuCxpW^ThlY zE9R5Z`!*R~vOf|t`5%xR|DgvFc8<`~9z@ThV0znH(k|$=8&kbY`aHBnOR2PN{*9jr znZ1_prQ+##P4d$92)cSHTo!J3d6LW1_)!jS*VIPm!ThN)gp#szvEY7m*mYQsZZLC! z*YV}2ge3_T2DXKthsI(I5UmIF=FpZ$L-q_tAGG#EMPWT2b)Nr8AEAn{o~4`dkeBGx zlagC;#^il=#)mKW&T7XPkggqzs!sC#y?bnwdk}M`j0CX}%*LHp_W#pX{_;2h2EWyh UHOa%p&V?R;o{q701Ih{ee}McV9RL6T literal 0 HcmV?d00001 diff --git a/media/donation-button-black.svg b/media/donation-button-black.svg new file mode 100644 index 00000000..25217129 --- /dev/null +++ b/media/donation-button-black.svg @@ -0,0 +1 @@ + \ No newline at end of file From 3757ae0b119c0efe4e6d38a37cea353fb82b0c27 Mon Sep 17 00:00:00 2001 From: Drahonn <26854619+Drahonn@users.noreply.github.com> Date: Fri, 19 Sep 2025 01:52:31 +0700 Subject: [PATCH 37/44] cpu history timeframe (#3509) --- web/html/index.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/web/html/index.html b/web/html/index.html index f2ca8472..84445fbf 100644 --- a/web/html/index.html +++ b/web/html/index.html @@ -431,12 +431,12 @@ CPU History - 2s - 30s - 1m - 2m - 3m - 5m + 2m + 30m + 1h + 2h + 3h + 5h

@@ -1124,4 +1124,4 @@ }, }); -{{ template "page/body_end" .}} \ No newline at end of file +{{ template "page/body_end" .}} From 054cb1dea0d93062e89b915c22f9f318bd82f563 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Thu, 18 Sep 2025 22:06:01 +0200 Subject: [PATCH 38/44] go package correction --- database/db.go | 11 +++--- database/model/model.go | 4 +-- go.mod | 2 +- main.go | 16 ++++----- sub/sub.go | 14 ++++---- sub/subController.go | 3 +- sub/subJsonService.go | 12 +++---- sub/subService.go | 14 ++++---- util/common/err.go | 2 +- web/controller/api.go | 2 +- web/controller/base.go | 6 ++-- web/controller/inbound.go | 6 ++-- web/controller/index.go | 12 +++---- web/controller/server.go | 4 +-- web/controller/setting.go | 8 ++--- web/controller/util.go | 6 ++-- web/controller/xray_setting.go | 2 +- web/entity/entity.go | 2 +- web/job/check_client_ip_job.go | 8 ++--- web/job/check_cpu_usage.go | 2 +- web/job/check_hash_storage.go | 2 +- web/job/check_xray_running_job.go | 4 +-- web/job/clear_logs_job.go | 4 +-- web/job/periodic_traffic_reset_job.go | 4 +-- web/job/stats_notify_job.go | 2 +- web/job/xray_traffic_job.go | 7 ++-- web/locale/locale.go | 2 +- web/service/inbound.go | 10 +++--- web/service/outbound.go | 8 ++--- web/service/panel.go | 2 +- web/service/server.go | 12 +++---- web/service/setting.go | 16 ++++----- web/service/tgbot.go | 49 +++++++++++++-------------- web/service/user.go | 8 ++--- web/service/warp.go | 5 +-- web/service/xray.go | 4 +-- web/service/xray_setting.go | 4 +-- web/session/session.go | 2 +- web/web.go | 18 +++++----- xray/api.go | 6 ++-- xray/config.go | 2 +- xray/inbound.go | 2 +- xray/log_writer.go | 2 +- xray/process.go | 6 ++-- 44 files changed, 161 insertions(+), 156 deletions(-) diff --git a/database/db.go b/database/db.go index c72d28cf..e85f0049 100644 --- a/database/db.go +++ b/database/db.go @@ -9,10 +9,10 @@ import ( "path" "slices" - "x-ui/config" - "x-ui/database/model" - "x-ui/util/crypto" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/util/crypto" + "github.com/mhsanaei/3x-ui/xray" "gorm.io/driver/sqlite" "gorm.io/gorm" @@ -141,6 +141,9 @@ func InitDB(dbPath string) error { } isUsersEmpty, err := isTableEmpty("users") + if err != nil { + return err + } if err := initUser(); err != nil { return err diff --git a/database/model/model.go b/database/model/model.go index dcb795c7..7ea7fd55 100644 --- a/database/model/model.go +++ b/database/model/model.go @@ -3,8 +3,8 @@ package model import ( "fmt" - "x-ui/util/json_util" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/util/json_util" + "github.com/mhsanaei/3x-ui/xray" ) type Protocol string diff --git a/go.mod b/go.mod index 41b9fee9..9fed4e54 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module x-ui +module github.com/mhsanaei/3x-ui go 1.25.1 diff --git a/main.go b/main.go index 9986ede1..ea7e57a4 100644 --- a/main.go +++ b/main.go @@ -9,14 +9,14 @@ import ( "syscall" _ "unsafe" - "x-ui/config" - "x-ui/database" - "x-ui/logger" - "x-ui/sub" - "x-ui/util/crypto" - "x-ui/web" - "x-ui/web/global" - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/sub" + "github.com/mhsanaei/3x-ui/util/crypto" + "github.com/mhsanaei/3x-ui/web" + "github.com/mhsanaei/3x-ui/web/global" + "github.com/mhsanaei/3x-ui/web/service" "github.com/joho/godotenv" "github.com/op/go-logging" diff --git a/sub/sub.go b/sub/sub.go index e2876a61..5c2e0aa0 100644 --- a/sub/sub.go +++ b/sub/sub.go @@ -13,13 +13,13 @@ import ( "strconv" "strings" - "x-ui/logger" - "x-ui/util/common" - webpkg "x-ui/web" - "x-ui/web/locale" - "x-ui/web/middleware" - "x-ui/web/network" - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" + webpkg "github.com/mhsanaei/3x-ui/web" + "github.com/mhsanaei/3x-ui/web/locale" + "github.com/mhsanaei/3x-ui/web/middleware" + "github.com/mhsanaei/3x-ui/web/network" + "github.com/mhsanaei/3x-ui/web/service" "github.com/gin-gonic/gin" ) diff --git a/sub/subController.go b/sub/subController.go index b29d019e..481ef9ab 100644 --- a/sub/subController.go +++ b/sub/subController.go @@ -4,7 +4,8 @@ import ( "encoding/base64" "fmt" "strings" - "x-ui/config" + + "github.com/mhsanaei/3x-ui/config" "github.com/gin-gonic/gin" ) diff --git a/sub/subJsonService.go b/sub/subJsonService.go index d3eceb55..4cb2bada 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -6,12 +6,12 @@ import ( "fmt" "strings" - "x-ui/database/model" - "x-ui/logger" - "x-ui/util/json_util" - "x-ui/util/random" - "x-ui/web/service" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/json_util" + "github.com/mhsanaei/3x-ui/util/random" + "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/xray" ) //go:embed default.json diff --git a/sub/subService.go b/sub/subService.go index 201fa09d..da5cd592 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -11,13 +11,13 @@ import ( "github.com/gin-gonic/gin" "github.com/goccy/go-json" - "x-ui/database" - "x-ui/database/model" - "x-ui/logger" - "x-ui/util/common" - "x-ui/util/random" - "x-ui/web/service" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/util/random" + "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/xray" ) type SubService struct { diff --git a/util/common/err.go b/util/common/err.go index 618bf8f3..078a0652 100644 --- a/util/common/err.go +++ b/util/common/err.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "x-ui/logger" + "github.com/mhsanaei/3x-ui/logger" ) func NewErrorf(format string, a ...any) error { diff --git a/web/controller/api.go b/web/controller/api.go index 6edd7939..121cb420 100644 --- a/web/controller/api.go +++ b/web/controller/api.go @@ -1,7 +1,7 @@ package controller import ( - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/service" "github.com/gin-gonic/gin" ) diff --git a/web/controller/base.go b/web/controller/base.go index 492fc2dc..cd4a2ba6 100644 --- a/web/controller/base.go +++ b/web/controller/base.go @@ -3,9 +3,9 @@ package controller import ( "net/http" - "x-ui/logger" - "x-ui/web/locale" - "x-ui/web/session" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/web/locale" + "github.com/mhsanaei/3x-ui/web/session" "github.com/gin-gonic/gin" ) diff --git a/web/controller/inbound.go b/web/controller/inbound.go index 8d610e7d..172e76bc 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -5,9 +5,9 @@ import ( "fmt" "strconv" - "x-ui/database/model" - "x-ui/web/service" - "x-ui/web/session" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/session" "github.com/gin-gonic/gin" ) diff --git a/web/controller/index.go b/web/controller/index.go index c19d1b6e..ee39875a 100644 --- a/web/controller/index.go +++ b/web/controller/index.go @@ -5,18 +5,18 @@ import ( "text/template" "time" - "x-ui/logger" - "x-ui/web/service" - "x-ui/web/session" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/session" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) type LoginForm struct { - Username string `json:"username" form:"username"` - Password string `json:"password" form:"password"` - TwoFactorCode string `json:"twoFactorCode" form:"twoFactorCode"` + Username string `json:"username" form:"username"` + Password string `json:"password" form:"password"` + TwoFactorCode string `json:"twoFactorCode" form:"twoFactorCode"` } type IndexController struct { diff --git a/web/controller/server.go b/web/controller/server.go index 169a1ae7..46a879bd 100644 --- a/web/controller/server.go +++ b/web/controller/server.go @@ -7,8 +7,8 @@ import ( "strconv" "time" - "x-ui/web/global" - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/global" + "github.com/mhsanaei/3x-ui/web/service" "github.com/gin-gonic/gin" ) diff --git a/web/controller/setting.go b/web/controller/setting.go index ddd9f55a..5bf226cc 100644 --- a/web/controller/setting.go +++ b/web/controller/setting.go @@ -4,10 +4,10 @@ import ( "errors" "time" - "x-ui/util/crypto" - "x-ui/web/entity" - "x-ui/web/service" - "x-ui/web/session" + "github.com/mhsanaei/3x-ui/util/crypto" + "github.com/mhsanaei/3x-ui/web/entity" + "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/session" "github.com/gin-gonic/gin" ) diff --git a/web/controller/util.go b/web/controller/util.go index a77d0e35..eb9b1d0a 100644 --- a/web/controller/util.go +++ b/web/controller/util.go @@ -5,9 +5,9 @@ import ( "net/http" "strings" - "x-ui/config" - "x-ui/logger" - "x-ui/web/entity" + "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/web/entity" "github.com/gin-gonic/gin" ) diff --git a/web/controller/xray_setting.go b/web/controller/xray_setting.go index 2b5e0db1..8d0bb19a 100644 --- a/web/controller/xray_setting.go +++ b/web/controller/xray_setting.go @@ -1,7 +1,7 @@ package controller import ( - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/service" "github.com/gin-gonic/gin" ) diff --git a/web/entity/entity.go b/web/entity/entity.go index dd6885f6..be89a582 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "x-ui/util/common" + "github.com/mhsanaei/3x-ui/util/common" ) type Msg struct { diff --git a/web/job/check_client_ip_job.go b/web/job/check_client_ip_job.go index a9b7302b..aa133291 100644 --- a/web/job/check_client_ip_job.go +++ b/web/job/check_client_ip_job.go @@ -12,10 +12,10 @@ import ( "sort" "time" - "x-ui/database" - "x-ui/database/model" - "x-ui/logger" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/xray" ) type CheckClientIpJob struct { diff --git a/web/job/check_cpu_usage.go b/web/job/check_cpu_usage.go index cd9fcc9a..eb93f331 100644 --- a/web/job/check_cpu_usage.go +++ b/web/job/check_cpu_usage.go @@ -4,7 +4,7 @@ import ( "strconv" "time" - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/service" "github.com/shirou/gopsutil/v4/cpu" ) diff --git a/web/job/check_hash_storage.go b/web/job/check_hash_storage.go index 468aa2e0..bffd9586 100644 --- a/web/job/check_hash_storage.go +++ b/web/job/check_hash_storage.go @@ -1,7 +1,7 @@ package job import ( - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/service" ) type CheckHashStorageJob struct { diff --git a/web/job/check_xray_running_job.go b/web/job/check_xray_running_job.go index b28caf2b..a2f8b08c 100644 --- a/web/job/check_xray_running_job.go +++ b/web/job/check_xray_running_job.go @@ -1,8 +1,8 @@ package job import ( - "x-ui/logger" - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/web/service" ) type CheckXrayRunningJob struct { diff --git a/web/job/clear_logs_job.go b/web/job/clear_logs_job.go index c6f1d7cc..d40260e1 100644 --- a/web/job/clear_logs_job.go +++ b/web/job/clear_logs_job.go @@ -5,8 +5,8 @@ import ( "os" "path/filepath" - "x-ui/logger" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/xray" ) type ClearLogsJob struct{} diff --git a/web/job/periodic_traffic_reset_job.go b/web/job/periodic_traffic_reset_job.go index 1369c200..32225139 100644 --- a/web/job/periodic_traffic_reset_job.go +++ b/web/job/periodic_traffic_reset_job.go @@ -1,8 +1,8 @@ package job import ( - "x-ui/logger" - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/web/service" ) type Period string diff --git a/web/job/stats_notify_job.go b/web/job/stats_notify_job.go index ae5eba70..996a19aa 100644 --- a/web/job/stats_notify_job.go +++ b/web/job/stats_notify_job.go @@ -1,7 +1,7 @@ package job import ( - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/web/service" ) type LoginStatus byte diff --git a/web/job/xray_traffic_job.go b/web/job/xray_traffic_job.go index 76022bc9..da56e148 100644 --- a/web/job/xray_traffic_job.go +++ b/web/job/xray_traffic_job.go @@ -2,9 +2,10 @@ package job import ( "encoding/json" - "x-ui/logger" - "x-ui/web/service" - "x-ui/xray" + + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/xray" "github.com/valyala/fasthttp" ) diff --git a/web/locale/locale.go b/web/locale/locale.go index c071dc68..fa41dba1 100644 --- a/web/locale/locale.go +++ b/web/locale/locale.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "x-ui/logger" + "github.com/mhsanaei/3x-ui/logger" "github.com/gin-gonic/gin" "github.com/nicksnyder/go-i18n/v2/i18n" diff --git a/web/service/inbound.go b/web/service/inbound.go index d6955992..8dafae9d 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -8,11 +8,11 @@ import ( "strings" "time" - "x-ui/database" - "x-ui/database/model" - "x-ui/logger" - "x-ui/util/common" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/xray" "gorm.io/gorm" ) diff --git a/web/service/outbound.go b/web/service/outbound.go index 506cf618..d7e738f1 100644 --- a/web/service/outbound.go +++ b/web/service/outbound.go @@ -1,10 +1,10 @@ package service import ( - "x-ui/database" - "x-ui/database/model" - "x-ui/logger" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/xray" "gorm.io/gorm" ) diff --git a/web/service/panel.go b/web/service/panel.go index 3b0c75a5..08c59f5e 100644 --- a/web/service/panel.go +++ b/web/service/panel.go @@ -5,7 +5,7 @@ import ( "syscall" "time" - "x-ui/logger" + "github.com/mhsanaei/3x-ui/logger" ) type PanelService struct{} diff --git a/web/service/server.go b/web/service/server.go index 670e622e..084a2ee2 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -19,12 +19,12 @@ import ( "sync" "time" - "x-ui/config" - "x-ui/database" - "x-ui/logger" - "x-ui/util/common" - "x-ui/util/sys" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/util/sys" + "github.com/mhsanaei/3x-ui/xray" "github.com/google/uuid" "github.com/shirou/gopsutil/v4/cpu" diff --git a/web/service/setting.go b/web/service/setting.go index 39961ad5..c3dc6a1d 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -10,14 +10,14 @@ import ( "strings" "time" - "x-ui/database" - "x-ui/database/model" - "x-ui/logger" - "x-ui/util/common" - "x-ui/util/random" - "x-ui/util/reflect_util" - "x-ui/web/entity" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/util/random" + "github.com/mhsanaei/3x-ui/util/reflect_util" + "github.com/mhsanaei/3x-ui/web/entity" + "github.com/mhsanaei/3x-ui/xray" ) //go:embed config.json diff --git a/web/service/tgbot.go b/web/service/tgbot.go index dd6ac196..bb2d89cf 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -18,14 +18,14 @@ import ( "strings" "time" - "x-ui/config" - "x-ui/database" - "x-ui/database/model" - "x-ui/logger" - "x-ui/util/common" - "x-ui/web/global" - "x-ui/web/locale" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/web/global" + "github.com/mhsanaei/3x-ui/web/locale" + "github.com/mhsanaei/3x-ui/xray" "github.com/google/uuid" "github.com/mymmrac/telego" @@ -1581,23 +1581,6 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool ) prompt_message := t.I18nBot("tgbot.messages.comment_prompt", "ClientComment=="+client_Comment) t.SendMsgToTgbot(chatId, prompt_message, cancel_btn_markup) - default: - // dynamic callbacks - if strings.HasPrefix(callbackQuery.Data, "client_sub_links ") { - email := strings.TrimPrefix(callbackQuery.Data, "client_sub_links ") - t.sendClientSubLinks(chatId, email) - return - } - if strings.HasPrefix(callbackQuery.Data, "client_individual_links ") { - email := strings.TrimPrefix(callbackQuery.Data, "client_individual_links ") - t.sendClientIndividualLinks(chatId, email) - return - } - if strings.HasPrefix(callbackQuery.Data, "client_qr_links ") { - email := strings.TrimPrefix(callbackQuery.Data, "client_qr_links ") - t.sendClientQRLinks(chatId, email) - return - } case "add_client_ch_default_traffic": inlineKeyboard := tu.InlineKeyboard( tu.InlineKeyboardRow( @@ -1813,6 +1796,22 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool t.SendMsgToTgbot(chatId, msg, tu.ReplyKeyboardRemove()) } + default: + if after, ok := strings.CutPrefix(callbackQuery.Data, "client_sub_links "); ok { + email := after + t.sendClientSubLinks(chatId, email) + return + } + if after, ok := strings.CutPrefix(callbackQuery.Data, "client_individual_links "); ok { + email := after + t.sendClientIndividualLinks(chatId, email) + return + } + if after, ok := strings.CutPrefix(callbackQuery.Data, "client_qr_links "); ok { + email := after + t.sendClientQRLinks(chatId, email) + return + } } } diff --git a/web/service/user.go b/web/service/user.go index ff5b8531..cfce219a 100644 --- a/web/service/user.go +++ b/web/service/user.go @@ -3,10 +3,10 @@ package service import ( "errors" - "x-ui/database" - "x-ui/database/model" - "x-ui/logger" - "x-ui/util/crypto" + "github.com/mhsanaei/3x-ui/database" + "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/crypto" "github.com/xlzd/gotp" "gorm.io/gorm" diff --git a/web/service/warp.go b/web/service/warp.go index 0ed8bee2..302d5cf3 100644 --- a/web/service/warp.go +++ b/web/service/warp.go @@ -7,8 +7,9 @@ import ( "net/http" "os" "time" - "x-ui/logger" - "x-ui/util/common" + + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" ) type WarpService struct { diff --git a/web/service/xray.go b/web/service/xray.go index f23ce9c4..8367d061 100644 --- a/web/service/xray.go +++ b/web/service/xray.go @@ -6,8 +6,8 @@ import ( "runtime" "sync" - "x-ui/logger" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/xray" "go.uber.org/atomic" ) diff --git a/web/service/xray_setting.go b/web/service/xray_setting.go index f497bf84..aadecd8d 100644 --- a/web/service/xray_setting.go +++ b/web/service/xray_setting.go @@ -4,8 +4,8 @@ import ( _ "embed" "encoding/json" - "x-ui/util/common" - "x-ui/xray" + "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/xray" ) type XraySettingService struct { diff --git a/web/session/session.go b/web/session/session.go index c793c713..961b01da 100644 --- a/web/session/session.go +++ b/web/session/session.go @@ -4,7 +4,7 @@ import ( "encoding/gob" "net/http" - "x-ui/database/model" + "github.com/mhsanaei/3x-ui/database/model" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" diff --git a/web/web.go b/web/web.go index 9d49cb80..1aa18fe7 100644 --- a/web/web.go +++ b/web/web.go @@ -14,15 +14,15 @@ import ( "strings" "time" - "x-ui/config" - "x-ui/logger" - "x-ui/util/common" - "x-ui/web/controller" - "x-ui/web/job" - "x-ui/web/locale" - "x-ui/web/middleware" - "x-ui/web/network" - "x-ui/web/service" + "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/web/controller" + "github.com/mhsanaei/3x-ui/web/job" + "github.com/mhsanaei/3x-ui/web/locale" + "github.com/mhsanaei/3x-ui/web/middleware" + "github.com/mhsanaei/3x-ui/web/network" + "github.com/mhsanaei/3x-ui/web/service" "github.com/gin-contrib/gzip" "github.com/gin-contrib/sessions" diff --git a/xray/api.go b/xray/api.go index d68b1f96..2a220e67 100644 --- a/xray/api.go +++ b/xray/api.go @@ -4,12 +4,12 @@ import ( "context" "encoding/json" "fmt" + "math" "regexp" "time" - "math" - "x-ui/logger" - "x-ui/util/common" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" "github.com/xtls/xray-core/app/proxyman/command" statsService "github.com/xtls/xray-core/app/stats/command" diff --git a/xray/config.go b/xray/config.go index a246b845..041036b8 100644 --- a/xray/config.go +++ b/xray/config.go @@ -3,7 +3,7 @@ package xray import ( "bytes" - "x-ui/util/json_util" + "github.com/mhsanaei/3x-ui/util/json_util" ) type Config struct { diff --git a/xray/inbound.go b/xray/inbound.go index ea11449d..db1d421c 100644 --- a/xray/inbound.go +++ b/xray/inbound.go @@ -3,7 +3,7 @@ package xray import ( "bytes" - "x-ui/util/json_util" + "github.com/mhsanaei/3x-ui/util/json_util" ) type InboundConfig struct { diff --git a/xray/log_writer.go b/xray/log_writer.go index d91ace3b..2e30c922 100644 --- a/xray/log_writer.go +++ b/xray/log_writer.go @@ -5,7 +5,7 @@ import ( "runtime" "strings" - "x-ui/logger" + "github.com/mhsanaei/3x-ui/logger" ) func NewLogWriter() *LogWriter { diff --git a/xray/process.go b/xray/process.go index 319f96d0..c8c7bb30 100644 --- a/xray/process.go +++ b/xray/process.go @@ -13,9 +13,9 @@ import ( "syscall" "time" - "x-ui/config" - "x-ui/logger" - "x-ui/util/common" + "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/util/common" ) func GetBinaryName() string { From 0ffd27c0aaa78196c015d112ad1ce96cccbb262d Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Thu, 18 Sep 2025 23:13:31 +0200 Subject: [PATCH 39/44] v2.8.2 --- config/version | 2 +- web/service/inbound.go | 2 -- xray/client_traffic.go | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/config/version b/config/version index 96d77177..cae9add9 100644 --- a/config/version +++ b/config/version @@ -1 +1 @@ -2.8.1 \ No newline at end of file +2.8.2 \ No newline at end of file diff --git a/web/service/inbound.go b/web/service/inbound.go index 8dafae9d..bd11339b 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -1953,7 +1953,6 @@ func (s *InboundService) GetClientTrafficByEmail(email string) (traffic *xray.Cl if t != nil && client != nil { t.Enable = client.Enable t.SubId = client.SubID - t.UUID = client.ID return t, nil } return nil, nil @@ -1995,7 +1994,6 @@ func (s *InboundService) GetClientTrafficByID(id string) ([]xray.ClientTraffic, if ct, client, e := s.GetClientByEmail(traffics[i].Email); e == nil && ct != nil && client != nil { traffics[i].Enable = client.Enable traffics[i].SubId = client.SubID - traffics[i].UUID = client.ID } } return traffics, err diff --git a/xray/client_traffic.go b/xray/client_traffic.go index 6300269e..84c509ac 100644 --- a/xray/client_traffic.go +++ b/xray/client_traffic.go @@ -5,7 +5,6 @@ type ClientTraffic struct { InboundId int `json:"inboundId" form:"inboundId"` Enable bool `json:"enable" form:"enable"` Email string `json:"email" form:"email" gorm:"unique"` - UUID string `json:"uuid" form:"uuid" gorm:"unique;type:char(36)"` SubId string `json:"subId" form:"subId" gorm:"-"` Up int64 `json:"up" form:"up"` Down int64 `json:"down" form:"down"` From 7447cec17ed6735c3faf44e88d47dd71a81e9643 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Fri, 19 Sep 2025 10:05:43 +0200 Subject: [PATCH 40/44] go package correction v2 --- database/db.go | 8 ++++---- database/model/model.go | 4 ++-- go.mod | 2 +- main.go | 16 ++++++++-------- sub/sub.go | 14 +++++++------- sub/subController.go | 2 +- sub/subJsonService.go | 12 ++++++------ sub/subService.go | 14 +++++++------- util/common/err.go | 2 +- web/controller/api.go | 2 +- web/controller/base.go | 6 +++--- web/controller/inbound.go | 6 +++--- web/controller/index.go | 6 +++--- web/controller/server.go | 4 ++-- web/controller/setting.go | 8 ++++---- web/controller/util.go | 6 +++--- web/controller/xray_setting.go | 2 +- web/entity/entity.go | 2 +- web/job/check_client_ip_job.go | 8 ++++---- web/job/check_cpu_usage.go | 2 +- web/job/check_hash_storage.go | 2 +- web/job/check_xray_running_job.go | 4 ++-- web/job/clear_logs_job.go | 4 ++-- web/job/periodic_traffic_reset_job.go | 4 ++-- web/job/stats_notify_job.go | 2 +- web/job/xray_traffic_job.go | 6 +++--- web/locale/locale.go | 2 +- web/service/inbound.go | 10 +++++----- web/service/outbound.go | 8 ++++---- web/service/panel.go | 2 +- web/service/server.go | 12 ++++++------ web/service/setting.go | 16 ++++++++-------- web/service/tgbot.go | 16 ++++++++-------- web/service/user.go | 8 ++++---- web/service/warp.go | 4 ++-- web/service/xray.go | 4 ++-- web/service/xray_setting.go | 4 ++-- web/session/session.go | 2 +- web/web.go | 18 +++++++++--------- xray/api.go | 4 ++-- xray/config.go | 2 +- xray/inbound.go | 2 +- xray/log_writer.go | 2 +- xray/process.go | 6 +++--- 44 files changed, 135 insertions(+), 135 deletions(-) diff --git a/database/db.go b/database/db.go index e85f0049..8414b118 100644 --- a/database/db.go +++ b/database/db.go @@ -9,10 +9,10 @@ import ( "path" "slices" - "github.com/mhsanaei/3x-ui/config" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/util/crypto" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/config" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/util/crypto" + "github.com/mhsanaei/3x-ui/v2/xray" "gorm.io/driver/sqlite" "gorm.io/gorm" diff --git a/database/model/model.go b/database/model/model.go index 7ea7fd55..abf8075c 100644 --- a/database/model/model.go +++ b/database/model/model.go @@ -3,8 +3,8 @@ package model import ( "fmt" - "github.com/mhsanaei/3x-ui/util/json_util" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/util/json_util" + "github.com/mhsanaei/3x-ui/v2/xray" ) type Protocol string diff --git a/go.mod b/go.mod index 9fed4e54..cef61eca 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/mhsanaei/3x-ui +module github.com/mhsanaei/3x-ui/v2 go 1.25.1 diff --git a/main.go b/main.go index ea7e57a4..d02a37eb 100644 --- a/main.go +++ b/main.go @@ -9,14 +9,14 @@ import ( "syscall" _ "unsafe" - "github.com/mhsanaei/3x-ui/config" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/sub" - "github.com/mhsanaei/3x-ui/util/crypto" - "github.com/mhsanaei/3x-ui/web" - "github.com/mhsanaei/3x-ui/web/global" - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/config" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/sub" + "github.com/mhsanaei/3x-ui/v2/util/crypto" + "github.com/mhsanaei/3x-ui/v2/web" + "github.com/mhsanaei/3x-ui/v2/web/global" + "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/joho/godotenv" "github.com/op/go-logging" diff --git a/sub/sub.go b/sub/sub.go index 5c2e0aa0..448842ae 100644 --- a/sub/sub.go +++ b/sub/sub.go @@ -13,13 +13,13 @@ import ( "strconv" "strings" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" - webpkg "github.com/mhsanaei/3x-ui/web" - "github.com/mhsanaei/3x-ui/web/locale" - "github.com/mhsanaei/3x-ui/web/middleware" - "github.com/mhsanaei/3x-ui/web/network" - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" + webpkg "github.com/mhsanaei/3x-ui/v2/web" + "github.com/mhsanaei/3x-ui/v2/web/locale" + "github.com/mhsanaei/3x-ui/v2/web/middleware" + "github.com/mhsanaei/3x-ui/v2/web/network" + "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/gin-gonic/gin" ) diff --git a/sub/subController.go b/sub/subController.go index 481ef9ab..d6bc0923 100644 --- a/sub/subController.go +++ b/sub/subController.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/mhsanaei/3x-ui/config" + "github.com/mhsanaei/3x-ui/v2/config" "github.com/gin-gonic/gin" ) diff --git a/sub/subJsonService.go b/sub/subJsonService.go index 4cb2bada..d55c7f81 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -6,12 +6,12 @@ import ( "fmt" "strings" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/json_util" - "github.com/mhsanaei/3x-ui/util/random" - "github.com/mhsanaei/3x-ui/web/service" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/json_util" + "github.com/mhsanaei/3x-ui/v2/util/random" + "github.com/mhsanaei/3x-ui/v2/web/service" + "github.com/mhsanaei/3x-ui/v2/xray" ) //go:embed default.json diff --git a/sub/subService.go b/sub/subService.go index da5cd592..206be24e 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -11,13 +11,13 @@ import ( "github.com/gin-gonic/gin" "github.com/goccy/go-json" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" - "github.com/mhsanaei/3x-ui/util/random" - "github.com/mhsanaei/3x-ui/web/service" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" + "github.com/mhsanaei/3x-ui/v2/util/random" + "github.com/mhsanaei/3x-ui/v2/web/service" + "github.com/mhsanaei/3x-ui/v2/xray" ) type SubService struct { diff --git a/util/common/err.go b/util/common/err.go index 078a0652..85a743ad 100644 --- a/util/common/err.go +++ b/util/common/err.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/v2/logger" ) func NewErrorf(format string, a ...any) error { diff --git a/web/controller/api.go b/web/controller/api.go index 121cb420..506f8cc3 100644 --- a/web/controller/api.go +++ b/web/controller/api.go @@ -1,7 +1,7 @@ package controller import ( - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/gin-gonic/gin" ) diff --git a/web/controller/base.go b/web/controller/base.go index cd4a2ba6..15e8cb57 100644 --- a/web/controller/base.go +++ b/web/controller/base.go @@ -3,9 +3,9 @@ package controller import ( "net/http" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/web/locale" - "github.com/mhsanaei/3x-ui/web/session" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/web/locale" + "github.com/mhsanaei/3x-ui/v2/web/session" "github.com/gin-gonic/gin" ) diff --git a/web/controller/inbound.go b/web/controller/inbound.go index 172e76bc..19af2e1d 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -5,9 +5,9 @@ import ( "fmt" "strconv" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/web/service" - "github.com/mhsanaei/3x-ui/web/session" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/web/service" + "github.com/mhsanaei/3x-ui/v2/web/session" "github.com/gin-gonic/gin" ) diff --git a/web/controller/index.go b/web/controller/index.go index ee39875a..f21e3128 100644 --- a/web/controller/index.go +++ b/web/controller/index.go @@ -5,9 +5,9 @@ import ( "text/template" "time" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/web/service" - "github.com/mhsanaei/3x-ui/web/session" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/web/service" + "github.com/mhsanaei/3x-ui/v2/web/session" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" diff --git a/web/controller/server.go b/web/controller/server.go index 46a879bd..768adb52 100644 --- a/web/controller/server.go +++ b/web/controller/server.go @@ -7,8 +7,8 @@ import ( "strconv" "time" - "github.com/mhsanaei/3x-ui/web/global" - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/web/global" + "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/gin-gonic/gin" ) diff --git a/web/controller/setting.go b/web/controller/setting.go index 5bf226cc..46f760af 100644 --- a/web/controller/setting.go +++ b/web/controller/setting.go @@ -4,10 +4,10 @@ import ( "errors" "time" - "github.com/mhsanaei/3x-ui/util/crypto" - "github.com/mhsanaei/3x-ui/web/entity" - "github.com/mhsanaei/3x-ui/web/service" - "github.com/mhsanaei/3x-ui/web/session" + "github.com/mhsanaei/3x-ui/v2/util/crypto" + "github.com/mhsanaei/3x-ui/v2/web/entity" + "github.com/mhsanaei/3x-ui/v2/web/service" + "github.com/mhsanaei/3x-ui/v2/web/session" "github.com/gin-gonic/gin" ) diff --git a/web/controller/util.go b/web/controller/util.go index eb9b1d0a..e180b1fe 100644 --- a/web/controller/util.go +++ b/web/controller/util.go @@ -5,9 +5,9 @@ import ( "net/http" "strings" - "github.com/mhsanaei/3x-ui/config" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/web/entity" + "github.com/mhsanaei/3x-ui/v2/config" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/web/entity" "github.com/gin-gonic/gin" ) diff --git a/web/controller/xray_setting.go b/web/controller/xray_setting.go index 8d0bb19a..bdbb370c 100644 --- a/web/controller/xray_setting.go +++ b/web/controller/xray_setting.go @@ -1,7 +1,7 @@ package controller import ( - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/gin-gonic/gin" ) diff --git a/web/entity/entity.go b/web/entity/entity.go index be89a582..41d19d3b 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/v2/util/common" ) type Msg struct { diff --git a/web/job/check_client_ip_job.go b/web/job/check_client_ip_job.go index aa133291..7704e10d 100644 --- a/web/job/check_client_ip_job.go +++ b/web/job/check_client_ip_job.go @@ -12,10 +12,10 @@ import ( "sort" "time" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/xray" ) type CheckClientIpJob struct { diff --git a/web/job/check_cpu_usage.go b/web/job/check_cpu_usage.go index eb93f331..5cb9a21e 100644 --- a/web/job/check_cpu_usage.go +++ b/web/job/check_cpu_usage.go @@ -4,7 +4,7 @@ import ( "strconv" "time" - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/shirou/gopsutil/v4/cpu" ) diff --git a/web/job/check_hash_storage.go b/web/job/check_hash_storage.go index bffd9586..5f826d63 100644 --- a/web/job/check_hash_storage.go +++ b/web/job/check_hash_storage.go @@ -1,7 +1,7 @@ package job import ( - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/web/service" ) type CheckHashStorageJob struct { diff --git a/web/job/check_xray_running_job.go b/web/job/check_xray_running_job.go index a2f8b08c..8f5f0889 100644 --- a/web/job/check_xray_running_job.go +++ b/web/job/check_xray_running_job.go @@ -1,8 +1,8 @@ package job import ( - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/web/service" ) type CheckXrayRunningJob struct { diff --git a/web/job/clear_logs_job.go b/web/job/clear_logs_job.go index d40260e1..70e03688 100644 --- a/web/job/clear_logs_job.go +++ b/web/job/clear_logs_job.go @@ -5,8 +5,8 @@ import ( "os" "path/filepath" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/xray" ) type ClearLogsJob struct{} diff --git a/web/job/periodic_traffic_reset_job.go b/web/job/periodic_traffic_reset_job.go index 32225139..65aefb9d 100644 --- a/web/job/periodic_traffic_reset_job.go +++ b/web/job/periodic_traffic_reset_job.go @@ -1,8 +1,8 @@ package job import ( - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/web/service" ) type Period string diff --git a/web/job/stats_notify_job.go b/web/job/stats_notify_job.go index 996a19aa..0d0907e0 100644 --- a/web/job/stats_notify_job.go +++ b/web/job/stats_notify_job.go @@ -1,7 +1,7 @@ package job import ( - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/web/service" ) type LoginStatus byte diff --git a/web/job/xray_traffic_job.go b/web/job/xray_traffic_job.go index da56e148..8ba5a9f9 100644 --- a/web/job/xray_traffic_job.go +++ b/web/job/xray_traffic_job.go @@ -3,9 +3,9 @@ package job import ( "encoding/json" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/web/service" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/web/service" + "github.com/mhsanaei/3x-ui/v2/xray" "github.com/valyala/fasthttp" ) diff --git a/web/locale/locale.go b/web/locale/locale.go index fa41dba1..2f0a7147 100644 --- a/web/locale/locale.go +++ b/web/locale/locale.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/v2/logger" "github.com/gin-gonic/gin" "github.com/nicksnyder/go-i18n/v2/i18n" diff --git a/web/service/inbound.go b/web/service/inbound.go index bd11339b..4c0b344a 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -8,11 +8,11 @@ import ( "strings" "time" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" + "github.com/mhsanaei/3x-ui/v2/xray" "gorm.io/gorm" ) diff --git a/web/service/outbound.go b/web/service/outbound.go index d7e738f1..94a8f0b3 100644 --- a/web/service/outbound.go +++ b/web/service/outbound.go @@ -1,10 +1,10 @@ package service import ( - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/xray" "gorm.io/gorm" ) diff --git a/web/service/panel.go b/web/service/panel.go index 08c59f5e..72576299 100644 --- a/web/service/panel.go +++ b/web/service/panel.go @@ -5,7 +5,7 @@ import ( "syscall" "time" - "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/v2/logger" ) type PanelService struct{} diff --git a/web/service/server.go b/web/service/server.go index 084a2ee2..03199b50 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -19,12 +19,12 @@ import ( "sync" "time" - "github.com/mhsanaei/3x-ui/config" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" - "github.com/mhsanaei/3x-ui/util/sys" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/config" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" + "github.com/mhsanaei/3x-ui/v2/util/sys" + "github.com/mhsanaei/3x-ui/v2/xray" "github.com/google/uuid" "github.com/shirou/gopsutil/v4/cpu" diff --git a/web/service/setting.go b/web/service/setting.go index c3dc6a1d..7046464a 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -10,14 +10,14 @@ import ( "strings" "time" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" - "github.com/mhsanaei/3x-ui/util/random" - "github.com/mhsanaei/3x-ui/util/reflect_util" - "github.com/mhsanaei/3x-ui/web/entity" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" + "github.com/mhsanaei/3x-ui/v2/util/random" + "github.com/mhsanaei/3x-ui/v2/util/reflect_util" + "github.com/mhsanaei/3x-ui/v2/web/entity" + "github.com/mhsanaei/3x-ui/v2/xray" ) //go:embed config.json diff --git a/web/service/tgbot.go b/web/service/tgbot.go index bb2d89cf..bbea32c5 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -18,14 +18,14 @@ import ( "strings" "time" - "github.com/mhsanaei/3x-ui/config" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" - "github.com/mhsanaei/3x-ui/web/global" - "github.com/mhsanaei/3x-ui/web/locale" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/config" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" + "github.com/mhsanaei/3x-ui/v2/web/global" + "github.com/mhsanaei/3x-ui/v2/web/locale" + "github.com/mhsanaei/3x-ui/v2/xray" "github.com/google/uuid" "github.com/mymmrac/telego" diff --git a/web/service/user.go b/web/service/user.go index cfce219a..074eb7ef 100644 --- a/web/service/user.go +++ b/web/service/user.go @@ -3,10 +3,10 @@ package service import ( "errors" - "github.com/mhsanaei/3x-ui/database" - "github.com/mhsanaei/3x-ui/database/model" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/crypto" + "github.com/mhsanaei/3x-ui/v2/database" + "github.com/mhsanaei/3x-ui/v2/database/model" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/crypto" "github.com/xlzd/gotp" "gorm.io/gorm" diff --git a/web/service/warp.go b/web/service/warp.go index 302d5cf3..ef9e573b 100644 --- a/web/service/warp.go +++ b/web/service/warp.go @@ -8,8 +8,8 @@ import ( "os" "time" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" ) type WarpService struct { diff --git a/web/service/xray.go b/web/service/xray.go index 8367d061..93cbd9f0 100644 --- a/web/service/xray.go +++ b/web/service/xray.go @@ -6,8 +6,8 @@ import ( "runtime" "sync" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/xray" "go.uber.org/atomic" ) diff --git a/web/service/xray_setting.go b/web/service/xray_setting.go index aadecd8d..06131ea3 100644 --- a/web/service/xray_setting.go +++ b/web/service/xray_setting.go @@ -4,8 +4,8 @@ import ( _ "embed" "encoding/json" - "github.com/mhsanaei/3x-ui/util/common" - "github.com/mhsanaei/3x-ui/xray" + "github.com/mhsanaei/3x-ui/v2/util/common" + "github.com/mhsanaei/3x-ui/v2/xray" ) type XraySettingService struct { diff --git a/web/session/session.go b/web/session/session.go index 961b01da..b201f15d 100644 --- a/web/session/session.go +++ b/web/session/session.go @@ -4,7 +4,7 @@ import ( "encoding/gob" "net/http" - "github.com/mhsanaei/3x-ui/database/model" + "github.com/mhsanaei/3x-ui/v2/database/model" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" diff --git a/web/web.go b/web/web.go index 1aa18fe7..daf312cb 100644 --- a/web/web.go +++ b/web/web.go @@ -14,15 +14,15 @@ import ( "strings" "time" - "github.com/mhsanaei/3x-ui/config" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" - "github.com/mhsanaei/3x-ui/web/controller" - "github.com/mhsanaei/3x-ui/web/job" - "github.com/mhsanaei/3x-ui/web/locale" - "github.com/mhsanaei/3x-ui/web/middleware" - "github.com/mhsanaei/3x-ui/web/network" - "github.com/mhsanaei/3x-ui/web/service" + "github.com/mhsanaei/3x-ui/v2/config" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" + "github.com/mhsanaei/3x-ui/v2/web/controller" + "github.com/mhsanaei/3x-ui/v2/web/job" + "github.com/mhsanaei/3x-ui/v2/web/locale" + "github.com/mhsanaei/3x-ui/v2/web/middleware" + "github.com/mhsanaei/3x-ui/v2/web/network" + "github.com/mhsanaei/3x-ui/v2/web/service" "github.com/gin-contrib/gzip" "github.com/gin-contrib/sessions" diff --git a/xray/api.go b/xray/api.go index 2a220e67..d7ca4114 100644 --- a/xray/api.go +++ b/xray/api.go @@ -8,8 +8,8 @@ import ( "regexp" "time" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" "github.com/xtls/xray-core/app/proxyman/command" statsService "github.com/xtls/xray-core/app/stats/command" diff --git a/xray/config.go b/xray/config.go index 041036b8..b10592d0 100644 --- a/xray/config.go +++ b/xray/config.go @@ -3,7 +3,7 @@ package xray import ( "bytes" - "github.com/mhsanaei/3x-ui/util/json_util" + "github.com/mhsanaei/3x-ui/v2/util/json_util" ) type Config struct { diff --git a/xray/inbound.go b/xray/inbound.go index db1d421c..5a328f31 100644 --- a/xray/inbound.go +++ b/xray/inbound.go @@ -3,7 +3,7 @@ package xray import ( "bytes" - "github.com/mhsanaei/3x-ui/util/json_util" + "github.com/mhsanaei/3x-ui/v2/util/json_util" ) type InboundConfig struct { diff --git a/xray/log_writer.go b/xray/log_writer.go index 2e30c922..3be39b3e 100644 --- a/xray/log_writer.go +++ b/xray/log_writer.go @@ -5,7 +5,7 @@ import ( "runtime" "strings" - "github.com/mhsanaei/3x-ui/logger" + "github.com/mhsanaei/3x-ui/v2/logger" ) func NewLogWriter() *LogWriter { diff --git a/xray/process.go b/xray/process.go index c8c7bb30..0df9c44b 100644 --- a/xray/process.go +++ b/xray/process.go @@ -13,9 +13,9 @@ import ( "syscall" "time" - "github.com/mhsanaei/3x-ui/config" - "github.com/mhsanaei/3x-ui/logger" - "github.com/mhsanaei/3x-ui/util/common" + "github.com/mhsanaei/3x-ui/v2/config" + "github.com/mhsanaei/3x-ui/v2/logger" + "github.com/mhsanaei/3x-ui/v2/util/common" ) func GetBinaryName() string { From ca0a7aeb5a3a46448b31514a7f876760c50dcc2d Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Fri, 19 Sep 2025 10:29:34 +0200 Subject: [PATCH 41/44] readme: Go Report Card,Go Reference --- README.ar_EG.md | 12 +++++++----- README.es_ES.md | 12 +++++++----- README.fa_IR.md | 12 +++++++----- README.md | 12 +++++++----- README.ru_RU.md | 12 +++++++----- README.zh_CN.md | 12 +++++++----- 6 files changed, 42 insertions(+), 30 deletions(-) diff --git a/README.ar_EG.md b/README.ar_EG.md index 5990a829..01acad34 100644 --- a/README.ar_EG.md +++ b/README.ar_EG.md @@ -7,11 +7,13 @@

-[![](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases) -[![](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/actions) -[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg?style=for-the-badge)](#) -[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases/latest) -[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true&style=for-the-badge)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Release](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg)](https://github.com/MHSanaei/3x-ui/releases) +[![Build](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg)](https://github.com/MHSanaei/3x-ui/actions) +[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg)](#) +[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg)](https://github.com/MHSanaei/3x-ui/releases/latest) +[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Go Reference](https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v2.svg)](https://pkg.go.dev/github.com/mhsanaei/3x-ui/v2) +[![Go Report Card](https://goreportcard.com/badge/github.com/mhsanaei/3x-ui/v2)](https://goreportcard.com/report/github.com/mhsanaei/3x-ui/v2) **3X-UI** — لوحة تحكم متقدمة مفتوحة المصدر تعتمد على الويب مصممة لإدارة خادم Xray-core. توفر واجهة سهلة الاستخدام لتكوين ومراقبة بروتوكولات VPN والوكيل المختلفة. diff --git a/README.es_ES.md b/README.es_ES.md index 61933b14..63d6ce49 100644 --- a/README.es_ES.md +++ b/README.es_ES.md @@ -7,11 +7,13 @@

-[![](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases) -[![](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/actions) -[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg?style=for-the-badge)](#) -[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases/latest) -[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true&style=for-the-badge)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Release](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg)](https://github.com/MHSanaei/3x-ui/releases) +[![Build](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg)](https://github.com/MHSanaei/3x-ui/actions) +[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg)](#) +[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg)](https://github.com/MHSanaei/3x-ui/releases/latest) +[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Go Reference](https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v2.svg)](https://pkg.go.dev/github.com/mhsanaei/3x-ui/v2) +[![Go Report Card](https://goreportcard.com/badge/github.com/mhsanaei/3x-ui/v2)](https://goreportcard.com/report/github.com/mhsanaei/3x-ui/v2) **3X-UI** — panel de control avanzado basado en web de código abierto diseñado para gestionar el servidor Xray-core. Ofrece una interfaz fácil de usar para configurar y monitorear varios protocolos VPN y proxy. diff --git a/README.fa_IR.md b/README.fa_IR.md index 4d363eef..94165260 100644 --- a/README.fa_IR.md +++ b/README.fa_IR.md @@ -7,11 +7,13 @@

-[![](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases) -[![](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/actions) -[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg?style=for-the-badge)](#) -[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases/latest) -[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true&style=for-the-badge)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Release](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg)](https://github.com/MHSanaei/3x-ui/releases) +[![Build](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg)](https://github.com/MHSanaei/3x-ui/actions) +[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg)](#) +[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg)](https://github.com/MHSanaei/3x-ui/releases/latest) +[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Go Reference](https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v2.svg)](https://pkg.go.dev/github.com/mhsanaei/3x-ui/v2) +[![Go Report Card](https://goreportcard.com/badge/github.com/mhsanaei/3x-ui/v2)](https://goreportcard.com/report/github.com/mhsanaei/3x-ui/v2) **3X-UI** — یک پنل کنترل پیشرفته مبتنی بر وب با کد باز که برای مدیریت سرور Xray-core طراحی شده است. این پنل یک رابط کاربری آسان برای پیکربندی و نظارت بر پروتکل‌های مختلف VPN و پراکسی ارائه می‌دهد. diff --git a/README.md b/README.md index b7ce4854..9d20850e 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,13 @@

-[![](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases) -[![](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/actions) -[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg?style=for-the-badge)](#) -[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases/latest) -[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true&style=for-the-badge)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Release](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg)](https://github.com/MHSanaei/3x-ui/releases) +[![Build](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg)](https://github.com/MHSanaei/3x-ui/actions) +[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg)](#) +[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg)](https://github.com/MHSanaei/3x-ui/releases/latest) +[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Go Reference](https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v2.svg)](https://pkg.go.dev/github.com/mhsanaei/3x-ui/v2) +[![Go Report Card](https://goreportcard.com/badge/github.com/mhsanaei/3x-ui/v2)](https://goreportcard.com/report/github.com/mhsanaei/3x-ui/v2) **3X-UI** — advanced, open-source web-based control panel designed for managing Xray-core server. It offers a user-friendly interface for configuring and monitoring various VPN and proxy protocols. diff --git a/README.ru_RU.md b/README.ru_RU.md index 3971b70c..6623a801 100644 --- a/README.ru_RU.md +++ b/README.ru_RU.md @@ -7,11 +7,13 @@

-[![](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases) -[![](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/actions) -[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg?style=for-the-badge)](#) -[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases/latest) -[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true&style=for-the-badge)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Release](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg)](https://github.com/MHSanaei/3x-ui/releases) +[![Build](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg)](https://github.com/MHSanaei/3x-ui/actions) +[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg)](#) +[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg)](https://github.com/MHSanaei/3x-ui/releases/latest) +[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Go Reference](https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v2.svg)](https://pkg.go.dev/github.com/mhsanaei/3x-ui/v2) +[![Go Report Card](https://goreportcard.com/badge/github.com/mhsanaei/3x-ui/v2)](https://goreportcard.com/report/github.com/mhsanaei/3x-ui/v2) **3X-UI** — продвинутая панель управления с открытым исходным кодом на основе веб-интерфейса, разработанная для управления сервером Xray-core. Предоставляет удобный интерфейс для настройки и мониторинга различных VPN и прокси-протоколов. diff --git a/README.zh_CN.md b/README.zh_CN.md index 4abbf087..6eb30ee0 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -7,11 +7,13 @@

-[![](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases) -[![](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/actions) -[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg?style=for-the-badge)](#) -[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg?style=for-the-badge)](https://github.com/MHSanaei/3x-ui/releases/latest) -[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true&style=for-the-badge)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Release](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg)](https://github.com/MHSanaei/3x-ui/releases) +[![Build](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg)](https://github.com/MHSanaei/3x-ui/actions) +[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg)](#) +[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg)](https://github.com/MHSanaei/3x-ui/releases/latest) +[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![Go Reference](https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v2.svg)](https://pkg.go.dev/github.com/mhsanaei/3x-ui/v2) +[![Go Report Card](https://goreportcard.com/badge/github.com/mhsanaei/3x-ui/v2)](https://goreportcard.com/report/github.com/mhsanaei/3x-ui/v2) **3X-UI** — 一个基于网页的高级开源控制面板,专为管理 Xray-core 服务器而设计。它提供了用户友好的界面,用于配置和监控各种 VPN 和代理协议。 From e262132b9dccc57cf3a216faf4c78a7f569351ca Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Fri, 19 Sep 2025 10:35:03 +0200 Subject: [PATCH 42/44] misspell --- web/locale/locale.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/locale/locale.go b/web/locale/locale.go index 2f0a7147..b4cb9464 100644 --- a/web/locale/locale.go +++ b/web/locale/locale.go @@ -49,10 +49,10 @@ func InitLocalizer(i18nFS embed.FS, settingService SettingService) error { return nil } -func createTemplateData(params []string, seperator ...string) map[string]any { +func createTemplateData(params []string, separator ...string) map[string]any { var sep string = "==" - if len(seperator) > 0 { - sep = seperator[0] + if len(separator) > 0 { + sep = separator[0] } templateData := make(map[string]any) From 151f1173a1b592d4df51258f7635de657512cbfc Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Fri, 19 Sep 2025 10:46:49 +0200 Subject: [PATCH 43/44] =?UTF-8?q?Fix=20ineffassign=20=E2=80=9Cdate?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/service/tgbot.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/service/tgbot.go b/web/service/tgbot.go index bbea32c5..44e4af28 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -856,7 +856,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool if len(dataArray) == 3 { days, err := strconv.Atoi(dataArray[2]) if err == nil { - var date int64 = 0 + var date int64 if days > 0 { traffic, err := t.inboundService.GetClientTrafficByEmail(email) if err != nil { @@ -960,7 +960,7 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool case "add_client_reset_exp_c": client_ExpiryTime = 0 days, _ := strconv.Atoi(dataArray[1]) - var date int64 = 0 + var date int64 if client_ExpiryTime > 0 { if client_ExpiryTime-time.Now().Unix()*1000 < 0 { date = -int64(days * 24 * 60 * 60000) From 5b00a52c652f2e037016c65c3228780e29b5bdfe Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Fri, 19 Sep 2025 10:47:28 +0200 Subject: [PATCH 44/44] fix: ineffectual assignment to needRestart --- web/controller/inbound.go | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/web/controller/inbound.go b/web/controller/inbound.go index 19af2e1d..0a988506 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -108,8 +108,7 @@ func (a *InboundController) addInbound(c *gin.Context) { inbound.Tag = fmt.Sprintf("inbound-%v:%v", inbound.Listen, inbound.Port) } - needRestart := false - inbound, needRestart, err = a.inboundService.AddInbound(inbound) + inbound, needRestart, err := a.inboundService.AddInbound(inbound) if err != nil { jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) return @@ -126,8 +125,7 @@ func (a *InboundController) delInbound(c *gin.Context) { jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.inboundDeleteSuccess"), err) return } - needRestart := true - needRestart, err = a.inboundService.DelInbound(id) + needRestart, err := a.inboundService.DelInbound(id) if err != nil { jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) return @@ -152,8 +150,7 @@ func (a *InboundController) updateInbound(c *gin.Context) { jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.inboundUpdateSuccess"), err) return } - needRestart := true - inbound, needRestart, err = a.inboundService.UpdateInbound(inbound) + inbound, needRestart, err := a.inboundService.UpdateInbound(inbound) if err != nil { jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) return @@ -195,9 +192,7 @@ func (a *InboundController) addInboundClient(c *gin.Context) { return } - needRestart := true - - needRestart, err = a.inboundService.AddInboundClient(data) + needRestart, err := a.inboundService.AddInboundClient(data) if err != nil { jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) return @@ -216,9 +211,7 @@ func (a *InboundController) delInboundClient(c *gin.Context) { } clientId := c.Param("clientId") - needRestart := true - - needRestart, err = a.inboundService.DelInboundClient(id, clientId) + needRestart, err := a.inboundService.DelInboundClient(id, clientId) if err != nil { jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) return @@ -239,9 +232,7 @@ func (a *InboundController) updateInboundClient(c *gin.Context) { return } - needRestart := true - - needRestart, err = a.inboundService.UpdateInboundClient(inbound, clientId) + needRestart, err := a.inboundService.UpdateInboundClient(inbound, clientId) if err != nil { jsonMsg(c, I18nWeb(c, "somethingWentWrong"), err) return