Merge pull request 'fix: reserve space for all error/status messages — closes #123' (#124) from fix/issue-123-layout-shift-audit into main
All checks were successful
check / check (push) Successful in 8s
All checks were successful
check / check (push) Successful in 8s
Reviewed-on: #124
This commit was merged in pull request #124.
This commit is contained in:
@@ -107,7 +107,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="add-wallet-phrase-warning"
|
id="add-wallet-phrase-warning"
|
||||||
class="text-xs mb-2 border border-border border-dashed p-2 hidden"
|
class="text-xs mb-2 border border-border border-dashed p-2"
|
||||||
|
style="visibility: hidden"
|
||||||
>
|
>
|
||||||
Write these words down and keep them safe. Anyone with
|
Write these words down and keep them safe. Anyone with
|
||||||
them can take your funds; if you lose them, your wallet
|
them can take your funds; if you lose them, your wallet
|
||||||
@@ -375,7 +376,8 @@
|
|||||||
</p>
|
</p>
|
||||||
<div
|
<div
|
||||||
id="export-privkey-flash"
|
id="export-privkey-flash"
|
||||||
class="text-xs mb-2 hidden"
|
class="text-xs mb-2 min-h-[1.25rem]"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
<div id="export-privkey-password-section" class="mb-2">
|
<div id="export-privkey-password-section" class="mb-2">
|
||||||
<label class="block mb-1">Password</label>
|
<label class="block mb-1">Password</label>
|
||||||
@@ -579,13 +581,17 @@
|
|||||||
<div class="text-xs text-muted mb-1">Your balance</div>
|
<div class="text-xs text-muted mb-1">Your balance</div>
|
||||||
<div id="confirm-balance" class="text-xs"></div>
|
<div id="confirm-balance" class="text-xs"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="confirm-fee" class="mb-3 hidden">
|
<div id="confirm-fee" class="mb-3" style="visibility: hidden">
|
||||||
<div class="text-xs text-muted mb-1">
|
<div class="text-xs text-muted mb-1">
|
||||||
Estimated network fee
|
Estimated network fee
|
||||||
</div>
|
</div>
|
||||||
<div id="confirm-fee-amount" class="text-xs"></div>
|
<div id="confirm-fee-amount" class="text-xs"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="confirm-warnings" class="mb-2 hidden"></div>
|
<div
|
||||||
|
id="confirm-warnings"
|
||||||
|
class="mb-2"
|
||||||
|
style="visibility: hidden"
|
||||||
|
></div>
|
||||||
<div
|
<div
|
||||||
id="confirm-recipient-warning"
|
id="confirm-recipient-warning"
|
||||||
class="mb-2"
|
class="mb-2"
|
||||||
@@ -601,7 +607,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="confirm-errors"
|
id="confirm-errors"
|
||||||
class="mb-2 border border-border border-dashed p-2 hidden"
|
class="mb-2 border border-border border-dashed p-2"
|
||||||
|
style="visibility: hidden; min-height: 1.25rem"
|
||||||
></div>
|
></div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="block mb-1 text-xs">Password</label>
|
<label class="block mb-1 text-xs">Password</label>
|
||||||
@@ -614,6 +621,7 @@
|
|||||||
<div
|
<div
|
||||||
id="confirm-tx-password-error"
|
id="confirm-tx-password-error"
|
||||||
class="text-xs mb-2 min-h-[1.25rem]"
|
class="text-xs mb-2 min-h-[1.25rem]"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
<button
|
<button
|
||||||
id="btn-confirm-send"
|
id="btn-confirm-send"
|
||||||
@@ -728,7 +736,8 @@
|
|||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
id="receive-erc20-warning"
|
id="receive-erc20-warning"
|
||||||
class="text-xs border border-border border-dashed p-2 mt-3 hidden"
|
class="text-xs border border-border border-dashed p-2 mt-3"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -756,7 +765,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="add-token-info"
|
id="add-token-info"
|
||||||
class="text-xs text-muted mb-2 hidden"
|
class="text-xs text-muted mb-2 min-h-[1.25rem]"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="block mb-1 text-xs text-muted"
|
<label class="block mb-1 text-xs text-muted"
|
||||||
@@ -938,7 +948,8 @@
|
|||||||
</p>
|
</p>
|
||||||
<div
|
<div
|
||||||
id="delete-wallet-flash"
|
id="delete-wallet-flash"
|
||||||
class="text-xs text-red-500 mb-2 hidden"
|
class="text-xs text-red-500 mb-2 min-h-[1.25rem]"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="block mb-1">Password</label>
|
<label class="block mb-1">Password</label>
|
||||||
@@ -1013,7 +1024,8 @@
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
id="settings-addtoken-info"
|
id="settings-addtoken-info"
|
||||||
class="text-xs text-muted mt-1 hidden"
|
class="text-xs text-muted mt-1 min-h-[1.25rem]"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
<button
|
<button
|
||||||
id="btn-settings-addtoken-manual"
|
id="btn-settings-addtoken-manual"
|
||||||
@@ -1139,7 +1151,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="approve-tx-error"
|
id="approve-tx-error"
|
||||||
class="text-xs mb-2 border border-border border-dashed p-1 min-h-[1.25rem] hidden"
|
class="text-xs mb-2 border border-border border-dashed p-1 min-h-[1.25rem]"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<button
|
<button
|
||||||
@@ -1167,8 +1180,10 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
id="approve-sign-danger-warning"
|
id="approve-sign-danger-warning"
|
||||||
class="hidden mb-3 p-2 text-xs font-bold"
|
class="mb-3 p-2 text-xs font-bold"
|
||||||
style="
|
style="
|
||||||
|
visibility: hidden;
|
||||||
|
min-height: 1.25rem;
|
||||||
background: #fee2e2;
|
background: #fee2e2;
|
||||||
color: #991b1b;
|
color: #991b1b;
|
||||||
border: 2px solid #dc2626;
|
border: 2px solid #dc2626;
|
||||||
@@ -1205,7 +1220,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="approve-sign-error"
|
id="approve-sign-error"
|
||||||
class="text-xs mb-2 border border-border border-dashed p-1 min-h-[1.25rem] hidden"
|
class="text-xs mb-2 border border-border border-dashed p-1 min-h-[1.25rem]"
|
||||||
|
style="visibility: hidden"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ const { log } = require("../../shared/log");
|
|||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
$("add-token-address").value = "";
|
$("add-token-address").value = "";
|
||||||
$("add-token-info").classList.add("hidden");
|
$("add-token-info").textContent = "";
|
||||||
|
$("add-token-info").style.visibility = "hidden";
|
||||||
const list = $("common-token-list");
|
const list = $("common-token-list");
|
||||||
list.innerHTML = getTopTokens(25)
|
list.innerHTML = getTopTokens(25)
|
||||||
.map(
|
.map(
|
||||||
@@ -45,7 +46,7 @@ function init(ctx) {
|
|||||||
}
|
}
|
||||||
const infoEl = $("add-token-info");
|
const infoEl = $("add-token-info");
|
||||||
infoEl.textContent = "Looking up token...";
|
infoEl.textContent = "Looking up token...";
|
||||||
infoEl.classList.remove("hidden");
|
infoEl.style.visibility = "visible";
|
||||||
log.debugf("Looking up token contract", contractAddr);
|
log.debugf("Looking up token contract", contractAddr);
|
||||||
try {
|
try {
|
||||||
const info = await lookupTokenInfo(contractAddr, state.rpcUrl);
|
const info = await lookupTokenInfo(contractAddr, state.rpcUrl);
|
||||||
@@ -63,7 +64,8 @@ function init(ctx) {
|
|||||||
const detail = e.shortMessage || e.message || String(e);
|
const detail = e.shortMessage || e.message || String(e);
|
||||||
log.errorf("Token lookup failed for", contractAddr, detail);
|
log.errorf("Token lookup failed for", contractAddr, detail);
|
||||||
showFlash(detail);
|
showFlash(detail);
|
||||||
infoEl.classList.add("hidden");
|
infoEl.textContent = "";
|
||||||
|
infoEl.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ function show() {
|
|||||||
$("import-xprv-key").value = "";
|
$("import-xprv-key").value = "";
|
||||||
$("add-wallet-password").value = "";
|
$("add-wallet-password").value = "";
|
||||||
$("add-wallet-password-confirm").value = "";
|
$("add-wallet-password-confirm").value = "";
|
||||||
$("add-wallet-phrase-warning").classList.add("hidden");
|
$("add-wallet-phrase-warning").style.visibility = "hidden";
|
||||||
switchMode("mnemonic");
|
switchMode("mnemonic");
|
||||||
showView("add-wallet");
|
showView("add-wallet");
|
||||||
}
|
}
|
||||||
@@ -281,7 +281,7 @@ function init(ctx) {
|
|||||||
// Generate mnemonic
|
// Generate mnemonic
|
||||||
$("btn-generate-phrase").addEventListener("click", () => {
|
$("btn-generate-phrase").addEventListener("click", () => {
|
||||||
$("wallet-mnemonic").value = generateMnemonic();
|
$("wallet-mnemonic").value = generateMnemonic();
|
||||||
$("add-wallet-phrase-warning").classList.remove("hidden");
|
$("add-wallet-phrase-warning").style.visibility = "visible";
|
||||||
});
|
});
|
||||||
|
|
||||||
// Import / confirm
|
// Import / confirm
|
||||||
|
|||||||
@@ -312,8 +312,8 @@ function init(_ctx) {
|
|||||||
$("export-privkey-address").textContent = addr.address;
|
$("export-privkey-address").textContent = addr.address;
|
||||||
$("export-privkey-address").dataset.full = addr.address;
|
$("export-privkey-address").dataset.full = addr.address;
|
||||||
$("export-privkey-password").value = "";
|
$("export-privkey-password").value = "";
|
||||||
$("export-privkey-flash").classList.add("hidden");
|
|
||||||
$("export-privkey-flash").textContent = "";
|
$("export-privkey-flash").textContent = "";
|
||||||
|
$("export-privkey-flash").style.visibility = "hidden";
|
||||||
$("export-privkey-password-section").classList.remove("hidden");
|
$("export-privkey-password-section").classList.remove("hidden");
|
||||||
$("export-privkey-result").classList.add("hidden");
|
$("export-privkey-result").classList.add("hidden");
|
||||||
$("export-privkey-value").textContent = "";
|
$("export-privkey-value").textContent = "";
|
||||||
@@ -324,7 +324,7 @@ function init(_ctx) {
|
|||||||
const password = $("export-privkey-password").value;
|
const password = $("export-privkey-password").value;
|
||||||
if (!password) {
|
if (!password) {
|
||||||
$("export-privkey-flash").textContent = "Password is required.";
|
$("export-privkey-flash").textContent = "Password is required.";
|
||||||
$("export-privkey-flash").classList.remove("hidden");
|
$("export-privkey-flash").style.visibility = "visible";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const btn = $("btn-export-privkey-confirm");
|
const btn = $("btn-export-privkey-confirm");
|
||||||
@@ -345,10 +345,10 @@ function init(_ctx) {
|
|||||||
$("export-privkey-password-section").classList.add("hidden");
|
$("export-privkey-password-section").classList.add("hidden");
|
||||||
$("export-privkey-value").textContent = privateKey;
|
$("export-privkey-value").textContent = privateKey;
|
||||||
$("export-privkey-result").classList.remove("hidden");
|
$("export-privkey-result").classList.remove("hidden");
|
||||||
$("export-privkey-flash").classList.add("hidden");
|
$("export-privkey-flash").style.visibility = "hidden";
|
||||||
} catch {
|
} catch {
|
||||||
$("export-privkey-flash").textContent = "Wrong password.";
|
$("export-privkey-flash").textContent = "Wrong password.";
|
||||||
$("export-privkey-flash").classList.remove("hidden");
|
$("export-privkey-flash").style.visibility = "visible";
|
||||||
} finally {
|
} finally {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.classList.remove("text-muted");
|
btn.classList.remove("text-muted");
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ function showTxApproval(details) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$("approve-tx-password").value = "";
|
$("approve-tx-password").value = "";
|
||||||
$("approve-tx-error").classList.add("hidden");
|
hideError("approve-tx-error");
|
||||||
|
|
||||||
showView("approve-tx");
|
showView("approve-tx");
|
||||||
}
|
}
|
||||||
@@ -351,10 +351,10 @@ function showSignApproval(details) {
|
|||||||
if (warningEl) {
|
if (warningEl) {
|
||||||
if (sp.dangerWarning) {
|
if (sp.dangerWarning) {
|
||||||
warningEl.textContent = sp.dangerWarning;
|
warningEl.textContent = sp.dangerWarning;
|
||||||
warningEl.classList.remove("hidden");
|
warningEl.style.visibility = "visible";
|
||||||
} else {
|
} else {
|
||||||
warningEl.textContent = "";
|
warningEl.textContent = "";
|
||||||
warningEl.classList.add("hidden");
|
warningEl.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,9 +186,10 @@ function show(txInfo) {
|
|||||||
`<div class="border border-border border-dashed p-2 mb-1 text-xs font-bold">WARNING: ${w}</div>`,
|
`<div class="border border-border border-dashed p-2 mb-1 text-xs font-bold">WARNING: ${w}</div>`,
|
||||||
)
|
)
|
||||||
.join("");
|
.join("");
|
||||||
warningsEl.classList.remove("hidden");
|
warningsEl.style.visibility = "visible";
|
||||||
} else {
|
} else {
|
||||||
warningsEl.classList.add("hidden");
|
warningsEl.innerHTML = "";
|
||||||
|
warningsEl.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
@@ -226,11 +227,12 @@ function show(txInfo) {
|
|||||||
errorsEl.innerHTML = errors
|
errorsEl.innerHTML = errors
|
||||||
.map((e) => `<div class="text-xs">${e}</div>`)
|
.map((e) => `<div class="text-xs">${e}</div>`)
|
||||||
.join("");
|
.join("");
|
||||||
errorsEl.classList.remove("hidden");
|
errorsEl.style.visibility = "visible";
|
||||||
sendBtn.disabled = true;
|
sendBtn.disabled = true;
|
||||||
sendBtn.classList.add("text-muted");
|
sendBtn.classList.add("text-muted");
|
||||||
} else {
|
} else {
|
||||||
errorsEl.classList.add("hidden");
|
errorsEl.innerHTML = "";
|
||||||
|
errorsEl.style.visibility = "hidden";
|
||||||
sendBtn.disabled = false;
|
sendBtn.disabled = false;
|
||||||
sendBtn.classList.remove("text-muted");
|
sendBtn.classList.remove("text-muted");
|
||||||
}
|
}
|
||||||
@@ -240,7 +242,7 @@ function show(txInfo) {
|
|||||||
hideError("confirm-tx-password-error");
|
hideError("confirm-tx-password-error");
|
||||||
|
|
||||||
// Gas estimate — show placeholder then fetch async
|
// Gas estimate — show placeholder then fetch async
|
||||||
$("confirm-fee").classList.remove("hidden");
|
$("confirm-fee").style.visibility = "visible";
|
||||||
$("confirm-fee-amount").textContent = "Estimating...";
|
$("confirm-fee-amount").textContent = "Estimating...";
|
||||||
state.viewData = { pendingTx: txInfo };
|
state.viewData = { pendingTx: txInfo };
|
||||||
showView("confirm-tx");
|
showView("confirm-tx");
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ function show(walletIdx) {
|
|||||||
wallet.name || "Wallet " + (walletIdx + 1);
|
wallet.name || "Wallet " + (walletIdx + 1);
|
||||||
$("delete-wallet-password").value = "";
|
$("delete-wallet-password").value = "";
|
||||||
$("delete-wallet-flash").textContent = "";
|
$("delete-wallet-flash").textContent = "";
|
||||||
$("delete-wallet-flash").classList.add("hidden");
|
$("delete-wallet-flash").style.visibility = "hidden";
|
||||||
showView("delete-wallet-confirm");
|
showView("delete-wallet-confirm");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,14 +29,14 @@ function init(_ctx) {
|
|||||||
if (!pw) {
|
if (!pw) {
|
||||||
$("delete-wallet-flash").textContent =
|
$("delete-wallet-flash").textContent =
|
||||||
"Please enter your password.";
|
"Please enter your password.";
|
||||||
$("delete-wallet-flash").classList.remove("hidden");
|
$("delete-wallet-flash").style.visibility = "visible";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteWalletIndex === null) {
|
if (deleteWalletIndex === null) {
|
||||||
$("delete-wallet-flash").textContent =
|
$("delete-wallet-flash").textContent =
|
||||||
"No wallet selected for deletion.";
|
"No wallet selected for deletion.";
|
||||||
$("delete-wallet-flash").classList.remove("hidden");
|
$("delete-wallet-flash").style.visibility = "visible";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ function init(_ctx) {
|
|||||||
await decryptWithPassword(wallet.encryptedSecret, pw);
|
await decryptWithPassword(wallet.encryptedSecret, pw);
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
$("delete-wallet-flash").textContent = "Wrong password.";
|
$("delete-wallet-flash").textContent = "Wrong password.";
|
||||||
$("delete-wallet-flash").classList.remove("hidden");
|
$("delete-wallet-flash").style.visibility = "visible";
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.classList.remove("text-muted");
|
btn.classList.remove("text-muted");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -40,11 +40,13 @@ function $(id) {
|
|||||||
function showError(id, msg) {
|
function showError(id, msg) {
|
||||||
const el = $(id);
|
const el = $(id);
|
||||||
el.textContent = msg;
|
el.textContent = msg;
|
||||||
el.classList.remove("hidden");
|
el.style.visibility = "visible";
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideError(id) {
|
function hideError(id) {
|
||||||
$(id).classList.add("hidden");
|
const el = $(id);
|
||||||
|
el.textContent = "";
|
||||||
|
el.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
function showView(name) {
|
function showView(name) {
|
||||||
|
|||||||
@@ -53,9 +53,10 @@ function show() {
|
|||||||
"This is an ERC-20 token. Only send " +
|
"This is an ERC-20 token. Only send " +
|
||||||
symbol +
|
symbol +
|
||||||
" on the Ethereum network to this address. Sending tokens on other networks will result in permanent loss.";
|
" on the Ethereum network to this address. Sending tokens on other networks will result in permanent loss.";
|
||||||
warningEl.classList.remove("hidden");
|
warningEl.style.visibility = "visible";
|
||||||
} else {
|
} else {
|
||||||
warningEl.classList.add("hidden");
|
warningEl.textContent = "";
|
||||||
|
warningEl.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
showView("receive");
|
showView("receive");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ function renderDropdown() {
|
|||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
$("settings-addtoken-address").value = "";
|
$("settings-addtoken-address").value = "";
|
||||||
$("settings-addtoken-info").classList.add("hidden");
|
$("settings-addtoken-info").textContent = "";
|
||||||
|
$("settings-addtoken-info").style.visibility = "hidden";
|
||||||
renderTop10();
|
renderTop10();
|
||||||
renderDropdown();
|
renderDropdown();
|
||||||
showView("settings-addtoken");
|
showView("settings-addtoken");
|
||||||
@@ -129,7 +130,7 @@ function init(_ctx) {
|
|||||||
}
|
}
|
||||||
const infoEl = $("settings-addtoken-info");
|
const infoEl = $("settings-addtoken-info");
|
||||||
infoEl.textContent = "Looking up token...";
|
infoEl.textContent = "Looking up token...";
|
||||||
infoEl.classList.remove("hidden");
|
infoEl.style.visibility = "visible";
|
||||||
log.debugf("Looking up token contract", addr);
|
log.debugf("Looking up token contract", addr);
|
||||||
try {
|
try {
|
||||||
const info = await lookupTokenInfo(addr, state.rpcUrl);
|
const info = await lookupTokenInfo(addr, state.rpcUrl);
|
||||||
@@ -143,7 +144,8 @@ function init(_ctx) {
|
|||||||
await saveState();
|
await saveState();
|
||||||
showFlash("Added " + info.symbol);
|
showFlash("Added " + info.symbol);
|
||||||
$("settings-addtoken-address").value = "";
|
$("settings-addtoken-address").value = "";
|
||||||
infoEl.classList.add("hidden");
|
infoEl.textContent = "";
|
||||||
|
infoEl.style.visibility = "hidden";
|
||||||
renderTop10();
|
renderTop10();
|
||||||
renderDropdown();
|
renderDropdown();
|
||||||
ctx.doRefreshAndRender();
|
ctx.doRefreshAndRender();
|
||||||
@@ -151,7 +153,8 @@ function init(_ctx) {
|
|||||||
const detail = e.shortMessage || e.message || String(e);
|
const detail = e.shortMessage || e.message || String(e);
|
||||||
log.errorf("Token lookup failed for", addr, detail);
|
log.errorf("Token lookup failed for", addr, detail);
|
||||||
showFlash(detail);
|
showFlash(detail);
|
||||||
infoEl.classList.add("hidden");
|
infoEl.textContent = "";
|
||||||
|
infoEl.style.visibility = "hidden";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user