v1.1
@@ -0,0 +1,619 @@
|
||||
html, body {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 0.50rem 1.00rem;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
span.badge {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.fade:not(.show) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: fixed;
|
||||
color: #65686a;
|
||||
display: none;
|
||||
z-index: 1000000;
|
||||
}
|
||||
|
||||
#loading-spinner {
|
||||
position: fixed;
|
||||
overflow: visible;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#loading:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
/* margin-bottom: 10px; */
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
img .flag {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.information {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
color: #343a40;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
color: #868888;
|
||||
margin-bottom: 0px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.border {
|
||||
display: flex;
|
||||
min-height: 125px;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.my-3 {
|
||||
margin-bottom: 1rem!important;
|
||||
}
|
||||
|
||||
.without-mb {
|
||||
margin-bottom: 0rem!important;
|
||||
}
|
||||
|
||||
.p-2 {
|
||||
padding: .5rem!important;
|
||||
}
|
||||
|
||||
i.fa-play.start {
|
||||
color: #06d79c;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
i.fa-stop.stop {
|
||||
color: #656373;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
i.fa-sync.reboot {
|
||||
color: #398bf7;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.vnc {
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
color: #3d3d3d;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.dashboard-value {
|
||||
color: #586271 !important;
|
||||
}
|
||||
|
||||
.usage-details {
|
||||
border: 1px solid #e7e4e4;
|
||||
transition: all ease-in .2s;
|
||||
}
|
||||
|
||||
.usage-details:hover {
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 1px 1px 8px 6px #e5e3e3bf;
|
||||
}
|
||||
|
||||
.overview-label {
|
||||
color: #99abb4;
|
||||
}
|
||||
|
||||
.progress.disk-bar {
|
||||
height: 14px;
|
||||
margin-top: 25px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 6px;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.used_disk_percent {
|
||||
color: #1e88e5;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.dashboard-tab .nav-tabs {
|
||||
border-bottom: 1px solid #dfd8d8;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dashboard-tab .nav-tabs .nav-item {
|
||||
border-bottom: 1px solid #dfd8d8;
|
||||
}
|
||||
|
||||
.dashboard-tab .nav-tabs li a {
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
margin-right: 10px;
|
||||
color: #374045 !important;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
transition: all 0.3s ease 0s;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.dashboard-tab .nav-tabs li a:before {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.dashboard-tab .nav-tabs li a:after {
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 4px;
|
||||
background: linear-gradient(to right, #396afc, #2948ff);
|
||||
border-bottom: 1px solid #727cb6;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 0;
|
||||
transition: all .4s ease 0s;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.dashboard-tab .nav-tabs li a.active:after {
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.vertical-tabs .nav-link {
|
||||
color: #515a68;
|
||||
padding: 7px 5px;
|
||||
margin-bottom: 10px;
|
||||
transition: all ease-in 0.2s;
|
||||
text-align: left!important;
|
||||
}
|
||||
|
||||
.vertical-tabs .nav-link.active {
|
||||
border-radius: 0px;
|
||||
color: #2948ff;
|
||||
}
|
||||
|
||||
.v-tabs-container {
|
||||
border-right: 1px solid #dfd8d8;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link.active {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
.custom-control-input:checked~.custom-control-label::before {
|
||||
color: #fff;
|
||||
border-color: #007bff;
|
||||
background-color: #007bff;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
color: #398bf7;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#graphs-tab .nav-link,
|
||||
#sub-tasks-and-logs .nav-link {
|
||||
color: #576170;
|
||||
transition: all 0.4s linear;
|
||||
}
|
||||
|
||||
#graphs-tab .nav-link.active,
|
||||
#sub-tasks-and-logs .nav-link.active {
|
||||
border-radius: 0px;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(to right, #396afc, #2948ff);
|
||||
}
|
||||
|
||||
.prev-mnth.green_but,
|
||||
.next-mnth.green_but {
|
||||
padding: 4px 10px;
|
||||
}
|
||||
|
||||
.graphs img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background-color: #398bf7;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
padding: 7px 12px;
|
||||
transition: 0.2s ease-in;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background-color: #5a6268;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
padding: 7px 12px;
|
||||
transition: 0.2s ease-in;
|
||||
}
|
||||
|
||||
.danger-btn {
|
||||
background-color: #dc3545;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
padding: 7px 12px;
|
||||
transition: 0.2s ease-in;
|
||||
}
|
||||
|
||||
.submit-btn:hover {
|
||||
color: #ffffff !important;
|
||||
box-shadow: 0 14px 26px -12px #1769ff6b, 0 4px 23px 0 #0000001f, 0 8px 10px -5px #1769ff33;
|
||||
}
|
||||
|
||||
.cancel-btn:hover {
|
||||
color: #ffffff !important;
|
||||
box-shadow: 0 14px 26px -12px #000000, 0 4px 23px 0 #0000001f, 0 8px 10px -5px #07183533;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-weight: 400;
|
||||
color: #455a64;
|
||||
}
|
||||
|
||||
.modal-title i.success {
|
||||
font-size: 40px;
|
||||
color: #06d79c;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.modal-title i.warning {
|
||||
font-size: 40px;
|
||||
color: orange;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.modal-title i.error {
|
||||
font-size: 40px;
|
||||
color: #ef5350;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
color: #868888;
|
||||
font-weight: 500;
|
||||
line-height: 30px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.modal-body p {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.link-btn {
|
||||
background-color: #398bf7;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
text-decoration: none !important;
|
||||
color: #ffffff !important;
|
||||
font-size: 14px;
|
||||
padding: 7px 12px;
|
||||
transition: 0.2s ease-in;
|
||||
}
|
||||
|
||||
.link-btn:hover {
|
||||
text-decoration: none;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 14px 26px -12px rgba(23, 105, 255, 0.42), 0 4px 23px 0 rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(23, 105, 255, 0.2);
|
||||
}
|
||||
|
||||
.v-tab-heading {
|
||||
color: #515557;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.distro_img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.distro_name.media-heading {
|
||||
color: #3d3d3d;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.float-left {
|
||||
float: left!important;
|
||||
}
|
||||
|
||||
.media {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.version {
|
||||
color: #586271;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
background-color: #007bff;
|
||||
color: #fff;
|
||||
padding: 4px 12px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.info-icon:hover,
|
||||
.info-icon:focus {
|
||||
border: none;
|
||||
box-shadow: 0 14px 26px -12px rgba(23, 105, 255, 0.42), 0 4px 23px 0 rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(23, 105, 255, 0.2);
|
||||
}
|
||||
|
||||
.info-icon i {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.os_badge {
|
||||
border: 1px solid #ccc;
|
||||
cursor: pointer;
|
||||
transition: height 0.5s;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#os_list .dropdown-menu {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.os_badge_list a {
|
||||
color: #576170;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
display: block;
|
||||
padding: 8px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.os_badge_list a:hover {
|
||||
color: #2f3235;
|
||||
background-color: #f9f6f6;
|
||||
}
|
||||
|
||||
.os_badge_list .SelectedOS {
|
||||
color: #ffffff;
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
.os_badge.selected .version,
|
||||
.os_badge.selected .distro_name.media-heading,
|
||||
.os_badge.selected i {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.os_badge.selected {
|
||||
color: #fff;
|
||||
background-color: #06d79c;
|
||||
}
|
||||
|
||||
.os_badge i {
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
right: 16px;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.os_badge .media-left {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.os_badge .media-body {
|
||||
padding: 8px;
|
||||
vertical-align: middle;
|
||||
text-align: left!important;
|
||||
}
|
||||
|
||||
.os_badge .version {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.os_badge.expanded {
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.os_badge .dropdown-toggle::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.tab-content>.tab-pane {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-content>.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.head {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.head>img {
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.restore-icon {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.create {
|
||||
color: #06d79c;
|
||||
}
|
||||
|
||||
.delete {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.table.dataTable.no-footer {
|
||||
border-bottom: 1px solid #5d5b63 !important;
|
||||
}
|
||||
|
||||
table.tablesorter {
|
||||
box-shadow: 0 2px 12px -3px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
table.dataTable {
|
||||
clear: both;
|
||||
margin-top: 6px !important;
|
||||
margin-bottom: 6px !important;
|
||||
max-width: none !important;
|
||||
border-collapse: separate !important;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
#firewallTable th,
|
||||
#backupTable th {
|
||||
color: #ffffff;
|
||||
background-color: #36304a !important;
|
||||
border: unset !important;
|
||||
font-weight: unset !important;
|
||||
position: sticky !important;
|
||||
top: -1px;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.fa-1x {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
|
||||
.grey-txt {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.showPassword {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.scrtabs-tab-scroll-arrow {
|
||||
top: calc(50% - 10px);
|
||||
color: #396afc;
|
||||
height: 20px;
|
||||
border: none;
|
||||
position: relative;
|
||||
padding-top: 0px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
select,
|
||||
textarea,
|
||||
input[type=text],
|
||||
input[type=textbox],
|
||||
input[type=password] {
|
||||
background: #fff;
|
||||
font-size: 12px;
|
||||
color: #455a64;
|
||||
border: 1px #CCCCCC solid;
|
||||
transition: background 0.3s linear;
|
||||
-webkit-transition: background 0.3s linear;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
select,
|
||||
textarea,
|
||||
input[type=text],
|
||||
input[type=number],
|
||||
input[type=textbox],
|
||||
input[type=password] {
|
||||
box-shadow: 0 2px 2px 0 #a9a9a924, 0 3px 1px -2px #a9a9a933, 0 1px 5px 0 #a9a9a91f;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
height: 35px;
|
||||
font-size: 14px !important;
|
||||
min-height: 40px;
|
||||
margin-bottom: 8px;
|
||||
color: #67757c;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.input-group-text {
|
||||
height: 35px;
|
||||
font-size: 14px !important;
|
||||
min-height: 40px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ml-auto,
|
||||
.mx-auto {
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
.mr-2,
|
||||
.mx-2 {
|
||||
margin-right: .5rem!important;
|
||||
}
|
||||
|
||||
@media all and (max-width: 576px) {
|
||||
.left-side-tabs {
|
||||
border-bottom: 1px solid #dfd8d8;
|
||||
}
|
||||
|
||||
.vertical-tabs .nav-link {
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
||||
.left-side-tabs .nav-link.active {
|
||||
color: #ffffff;
|
||||
background:linear-gradient(to right, #396afc, #2948ff);
|
||||
}
|
||||
|
||||
.vertical-tab-content form select,
|
||||
.vertical-tab-content form input[type=text],
|
||||
.vertical-tab-content form input[type=textbox],
|
||||
.vertical-tab-content form input[type=password] {
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{**
|
||||
* VPSAG WHMCS Server Provisioning version 1.1
|
||||
*
|
||||
* @package WHMCS
|
||||
* @copyright ArkHost
|
||||
* @link https://arkhost.com
|
||||
* @author ArkHost <support@arkhost.com>
|
||||
*}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
||||
<meta name="author" content="ArkHost">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>ArkHost - VPS Panel</title>
|
||||
|
||||
|
||||
</head>
|
||||
<body class="text-center">
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<div class="notice">
|
||||
<img src="{$image}" class="mr-2">{$error}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 269 B |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,295 @@
|
||||
|
||||
function $_(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function ArkHostVPS_API(action, alert = true, json = {}) {
|
||||
ArkHostVPS_Loading(true);
|
||||
|
||||
$.post(productURL + '&modop=custom&a=ClientAreaAPI&api=' + action, json,
|
||||
function(data) {
|
||||
if (data.result === 'success') {
|
||||
switch (action) {
|
||||
case 'IPv6':
|
||||
$_('ipv6').parentElement.innerHTML = data.data;
|
||||
data.data = 'IPv6 created: ' + data.data;
|
||||
|
||||
break;
|
||||
|
||||
case 'Graphs':
|
||||
// Hide loading indicator (if it exists)
|
||||
if ($_('graphs-loading')) $_('graphs-loading').style.display = 'none';
|
||||
if ($_('graphs-container')) $_('graphs-container').style.opacity = '1';
|
||||
|
||||
// Display graphs (they should be base64 images or img tags)
|
||||
if ($_('cpu-graph')) $_('cpu-graph').innerHTML = data.cpu_img ? data.cpu_img : '<p class="text-muted">No CPU graph available</p>';
|
||||
if ($_('ram-graph')) $_('ram-graph').innerHTML = data.mem_img ? data.mem_img : '<p class="text-muted">No RAM graph available</p>';
|
||||
if ($_('disk-graph')) $_('disk-graph').innerHTML = data.disk_img ? data.disk_img : '<p class="text-muted">No Disk graph available</p>';
|
||||
if ($_('network-graph')) $_('network-graph').innerHTML = data.net_img ? data.net_img : '<p class="text-muted">No Network graph available</p>';
|
||||
|
||||
// Add graphs class for styling
|
||||
if ($_('cpu-graph')) $_('cpu-graph').classList.add('graphs');
|
||||
if ($_('ram-graph')) $_('ram-graph').classList.add('graphs');
|
||||
if ($_('disk-graph')) $_('disk-graph').classList.add('graphs');
|
||||
if ($_('network-graph')) $_('network-graph').classList.add('graphs');
|
||||
|
||||
break;
|
||||
|
||||
case 'Reinstall':
|
||||
window.location.reload();
|
||||
break;
|
||||
|
||||
case 'List backups':
|
||||
const backupTable = $_('backupTable').getElementsByTagName('tbody')[0];
|
||||
|
||||
delete data.result;
|
||||
$('#backupTable tbody').find('tr').remove();
|
||||
|
||||
for (let i = 0; i < Object.keys(data).length; i++) {
|
||||
const backup = data[Object.keys(data)[i]];
|
||||
|
||||
const row = backupTable.insertRow();
|
||||
const date = row.insertCell(0);
|
||||
const size = row.insertCell(1);
|
||||
const type = row.insertCell(2);
|
||||
const status = row.insertCell(3);
|
||||
const actions = row.insertCell(4);
|
||||
|
||||
date.innerHTML = new Date(backup.date).toLocaleString();
|
||||
size.innerHTML = (backup.size !== '' ? backup.size : '0.00GB');
|
||||
type.innerHTML = backup.type;
|
||||
|
||||
if (backup.status === 'ok') {
|
||||
status.innerHTML = '<div class="badge bg-success">Completed</div>';
|
||||
actions.innerHTML = '<a href="#" onclick="ArkHostVPS_API(\'Restore backup\', true, { file: ' + backup.file + ' });return false;"><i class="fas fa-history restore-icon text-secondary mr-2"></i></a> <a href="#" onclick="ArkHostVPS_API(\'Delete backup\', true, { file: ' + backup.file + ' });return false;"><i class="fas fa-1x fa-times delete" aria-hidden="true"></i></a>';
|
||||
} else if (backup.status === 'preparing') {
|
||||
status.innerHTML = '<div class="badge bg-info">Preparing</div>';
|
||||
} else if (backup.status === 'creating') {
|
||||
status.innerHTML = '<div class="badge bg-warning">Creating ' + backup.percentage + '%</div>';
|
||||
} else {
|
||||
status.innerHTML = '<div class="badge bg-danger">' + backup.status + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'Create backup':
|
||||
ArkHostVPS_API('List backups', false);
|
||||
break;
|
||||
|
||||
case 'Delete backup':
|
||||
ArkHostVPS_API('List backups', false);
|
||||
break;
|
||||
|
||||
case 'Get Firewall rules':
|
||||
const firewallTable = $_('firewallTable').getElementsByTagName('tbody')[0];
|
||||
|
||||
delete data.result;
|
||||
$('#firewallTable tbody').find('tr:not(:last)').remove();
|
||||
|
||||
for (let i = 0; i < Object.keys(data).length; i++) {
|
||||
const rule = data[Object.keys(data)[i]];
|
||||
|
||||
const row = firewallTable.insertRow(1);
|
||||
const action = row.insertCell(0);
|
||||
const port = row.insertCell(1);
|
||||
const protocol = row.insertCell(2);
|
||||
const source = row.insertCell(3);
|
||||
const note = row.insertCell(4);
|
||||
const actions = row.insertCell(5);
|
||||
|
||||
action.innerHTML = rule.action;
|
||||
port.innerHTML = rule.port;
|
||||
protocol.innerHTML = rule.protocol;
|
||||
source.innerHTML = rule.source;
|
||||
note.innerHTML = rule.note;
|
||||
actions.innerHTML = '<a href="#" onclick="ArkHostVPS_API(\'Delete Firewall rule\', true, { rule_id: ' + rule.id + ' });return false;"><i class="fas fa-1x fa-times delete" aria-hidden="true"></i></a>';
|
||||
}
|
||||
|
||||
$('#firewallTable tbody').append($('#firewallTable tbody tr:first'));
|
||||
|
||||
break;
|
||||
|
||||
case 'Add Firewall rules':
|
||||
ArkHostVPS_API('Get Firewall rules', false);
|
||||
break;
|
||||
|
||||
case 'Delete Firewall rule':
|
||||
ArkHostVPS_API('Get Firewall rules', false);
|
||||
break;
|
||||
|
||||
case 'Commit Firewall rules':
|
||||
ArkHostVPS_API('Get Firewall rules', false);
|
||||
break;
|
||||
|
||||
case 'ISO Images':
|
||||
const isoSelect = $_('isoID');
|
||||
|
||||
$('#isoID').empty();
|
||||
|
||||
for (let i = 0; i < data.iso.length; i++) {
|
||||
const iso = data.iso[i];
|
||||
const option = document.createElement('option');
|
||||
|
||||
option.value = iso.id;
|
||||
option.innerHTML = iso.iso_image;
|
||||
option.selected = (data.current_iso !== 0 && data.current_iso == iso.id);
|
||||
|
||||
isoSelect.appendChild(option);
|
||||
}
|
||||
}
|
||||
|
||||
ArkHostVPS_Loading(false);
|
||||
|
||||
if (alert) {
|
||||
ArkHostVPS_Alert('success', (typeof data.data === 'string' ? data.data : lang.moduleactionsuccess));
|
||||
}
|
||||
} else {
|
||||
ArkHostVPS_Loading(false);
|
||||
ArkHostVPS_Alert('error', (typeof data.message === 'string' ? data.message : lang.moduleactionfailed));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ArkHostVPS_VNC() {
|
||||
window.open(productURL + '&modop=custom&a=VNC', '_blank', 'toolbar=0,location=0,menubar=0');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function ArkHostVPS_Loading(status) {
|
||||
$_('loading').style.left = ((document.body.clientWidth - $('#loading').width()) / 2).toString() + 'px';
|
||||
|
||||
if (status) {
|
||||
$('#loading').show();
|
||||
} else {
|
||||
$('#loading').hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ArkHostVPS_ChooseOS(button) {
|
||||
var newOS = $_('newOS').value;
|
||||
|
||||
if (newOS !== '0') {
|
||||
newOS = $('[data-os="' + newOS + '"]')[0];
|
||||
newOS.classList.remove('SelectedOS');
|
||||
$_(newOS.dataset.group + '-os').classList.remove('selected');
|
||||
$_(newOS.dataset.group + '-version').innerText = 'CHOOSE VERSION';
|
||||
}
|
||||
|
||||
$_('newOS').value = button.dataset.os;
|
||||
button.classList.add('SelectedOS');
|
||||
$_(button.dataset.group + '-os').classList.add('selected');
|
||||
$_(button.dataset.group + '-version').innerText = button.innerText;
|
||||
}
|
||||
|
||||
function ArkHostVPS_ShowPassword() {
|
||||
let passwordField = $_('vpsPassword');
|
||||
let showPasswordIcon = $_('showPasswordIcon');
|
||||
|
||||
if (passwordField.type === 'password') {
|
||||
passwordField.type = 'text';
|
||||
showPasswordIcon.classList = 'fa-solid fa-eye-slash';
|
||||
} else {
|
||||
passwordField.type = 'password';
|
||||
showPasswordIcon.classList = 'fa-solid fa-eye';
|
||||
}
|
||||
}
|
||||
|
||||
function ArkHostVPS_Alert(type, message) {
|
||||
let Toast = Swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000
|
||||
});
|
||||
|
||||
Toast.fire({
|
||||
icon: type,
|
||||
title: message
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#pills-tab').scrollingTabs({
|
||||
enableSwiping: true,
|
||||
bootstrapVersion: 5,
|
||||
cssClassLeftArrow: 'fa-solid fa-chevron-left',
|
||||
cssClassRightArrow: 'fa-solid fa-chevron-right'
|
||||
});
|
||||
|
||||
|
||||
|
||||
function ArkHostVPS_UpdateStatitics() {
|
||||
if ($_('overview-tab').ariaSelected !== 'true') return timerServerLoads = setTimeout(ArkHostVPS_UpdateStatitics, 10000);
|
||||
|
||||
clearTimeout(timerServerLoads);
|
||||
|
||||
if (timerServerLoads) {
|
||||
$.get(productURL + '&modop=custom&a=ClientAreaAPI&api=Server Info',
|
||||
function(serverInfo) {
|
||||
if (serverInfo.result === 'success') {
|
||||
// Update CPU display: handle both decimal (0.0-1.0) and percentage (0-100) formats
|
||||
var cpuDisplay;
|
||||
if (serverInfo.cpu_usage <= 1) {
|
||||
// Decimal format (0.0-1.0), convert to percentage
|
||||
cpuDisplay = Math.round(serverInfo.cpu_usage * 100);
|
||||
} else {
|
||||
// Already percentage format (0-100)
|
||||
cpuDisplay = Math.ceil(serverInfo.cpu_usage);
|
||||
}
|
||||
$('.used-cpu').html(cpuDisplay + '%');
|
||||
} else {
|
||||
ArkHostVPS_Alert('error', (typeof serverInfo.message === 'string' ? serverInfo.message : lang.moduleactionfailed));
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
let serverInfo = serverInfoInitial;
|
||||
serverInfo.ram_usage = serverInfo.ram_usage / 1000000000;
|
||||
serverInfo.ram_usage_view = serverInfo.ram_usage.toFixed(2);
|
||||
serverInfo.ram_percent = (serverInfo.ram_usage / serverInfo.ram) * 100;
|
||||
serverInfo.ram_percent_view = serverInfo.ram_percent.toFixed(0);
|
||||
|
||||
serverInfo.bandwidth_used_view = (serverInfo.bandwidth_used / 1024).toFixed(2);
|
||||
serverInfo.bandwidth_percent = ((serverInfo.bandwidth_used / 1024) / serverInfo.bandwidth) * 100;
|
||||
serverInfo.bandwidth_percent_view = serverInfo.bandwidth_percent.toFixed(0);
|
||||
|
||||
// Disk usage not available from API, show total disk size instead
|
||||
serverInfo.disk_used_view = serverInfo.disk;
|
||||
serverInfo.disk_percent = 100;
|
||||
serverInfo.disk_percent_view = '100';
|
||||
|
||||
$_('ramPercentBar').style.width = serverInfo.ram_percent_view + '%';
|
||||
$_('ramPercentBar').innerHTML = serverInfo.ram_percent_view + '%';
|
||||
$_('ramPercentVal').innerHTML = serverInfo.ram_usage_view + ' / ' + serverInfo.ram + ' GB';
|
||||
|
||||
$_('bandwidthPercentBar').style.width = serverInfo.bandwidth_percent_view + '%';
|
||||
$_('bandwidthPercentBar').innerHTML = serverInfo.bandwidth_percent_view + '%';
|
||||
$_('bandwidthPercentVal').innerHTML = serverInfo.bandwidth_used_view + ' / ' + serverInfo.bandwidth + ' TB';
|
||||
|
||||
$_('diskPercentVal').innerHTML = serverInfo.disk + ' GB';
|
||||
|
||||
// Update CPU display: handle both decimal (0.0-1.0) and percentage (0-100) formats
|
||||
var cpuDisplay;
|
||||
if (serverInfo.cpu_usage <= 1) {
|
||||
// Decimal format (0.0-1.0), convert to percentage
|
||||
cpuDisplay = Math.round(serverInfo.cpu_usage * 100);
|
||||
} else {
|
||||
// Already percentage format (0-100)
|
||||
cpuDisplay = Math.ceil(serverInfo.cpu_usage);
|
||||
}
|
||||
$('.used-cpu').html(cpuDisplay + '%');
|
||||
}
|
||||
|
||||
timerServerLoads = setTimeout(ArkHostVPS_UpdateStatitics, 10000);
|
||||
}
|
||||
|
||||
$_('ArkHostVPS').style.display = 'block';
|
||||
ArkHostVPS_UpdateStatitics();
|
||||
});
|
||||
@@ -0,0 +1,295 @@
|
||||
|
||||
function $_(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function ArkHostVPS_API(action, alert = true, json = {}) {
|
||||
ArkHostVPS_Loading(true);
|
||||
|
||||
$.post(productURL + '&modop=custom&a=ClientAreaAPI&api=' + action, json,
|
||||
function(data) {
|
||||
if (data.result === 'success') {
|
||||
switch (action) {
|
||||
case 'IPv6':
|
||||
$_('ipv6').parentElement.innerHTML = data.data;
|
||||
data.data = 'IPv6 created: ' + data.data;
|
||||
|
||||
break;
|
||||
|
||||
case 'Graphs':
|
||||
// Hide loading indicator (if it exists)
|
||||
if ($_('graphs-loading')) $_('graphs-loading').style.display = 'none';
|
||||
if ($_('graphs-container')) $_('graphs-container').style.opacity = '1';
|
||||
|
||||
// Display graphs (they should be base64 images or img tags)
|
||||
if ($_('cpu-graph')) $_('cpu-graph').innerHTML = data.cpu_img ? data.cpu_img : '<p class="text-muted">No CPU graph available</p>';
|
||||
if ($_('ram-graph')) $_('ram-graph').innerHTML = data.mem_img ? data.mem_img : '<p class="text-muted">No RAM graph available</p>';
|
||||
if ($_('disk-graph')) $_('disk-graph').innerHTML = data.disk_img ? data.disk_img : '<p class="text-muted">No Disk graph available</p>';
|
||||
if ($_('network-graph')) $_('network-graph').innerHTML = data.net_img ? data.net_img : '<p class="text-muted">No Network graph available</p>';
|
||||
|
||||
// Add graphs class for styling
|
||||
if ($_('cpu-graph')) $_('cpu-graph').classList.add('graphs');
|
||||
if ($_('ram-graph')) $_('ram-graph').classList.add('graphs');
|
||||
if ($_('disk-graph')) $_('disk-graph').classList.add('graphs');
|
||||
if ($_('network-graph')) $_('network-graph').classList.add('graphs');
|
||||
|
||||
break;
|
||||
|
||||
case 'Reinstall':
|
||||
window.location.reload();
|
||||
break;
|
||||
|
||||
case 'List backups':
|
||||
const backupTable = $_('backupTable').getElementsByTagName('tbody')[0];
|
||||
|
||||
delete data.result;
|
||||
$('#backupTable tbody').find('tr').remove();
|
||||
|
||||
for (let i = 0; i < Object.keys(data).length; i++) {
|
||||
const backup = data[Object.keys(data)[i]];
|
||||
|
||||
const row = backupTable.insertRow();
|
||||
const date = row.insertCell(0);
|
||||
const size = row.insertCell(1);
|
||||
const type = row.insertCell(2);
|
||||
const status = row.insertCell(3);
|
||||
const actions = row.insertCell(4);
|
||||
|
||||
date.innerHTML = new Date(backup.date).toLocaleString();
|
||||
size.innerHTML = (backup.size !== '' ? backup.size : '0.00GB');
|
||||
type.innerHTML = backup.type;
|
||||
|
||||
if (backup.status === 'ok') {
|
||||
status.innerHTML = '<div class="badge bg-success">Completed</div>';
|
||||
actions.innerHTML = '<a href="#" onclick="ArkHostVPS_API(\'Restore backup\', true, { file: ' + backup.file + ' });return false;"><i class="fas fa-history restore-icon text-secondary mr-2"></i></a> <a href="#" onclick="ArkHostVPS_API(\'Delete backup\', true, { file: ' + backup.file + ' });return false;"><i class="fas fa-1x fa-times delete" aria-hidden="true"></i></a>';
|
||||
} else if (backup.status === 'preparing') {
|
||||
status.innerHTML = '<div class="badge bg-info">Preparing</div>';
|
||||
} else if (backup.status === 'creating') {
|
||||
status.innerHTML = '<div class="badge bg-warning">Creating ' + backup.percentage + '%</div>';
|
||||
} else {
|
||||
status.innerHTML = '<div class="badge bg-danger">' + backup.status + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'Create backup':
|
||||
ArkHostVPS_API('List backups', false);
|
||||
break;
|
||||
|
||||
case 'Delete backup':
|
||||
ArkHostVPS_API('List backups', false);
|
||||
break;
|
||||
|
||||
case 'Get Firewall rules':
|
||||
const firewallTable = $_('firewallTable').getElementsByTagName('tbody')[0];
|
||||
|
||||
delete data.result;
|
||||
$('#firewallTable tbody').find('tr:not(:last)').remove();
|
||||
|
||||
for (let i = 0; i < Object.keys(data).length; i++) {
|
||||
const rule = data[Object.keys(data)[i]];
|
||||
|
||||
const row = firewallTable.insertRow(1);
|
||||
const action = row.insertCell(0);
|
||||
const port = row.insertCell(1);
|
||||
const protocol = row.insertCell(2);
|
||||
const source = row.insertCell(3);
|
||||
const note = row.insertCell(4);
|
||||
const actions = row.insertCell(5);
|
||||
|
||||
action.innerHTML = rule.action;
|
||||
port.innerHTML = rule.port;
|
||||
protocol.innerHTML = rule.protocol;
|
||||
source.innerHTML = rule.source;
|
||||
note.innerHTML = rule.note;
|
||||
actions.innerHTML = '<a href="#" onclick="ArkHostVPS_API(\'Delete Firewall rule\', true, { rule_id: ' + rule.id + ' });return false;"><i class="fas fa-1x fa-times delete" aria-hidden="true"></i></a>';
|
||||
}
|
||||
|
||||
$('#firewallTable tbody').append($('#firewallTable tbody tr:first'));
|
||||
|
||||
break;
|
||||
|
||||
case 'Add Firewall rules':
|
||||
ArkHostVPS_API('Get Firewall rules', false);
|
||||
break;
|
||||
|
||||
case 'Delete Firewall rule':
|
||||
ArkHostVPS_API('Get Firewall rules', false);
|
||||
break;
|
||||
|
||||
case 'Commit Firewall rules':
|
||||
ArkHostVPS_API('Get Firewall rules', false);
|
||||
break;
|
||||
|
||||
case 'ISO Images':
|
||||
const isoSelect = $_('isoID');
|
||||
|
||||
$('#isoID').empty();
|
||||
|
||||
for (let i = 0; i < data.iso.length; i++) {
|
||||
const iso = data.iso[i];
|
||||
const option = document.createElement('option');
|
||||
|
||||
option.value = iso.id;
|
||||
option.innerHTML = iso.iso_image;
|
||||
option.selected = (data.current_iso !== 0 && data.current_iso == iso.id);
|
||||
|
||||
isoSelect.appendChild(option);
|
||||
}
|
||||
}
|
||||
|
||||
ArkHostVPS_Loading(false);
|
||||
|
||||
if (alert) {
|
||||
ArkHostVPS_Alert('success', (typeof data.data === 'string' ? data.data : lang.moduleactionsuccess));
|
||||
}
|
||||
} else {
|
||||
ArkHostVPS_Loading(false);
|
||||
ArkHostVPS_Alert('error', (typeof data.message === 'string' ? data.message : lang.moduleactionfailed));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ArkHostVPS_VNC() {
|
||||
window.open(productURL + '&modop=custom&a=VNC', '_blank', 'toolbar=0,location=0,menubar=0');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function ArkHostVPS_Loading(status) {
|
||||
$_('loading').style.left = ((document.body.clientWidth - $('#loading').width()) / 2).toString() + 'px';
|
||||
|
||||
if (status) {
|
||||
$('#loading').show();
|
||||
} else {
|
||||
$('#loading').hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ArkHostVPS_ChooseOS(button) {
|
||||
var newOS = $_('newOS').value;
|
||||
|
||||
if (newOS !== '0') {
|
||||
newOS = $('[data-os="' + newOS + '"]')[0];
|
||||
newOS.classList.remove('SelectedOS');
|
||||
$_(newOS.dataset.group + '-os').classList.remove('selected');
|
||||
$_(newOS.dataset.group + '-version').innerText = 'CHOOSE VERSION';
|
||||
}
|
||||
|
||||
$_('newOS').value = button.dataset.os;
|
||||
button.classList.add('SelectedOS');
|
||||
$_(button.dataset.group + '-os').classList.add('selected');
|
||||
$_(button.dataset.group + '-version').innerText = button.innerText;
|
||||
}
|
||||
|
||||
function ArkHostVPS_ShowPassword() {
|
||||
let passwordField = $_('vpsPassword');
|
||||
let showPasswordIcon = $_('showPasswordIcon');
|
||||
|
||||
if (passwordField.type === 'password') {
|
||||
passwordField.type = 'text';
|
||||
showPasswordIcon.classList = 'fa-solid fa-eye-slash';
|
||||
} else {
|
||||
passwordField.type = 'password';
|
||||
showPasswordIcon.classList = 'fa-solid fa-eye';
|
||||
}
|
||||
}
|
||||
|
||||
function ArkHostVPS_Alert(type, message) {
|
||||
let Toast = Swal.mixin({
|
||||
toast: true,
|
||||
position: 'top-end',
|
||||
showConfirmButton: false,
|
||||
timer: 3000
|
||||
});
|
||||
|
||||
Toast.fire({
|
||||
icon: type,
|
||||
title: message
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#pills-tab').scrollingTabs({
|
||||
enableSwiping: true,
|
||||
bootstrapVersion: 5,
|
||||
cssClassLeftArrow: 'fa-solid fa-chevron-left',
|
||||
cssClassRightArrow: 'fa-solid fa-chevron-right'
|
||||
});
|
||||
|
||||
|
||||
|
||||
function ArkHostVPS_UpdateStatitics() {
|
||||
if ($_('overview-tab').ariaSelected !== 'true') return timerServerLoads = setTimeout(ArkHostVPS_UpdateStatitics, 10000);
|
||||
|
||||
clearTimeout(timerServerLoads);
|
||||
|
||||
if (timerServerLoads) {
|
||||
$.get(productURL + '&modop=custom&a=ClientAreaAPI&api=Server Info',
|
||||
function(serverInfo) {
|
||||
if (serverInfo.result === 'success') {
|
||||
// Update CPU display: handle both decimal (0.0-1.0) and percentage (0-100) formats
|
||||
var cpuDisplay;
|
||||
if (serverInfo.cpu_usage <= 1) {
|
||||
// Decimal format (0.0-1.0), convert to percentage
|
||||
cpuDisplay = Math.round(serverInfo.cpu_usage * 100);
|
||||
} else {
|
||||
// Already percentage format (0-100)
|
||||
cpuDisplay = Math.ceil(serverInfo.cpu_usage);
|
||||
}
|
||||
$('.used-cpu').html(cpuDisplay + '%');
|
||||
} else {
|
||||
ArkHostVPS_Alert('error', (typeof serverInfo.message === 'string' ? serverInfo.message : lang.moduleactionfailed));
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
let serverInfo = serverInfoInitial;
|
||||
serverInfo.ram_usage = serverInfo.ram_usage / 1000000000;
|
||||
serverInfo.ram_usage_view = serverInfo.ram_usage.toFixed(2);
|
||||
serverInfo.ram_percent = (serverInfo.ram_usage / serverInfo.ram) * 100;
|
||||
serverInfo.ram_percent_view = serverInfo.ram_percent.toFixed(0);
|
||||
|
||||
serverInfo.bandwidth_used_view = (serverInfo.bandwidth_used / 1024).toFixed(2);
|
||||
serverInfo.bandwidth_percent = ((serverInfo.bandwidth_used / 1024) / serverInfo.bandwidth) * 100;
|
||||
serverInfo.bandwidth_percent_view = serverInfo.bandwidth_percent.toFixed(0);
|
||||
|
||||
// Disk usage not available from API, show total disk size instead
|
||||
serverInfo.disk_used_view = serverInfo.disk;
|
||||
serverInfo.disk_percent = 100;
|
||||
serverInfo.disk_percent_view = '100';
|
||||
|
||||
$_('ramPercentBar').style.width = serverInfo.ram_percent_view + '%';
|
||||
$_('ramPercentBar').innerHTML = serverInfo.ram_percent_view + '%';
|
||||
$_('ramPercentVal').innerHTML = serverInfo.ram_usage_view + ' / ' + serverInfo.ram + ' GB';
|
||||
|
||||
$_('bandwidthPercentBar').style.width = serverInfo.bandwidth_percent_view + '%';
|
||||
$_('bandwidthPercentBar').innerHTML = serverInfo.bandwidth_percent_view + '%';
|
||||
$_('bandwidthPercentVal').innerHTML = serverInfo.bandwidth_used_view + ' / ' + serverInfo.bandwidth + ' TB';
|
||||
|
||||
$_('diskPercentVal').innerHTML = serverInfo.disk + ' GB';
|
||||
|
||||
// Update CPU display: handle both decimal (0.0-1.0) and percentage (0-100) formats
|
||||
var cpuDisplay;
|
||||
if (serverInfo.cpu_usage <= 1) {
|
||||
// Decimal format (0.0-1.0), convert to percentage
|
||||
cpuDisplay = Math.round(serverInfo.cpu_usage * 100);
|
||||
} else {
|
||||
// Already percentage format (0-100)
|
||||
cpuDisplay = Math.ceil(serverInfo.cpu_usage);
|
||||
}
|
||||
$('.used-cpu').html(cpuDisplay + '%');
|
||||
}
|
||||
|
||||
timerServerLoads = setTimeout(ArkHostVPS_UpdateStatitics, 10000);
|
||||
}
|
||||
|
||||
$_('ArkHostVPS').style.display = 'block';
|
||||
ArkHostVPS_UpdateStatitics();
|
||||
});
|
||||