forked from circlecloud/tera
sync: sync upstream code
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
c666069889
commit
eeb045687c
@ -1,4 +1,21 @@
|
|||||||
/*@import url('https://fonts.googleapis.com/css?family=Roboto:400,500,700&subset=cyrillic');*/
|
/*@import url('https://fonts.googleapis.com/css?family=Roboto:400,500,700&subset=cyrillic');*/
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v19/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v19/KFOmCnqEu92Fr1Mu5mxKKTU1Kvnz.woff2) format('woff2');
|
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--blue-grey: #445368;
|
--blue-grey: #445368;
|
||||||
@ -1104,7 +1121,7 @@ textarea {
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
.dapp-modal {
|
.dapp-modal {
|
||||||
top: calc(50% - 210px);
|
top: calc(50% - 160px);
|
||||||
left: 20px;
|
left: 20px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
transform: none;
|
transform: none;
|
||||||
@ -1272,7 +1289,7 @@ textarea {
|
|||||||
transform: rotate(-45deg);
|
transform: rotate(-45deg);
|
||||||
}
|
}
|
||||||
.modal__btns-wrap .btn {
|
.modal__btns-wrap .btn {
|
||||||
margin: 0 15px;
|
margin: 0 5px;
|
||||||
padding: 14px 10px;
|
padding: 14px 10px;
|
||||||
min-width: 125px;
|
min-width: 125px;
|
||||||
}
|
}
|
||||||
@ -2774,10 +2791,22 @@ iframe
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
.btn--float
|
.btn--setdapp
|
||||||
{
|
{
|
||||||
float: left;
|
float: left;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
.dapp_desc
|
||||||
|
{
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px)
|
||||||
|
{
|
||||||
|
.btn--setdapp
|
||||||
|
{
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -959,7 +959,7 @@ function RetOpenDapps(Item,bNum,AccountNum)
|
|||||||
if(Item.HTMLLength > 0)
|
if(Item.HTMLLength > 0)
|
||||||
{
|
{
|
||||||
var StrText = RetIconDapp(Item) + Name;
|
var StrText = RetIconDapp(Item) + Name;
|
||||||
return '<button type="button" class="bt_open_dapp" style="margin: -2px 0 0 0" onclick="OpenDapps(' + Item.Num + ',' + AccountNum + ')">' + StrText + '</button>';
|
return '<button type="button" class="bt_open_dapp" style="margin: -2px 0 0 0" onclick="OpenDapps(' + Item.Num + ',' + AccountNum + ',1)">' + StrText + '</button>';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return RetIconDapp(Item) + Name;
|
return RetIconDapp(Item) + Name;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Telegram: https://t.me/terafoundation
|
* Telegram: https://t.me/terafoundation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var WEB_WALLET_VERSION = "0.04";
|
var WEB_WALLET_VERSION = "0.05";
|
||||||
var SaveIdArr = ["idAccount", "idTo", "idSumSend", "idDescription", "idCurTabName", "idViewBlockNum", "idViewAccountNum", "idViewDappNum",
|
var SaveIdArr = ["idAccount", "idTo", "idSumSend", "idDescription", "idCurTabName", "idViewBlockNum", "idViewAccountNum", "idViewDappNum",
|
||||||
"idLang"];
|
"idLang"];
|
||||||
var CONFIG_DATA = {PRICE_DAO:{NewAccount:10}, MaxNumBlockDB:0, MaxAccID:0, MaxDappsID:0};
|
var CONFIG_DATA = {PRICE_DAO:{NewAccount:10}, MaxNumBlockDB:0, MaxAccID:0, MaxDappsID:0};
|
||||||
@ -1265,27 +1265,27 @@ var LangMap = {};
|
|||||||
LangMap["ENG"] = {};
|
LangMap["ENG"] = {};
|
||||||
LangMap["RUS"] = {"TERA WALLET":"TERA КОШЕЛЕК", "Generate key":"Сгенерировать ключ", "OK":"OK", "Cancel":"Отмена", "Edit":"Редактирование",
|
LangMap["RUS"] = {"TERA WALLET":"TERA КОШЕЛЕК", "Generate key":"Сгенерировать ключ", "OK":"OK", "Cancel":"Отмена", "Edit":"Редактирование",
|
||||||
"Save key":"Сохран.", "+ CREATE A NEW ACCOUNT":"+ СОЗДАТЬ НОВЫЙ СЧЕТ", "Create account":"Создать счет", "Send":"Отправить",
|
"Save key":"Сохран.", "+ CREATE A NEW ACCOUNT":"+ СОЗДАТЬ НОВЫЙ СЧЕТ", "Create account":"Создать счет", "Send":"Отправить",
|
||||||
"CONFIRM":"Подтверждение", "Accounts":"Счета", "Account(s)":"Счет(а,ов)", "Blocks and Tx":"Блоки и Транзакции", "Counters":"Показатели",
|
"CONFIRM":"Подтвердить", "Accounts":"Счета", "Account(s)":"Счет(а,ов)", "Blocks and Tx":"Блоки и Транзакции", "Counters":"Показатели",
|
||||||
"Open DApp":"Открыть Дапп", "Back":"Назад", "Delete":"Удалить", "Save to book":"Сохранить в книгу", "Choose":"Выбрать", "RECONNECT":"КОННЕКТ",
|
"Open DApp":"Открыть", "Back":"Назад", "Delete":"Удалить", "Save to book":"Сохранить в книгу", "Choose":"Выбрать", "RECONNECT":"КОННЕКТ",
|
||||||
"DApps":"DApps", "ID":"ИД", "Amount":"Величина", "Cur":"Вал", "Name":"Имя", "PubKey":"Пуб.ключ", "Operation":"Операция", "Smart":"Смарт",
|
"DApps":"DApps", "ID":"ИД", "Amount":"Величина", "Cur":"Вал", "Name":"Имя", "PubKey":"Пуб.ключ", "Operation":"Операция", "Smart":"Смарт",
|
||||||
"Block Num":"Ном блока", "Num":"Ном", "Date":"Дата", "Data Hash":"Хеш данных", "PowHash":"Хеш сложности", "Block Hash":"Хеш блока",
|
"Block Num":"Ном блока", "Num":"Ном", "Date":"Дата", "Data Hash":"Хеш данных", "PowHash":"Хеш сложности", "Block Hash":"Хеш блока",
|
||||||
"Bytes":"Байт", "Pow":"Сложн", "Miner":"Майнер", "(secret)":"(секрет)", "Show":"Показать", "TERA":"TERA", "Blockchain height:":"Высота блокчейна:",
|
"Bytes":"Байт", "Pow":"Сложн", "Miner":"Майнер", "(secret)":"(секрет)", "Show":"Показать", "TERA":"TERA", "Blockchain height:":"Высота блокчейна:",
|
||||||
"Current create:":"Текущий блок:", "Protocol ver:":"Версия протокола:", "ID: $Item.Num":"ИД: $Item.Num", "Token generate":"Генерация токенов",
|
"Current create:":"Текущий блок:", "Protocol ver:":"Версия протокола:", "ID: $Item.Num":"ИД: $Item.Num", "Token generate":"Генерация токенов",
|
||||||
"ACCOUNTS":"СЧЕТА", "SEND":"ОТПРАВИТЬ", "DAPPS":"ДАППС", "EXPLORER":"ПРОСМ", "ATTENTION: Before using the wallet, save the private key.":"ВНИМАНИЕ: Перед использованием кошелька сохраните приватный ключ",
|
"ACCOUNTS":"СЧЕТА", "SEND":"ОТПРАВИТЬ", "DAPPS":"ДАППС", "EXPLORER":"ПРОСМ", "ATTENTION: Before using the wallet, save the private key.":"ВНИМАНИЕ: Перед использованием кошелька сохраните приватный ключ",
|
||||||
"Web-site":"Веб-сайт", "Bitcointalk":"Bitcointalk", "Twitter":"Твиттер", "Telegram":"Телеграм", "Discord":"Дискорд", "QQchat":"QQchat",
|
"Web-site":"Веб-сайт", "Bitcointalk":"Bitcointalk", "Twitter":"Твиттер", "Telegram":"Телеграм", "Discord":"Дискорд", "QQchat":"QQchat",
|
||||||
"Buy/sell/mine TERA":"Купить/Продать", "+ CREATE NEW":"+ СОЗДАТЬ", "Confirm Transaction":"Подтверждение транзакции", "CREATE DAPPS":"СОЗДАТЬ",
|
"Buy/sell/mine TERA":"Купить/продать/майнить", "+ CREATE NEW":"+ СОЗДАТЬ", "Confirm Transaction":"Подтверждение транзакции",
|
||||||
"Set pass":"Установить пароль", "Unlock":"Разблокировать", "Entrance to sub-wallet":"Войти в под-кошелек", "Public name":"Публичное имя",
|
"CREATE DAPPS":"СОЗДАТЬ", "Set pass":"Установить пароль", "Unlock":"Разблокировать", "Entrance to sub-wallet":"Войти в под-кошелек",
|
||||||
"Currency":"Валюта", "Pay to:":"Получатель:", "Amount:":"Сумма:", "Description:":"Описание:", "Welcome to TERA Wallet":"Добро пожаловать в кошелек TERA",
|
"Public name":"Публичное имя", "Currency":"Валюта", "Pay to:":"Получатель:", "Amount:":"Сумма:", "Description:":"Описание:",
|
||||||
"Edit your wallet":"Редактирование вашего кошелька", "Key settings":"Задание ключей", "KEY SETTINGS":"КЛЮЧИ", "Create an account":"Создание счета",
|
"Welcome to TERA Wallet":"Добро пожаловать в кошелек TERA", "Edit your wallet":"Редактирование вашего кошелька", "Key settings":"Задание ключей",
|
||||||
"Sending coins":"Отправка монет", "Decentralized applications (dApps)":"Децентрализованные приложения (DApps)", "Secure your wallet":"Безопасность вашего кошелька",
|
"KEY SETTINGS":"КЛЮЧИ", "Create an account":"Создание счета", "Sending coins":"Отправка монет", "Decentralized applications (dApps)":"Децентрализованные приложения (DApps)",
|
||||||
"Wallet is secured":"Установлен пароль", "Total":"Всего", "Item.Name":"Item.Name", "You have no accounts yet":"У вас нет ни одного счета",
|
"Secure your wallet":"Безопасность вашего кошелька", "Wallet is secured":"Установлен пароль", "Total":"Всего", "Item.Name":"Item.Name",
|
||||||
"Wait 10-15 sec":"Ждите 10-15 сек", "Creating your account":"Идет создание вашего счета", "From:":"Отправитель:", "Set a password for protect entry":"Установите пароль для безопасности",
|
"You have no accounts yet":"У вас нет ни одного счета", "Wait 10-15 sec":"Ждите 10-15 сек", "Creating your account":"Идет создание вашего счета",
|
||||||
"Enter password to unlock wallet":"Введите пароль для разблокировки кошелька", "From ID:":"Отправитель:", "Pay to ID:":"Получатель:",
|
"From:":"Отправитель:", "Set a password for protect entry":"Установите пароль для безопасности", "Enter password to unlock wallet":"Введите пароль для разблокировки кошелька",
|
||||||
"Account":"Счет", "Owner":"Владелец", "Block num":"Ном блока", "Private key (secret)":"Приватный ключ (секретно)", "Load key":"Загруз.",
|
"From ID:":"Отправитель:", "Pay to ID:":"Получатель:", "Account":"Счет", "Owner":"Владелец", "Block num":"Ном блока", "Private key (secret)":"Приватный ключ (секретно)",
|
||||||
"Create your first account and start using TERA":"Создайте свой первый счет и начните использовать TERA", "0 Accounts":"0 Счетов",
|
"Load key":"Загруз.", "Create your first account and start using TERA":"Создайте свой первый счет и начните использовать TERA",
|
||||||
"OWNER: {Item.Owner}":"Владелец: {Item.Owner}", "More info":"Информация", "Public key":"Публичный ключ", "Enter number of dapp":"Введите номер Даппа",
|
"0 Accounts":"0 Счетов", "OWNER: {Item.Owner}":"Владелец: {Item.Owner}", "More info":"Инфо", "Public key":"Публичный ключ",
|
||||||
"Enter the dapps number that will be added to your account. Attention make sure that you trust this dapp, otherwise you may lose all funds in this account.":"Введите номер Даппа, который будет добавлен в ваш аккаунт. Внимание убедитесь, что Вы доверяете ему, в противном случае вы можете потерять все средства на этом счете.",
|
"Enter number of dapp":"Введите номер Dapp", "Enter the dapps number that will be added to your account. Attention make sure that you trust this dapp, otherwise you may lose all funds in this account.":"Введите номер Dapp, который будет добавлен в ваш аккаунт. Внимание убедитесь, что Вы доверяете ему, в противном случае вы можете потерять все средства на этом счете.",
|
||||||
"Sending Tx":"Отправка транзакции", };
|
"Sending Tx":"Отправка транзакции", "Wallet ver:":"Версия:", };
|
||||||
LangMap["简体中文"] = {"TERA WALLET":"TERA 钱包", "Generate key":"生成私钥", "OK":"OK", "Cancel":"取消", "Edit":"编辑", "Save key":"保存私钥",
|
LangMap["简体中文"] = {"TERA WALLET":"TERA 钱包", "Generate key":"生成私钥", "OK":"OK", "Cancel":"取消", "Edit":"编辑", "Save key":"保存私钥",
|
||||||
"+ CREATE A NEW ACCOUNT":"+ 新建账号", "Create account":"创建账号", "Send":"发送", "SEND":"转账", "CONFIRM":"确认", "Accounts":"账号", "Account(s)":"账号",
|
"+ CREATE A NEW ACCOUNT":"+ 新建账号", "Create account":"创建账号", "Send":"发送", "SEND":"转账", "CONFIRM":"确认", "Accounts":"账号", "Account(s)":"账号",
|
||||||
"Blocks and Tx":"区块和交易", "Counters":"状态统计", "Open DApp":"打开DApp", "Back":"返回", "Delete":"删除", "Save to book":"保存到地址本", "Choose":"选择",
|
"Blocks and Tx":"区块和交易", "Counters":"状态统计", "Open DApp":"打开DApp", "Back":"返回", "Delete":"删除", "Save to book":"保存到地址本", "Choose":"选择",
|
||||||
|
@ -510,11 +510,11 @@
|
|||||||
<div class="modal__title-wrap">
|
<div class="modal__title-wrap">
|
||||||
<span class="light-grey-text">ID: $Item.Num</span>
|
<span class="light-grey-text">ID: $Item.Num</span>
|
||||||
<h3>$Item.Name</h3>
|
<h3>$Item.Name</h3>
|
||||||
<ol class="modal__ol">
|
<ul class="modal__ol">
|
||||||
<li class="modal__category dappcategory1">$Item.Category1</li>
|
<li class="modal__category dappcategory1">$Item.Category1</li>
|
||||||
<li class="modal__category dappcategory2">$Item.Category2</li>
|
<li class="modal__category dappcategory2">$Item.Category2</li>
|
||||||
<li class="modal__category dappcategory3">$Item.Category3</li>
|
<li class="modal__category dappcategory3">$Item.Category3</li>
|
||||||
</ol>
|
</ul>
|
||||||
<p class="dapp-modal__token-status dapp-modal__token-status--ok">
|
<p class="dapp-modal__token-status dapp-modal__token-status--ok">
|
||||||
<!--<span class="light-grey-text">Without token generate</span>-->
|
<!--<span class="light-grey-text">Without token generate</span>-->
|
||||||
<span class="dapp-modal__ok-token">Token generate</span>
|
<span class="dapp-modal__ok-token">Token generate</span>
|
||||||
@ -524,7 +524,7 @@
|
|||||||
<img $item.iconpath alt="dApp logo" width="32">
|
<img $item.iconpath alt="dApp logo" width="32">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>$Item.Description</p>
|
<p class="dapp_desc">$Item.Description</p>
|
||||||
<dl class="modal__def-list def-list">
|
<dl class="modal__def-list def-list">
|
||||||
<div class="def-list__item">
|
<div class="def-list__item">
|
||||||
<dt>Account</dt>
|
<dt>Account</dt>
|
||||||
@ -628,13 +628,14 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<section class="modal dapp-modal" id="idSmartEnter" style="display: none; margin-top: 20px; padding: 20px">
|
<section class="modal dapp-modal" id="idSmartEnter" style="display: none; margin-top: -10px; padding: 20px">
|
||||||
<h2 class="password-modal__title"><span>Enter number of dapp</span></h2>
|
<h2 class="password-modal__title"><span>Enter number of dapp</span></h2>
|
||||||
<p class="password-modal__subtitle">Enter the dapps number that will be added to your account. Attention make sure that you trust this dapp, otherwise you may lose all funds in this account.</p>
|
<p class="password-modal__subtitle">Enter the dapps number that will be added to your account. Attention make sure that you trust this dapp, otherwise you may lose all funds in this account.</p>
|
||||||
|
<DIV align='center'>
|
||||||
<input type="number" class="password-modal__input" placeholder="Dapp number" id="idSmartNum">
|
<input type="number" class="password-modal__input" placeholder="" id="idSmartNum">
|
||||||
<a class="btn btn--270 btn--float" onclick="DoSetSmartLocal()">OK</a>
|
<a class="btn btn--270 btn--setdapp" onclick="DoSetSmartLocal()">OK</a>
|
||||||
<a class="btn btn--270 btn--float btn--white" onclick="closeModal()">Cancel</a>
|
<a class="btn btn--270 btn--setdapp btn--white" onclick="closeModal()">Cancel</a>
|
||||||
|
</DIV>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ global.CONST_NAME_ARR = [
|
|||||||
"RESTART_PERIOD_SEC",
|
"RESTART_PERIOD_SEC",
|
||||||
"MAX_GRAY_CONNECTIONS_TO_SERVER",
|
"MAX_GRAY_CONNECTIONS_TO_SERVER",
|
||||||
"TRANSACTION_PROOF_COUNT",
|
"TRANSACTION_PROOF_COUNT",
|
||||||
"UPDATE_NUM_COMPLETE",
|
|
||||||
"LIMIT_SEND_TRAFIC",
|
"LIMIT_SEND_TRAFIC",
|
||||||
"WATCHDOG_DEV",
|
"WATCHDOG_DEV",
|
||||||
"ADDRLIST_MODE",
|
"ADDRLIST_MODE",
|
||||||
@ -78,7 +77,7 @@ global.WATCHDOG_BADACCOUNT = 1;
|
|||||||
global.WATCHDOG_DEV = 0;
|
global.WATCHDOG_DEV = 0;
|
||||||
global.RESYNC_CONDITION = { "OWN_BLOCKS": 20, "K_POW": 5 };
|
global.RESYNC_CONDITION = { "OWN_BLOCKS": 20, "K_POW": 5 };
|
||||||
global.REST_BLOCK_SCALE = 1000;
|
global.REST_BLOCK_SCALE = 1000;
|
||||||
global.REST_START_COUNT = 1000;
|
global.REST_START_COUNT = 10000;
|
||||||
global.LOAD_TO_BEGIN = 2;
|
global.LOAD_TO_BEGIN = 2;
|
||||||
global.DEBUG_WALLET = 0;
|
global.DEBUG_WALLET = 0;
|
||||||
global.CHECK_GLOBAL_TIME = 1;
|
global.CHECK_GLOBAL_TIME = 1;
|
||||||
@ -91,7 +90,6 @@ global.USE_NET_FOR_SERVER_ADDRES = 1;
|
|||||||
global.NET_WORK_MODE = undefined;
|
global.NET_WORK_MODE = undefined;
|
||||||
global.STAT_MODE = 0;
|
global.STAT_MODE = 0;
|
||||||
global.MAX_STAT_PERIOD = 1 * 3600;
|
global.MAX_STAT_PERIOD = 1 * 3600;
|
||||||
global.UPDATE_NUM_COMPLETE = 0;
|
|
||||||
global.WALLET_NAME = "TERA";
|
global.WALLET_NAME = "TERA";
|
||||||
global.WALLET_DESCRIPTION = "";
|
global.WALLET_DESCRIPTION = "";
|
||||||
global.USE_MINING = 0;
|
global.USE_MINING = 0;
|
||||||
|
@ -35,14 +35,13 @@ ContenTypeMap["html"] = "text/html";
|
|||||||
ContenTypeMap["txt"] = "text/plain";
|
ContenTypeMap["txt"] = "text/plain";
|
||||||
ContenTypeMap["csv"] = "text/csv";
|
ContenTypeMap["csv"] = "text/csv";
|
||||||
ContenTypeMap["svg"] = "image/svg+xml";
|
ContenTypeMap["svg"] = "image/svg+xml";
|
||||||
ContenTypeMap[""] = "application/octet-stream";
|
|
||||||
ContenTypeMap["zip"] = "application/zip";
|
ContenTypeMap["zip"] = "application/zip";
|
||||||
ContenTypeMap["pdf"] = "application/pdf";
|
ContenTypeMap["pdf"] = "application/pdf";
|
||||||
ContenTypeMap["exe"] = "application/octet-stream";
|
ContenTypeMap["exe"] = "application/octet-stream";
|
||||||
ContenTypeMap["msi"] = "application/octet-stream";
|
ContenTypeMap["msi"] = "application/octet-stream";
|
||||||
ContenTypeMap["woff"] = "application/font-woff";
|
ContenTypeMap["woff"] = "application/font-woff";
|
||||||
ContenTypeMap["html"] = "text/html";
|
|
||||||
ContenTypeMap["psd"] = "application/octet-stream";
|
ContenTypeMap["psd"] = "application/octet-stream";
|
||||||
|
var DefaultContentType = "application/octet-stream";
|
||||||
global.HTTPCaller = {};
|
global.HTTPCaller = {};
|
||||||
|
|
||||||
function DoCommand(response, Type, Path, params, remoteAddress) {
|
function DoCommand(response, Type, Path, params, remoteAddress) {
|
||||||
@ -1355,8 +1354,8 @@ var MapFileHTML5 = {};
|
|||||||
|
|
||||||
function SendWebFile(response, name?, StrCookie?, bParsing?) {
|
function SendWebFile(response, name?, StrCookie?, bParsing?) {
|
||||||
var type = name.substr(name.length - 4, 4);
|
var type = name.substr(name.length - 4, 4);
|
||||||
if (type.substr(0, 1) === ".")
|
var index1 = type.indexOf(".");
|
||||||
type = type.substr(1);
|
type = type.substr(index1 + 1);
|
||||||
var Path;
|
var Path;
|
||||||
if (name.substr(0, 2) !== "./")
|
if (name.substr(0, 2) !== "./")
|
||||||
Path = "./" + name;
|
Path = "./" + name;
|
||||||
@ -1373,7 +1372,9 @@ function SendWebFile(response, name?, StrCookie?, bParsing?) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var StrContentType = ContenTypeMap[type];
|
var StrContentType = ContenTypeMap[type];
|
||||||
if (!StrContentType || StrContentType === "text/html") {
|
if (!StrContentType)
|
||||||
|
StrContentType = DefaultContentType;
|
||||||
|
if (StrContentType === "text/html") {
|
||||||
var Headers = { 'Content-Type': 'text/html', "X-Frame-Options": "sameorigin" };
|
var Headers = { 'Content-Type': 'text/html', "X-Frame-Options": "sameorigin" };
|
||||||
if (StrCookie)
|
if (StrCookie)
|
||||||
Headers['Set-Cookie'] = StrCookie;
|
Headers['Set-Cookie'] = StrCookie;
|
||||||
@ -1566,8 +1567,10 @@ function SetSafeResponce(response) {
|
|||||||
response._writeHead = response.writeHead;
|
response._writeHead = response.writeHead;
|
||||||
response.end = function() {
|
response.end = function() {
|
||||||
try {
|
try {
|
||||||
if (arguments && arguments[0] && arguments[0].length) {
|
if (global.STAT_MODE === 2 && arguments && arguments[0] && arguments[0].length) {
|
||||||
global.ADD_TO_STAT("HTTP_SEND", arguments[0].length);
|
global.ADD_TO_STAT("HTTP_SEND", arguments[0].length);
|
||||||
|
if (response.DetailStatName)
|
||||||
|
global.ADD_TO_STAT("HTTP_SEND" + response.DetailStatName, arguments[0].length);
|
||||||
}
|
}
|
||||||
response._end.apply(response, arguments);
|
response._end.apply(response, arguments);
|
||||||
}
|
}
|
||||||
|
@ -294,12 +294,13 @@ function CheckGlobalTime() {
|
|||||||
global.DELTA_CURRENT_TIME = global.DELTA_CURRENT_TIME * -1;
|
global.DELTA_CURRENT_TIME = global.DELTA_CURRENT_TIME * -1;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
global.DELTA_CURRENT_TIME = global.DELTA_CURRENT_TIME * -1
|
global.DELTA_CURRENT_TIME = global.DELTA_CURRENT_TIME * -1
|
||||||
// if (!global.CAN_START) {
|
if (!global.CAN_START) {
|
||||||
// global.DELTA_CURRENT_TIME = global.DELTA_CURRENT_TIME + 3000;
|
let temp = global.DELTA_CURRENT_TIME
|
||||||
// setTimeout(() => {
|
global.DELTA_CURRENT_TIME = 3000;
|
||||||
// global.DELTA_CURRENT_TIME = global.DELTA_CURRENT_TIME - 3000;
|
setTimeout(() => {
|
||||||
// }, 3000)
|
global.DELTA_CURRENT_TIME = temp;
|
||||||
// }
|
}, 3000)
|
||||||
|
}
|
||||||
}, 3000)
|
}, 3000)
|
||||||
}, 5000)
|
}, 5000)
|
||||||
global.SAVE_CONST();
|
global.SAVE_CONST();
|
||||||
|
1
src/global.d.ts
vendored
1
src/global.d.ts
vendored
@ -387,6 +387,7 @@ declare global {
|
|||||||
//#region web-process.ts
|
//#region web-process.ts
|
||||||
LoadBlockFromNetwork: (Params, F?) => any;
|
LoadBlockFromNetwork: (Params, F?) => any;
|
||||||
GlobalRunID: number;
|
GlobalRunID: number;
|
||||||
|
AddonCommand: Function;
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region base.ts
|
//#region base.ts
|
||||||
|
@ -127,7 +127,7 @@ if (global.HTTP_HOSTING_PORT && !global.NWMODE) {
|
|||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function OnMessageWeb(msg) {
|
function OnMessageWeb(msg: TeraMessage) {
|
||||||
switch (msg.cmd) {
|
switch (msg.cmd) {
|
||||||
case "SetSmartEvent":
|
case "SetSmartEvent":
|
||||||
{
|
{
|
||||||
@ -171,7 +171,7 @@ global.STATIC_PROCESS = {
|
|||||||
};
|
};
|
||||||
ArrChildProcess.push(global.STATIC_PROCESS);
|
ArrChildProcess.push(global.STATIC_PROCESS);
|
||||||
|
|
||||||
function OnMessageStatic(msg) {
|
function OnMessageStatic(msg: TeraMessage) {
|
||||||
switch (msg.cmd) {
|
switch (msg.cmd) {
|
||||||
case "Send":
|
case "Send":
|
||||||
{
|
{
|
||||||
@ -197,7 +197,7 @@ global.TX_PROCESS = {
|
|||||||
};
|
};
|
||||||
ArrChildProcess.push(global.TX_PROCESS);
|
ArrChildProcess.push(global.TX_PROCESS);
|
||||||
|
|
||||||
function OnMessageTX(msg) {
|
function OnMessageTX(msg: TeraMessage) {
|
||||||
switch (msg.cmd) {
|
switch (msg.cmd) {
|
||||||
case "DappEvent":
|
case "DappEvent":
|
||||||
{
|
{
|
||||||
@ -210,7 +210,7 @@ function OnMessageTX(msg) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function StartAllProcess(bClose) {
|
function StartAllProcess(bClose: boolean) {
|
||||||
for (var i = 0; i < ArrChildProcess.length; i++) {
|
for (var i = 0; i < ArrChildProcess.length; i++) {
|
||||||
var Item = ArrChildProcess[i];
|
var Item = ArrChildProcess[i];
|
||||||
StartChildProcess(Item);
|
StartChildProcess(Item);
|
||||||
@ -251,7 +251,7 @@ function StartChildProcess(Item: TeraProcess) {
|
|||||||
ITEM.Worker = Fork(ITEM.Path, ["READONLYDB"]);
|
ITEM.Worker = Fork(ITEM.Path, ["READONLYDB"]);
|
||||||
ITEM.pid = ITEM.Worker.pid;
|
ITEM.pid = ITEM.Worker.pid;
|
||||||
global.ToLog("STARTED " + ITEM.Name + ":" + ITEM.pid);
|
global.ToLog("STARTED " + ITEM.Name + ":" + ITEM.pid);
|
||||||
ITEM.Worker.on('message', function(msg) {
|
ITEM.Worker.on('message', function(msg: TeraMessage) {
|
||||||
if (ITEM.LastAlive < Date.now())
|
if (ITEM.LastAlive < Date.now())
|
||||||
ITEM.LastAlive = Date.now();
|
ITEM.LastAlive = Date.now();
|
||||||
switch (msg.cmd) {
|
switch (msg.cmd) {
|
||||||
@ -333,7 +333,7 @@ function StartChildProcess(Item: TeraProcess) {
|
|||||||
ITEM.Worker.send({ cmd: "Alive", DELTA_CURRENT_TIME: global.DELTA_CURRENT_TIME });
|
ITEM.Worker.send({ cmd: "Alive", DELTA_CURRENT_TIME: global.DELTA_CURRENT_TIME });
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
ITEM.RunRPC = function(Name, Params, F) {
|
ITEM.RunRPC = function(Name: string, Params: any, F: Function) {
|
||||||
if (!ITEM.Worker)
|
if (!ITEM.Worker)
|
||||||
return;
|
return;
|
||||||
if (F) {
|
if (F) {
|
||||||
@ -388,9 +388,9 @@ setInterval(function run2() {
|
|||||||
}, 500);
|
}, 500);
|
||||||
var StartCheckMining = 0;
|
var StartCheckMining = 0;
|
||||||
global.MiningPaused = 0;
|
global.MiningPaused = 0;
|
||||||
var ProcessMemorySize = 0;
|
// var ProcessMemorySize = 0;
|
||||||
global.ArrMiningWrk = [];
|
global.ArrMiningWrk = [];
|
||||||
var BlockMining;
|
// var BlockMining;
|
||||||
if (global.ADDRLIST_MODE) {
|
if (global.ADDRLIST_MODE) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return;
|
return;
|
||||||
@ -409,7 +409,7 @@ function AllAlive() {
|
|||||||
// global.ArrMiningWrk = [];
|
// global.ArrMiningWrk = [];
|
||||||
// };
|
// };
|
||||||
|
|
||||||
function RunStopPOWProcess(Mode) {
|
function RunStopPOWProcess(Mode: string) {
|
||||||
if (!StartCheckMining) {
|
if (!StartCheckMining) {
|
||||||
StartCheckMining = 1;
|
StartCheckMining = 1;
|
||||||
global.COUNT_MINING_CPU = 0
|
global.COUNT_MINING_CPU = 0
|
||||||
@ -528,7 +528,7 @@ function RunStopPOWProcess(Mode) {
|
|||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
function SetCalcPOW(Block, cmd) {
|
function SetCalcPOW(Block: TeraBlock, cmd: any) {
|
||||||
if (!global.USE_MINING)
|
if (!global.USE_MINING)
|
||||||
return;
|
return;
|
||||||
teraManager.SendToClient({
|
teraManager.SendToClient({
|
||||||
@ -595,7 +595,7 @@ function DoGetNodes() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function DoConnectToNodes(Arr, Mode) {
|
function DoConnectToNodes(Arr: CNode[], Mode: string) {
|
||||||
if (!global.SERVER)
|
if (!global.SERVER)
|
||||||
return;
|
return;
|
||||||
if (!global.GrayConnect() && global.SERVER.CanSend < 2) {
|
if (!global.GrayConnect() && global.SERVER.CanSend < 2) {
|
||||||
@ -684,7 +684,7 @@ function RunOnce() {
|
|||||||
clearInterval(idRunOnce);
|
clearInterval(idRunOnce);
|
||||||
require("../core/update");
|
require("../core/update");
|
||||||
global.RunOnUpdate();
|
global.RunOnUpdate();
|
||||||
StartAllProcess(1);
|
StartAllProcess(true);
|
||||||
teraManager.WsServer.start(8080);
|
teraManager.WsServer.start(8080);
|
||||||
// require("./dogs");
|
// require("./dogs");
|
||||||
if (global.RESTART_PERIOD_SEC) {
|
if (global.RESTART_PERIOD_SEC) {
|
||||||
@ -702,8 +702,10 @@ function RunOnce() {
|
|||||||
var glPortDebug = 49800;
|
var glPortDebug = 49800;
|
||||||
|
|
||||||
import { fork } from 'child_process'
|
import { fork } from 'child_process'
|
||||||
|
import { TeraBlock } from '../interfaces/server';
|
||||||
|
import CNode from '../core/node';
|
||||||
|
|
||||||
function Fork(Path, ArrArgs?): TeraChildProcess {
|
function Fork(Path: string, ArrArgs?: string[]): TeraChildProcess {
|
||||||
ArrArgs = ArrArgs || [];
|
ArrArgs = ArrArgs || [];
|
||||||
if (global.LOCAL_RUN)
|
if (global.LOCAL_RUN)
|
||||||
ArrArgs.push("LOCALRUN");
|
ArrArgs.push("LOCALRUN");
|
||||||
@ -728,7 +730,7 @@ function Fork(Path, ArrArgs?): TeraChildProcess {
|
|||||||
global.SpeedSignLib = 0;
|
global.SpeedSignLib = 0;
|
||||||
global.TestSignLib = TestSignLib;
|
global.TestSignLib = TestSignLib;
|
||||||
|
|
||||||
function TestSignLib(MaxTime) {
|
function TestSignLib(MaxTime: number) {
|
||||||
if (!MaxTime)
|
if (!MaxTime)
|
||||||
MaxTime = DEF_PERIOD_SIGN_LIB;
|
MaxTime = DEF_PERIOD_SIGN_LIB;
|
||||||
var hash = Buffer.from(global.GetArrFromHex("A6B0914953F515F4686B2BA921B8FAC66EE6A6D3E317B43E981EBBA52393BFC6"));
|
var hash = Buffer.from(global.GetArrFromHex("A6B0914953F515F4686B2BA921B8FAC66EE6A6D3E317B43E981EBBA52393BFC6"));
|
||||||
|
@ -27,9 +27,6 @@ process.on('message', function(msg) {
|
|||||||
case "GETBLOCKHEADER":
|
case "GETBLOCKHEADER":
|
||||||
GETBLOCKHEADER(msg);
|
GETBLOCKHEADER(msg);
|
||||||
break;
|
break;
|
||||||
case "GETBLOCKHEADER100":
|
|
||||||
GETBLOCKHEADER100(msg);
|
|
||||||
break;
|
|
||||||
case "GETBLOCK":
|
case "GETBLOCK":
|
||||||
GETBLOCK(msg);
|
GETBLOCK(msg);
|
||||||
break;
|
break;
|
||||||
@ -58,37 +55,6 @@ setInterval(function() {
|
|||||||
global.DApps.Smart.DBSmart.Close();
|
global.DApps.Smart.DBSmart.Close();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
function GETBLOCKHEADER100(msg) {
|
|
||||||
return;
|
|
||||||
var Data = msg.Data;
|
|
||||||
var BlockNum = Data.BlockNum;
|
|
||||||
if (BlockNum % 100 !== 0)
|
|
||||||
return;
|
|
||||||
var EndNum100 = BlockNum / 100;
|
|
||||||
var LoadHash100 = Data.Hash;
|
|
||||||
var Hash100;
|
|
||||||
var Count = Data.Count;
|
|
||||||
if (!Count || Count < 0 || !EndNum100)
|
|
||||||
return;
|
|
||||||
if (Count > global.COUNT_BLOCKS_FOR_LOAD)
|
|
||||||
Count = global.COUNT_BLOCKS_FOR_LOAD;
|
|
||||||
var Arr = [];
|
|
||||||
var Data100 = global.SERVER.DBHeader100.Read(EndNum100);
|
|
||||||
if (Data100 && global.CompareArr(Data100.Hash100, LoadHash100) === 0) {
|
|
||||||
var StartNum = EndNum100 - Count + 1;
|
|
||||||
if (StartNum < 0)
|
|
||||||
StartNum = 0;
|
|
||||||
for (var Num = StartNum; Num <= EndNum100; Num++) {
|
|
||||||
Data100 = global.SERVER.DBHeader100.Read(Num);
|
|
||||||
if (Num === StartNum)
|
|
||||||
Arr.push(Data100.Hash100);
|
|
||||||
Arr.push(Data100.Hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var BufWrite = global.BufLib.GetBufferFromObject(Arr, "[hash]", global.MAX_PACKET_LENGTH, {});
|
|
||||||
global.ToLog("GETBLOCKHEADER100 Send Arr=" + Arr.length + " - " + BlockNum);
|
|
||||||
process.send({ cmd: "Send", addrStr: msg.addrStr, Method: "RETBLOCKHEADER100", Context: msg.Context, Data: BufWrite });
|
|
||||||
};
|
|
||||||
|
|
||||||
function GETBLOCKHEADER(msg) {
|
function GETBLOCKHEADER(msg) {
|
||||||
var Data = msg.Data;
|
var Data = msg.Data;
|
||||||
@ -136,7 +102,7 @@ function GETBLOCK(msg) {
|
|||||||
}
|
}
|
||||||
var BufWrite: Buffer;
|
var BufWrite: Buffer;
|
||||||
var BlockDB = global.SERVER.ReadBlockDB(BlockNum);
|
var BlockDB = global.SERVER.ReadBlockDB(BlockNum);
|
||||||
var StrSend;
|
var StrSend: string;
|
||||||
if (BlockDB && (global.CompareArr(BlockDB.TreeHash, TreeHash) === 0 || global.IsZeroArr(TreeHash))) {
|
if (BlockDB && (global.CompareArr(BlockDB.TreeHash, TreeHash) === 0 || global.IsZeroArr(TreeHash))) {
|
||||||
var BufWrite = global.BufLib.GetBufferFromObject(BlockDB, DB_FORMAT.FORMAT_BLOCK_TRANSFER, global.MAX_PACKET_LENGTH, global.WRK_BLOCK_TRANSFER);
|
var BufWrite = global.BufLib.GetBufferFromObject(BlockDB, DB_FORMAT.FORMAT_BLOCK_TRANSFER, global.MAX_PACKET_LENGTH, global.WRK_BLOCK_TRANSFER);
|
||||||
StrSend = "OK";
|
StrSend = "OK";
|
||||||
|
@ -148,7 +148,10 @@ function MainHTTPFunction(request, response) {
|
|||||||
var DataURL = url.parse(request.url);
|
var DataURL = url.parse(request.url);
|
||||||
var Params = querystring.parse(DataURL.query);
|
var Params = querystring.parse(DataURL.query);
|
||||||
var Path = querystring.unescape(DataURL.pathname);
|
var Path = querystring.unescape(DataURL.pathname);
|
||||||
|
if (global.STAT_MODE === 2) {
|
||||||
global.ADD_TO_STAT("HTTP_ALL");
|
global.ADD_TO_STAT("HTTP_ALL");
|
||||||
|
response.DetailStatName = ":" + Path;
|
||||||
|
}
|
||||||
var Type = request.method;
|
var Type = request.method;
|
||||||
if (Type === "POST") {
|
if (Type === "POST") {
|
||||||
let Response = response;
|
let Response = response;
|
||||||
@ -173,10 +176,10 @@ function MainHTTPFunction(request, response) {
|
|||||||
Response.end("Error data parsing");
|
Response.end("Error data parsing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DoCommandNew(response, Type, Path, Data);
|
DoCommandNew(request, response, Type, Path, Data);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
DoCommandNew(response, Type, Path, Params);
|
DoCommandNew(request, response, Type, Path, Params);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var bWasRun = 0;
|
var bWasRun = 0;
|
||||||
@ -261,10 +264,14 @@ WalletFileMap["mobile-wallet.html"] = "web-wallet.html";
|
|||||||
global.WebApi2 = {};
|
global.WebApi2 = {};
|
||||||
let HostingCaller: HostingCaller = {}
|
let HostingCaller: HostingCaller = {}
|
||||||
global.HostingCaller = HostingCaller;
|
global.HostingCaller = HostingCaller;
|
||||||
function DoCommandNew(response, Type, Path, Params) {
|
function DoCommandNew(request, response, Type, Path, Params) {
|
||||||
if (Path.substring(0, 1) === "/")
|
if (Path.substring(0, 1) === "/")
|
||||||
Path = Path.substring(1);
|
Path = Path.substring(1);
|
||||||
var ArrPath = Path.split('/', 5);
|
var ArrPath = Path.split('/', 5);
|
||||||
|
if (global.AddonCommand) {
|
||||||
|
if (!global.AddonCommand(request, response, Type, Path, Params, ArrPath))
|
||||||
|
return;
|
||||||
|
}
|
||||||
var Caller = global.HostingCaller;
|
var Caller = global.HostingCaller;
|
||||||
var Method = ArrPath[0];
|
var Method = ArrPath[0];
|
||||||
if (ArrPath[0] === "api") {
|
if (ArrPath[0] === "api") {
|
||||||
@ -278,7 +285,10 @@ function DoCommandNew(response, Type, Path, Params) {
|
|||||||
}
|
}
|
||||||
Method = ArrPath[2];
|
Method = ArrPath[2];
|
||||||
}
|
}
|
||||||
|
if (global.STAT_MODE === 2) {
|
||||||
global.ADD_TO_STAT("HTTP:" + Method);
|
global.ADD_TO_STAT("HTTP:" + Method);
|
||||||
|
response.DetailStatName = ":" + Method;
|
||||||
|
}
|
||||||
var F = Caller[Method];
|
var F = Caller[Method];
|
||||||
if (F) {
|
if (F) {
|
||||||
response.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': "*" });
|
response.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': "*" });
|
||||||
|
@ -26,6 +26,7 @@ const WorkStructTransfer = {};
|
|||||||
const WorkStructTransfer2 = {};
|
const WorkStructTransfer2 = {};
|
||||||
const WorkStructTransfer3 = {};
|
const WorkStructTransfer3 = {};
|
||||||
import DApp from './dapp'
|
import DApp from './dapp'
|
||||||
|
import { TeraBlock } from '../interfaces/server';
|
||||||
class MerkleDBRow extends DBRow {
|
class MerkleDBRow extends DBRow {
|
||||||
MerkleTree
|
MerkleTree
|
||||||
MerkleArr
|
MerkleArr
|
||||||
@ -231,7 +232,6 @@ export default class AccountApp extends DApp {
|
|||||||
ControlActSize() {
|
ControlActSize() {
|
||||||
var MaxNum = this.DBAct.GetMaxNum();
|
var MaxNum = this.DBAct.GetMaxNum();
|
||||||
if (MaxNum >= global.TRANSACTION_PROOF_COUNT * 2) {
|
if (MaxNum >= global.TRANSACTION_PROOF_COUNT * 2) {
|
||||||
global.ToLog("Rename act files")
|
|
||||||
this.DBActPrev.CloseDBFile(this.DBActPrev.FileName)
|
this.DBActPrev.CloseDBFile(this.DBActPrev.FileName)
|
||||||
this.DBAct.CloseDBFile(this.DBAct.FileName)
|
this.DBAct.CloseDBFile(this.DBAct.FileName)
|
||||||
if (fs.existsSync(this.DBActPrev.FileNameFull)) {
|
if (fs.existsSync(this.DBActPrev.FileNameFull)) {
|
||||||
@ -354,7 +354,7 @@ export default class AccountApp extends DApp {
|
|||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
DoCoinBaseTR(Block) {
|
DoCoinBaseTR(Block: TeraBlock) {
|
||||||
if (Block.BlockNum < global.START_MINING)
|
if (Block.BlockNum < global.START_MINING)
|
||||||
return;
|
return;
|
||||||
var SysData = this.ReadStateTR(0);
|
var SysData = this.ReadStateTR(0);
|
||||||
@ -371,12 +371,10 @@ export default class AccountApp extends DApp {
|
|||||||
Sum = SysBalance * 43 * 43 / 100 / global.TOTAL_SUPPLY_TERA
|
Sum = SysBalance * 43 * 43 / 100 / global.TOTAL_SUPPLY_TERA
|
||||||
var KMult = (global.NEW_FORMULA_TARGET2 - Block.BlockNum) / (global.NEW_FORMULA_TARGET2 - global.NEW_FORMULA_START);
|
var KMult = (global.NEW_FORMULA_TARGET2 - Block.BlockNum) / (global.NEW_FORMULA_TARGET2 - global.NEW_FORMULA_START);
|
||||||
Sum = KMult * Sum
|
Sum = KMult * Sum
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Sum = global.NEW_FORMULA_KTERA * SysBalance / global.TOTAL_SUPPLY_TERA
|
Sum = global.NEW_FORMULA_KTERA * SysBalance / global.TOTAL_SUPPLY_TERA
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var Power = global.GetPowPower(Block.PowHash);
|
var Power = global.GetPowPower(Block.PowHash);
|
||||||
if (Block.BlockNum >= global.NEW_BLOCK_REWARD1)
|
if (Block.BlockNum >= global.NEW_BLOCK_REWARD1)
|
||||||
Power = 43
|
Power = 43
|
||||||
|
Loading…
Reference in New Issue
Block a user