Compare commits

...

34 Commits

Author SHA1 Message Date
wiz
ae6a408c05 Merge pull request #3493 from mempool/simon/update-softsimon-profile
Update softsimon profile photo
2023-03-21 20:58:11 +09:00
wiz
1015cbfa94 Merge pull request #3492 from mempool/simon/lightning-indexing-status
Lightning indexing indicators
2023-03-21 20:56:47 +09:00
wiz
876feef53f Fix frontend docker entrypoint umbrel LND detection 2023-03-21 18:11:10 +09:00
softsimon
f5f0329d39 Update softsimon profile photo 2023-03-21 18:03:19 +09:00
wiz
80a7b6d8d5 Merge branch 'master' into simon/lightning-indexing-status 2023-03-21 18:02:28 +09:00
wiz
f72e17c12e Merge pull request #3491 from mempool/simon/audit-off-hide-health
Audit disabled related UX fixes
2023-03-21 18:02:24 +09:00
wiz
f570b2762f Merge branch 'master' into simon/audit-off-hide-health 2023-03-21 17:43:56 +09:00
wiz
e2fda99578 Merge pull request #3490 from mempool/simon/auto-disable-ln-on-macaroon-fail
Auto disable LN on macaroon fail
2023-03-21 17:43:12 +09:00
softsimon
d7d45146c8 Lightning indexing indicators
refs  #2647
2023-03-21 17:33:14 +09:00
softsimon
45dbc6c6f6 Update logger network after modifying config 2023-03-21 16:21:11 +09:00
softsimon
d76e3a5939 Audit disabled related UX fixes 2023-03-21 16:02:46 +09:00
wiz
cb8fdb5e8d Hack docker frontend entrypoint to auto-enable lightning 2023-03-21 15:57:22 +09:00
softsimon
d337bf3ee2 Turn off LN if Macaroon is missing 2023-03-21 15:52:41 +09:00
softsimon
758e4d4f4c Disable LN on macaroon fail 2023-03-21 15:49:38 +09:00
softsimon
cd2bda4b49 Pull russian from transifex 2023-03-20 21:44:47 +09:00
wiz
493ea0641d Merge pull request #3487 from mempool/simon/catch-unhandled-lnd-axios-request
Catch exeptions in Lightning stats
2023-03-20 21:42:47 +09:00
wiz
ca1b6553c9 Merge branch 'master' into simon/catch-unhandled-lnd-axios-request 2023-03-20 20:53:41 +09:00
wiz
d479715d8e Merge pull request #3450 from mempool/nymkappa/configurable-timeout
Make core and lnd rpc calls timeout configurable
2023-03-20 20:50:51 +09:00
softsimon
e3109a8fec Catch exeptions in Lightning stats
fixes #3486
2023-03-20 20:46:11 +09:00
softsimon
e6bc5bef33 Updating russian i18n 2023-03-20 18:50:20 +09:00
softsimon
d82a7169b7 Pull from transifex 2023-03-20 18:28:15 +09:00
wiz
ba48b6f7ce Merge branch 'master' into nymkappa/configurable-timeout 2023-03-20 18:26:04 +09:00
wiz
8e1cf997f7 Merge pull request #3451 from mempool/simon/mining-difficulty-overflow-fix
Difficulty mining ellipsis fix
2023-03-20 18:25:51 +09:00
wiz
70d8548c92 Merge branch 'master' into simon/mining-difficulty-overflow-fix 2023-03-20 17:45:27 +09:00
wiz
cce7dd917f Merge branch 'master' into nymkappa/configurable-timeout 2023-03-20 17:38:40 +09:00
wiz
3dafb284a9 Merge pull request #3447 from mempool/hunicus/readme-video-poster
Add poster image for readme video
2023-03-20 17:37:21 +09:00
wiz
6a599a9a30 Merge pull request #3448 from mempool/simon/fix-missing-temp-cache-disk-cache
Fix missing temp cache in disk cache
2023-03-20 17:33:41 +09:00
softsimon
74fb292633 Difficulty mining ellipsis fix 2023-03-20 17:21:34 +09:00
nymkappa
c6e063ea2f Make lnd timeout configurable 2023-03-20 16:35:44 +09:00
nymkappa
81d563381a Make bitcoin core timeout configurable 2023-03-20 16:15:40 +09:00
softsimon
870e895144 Correcting docker disk cache config variable 2023-03-20 16:12:56 +09:00
softsimon
343d1345e2 Merge pull request #3445 from mempool/simon/liquid-blinding-tests-failing
Fixing broken liquid blinding tests
2023-03-20 15:46:41 +09:00
hunicus
1ed20a95df Add poster image for readme video
Also add line-break after video and remove screenshot.
2023-03-19 22:58:39 -04:00
softsimon
e27bdd3e2b Fixing broken liquid blinding tests 2023-03-19 17:30:06 +09:00
33 changed files with 213 additions and 97 deletions

View File

@@ -1,13 +1,13 @@
# The Mempool Open Source Project™ [![mempool](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/ry4br7/master&style=flat-square)](https://dashboard.cypress.io/projects/ry4br7/runs) # The Mempool Open Source Project™ [![mempool](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/ry4br7/master&style=flat-square)](https://dashboard.cypress.io/projects/ry4br7/runs)
https://user-images.githubusercontent.com/232186/222445818-234aa6c9-c233-4c52-b3f0-e32b8232893b.mp4 https://user-images.githubusercontent.com/93150691/226236121-375ea64f-b4a1-4cc0-8fad-a6fb33226840.mp4
<br>
Mempool is the fully-featured mempool visualizer, explorer, and API service running at [mempool.space](https://mempool.space/). Mempool is the fully-featured mempool visualizer, explorer, and API service running at [mempool.space](https://mempool.space/).
It is an open-source project developed and operated for the benefit of the Bitcoin community, with a focus on the emerging transaction fee market that is evolving Bitcoin into a multi-layer ecosystem. It is an open-source project developed and operated for the benefit of the Bitcoin community, with a focus on the emerging transaction fee market that is evolving Bitcoin into a multi-layer ecosystem.
![mempool](https://mempool.space/resources/screenshots/v2.4.0-dashboard.png)
# Installation Methods # Installation Methods
Mempool can be self-hosted on a wide variety of your own hardware, ranging from a simple one-click installation on a Raspberry Pi full-node distro all the way to a robust production instance on a powerful FreeBSD server. Mempool can be self-hosted on a wide variety of your own hardware, ranging from a simple one-click installation on a Raspberry Pi full-node distro all the way to a robust production instance on a powerful FreeBSD server.

View File

@@ -34,7 +34,8 @@
"HOST": "127.0.0.1", "HOST": "127.0.0.1",
"PORT": 8332, "PORT": 8332,
"USERNAME": "mempool", "USERNAME": "mempool",
"PASSWORD": "mempool" "PASSWORD": "mempool",
"TIMEOUT": 60000
}, },
"ELECTRUM": { "ELECTRUM": {
"HOST": "127.0.0.1", "HOST": "127.0.0.1",
@@ -48,7 +49,8 @@
"HOST": "127.0.0.1", "HOST": "127.0.0.1",
"PORT": 8332, "PORT": 8332,
"USERNAME": "mempool", "USERNAME": "mempool",
"PASSWORD": "mempool" "PASSWORD": "mempool",
"TIMEOUT": 60000
}, },
"DATABASE": { "DATABASE": {
"ENABLED": true, "ENABLED": true,
@@ -92,7 +94,8 @@
"LND": { "LND": {
"TLS_CERT_PATH": "tls.cert", "TLS_CERT_PATH": "tls.cert",
"MACAROON_PATH": "readonly.macaroon", "MACAROON_PATH": "readonly.macaroon",
"REST_API_URL": "https://localhost:8080" "REST_API_URL": "https://localhost:8080",
"TIMEOUT": 10000
}, },
"CLIGHTNING": { "CLIGHTNING": {
"SOCKET": "lightning-rpc" "SOCKET": "lightning-rpc"

View File

@@ -29,13 +29,14 @@
"ADVANCED_GBT_MEMPOOL": "__MEMPOOL_ADVANCED_GBT_MEMPOOL__", "ADVANCED_GBT_MEMPOOL": "__MEMPOOL_ADVANCED_GBT_MEMPOOL__",
"CPFP_INDEXING": "__MEMPOOL_CPFP_INDEXING__", "CPFP_INDEXING": "__MEMPOOL_CPFP_INDEXING__",
"MAX_BLOCKS_BULK_QUERY": "__MEMPOOL_MAX_BLOCKS_BULK_QUERY__", "MAX_BLOCKS_BULK_QUERY": "__MEMPOOL_MAX_BLOCKS_BULK_QUERY__",
"DISK_CACHE_BLOCK_INTERVAL": "__DISK_CACHE_BLOCK_INTERVAL__" "DISK_CACHE_BLOCK_INTERVAL": "__MEMPOOL_DISK_CACHE_BLOCK_INTERVAL__"
}, },
"CORE_RPC": { "CORE_RPC": {
"HOST": "__CORE_RPC_HOST__", "HOST": "__CORE_RPC_HOST__",
"PORT": 15, "PORT": 15,
"USERNAME": "__CORE_RPC_USERNAME__", "USERNAME": "__CORE_RPC_USERNAME__",
"PASSWORD": "__CORE_RPC_PASSWORD__" "PASSWORD": "__CORE_RPC_PASSWORD__",
"TIMEOUT": "__CORE_RPC_TIMEOUT__"
}, },
"ELECTRUM": { "ELECTRUM": {
"HOST": "__ELECTRUM_HOST__", "HOST": "__ELECTRUM_HOST__",
@@ -49,7 +50,8 @@
"HOST": "__SECOND_CORE_RPC_HOST__", "HOST": "__SECOND_CORE_RPC_HOST__",
"PORT": 17, "PORT": 17,
"USERNAME": "__SECOND_CORE_RPC_USERNAME__", "USERNAME": "__SECOND_CORE_RPC_USERNAME__",
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__" "PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
"TIMEOUT": "__SECOND_CORE_RPC_TIMEOUT__"
}, },
"DATABASE": { "DATABASE": {
"ENABLED": false, "ENABLED": false,
@@ -108,7 +110,8 @@
"LND": { "LND": {
"TLS_CERT_PATH": "", "TLS_CERT_PATH": "",
"MACAROON_PATH": "", "MACAROON_PATH": "",
"REST_API_URL": "https://localhost:8080" "REST_API_URL": "https://localhost:8080",
"TIMEOUT": 10000
}, },
"CLIGHTNING": { "CLIGHTNING": {
"SOCKET": "__CLIGHTNING_SOCKET__" "SOCKET": "__CLIGHTNING_SOCKET__"

View File

@@ -53,14 +53,16 @@ describe('Mempool Backend Config', () => {
HOST: '127.0.0.1', HOST: '127.0.0.1',
PORT: 8332, PORT: 8332,
USERNAME: 'mempool', USERNAME: 'mempool',
PASSWORD: 'mempool' PASSWORD: 'mempool',
TIMEOUT: 60000
}); });
expect(config.SECOND_CORE_RPC).toStrictEqual({ expect(config.SECOND_CORE_RPC).toStrictEqual({
HOST: '127.0.0.1', HOST: '127.0.0.1',
PORT: 8332, PORT: 8332,
USERNAME: 'mempool', USERNAME: 'mempool',
PASSWORD: 'mempool' PASSWORD: 'mempool',
TIMEOUT: 60000
}); });
expect(config.DATABASE).toStrictEqual({ expect(config.DATABASE).toStrictEqual({

View File

@@ -7,7 +7,7 @@ const nodeRpcCredentials: BitcoinRpcCredentials = {
port: config.CORE_RPC.PORT, port: config.CORE_RPC.PORT,
user: config.CORE_RPC.USERNAME, user: config.CORE_RPC.USERNAME,
pass: config.CORE_RPC.PASSWORD, pass: config.CORE_RPC.PASSWORD,
timeout: 60000, timeout: config.CORE_RPC.TIMEOUT,
}; };
export default new bitcoin.Client(nodeRpcCredentials); export default new bitcoin.Client(nodeRpcCredentials);

View File

@@ -7,7 +7,7 @@ const nodeRpcCredentials: BitcoinRpcCredentials = {
port: config.SECOND_CORE_RPC.PORT, port: config.SECOND_CORE_RPC.PORT,
user: config.SECOND_CORE_RPC.USERNAME, user: config.SECOND_CORE_RPC.USERNAME,
pass: config.SECOND_CORE_RPC.PASSWORD, pass: config.SECOND_CORE_RPC.PASSWORD,
timeout: 60000, timeout: config.SECOND_CORE_RPC.TIMEOUT,
}; };
export default new bitcoin.Client(nodeRpcCredentials); export default new bitcoin.Client(nodeRpcCredentials);

View File

@@ -4,21 +4,29 @@ import * as fs from 'fs';
import { AbstractLightningApi } from '../lightning-api-abstract-factory'; import { AbstractLightningApi } from '../lightning-api-abstract-factory';
import { ILightningApi } from '../lightning-api.interface'; import { ILightningApi } from '../lightning-api.interface';
import config from '../../../config'; import config from '../../../config';
import logger from '../../../logger';
class LndApi implements AbstractLightningApi { class LndApi implements AbstractLightningApi {
axiosConfig: AxiosRequestConfig = {}; axiosConfig: AxiosRequestConfig = {};
constructor() { constructor() {
if (config.LIGHTNING.ENABLED) { if (!config.LIGHTNING.ENABLED) {
return;
}
try {
this.axiosConfig = { this.axiosConfig = {
headers: { headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(config.LND.MACAROON_PATH).toString('hex') 'Grpc-Metadata-macaroon': fs.readFileSync(config.LND.MACAROON_PATH).toString('hex'),
}, },
httpsAgent: new Agent({ httpsAgent: new Agent({
ca: fs.readFileSync(config.LND.TLS_CERT_PATH) ca: fs.readFileSync(config.LND.TLS_CERT_PATH)
}), }),
timeout: 10000 timeout: config.LND.TIMEOUT
}; };
} catch (e) {
config.LIGHTNING.ENABLED = false;
logger.updateNetwork();
logger.err(`Could not initialize LND Macaroon/TLS Cert. Disabling LIGHTNING. ` + (e instanceof Error ? e.message : e));
} }
} }

View File

@@ -52,6 +52,7 @@ interface IConfig {
TLS_CERT_PATH: string; TLS_CERT_PATH: string;
MACAROON_PATH: string; MACAROON_PATH: string;
REST_API_URL: string; REST_API_URL: string;
TIMEOUT: number;
}; };
CLIGHTNING: { CLIGHTNING: {
SOCKET: string; SOCKET: string;
@@ -66,12 +67,14 @@ interface IConfig {
PORT: number; PORT: number;
USERNAME: string; USERNAME: string;
PASSWORD: string; PASSWORD: string;
TIMEOUT: number;
}; };
SECOND_CORE_RPC: { SECOND_CORE_RPC: {
HOST: string; HOST: string;
PORT: number; PORT: number;
USERNAME: string; USERNAME: string;
PASSWORD: string; PASSWORD: string;
TIMEOUT: number;
}; };
DATABASE: { DATABASE: {
ENABLED: boolean; ENABLED: boolean;
@@ -170,13 +173,15 @@ const defaults: IConfig = {
'HOST': '127.0.0.1', 'HOST': '127.0.0.1',
'PORT': 8332, 'PORT': 8332,
'USERNAME': 'mempool', 'USERNAME': 'mempool',
'PASSWORD': 'mempool' 'PASSWORD': 'mempool',
'TIMEOUT': 60000,
}, },
'SECOND_CORE_RPC': { 'SECOND_CORE_RPC': {
'HOST': '127.0.0.1', 'HOST': '127.0.0.1',
'PORT': 8332, 'PORT': 8332,
'USERNAME': 'mempool', 'USERNAME': 'mempool',
'PASSWORD': 'mempool' 'PASSWORD': 'mempool',
'TIMEOUT': 60000,
}, },
'DATABASE': { 'DATABASE': {
'ENABLED': true, 'ENABLED': true,
@@ -216,6 +221,7 @@ const defaults: IConfig = {
'TLS_CERT_PATH': '', 'TLS_CERT_PATH': '',
'MACAROON_PATH': '', 'MACAROON_PATH': '',
'REST_API_URL': 'https://localhost:8080', 'REST_API_URL': 'https://localhost:8080',
'TIMEOUT': 10000,
}, },
'CLIGHTNING': { 'CLIGHTNING': {
'SOCKET': '', 'SOCKET': '',

View File

@@ -215,11 +215,11 @@ class Server {
await lightningStatsUpdater.$startService(); await lightningStatsUpdater.$startService();
await forensicsService.$startService(); await forensicsService.$startService();
} catch(e) { } catch(e) {
logger.err(`Nodejs lightning backend crashed. Restarting in 1 minute. Reason: ${(e instanceof Error ? e.message : e)}`); logger.err(`Exception in $runLightningBackend. Restarting in 1 minute. Reason: ${(e instanceof Error ? e.message : e)}`);
await Common.sleep$(1000 * 60); await Common.sleep$(1000 * 60);
this.$runLightningBackend(); this.$runLightningBackend();
}; };
} }
setUpWebsocketHandling(): void { setUpWebsocketHandling(): void {
if (this.wss) { if (this.wss) {

View File

@@ -69,6 +69,10 @@ class Logger {
this.network = this.getNetwork(); this.network = this.getNetwork();
} }
public updateNetwork(): void {
this.network = this.getNetwork();
}
private addprio(prio): void { private addprio(prio): void {
this[prio] = (function(_this) { this[prio] = (function(_this) {
return function(msg, tag?: string) { return function(msg, tag?: string) {

View File

@@ -22,12 +22,15 @@ class LightningStatsUpdater {
* Update the latest entry for each node every config.LIGHTNING.STATS_REFRESH_INTERVAL seconds * Update the latest entry for each node every config.LIGHTNING.STATS_REFRESH_INTERVAL seconds
*/ */
private async $logStatsDaily(): Promise<void> { private async $logStatsDaily(): Promise<void> {
const date = new Date(); try {
Common.setDateMidnight(date); const date = new Date();
const networkGraph = await lightningApi.$getNetworkGraph(); Common.setDateMidnight(date);
await LightningStatsImporter.computeNetworkStats(date.getTime() / 1000, networkGraph); const networkGraph = await lightningApi.$getNetworkGraph();
await LightningStatsImporter.computeNetworkStats(date.getTime() / 1000, networkGraph);
logger.debug(`Updated latest network stats`, logger.tags.ln); logger.debug(`Updated latest network stats`, logger.tags.ln);
} catch (e) {
logger.err(`Exception in $logStatsDaily. Reason: ${(e instanceof Error ? e.message : e)}`);
}
} }
} }

View File

@@ -34,6 +34,7 @@ If you want to use different credentials, specify them in the `docker-compose.ym
CORE_RPC_PORT: "8332" CORE_RPC_PORT: "8332"
CORE_RPC_USERNAME: "customuser" CORE_RPC_USERNAME: "customuser"
CORE_RPC_PASSWORD: "custompassword" CORE_RPC_PASSWORD: "custompassword"
CORE_RPC_TIMEOUT: "60000"
``` ```
The IP address in the example above refers to Docker's default gateway IP address so that the container can hit the `bitcoind` instance running on the host machine. If your setup is different, update it accordingly. The IP address in the example above refers to Docker's default gateway IP address so that the container can hit the `bitcoind` instance running on the host machine. If your setup is different, update it accordingly.
@@ -160,7 +161,8 @@ Corresponding `docker-compose.yml` overrides:
"HOST": "127.0.0.1", "HOST": "127.0.0.1",
"PORT": 8332, "PORT": 8332,
"USERNAME": "mempool", "USERNAME": "mempool",
"PASSWORD": "mempool" "PASSWORD": "mempool",
"TIMEOUT": 60000
}, },
``` ```
@@ -172,6 +174,7 @@ Corresponding `docker-compose.yml` overrides:
CORE_RPC_PORT: "" CORE_RPC_PORT: ""
CORE_RPC_USERNAME: "" CORE_RPC_USERNAME: ""
CORE_RPC_PASSWORD: "" CORE_RPC_PASSWORD: ""
CORE_RPC_TIMEOUT: 60000
... ...
``` ```
@@ -221,7 +224,8 @@ Corresponding `docker-compose.yml` overrides:
"HOST": "127.0.0.1", "HOST": "127.0.0.1",
"PORT": 8332, "PORT": 8332,
"USERNAME": "mempool", "USERNAME": "mempool",
"PASSWORD": "mempool" "PASSWORD": "mempool",
"TIMEOUT": 60000
}, },
``` ```
@@ -233,6 +237,7 @@ Corresponding `docker-compose.yml` overrides:
SECOND_CORE_RPC_PORT: "" SECOND_CORE_RPC_PORT: ""
SECOND_CORE_RPC_USERNAME: "" SECOND_CORE_RPC_USERNAME: ""
SECOND_CORE_RPC_PASSWORD: "" SECOND_CORE_RPC_PASSWORD: ""
SECOND_CORE_RPC_TIMEOUT: ""
... ...
``` ```
@@ -405,6 +410,7 @@ Corresponding `docker-compose.yml` overrides:
"TLS_CERT_PATH": "" "TLS_CERT_PATH": ""
"MACAROON_PATH": "" "MACAROON_PATH": ""
"REST_API_URL": "https://localhost:8080" "REST_API_URL": "https://localhost:8080"
"TIMEOUT": 10000
} }
``` ```
@@ -415,6 +421,7 @@ Corresponding `docker-compose.yml` overrides:
LND_TLS_CERT_PATH: "" LND_TLS_CERT_PATH: ""
LND_MACAROON_PATH: "" LND_MACAROON_PATH: ""
LND_REST_API_URL: "https://localhost:8080" LND_REST_API_URL: "https://localhost:8080"
LND_TIMEOUT: 10000
... ...
``` ```

View File

@@ -27,13 +27,14 @@
"ADVANCED_GBT_MEMPOOL": __MEMPOOL_ADVANCED_GBT_MEMPOOL__, "ADVANCED_GBT_MEMPOOL": __MEMPOOL_ADVANCED_GBT_MEMPOOL__,
"CPFP_INDEXING": __MEMPOOL_CPFP_INDEXING__, "CPFP_INDEXING": __MEMPOOL_CPFP_INDEXING__,
"MAX_BLOCKS_BULK_QUERY": __MEMPOOL_MAX_BLOCKS_BULK_QUERY__, "MAX_BLOCKS_BULK_QUERY": __MEMPOOL_MAX_BLOCKS_BULK_QUERY__,
"DISK_CACHE_BLOCK_INTERVAL": __DISK_CACHE_BLOCK_INTERVAL__ "DISK_CACHE_BLOCK_INTERVAL": __MEMPOOL_DISK_CACHE_BLOCK_INTERVAL__
}, },
"CORE_RPC": { "CORE_RPC": {
"HOST": "__CORE_RPC_HOST__", "HOST": "__CORE_RPC_HOST__",
"PORT": __CORE_RPC_PORT__, "PORT": __CORE_RPC_PORT__,
"USERNAME": "__CORE_RPC_USERNAME__", "USERNAME": "__CORE_RPC_USERNAME__",
"PASSWORD": "__CORE_RPC_PASSWORD__" "PASSWORD": "__CORE_RPC_PASSWORD__",
"TIMEOUT": __CORE_RPC_TIMEOUT__
}, },
"ELECTRUM": { "ELECTRUM": {
"HOST": "__ELECTRUM_HOST__", "HOST": "__ELECTRUM_HOST__",
@@ -47,7 +48,8 @@
"HOST": "__SECOND_CORE_RPC_HOST__", "HOST": "__SECOND_CORE_RPC_HOST__",
"PORT": __SECOND_CORE_RPC_PORT__, "PORT": __SECOND_CORE_RPC_PORT__,
"USERNAME": "__SECOND_CORE_RPC_USERNAME__", "USERNAME": "__SECOND_CORE_RPC_USERNAME__",
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__" "PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
"TIMEOUT": __SECOND_CORE_RPC_TIMEOUT__
}, },
"DATABASE": { "DATABASE": {
"ENABLED": __DATABASE_ENABLED__, "ENABLED": __DATABASE_ENABLED__,
@@ -84,7 +86,8 @@
"LND": { "LND": {
"TLS_CERT_PATH": "__LND_TLS_CERT_PATH__", "TLS_CERT_PATH": "__LND_TLS_CERT_PATH__",
"MACAROON_PATH": "__LND_MACAROON_PATH__", "MACAROON_PATH": "__LND_MACAROON_PATH__",
"REST_API_URL": "__LND_REST_API_URL__" "REST_API_URL": "__LND_REST_API_URL__",
"TIMEOUT": "__LND_TIMEOUT__"
}, },
"CLIGHTNING": { "CLIGHTNING": {
"SOCKET": "__CLIGHTNING_SOCKET__" "SOCKET": "__CLIGHTNING_SOCKET__"

View File

@@ -37,6 +37,7 @@ __CORE_RPC_HOST__=${CORE_RPC_HOST:=127.0.0.1}
__CORE_RPC_PORT__=${CORE_RPC_PORT:=8332} __CORE_RPC_PORT__=${CORE_RPC_PORT:=8332}
__CORE_RPC_USERNAME__=${CORE_RPC_USERNAME:=mempool} __CORE_RPC_USERNAME__=${CORE_RPC_USERNAME:=mempool}
__CORE_RPC_PASSWORD__=${CORE_RPC_PASSWORD:=mempool} __CORE_RPC_PASSWORD__=${CORE_RPC_PASSWORD:=mempool}
__CORE_RPC_TIMEOUT__=${CORE_RPC_TIMEOUT:=60000}
# ELECTRUM # ELECTRUM
__ELECTRUM_HOST__=${ELECTRUM_HOST:=127.0.0.1} __ELECTRUM_HOST__=${ELECTRUM_HOST:=127.0.0.1}
@@ -51,6 +52,7 @@ __SECOND_CORE_RPC_HOST__=${SECOND_CORE_RPC_HOST:=127.0.0.1}
__SECOND_CORE_RPC_PORT__=${SECOND_CORE_RPC_PORT:=8332} __SECOND_CORE_RPC_PORT__=${SECOND_CORE_RPC_PORT:=8332}
__SECOND_CORE_RPC_USERNAME__=${SECOND_CORE_RPC_USERNAME:=mempool} __SECOND_CORE_RPC_USERNAME__=${SECOND_CORE_RPC_USERNAME:=mempool}
__SECOND_CORE_RPC_PASSWORD__=${SECOND_CORE_RPC_PASSWORD:=mempool} __SECOND_CORE_RPC_PASSWORD__=${SECOND_CORE_RPC_PASSWORD:=mempool}
__SECOND_CORE_RPC_TIMEOUT__=${SECOND_CORE_RPC_TIMEOUT:=60000}
# DATABASE # DATABASE
__DATABASE_ENABLED__=${DATABASE_ENABLED:=true} __DATABASE_ENABLED__=${DATABASE_ENABLED:=true}
@@ -108,6 +110,7 @@ __LIGHTNING_LOGGER_UPDATE_INTERVAL__=${LIGHTNING_LOGGER_UPDATE_INTERVAL:=30}
__LND_TLS_CERT_PATH__=${LND_TLS_CERT_PATH:=""} __LND_TLS_CERT_PATH__=${LND_TLS_CERT_PATH:=""}
__LND_MACAROON_PATH__=${LND_MACAROON_PATH:=""} __LND_MACAROON_PATH__=${LND_MACAROON_PATH:=""}
__LND_REST_API_URL__=${LND_REST_API_URL:="https://localhost:8080"} __LND_REST_API_URL__=${LND_REST_API_URL:="https://localhost:8080"}
__LND_TIMEOUT__=${LND_TIMEOUT:=10000}
# CLN # CLN
__CLIGHTNING_SOCKET__=${CLIGHTNING_SOCKET:=""} __CLIGHTNING_SOCKET__=${CLIGHTNING_SOCKET:=""}
@@ -156,6 +159,7 @@ sed -i "s/__CORE_RPC_HOST__/${__CORE_RPC_HOST__}/g" mempool-config.json
sed -i "s/__CORE_RPC_PORT__/${__CORE_RPC_PORT__}/g" mempool-config.json sed -i "s/__CORE_RPC_PORT__/${__CORE_RPC_PORT__}/g" mempool-config.json
sed -i "s/__CORE_RPC_USERNAME__/${__CORE_RPC_USERNAME__}/g" mempool-config.json sed -i "s/__CORE_RPC_USERNAME__/${__CORE_RPC_USERNAME__}/g" mempool-config.json
sed -i "s/__CORE_RPC_PASSWORD__/${__CORE_RPC_PASSWORD__}/g" mempool-config.json sed -i "s/__CORE_RPC_PASSWORD__/${__CORE_RPC_PASSWORD__}/g" mempool-config.json
sed -i "s/__CORE_RPC_TIMEOUT__/${__CORE_RPC_TIMEOUT__}/g" mempool-config.json
sed -i "s/__ELECTRUM_HOST__/${__ELECTRUM_HOST__}/g" mempool-config.json sed -i "s/__ELECTRUM_HOST__/${__ELECTRUM_HOST__}/g" mempool-config.json
sed -i "s/__ELECTRUM_PORT__/${__ELECTRUM_PORT__}/g" mempool-config.json sed -i "s/__ELECTRUM_PORT__/${__ELECTRUM_PORT__}/g" mempool-config.json
@@ -167,6 +171,7 @@ sed -i "s/__SECOND_CORE_RPC_HOST__/${__SECOND_CORE_RPC_HOST__}/g" mempool-config
sed -i "s/__SECOND_CORE_RPC_PORT__/${__SECOND_CORE_RPC_PORT__}/g" mempool-config.json sed -i "s/__SECOND_CORE_RPC_PORT__/${__SECOND_CORE_RPC_PORT__}/g" mempool-config.json
sed -i "s/__SECOND_CORE_RPC_USERNAME__/${__SECOND_CORE_RPC_USERNAME__}/g" mempool-config.json sed -i "s/__SECOND_CORE_RPC_USERNAME__/${__SECOND_CORE_RPC_USERNAME__}/g" mempool-config.json
sed -i "s/__SECOND_CORE_RPC_PASSWORD__/${__SECOND_CORE_RPC_PASSWORD__}/g" mempool-config.json sed -i "s/__SECOND_CORE_RPC_PASSWORD__/${__SECOND_CORE_RPC_PASSWORD__}/g" mempool-config.json
sed -i "s/__SECOND_CORE_RPC_TIMEOUT__/${__SECOND_CORE_RPC_TIMEOUT__}/g" mempool-config.json
sed -i "s/__DATABASE_ENABLED__/${__DATABASE_ENABLED__}/g" mempool-config.json sed -i "s/__DATABASE_ENABLED__/${__DATABASE_ENABLED__}/g" mempool-config.json
sed -i "s/__DATABASE_HOST__/${__DATABASE_HOST__}/g" mempool-config.json sed -i "s/__DATABASE_HOST__/${__DATABASE_HOST__}/g" mempool-config.json
@@ -218,6 +223,7 @@ sed -i "s!__LIGHTNING_LOGGER_UPDATE_INTERVAL__!${__LIGHTNING_LOGGER_UPDATE_INTER
sed -i "s!__LND_TLS_CERT_PATH__!${__LND_TLS_CERT_PATH__}!g" mempool-config.json sed -i "s!__LND_TLS_CERT_PATH__!${__LND_TLS_CERT_PATH__}!g" mempool-config.json
sed -i "s!__LND_MACAROON_PATH__!${__LND_MACAROON_PATH__}!g" mempool-config.json sed -i "s!__LND_MACAROON_PATH__!${__LND_MACAROON_PATH__}!g" mempool-config.json
sed -i "s!__LND_REST_API_URL__!${__LND_REST_API_URL__}!g" mempool-config.json sed -i "s!__LND_REST_API_URL__!${__LND_REST_API_URL__}!g" mempool-config.json
sed -i "s!__LND_TIMEOUT__!${__LND_TIMEOUT__}!g" mempool-config.json
# CLN # CLN
sed -i "s!__CLIGHTNING_SOCKET__!${__CLIGHTNING_SOCKET__}!g" mempool-config.json sed -i "s!__CLIGHTNING_SOCKET__!${__CLIGHTNING_SOCKET__}!g" mempool-config.json

View File

@@ -10,6 +10,10 @@ cp /etc/nginx/nginx.conf /patch/nginx.conf
sed -i "s/__MEMPOOL_FRONTEND_HTTP_PORT__/${__MEMPOOL_FRONTEND_HTTP_PORT__}/g" /patch/nginx.conf sed -i "s/__MEMPOOL_FRONTEND_HTTP_PORT__/${__MEMPOOL_FRONTEND_HTTP_PORT__}/g" /patch/nginx.conf
cat /patch/nginx.conf > /etc/nginx/nginx.conf cat /patch/nginx.conf > /etc/nginx/nginx.conf
if [ "${LIGHTNING_DETECTED_PORT}" = "9735" ];then
export LIGHTNING=true
fi
# Runtime overrides - read env vars defined in docker compose # Runtime overrides - read env vars defined in docker compose
__TESTNET_ENABLED__=${TESTNET_ENABLED:=false} __TESTNET_ENABLED__=${TESTNET_ENABLED:=false}

View File

@@ -158,10 +158,10 @@ describe('Liquid', () => {
it('show empty unblinded TX', () => { it('show empty unblinded TX', () => {
cy.visit(`${basePath}/tx/f2f41c0850e8e7e3f1af233161fd596662e67c11ef10ed15943884186fbb7f46#blinded=`); cy.visit(`${basePath}/tx/f2f41c0850e8e7e3f1af233161fd596662e67c11ef10ed15943884186fbb7f46#blinded=`);
cy.waitForSkeletonGone(); cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', ''); cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vin tr:nth-child(1) .amount').should('contain.text', 'Confidential'); cy.get('.table-tx-vin tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', ''); cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', ''); cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(1) .amount').should('contain.text', 'Confidential'); cy.get('.table-tx-vout tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(2) .amount').should('contain.text', 'Confidential'); cy.get('.table-tx-vout tr:nth-child(2) .amount').should('contain.text', 'Confidential');
}); });
@@ -169,8 +169,8 @@ describe('Liquid', () => {
it('show invalid unblinded TX hex', () => { it('show invalid unblinded TX hex', () => {
cy.visit(`${basePath}/tx/f2f41c0850e8e7e3f1af233161fd596662e67c11ef10ed15943884186fbb7f46#blinded=123`); cy.visit(`${basePath}/tx/f2f41c0850e8e7e3f1af233161fd596662e67c11ef10ed15943884186fbb7f46#blinded=123`);
cy.waitForSkeletonGone(); cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr').should('have.class', ''); cy.get('.table-tx-vin tr').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr').should('have.class', ''); cy.get('.table-tx-vout tr').should('have.class', 'ng-star-inserted');
cy.get('.error-unblinded').contains('Error: Invalid blinding data (invalid hex)'); cy.get('.error-unblinded').contains('Error: Invalid blinding data (invalid hex)');
}); });

View File

@@ -109,10 +109,10 @@ describe('Liquid Testnet', () => {
it('show empty unblinded TX', () => { it('show empty unblinded TX', () => {
cy.visit(`${basePath}/tx/c3d908ab77891e4c569b0df71aae90f4720b157019ebb20db176f4f9c4d626b8#blinded=`); cy.visit(`${basePath}/tx/c3d908ab77891e4c569b0df71aae90f4720b157019ebb20db176f4f9c4d626b8#blinded=`);
cy.waitForSkeletonGone(); cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', ''); cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vin tr:nth-child(1) .amount').should('contain.text', 'Confidential'); cy.get('.table-tx-vin tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', ''); cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', ''); cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(1) .amount').should('contain.text', 'Confidential'); cy.get('.table-tx-vout tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(2) .amount').should('contain.text', 'Confidential'); cy.get('.table-tx-vout tr:nth-child(2) .amount').should('contain.text', 'Confidential');
}); });
@@ -120,8 +120,8 @@ describe('Liquid Testnet', () => {
it('show invalid unblinded TX hex', () => { it('show invalid unblinded TX hex', () => {
cy.visit(`${basePath}/tx/2477f220eef1d03f8ffa4a2861c275d155c3562adf0d79523aeeb0c59ee611ba#blinded=5000`); cy.visit(`${basePath}/tx/2477f220eef1d03f8ffa4a2861c275d155c3562adf0d79523aeeb0c59ee611ba#blinded=5000`);
cy.waitForSkeletonGone(); cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr').should('have.class', ''); cy.get('.table-tx-vin tr').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr').should('have.class', ''); cy.get('.table-tx-vout tr').should('have.class', 'ng-star-inserted');
cy.get('.error-unblinded').contains('Error: Invalid blinding data (invalid hex)'); cy.get('.error-unblinded').contains('Error: Invalid blinding data (invalid hex)');
}); });

View File

@@ -47,7 +47,8 @@
</div> </div>
</div> </div>
<div class="item" *ngIf="showHalving"> <div class="item" *ngIf="showHalving">
<h5 class="card-title" i18n="difficulty-box.next-halving">Next Halving</h5> <h5 class="card-title" i18n="difficulty-box.next-halving" i18n-ngbTooltip="difficulty-box.next-halving"
ngbTooltip="Next Halving" placement="bottom" #averagefee [disableTooltip]="!isEllipsisActive(averagefee)">Next Halving</h5>
<div class="card-text"> <div class="card-text">
<ng-container *ngTemplateOutlet="epochData.blocksUntilHalving === 1 ? blocksSingular : blocksPlural; context: {$implicit: epochData.blocksUntilHalving }"></ng-container> <ng-container *ngTemplateOutlet="epochData.blocksUntilHalving === 1 ? blocksSingular : blocksPlural; context: {$implicit: epochData.blocksUntilHalving }"></ng-container>
<ng-template #blocksPlural let-i i18n="shared.blocks">{{ i }} <span class="shared-block">blocks</span></ng-template> <ng-template #blocksPlural let-i i18n="shared.blocks">{{ i }} <span class="shared-block">blocks</span></ng-template>
@@ -77,7 +78,7 @@
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<h5 class="card-title" i18n="difficulty-box.current-period">Current Period</h5> <h5 class="card-title" i18n="difficulty-box.next-halving">Next Halving</h5>
<div class="card-text"> <div class="card-text">
<div class="skeleton-loader"></div> <div class="skeleton-loader"></div>
<div class="skeleton-loader"></div> <div class="skeleton-loader"></div>

View File

@@ -10,6 +10,7 @@
.item { .item {
padding: 0 5px; padding: 0 5px;
width: 100%; width: 100%;
max-width: 150px;
&:nth-child(1) { &:nth-child(1) {
display: none; display: none;
@media (min-width: 485px) { @media (min-width: 485px) {
@@ -85,6 +86,9 @@
.card-title { .card-title {
color: #4a68b9; color: #4a68b9;
font-size: 1rem; font-size: 1rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.progress { .progress {

View File

@@ -83,4 +83,8 @@ export class DifficultyMiningComponent implements OnInit {
}) })
); );
} }
isEllipsisActive(e): boolean {
return (e.offsetWidth < e.scrollWidth);
}
} }

View File

@@ -32,7 +32,7 @@
</div> </div>
<div class="card-header" *ngIf="!widget"> <div class="card-header" *ngIf="!widget">
<div class="d-flex d-md-block align-items-baseline"> <div class="d-flex d-md-table-cell align-items-baseline">
<span i18n="mining.pools">Pools Ranking</span> <span i18n="mining.pools">Pools Ranking</span>
<button class="btn p-0 pl-2" style="margin: 0 0 4px 0px" (click)="onSaveChart()"> <button class="btn p-0 pl-2" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon> <fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
@@ -87,19 +87,19 @@
<table *ngIf="widget === false" class="table table-borderless text-center pools-table"> <table *ngIf="widget === false" class="table table-borderless text-center pools-table">
<thead> <thead>
<tr> <tr>
<th class="d-none d-md-block" i18n="mining.rank">Rank</th> <th class="d-none d-md-table-cell" i18n="mining.rank">Rank</th>
<th class=""></th> <th class=""></th>
<th class="" i18n="mining.pool-name">Pool</th> <th class="" i18n="mining.pool-name">Pool</th>
<th class="" *ngIf="this.miningWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th> <th class="" *ngIf="this.miningWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th>
<th class="" i18n="master-page.blocks">Blocks</th> <th class="" i18n="master-page.blocks">Blocks</th>
<th *ngIf="auditAvailable" class="health text-right widget" i18n="latest-blocks.avg_health" <th *ngIf="auditAvailable" class="health text-right widget" i18n="latest-blocks.avg_health"
i18n-ngbTooltip="latest-blocks.avg_health" ngbTooltip="Avg Health" placement="bottom" #health [disableTooltip]="!isEllipsisActive(health)">Avg Health</th> i18n-ngbTooltip="latest-blocks.avg_health" ngbTooltip="Avg Health" placement="bottom" #health [disableTooltip]="!isEllipsisActive(health)">Avg Health</th>
<th class="d-none d-md-block" i18n="mining.empty-blocks">Empty blocks</th> <th class="d-none d-md-table-cell" i18n="mining.empty-blocks">Empty blocks</th>
</tr> </tr>
</thead> </thead>
<tbody [attr.data-cy]="'pools-table'" *ngIf="(miningStatsObservable$ | async) as miningStats"> <tbody [attr.data-cy]="'pools-table'" *ngIf="(miningStatsObservable$ | async) as miningStats">
<tr *ngFor="let pool of miningStats.pools"> <tr *ngFor="let pool of miningStats.pools">
<td class="d-none d-md-block">{{ pool.rank }}</td> <td class="d-none d-md-table-cell">{{ pool.rank }}</td>
<td class="text-right"> <td class="text-right">
<img width="25" height="25" src="{{ pool.logo }}" [alt]="pool.name + ' mining pool logo'" onError="this.src = '/resources/mining-pools/default.svg'"> <img width="25" height="25" src="{{ pool.logo }}" [alt]="pool.name + ' mining pool logo'" onError="this.src = '/resources/mining-pools/default.svg'">
</td> </td>
@@ -107,7 +107,7 @@
<td class="" *ngIf="this.miningWindowPreference === '24h'">{{ pool.lastEstimatedHashrate }} {{ <td class="" *ngIf="this.miningWindowPreference === '24h'">{{ pool.lastEstimatedHashrate }} {{
miningStats.miningUnits.hashrateUnit }}</td> miningStats.miningUnits.hashrateUnit }}</td>
<td class="d-flex justify-content-center"> <td class="d-flex justify-content-center">
{{ pool.blockCount }}<span class="d-none d-md-block">&nbsp;({{ pool.share }}%)</span> {{ pool.blockCount }}<span class="d-none d-md-table-cell">&nbsp;({{ pool.share }}%)</span>
</td> </td>
<td *ngIf="auditAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"> <td *ngIf="auditAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}">
<a <a
@@ -121,16 +121,16 @@
<span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span> <span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span>
</ng-template> </ng-template>
</td> </td>
<td class="d-none d-md-block">{{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)</td> <td class="d-none d-md-table-cell">{{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%)</td>
</tr> </tr>
<tr style="border-top: 1px solid #555"> <tr style="border-top: 1px solid #555">
<td class="d-none d-md-block"></td> <td class="d-none d-md-table-cell"></td>
<td class="text-right"></td> <td class="text-right"></td>
<td class=""><b i18n="mining.all-miners">All miners</b></td> <td class=""><b i18n="mining.all-miners">All miners</b></td>
<td class="" *ngIf="this.miningWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{ <td class="" *ngIf="this.miningWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{
miningStats.miningUnits.hashrateUnit }}</b></td> miningStats.miningUnits.hashrateUnit }}</b></td>
<td class=""><b>{{ miningStats.blockCount }}</b></td> <td class=""><b>{{ miningStats.blockCount }}</b></td>
<td class="d-none d-md-block"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio <td class="d-none d-md-table-cell"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio
}}%)</b></td> }}%)</b></td>
</tr> </tr>
</tbody> </tbody>

View File

@@ -94,13 +94,13 @@
<tr> <tr>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.reward">Reward</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.reward">Reward</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="latest-blocks.avg_health">Avg Health</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="latest-blocks.avg_health" *ngIf="auditAvailable">Avg Health</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<td class="text-center"><app-amount [satoshis]="poolStats.totalReward" digitsInfo="1.0-0" [noFiat]="true"></app-amount></td> <td class="text-center"><app-amount [satoshis]="poolStats.totalReward" digitsInfo="1.0-0" [noFiat]="true"></app-amount></td>
<td class="text-center">{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td> <td class="text-center">{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td>
<td class="text-center"><span class="health-badge badge" [class.badge-success]="poolStats.avgBlockHealth >= 99" <td class="text-center" *ngIf="auditAvailable; else emptyTd"><span class="health-badge badge" [class.badge-success]="poolStats.avgBlockHealth >= 99"
[class.badge-warning]="poolStats.avgBlockHealth >= 75 && poolStats.avgBlockHealth < 99" [class.badge-danger]="poolStats.avgBlockHealth < 75" [class.badge-warning]="poolStats.avgBlockHealth >= 75 && poolStats.avgBlockHealth < 99" [class.badge-danger]="poolStats.avgBlockHealth < 75"
*ngIf="poolStats.avgBlockHealth != null; else nullHealth">{{ poolStats.avgBlockHealth }}%</span> *ngIf="poolStats.avgBlockHealth != null; else nullHealth">{{ poolStats.avgBlockHealth }}%</span>
<ng-template #nullHealth> <ng-template #nullHealth>
@@ -119,13 +119,13 @@
<tr> <tr>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.reward">Reward</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.reward">Reward</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="latest-blocks.avg_health">Avg Health</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="latest-blocks.avg_health" *ngIf="auditAvailable">Avg Health</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<td class="text-center"><app-amount [satoshis]="poolStats.totalReward" digitsInfo="1.0-0" [noFiat]="true"></app-amount></td> <td class="text-center"><app-amount [satoshis]="poolStats.totalReward" digitsInfo="1.0-0" [noFiat]="true"></app-amount></td>
<td class="text-center">{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td> <td class="text-center">{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td>
<td class="text-center"><span class="health-badge badge" [class.badge-success]="poolStats.avgBlockHealth >= 99" <td *ngIf="auditAvailable; else emptyTd" class="text-center"><span class="health-badge badge" [class.badge-success]="poolStats.avgBlockHealth >= 99"
[class.badge-warning]="poolStats.avgBlockHealth >= 75 && poolStats.avgBlockHealth < 99" [class.badge-danger]="poolStats.avgBlockHealth < 75" [class.badge-warning]="poolStats.avgBlockHealth >= 75 && poolStats.avgBlockHealth < 99" [class.badge-danger]="poolStats.avgBlockHealth < 75"
*ngIf="poolStats.avgBlockHealth != null; else nullHealth">{{ poolStats.avgBlockHealth }}%</span> *ngIf="poolStats.avgBlockHealth != null; else nullHealth">{{ poolStats.avgBlockHealth }}%</span>
<ng-template #nullHealth> <ng-template #nullHealth>
@@ -384,7 +384,7 @@
<tr> <tr>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.total-reward">Reward</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.total-reward">Reward</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.luck">Avg Health</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.luck" *ngIf="auditAvailable">Avg Health</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -394,7 +394,7 @@
<td class="text-center"> <td class="text-center">
<div class="skeleton-loader data"></div> <div class="skeleton-loader data"></div>
</td> </td>
<td class="text-center"> <td class="text-center" *ngIf="auditAvailable">
<div class="skeleton-loader data"></div> <div class="skeleton-loader data"></div>
</td> </td>
</tbody> </tbody>
@@ -409,7 +409,7 @@
<tr> <tr>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.total-reward">Reward</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.total-reward">Reward</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th>
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.luck">Avg Health</th> <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.luck" *ngIf="auditAvailable">Avg Health</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -419,7 +419,7 @@
<td class="text-center"> <td class="text-center">
<div class="skeleton-loader data"></div> <div class="skeleton-loader data"></div>
</td> </td>
<td class="text-center"> <td class="text-center" *ngIf="auditAvailable">
<div class="skeleton-loader data"></div> <div class="skeleton-loader data"></div>
</td> </td>
</tbody> </tbody>
@@ -485,4 +485,8 @@
</div> </div>
</div> </div>
</div> </div>
</ng-template>
<ng-template #emptyTd>
<td class="text-center"></td>
</ng-template> </ng-template>

View File

@@ -50,14 +50,14 @@
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<h5 class="card-title" i18n="mining.rewards-per-tx">Reward Per Tx</h5> <h5 class="card-title" i18n="mining.fees-per-block">Avg Block Fees</h5>
<div class="card-text"> <div class="card-text">
<div class="skeleton-loader"></div> <div class="skeleton-loader"></div>
<div class="skeleton-loader"></div> <div class="skeleton-loader"></div>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<h5 class="card-title" i18n="mining.average-fee">Reward Per Tx</h5> <h5 class="card-title" i18n="mining.average-fee">Avg Tx Fee</h5>
<div class="card-text"> <div class="card-text">
<div class="skeleton-loader"></div> <div class="skeleton-loader"></div>
<div class="skeleton-loader"></div> <div class="skeleton-loader"></div>

View File

@@ -18,5 +18,8 @@
<div class="text-center loading-spinner" [class]="style" *ngIf="isLoading && !disableSpinner"> <div class="text-center loading-spinner" [class]="style" *ngIf="isLoading && !disableSpinner">
<div class="spinner-border text-light"></div> <div class="spinner-border text-light"></div>
</div> </div>
<div *ngIf="showIndexingInProgress" class="indexing-message">
<span class="badge badge-pill badge-warning" i18n="lightning.indexing-in-progress">Indexing in progress</span>
</div>
</ng-container> </ng-container>
</div> </div>

View File

@@ -133,3 +133,10 @@
top: 450px; top: 450px;
} }
} }
.indexing-message {
position: absolute;
width: 100%;
text-align: center;
margin-top: 100px;
}

View File

@@ -36,6 +36,7 @@ export class NodesChannelsMap implements OnInit {
channelCurve = 0; channelCurve = 0;
nodeSize = 4; nodeSize = 4;
isLoading = false; isLoading = false;
showIndexingInProgress = false;
chartInstance = undefined; chartInstance = undefined;
chartOptions: EChartsOption = {}; chartOptions: EChartsOption = {};
@@ -206,6 +207,8 @@ export class NodesChannelsMap implements OnInit {
let title: object; let title: object;
if (channels.length === 0 && !this.placeholder) { if (channels.length === 0 && !this.placeholder) {
this.chartOptions = null; this.chartOptions = null;
this.showIndexingInProgress = true;
this.isLoading = false;
return; return;
} }

View File

@@ -38,7 +38,7 @@
</small> </small>
</div> </div>
<div [class]="!widget ? 'bottom-padding' : 'pb-0'" class="container pb-lg-0"> <div *ngIf="!indexingInProgress else indexing" [class]="!widget ? 'bottom-padding' : 'pb-0'" class="container pb-lg-0">
<div [class]="widget ? 'chart-widget' : 'chart'" echarts [initOpts]="chartInitOptions" [options]="chartOptions" <div [class]="widget ? 'chart-widget' : 'chart'" echarts [initOpts]="chartInitOptions" [options]="chartOptions"
(chartInit)="onChartInit($event)"> (chartInit)="onChartInit($event)">
</div> </div>
@@ -99,3 +99,7 @@
</div> </div>
</div> </div>
</ng-template> </ng-template>
<ng-template #indexing>
<div class="indexing-message" i18n="lightning.indexing-in-progress">Indexing in progress</div>
</ng-template>

View File

@@ -167,4 +167,14 @@
padding-left: 105px; padding-left: 105px;
padding-right: 105px; padding-right: 105px;
} }
} }
.indexing-message {
font-size: 15px;
color: grey;
font-weight: bold;
width: 100%;
padding-top: 100px;
text-align: center;
height: 240px;
}

View File

@@ -29,6 +29,7 @@ export class NodesPerISPChartComponent implements OnInit {
sortBy = 'capacity'; sortBy = 'capacity';
showUnknown = false; showUnknown = false;
chartInstance = undefined; chartInstance = undefined;
indexingInProgress = false;
@HostBinding('attr.dir') dir = 'ltr'; @HostBinding('attr.dir') dir = 'ltr';
@@ -88,6 +89,8 @@ export class NodesPerISPChartComponent implements OnInit {
this.prepareChartOptions(data.ispRanking); this.prepareChartOptions(data.ispRanking);
this.indexingInProgress = !data.ispRanking.length;
return { return {
taggedISP: data.ispRanking.length, taggedISP: data.ispRanking.length,
clearnetCapacity: data.clearnetCapacity, clearnetCapacity: data.clearnetCapacity,

View File

@@ -3203,7 +3203,7 @@
</trans-unit> </trans-unit>
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html"> <trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke erwartet</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke erwartet</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
@@ -3221,7 +3221,7 @@
</trans-unit> </trans-unit>
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html"> <trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke gefunden</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke gefunden</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">18</context> <context context-type="linenumber">18</context>
@@ -3239,7 +3239,7 @@
</trans-unit> </trans-unit>
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html"> <trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> verbleibende Blöcke</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> verbleibende Blöcke</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
@@ -3257,7 +3257,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html"> <trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke voraus</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke voraus</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">29</context> <context context-type="linenumber">29</context>
@@ -3275,7 +3275,7 @@
</trans-unit> </trans-unit>
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html"> <trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke dahinter</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke dahinter</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">34</context> <context context-type="linenumber">34</context>
@@ -3995,6 +3995,7 @@
</trans-unit> </trans-unit>
<trans-unit id="312539377512157124" datatype="html"> <trans-unit id="312539377512157124" datatype="html">
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source> <source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
<target><x id="INTERPOLATION" equiv-text="i"/> blöcke</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">165,163</context> <context context-type="linenumber">165,163</context>
@@ -4014,6 +4015,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3666195172774554282" datatype="html"> <trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source> <source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<target>Andere (<x id="PH" equiv-text="percentage"/>)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">201</context> <context context-type="linenumber">201</context>
@@ -6773,6 +6775,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5222540403093176126" datatype="html"> <trans-unit id="5222540403093176126" datatype="html">
<source><x id="PH" equiv-text="nodeCount"/> nodes</source> <source><x id="PH" equiv-text="nodeCount"/> nodes</source>
<target><x id="PH" equiv-text="nodeCount"/> nodes</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
<context context-type="linenumber">104,103</context> <context context-type="linenumber">104,103</context>

View File

@@ -3995,6 +3995,7 @@
</trans-unit> </trans-unit>
<trans-unit id="312539377512157124" datatype="html"> <trans-unit id="312539377512157124" datatype="html">
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source> <source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
<target><x id="INTERPOLATION" equiv-text="i"/> blocos</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">165,163</context> <context context-type="linenumber">165,163</context>
@@ -4014,6 +4015,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3666195172774554282" datatype="html"> <trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source> <source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<target>Outras (<x id="PH" equiv-text="percentage"/>)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">201</context> <context context-type="linenumber">201</context>
@@ -6773,6 +6775,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5222540403093176126" datatype="html"> <trans-unit id="5222540403093176126" datatype="html">
<source><x id="PH" equiv-text="nodeCount"/> nodes</source> <source><x id="PH" equiv-text="nodeCount"/> nodes</source>
<target><x id="PH" equiv-text="nodeCount"/> nós</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
<context context-type="linenumber">104,103</context> <context context-type="linenumber">104,103</context>

View File

@@ -348,7 +348,7 @@
</trans-unit> </trans-unit>
<trans-unit id="27387c2af5dcaf343a548feba821515f5dc00faa" datatype="html"> <trans-unit id="27387c2af5dcaf343a548feba821515f5dc00faa" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> transaction</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> transaction</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакция</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакция</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-address/bisq-address.component.html</context> <context context-type="sourcefile">src/app/bisq/bisq-address/bisq-address.component.html</context>
<context context-type="linenumber">48</context> <context context-type="linenumber">48</context>
@@ -373,7 +373,7 @@
</trans-unit> </trans-unit>
<trans-unit id="14779b0ce4cbc4d975a35a8fe074426228a324f3" datatype="html"> <trans-unit id="14779b0ce4cbc4d975a35a8fe074426228a324f3" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> transactions</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> transactions</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакции(й)</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакции(й)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-address/bisq-address.component.html</context> <context context-type="sourcefile">src/app/bisq/bisq-address/bisq-address.component.html</context>
<context context-type="linenumber">49</context> <context context-type="linenumber">49</context>
@@ -1109,7 +1109,7 @@
</trans-unit> </trans-unit>
<trans-unit id="8e623d3cfecb7c560c114390db53c1f430ffd0de" datatype="html"> <trans-unit id="8e623d3cfecb7c560c114390db53c1f430ffd0de" datatype="html">
<source><x id="INTERPOLATION" equiv-text="confirmation&lt;/ng-template&gt; &lt;ng-template #confirmationPlural let-i i18n=&quot;shared.confirmation-count.plural|Transaction plural confir"/> confirmation</source> <source><x id="INTERPOLATION" equiv-text="confirmation&lt;/ng-template&gt; &lt;ng-template #confirmationPlural let-i i18n=&quot;shared.confirmation-count.plural|Transaction plural confir"/> confirmation</source>
<target> <x id="INTERPOLATION" equiv-text="confirmation&lt;/ng-template&gt; &lt;ng-template #confirmationPlural let-i i18n=&quot;shared.confirmation-count.plural|Transaction plural confir"/> подтверждение</target> <target><x id="INTERPOLATION" equiv-text="confirmation&lt;/ng-template&gt; &lt;ng-template #confirmationPlural let-i i18n=&quot;shared.confirmation-count.plural|Transaction plural confir"/> подтверждение</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-transaction/bisq-transaction.component.html</context> <context context-type="sourcefile">src/app/bisq/bisq-transaction/bisq-transaction.component.html</context>
<context context-type="linenumber">20,21</context> <context context-type="linenumber">20,21</context>
@@ -1131,7 +1131,7 @@
</trans-unit> </trans-unit>
<trans-unit id="bc5b0a2631f0b7bc71aaec6aa6f01af21f9a80d4" datatype="html"> <trans-unit id="bc5b0a2631f0b7bc71aaec6aa6f01af21f9a80d4" datatype="html">
<source><x id="INTERPOLATION" equiv-text="confirmations&lt;/ng-template&gt; &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt; &lt;div class=&quot;box tran"/> confirmations</source> <source><x id="INTERPOLATION" equiv-text="confirmations&lt;/ng-template&gt; &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt; &lt;div class=&quot;box tran"/> confirmations</source>
<target> <x id="INTERPOLATION" equiv-text="confirmations&lt;/ng-template&gt; &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt; &lt;div class=&quot;box tran"/> подтверждения(й)</target> <target><x id="INTERPOLATION" equiv-text="confirmations&lt;/ng-template&gt; &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt; &lt;div class=&quot;box tran"/> подтверждения(й)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-transaction/bisq-transaction.component.html</context> <context context-type="sourcefile">src/app/bisq/bisq-transaction/bisq-transaction.component.html</context>
<context context-type="linenumber">21,22</context> <context context-type="linenumber">21,22</context>
@@ -1764,7 +1764,7 @@
</trans-unit> </trans-unit>
<trans-unit id="c3360a933cb312b395d276a2b865214cf832df58" datatype="html"> <trans-unit id="c3360a933cb312b395d276a2b865214cf832df58" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ (transactions?.length | number) || '?' }}"/> of <x id="INTERPOLATION_1" equiv-text="{{ txCount | number }}"/> </source> <source><x id="INTERPOLATION" equiv-text="{{ (transactions?.length | number) || '?' }}"/> of <x id="INTERPOLATION_1" equiv-text="{{ txCount | number }}"/> </source>
<target> <x id="INTERPOLATION" equiv-text="{{ (transactions?.length | number) || '?' }}"/> из <x id="INTERPOLATION_1" equiv-text="{{ txCount | number }}"/></target> <target><x id="INTERPOLATION" equiv-text="{{ (transactions?.length | number) || '?' }}"/> из <x id="INTERPOLATION_1" equiv-text="{{ txCount | number }}"/></target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/asset/asset.component.html</context> <context context-type="sourcefile">src/app/components/asset/asset.component.html</context>
<context context-type="linenumber">78</context> <context context-type="linenumber">78</context>
@@ -3203,6 +3203,7 @@
</trans-unit> </trans-unit>
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html"> <trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков добавлено</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
@@ -3211,6 +3212,7 @@
</trans-unit> </trans-unit>
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html"> <trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок добавлен</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">14</context> <context context-type="linenumber">14</context>
@@ -3219,6 +3221,7 @@
</trans-unit> </trans-unit>
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html"> <trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков намайнено</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">18</context> <context context-type="linenumber">18</context>
@@ -3227,6 +3230,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html"> <trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок намайнен</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">19</context> <context context-type="linenumber">19</context>
@@ -3235,6 +3239,7 @@
</trans-unit> </trans-unit>
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html"> <trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков осталось</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">24</context> <context context-type="linenumber">24</context>
@@ -3243,6 +3248,7 @@
</trans-unit> </trans-unit>
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html"> <trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок остался</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">25</context> <context context-type="linenumber">25</context>
@@ -3251,6 +3257,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html"> <trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков ожидает</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">29</context> <context context-type="linenumber">29</context>
@@ -3259,6 +3266,7 @@
</trans-unit> </trans-unit>
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html"> <trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок ожидает</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
@@ -3267,6 +3275,7 @@
</trans-unit> </trans-unit>
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html"> <trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков позади</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">34</context> <context context-type="linenumber">34</context>
@@ -3275,6 +3284,7 @@
</trans-unit> </trans-unit>
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html"> <trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок позади</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">35</context> <context context-type="linenumber">35</context>
@@ -3283,6 +3293,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html"> <trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
<source>Average block time</source> <source>Average block time</source>
<target>Среднее время блока</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context> <context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">42,45</context> <context context-type="linenumber">42,45</context>
@@ -3984,6 +3995,7 @@
</trans-unit> </trans-unit>
<trans-unit id="312539377512157124" datatype="html"> <trans-unit id="312539377512157124" datatype="html">
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source> <source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
<target><x id="INTERPOLATION" equiv-text="i"/> блоков</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">165,163</context> <context context-type="linenumber">165,163</context>
@@ -4003,6 +4015,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3666195172774554282" datatype="html"> <trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source> <source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<target>Другое ( <x id="PH" equiv-text="percentage"/> )</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">201</context> <context context-type="linenumber">201</context>
@@ -4505,7 +4518,7 @@
</trans-unit> </trans-unit>
<trans-unit id="time-since" datatype="html"> <trans-unit id="time-since" datatype="html">
<source><x id="DATE" equiv-text="dateStrings.i18nYear"/> ago</source> <source><x id="DATE" equiv-text="dateStrings.i18nYear"/> ago</source>
<target> <x id="DATE" equiv-text="dateStrings.i18nYear"/> назад</target> <target><x id="DATE" equiv-text="dateStrings.i18nYear"/> назад</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context> <context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">103</context> <context context-type="linenumber">103</context>
@@ -4565,6 +4578,7 @@
</trans-unit> </trans-unit>
<trans-unit id="time-until" datatype="html"> <trans-unit id="time-until" datatype="html">
<source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source> <source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
<target>Через ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context> <context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">126</context> <context context-type="linenumber">126</context>
@@ -5053,7 +5067,7 @@
</trans-unit> </trans-unit>
<trans-unit id="ea7c261363dc5f6134b7bacba2a1ef97f4ff7859" datatype="html"> <trans-unit id="ea7c261363dc5f6134b7bacba2a1ef97f4ff7859" datatype="html">
<source><x id="INTERPOLATION" equiv-text="remaining&lt;/ng-template&gt;"/> remaining</source> <source><x id="INTERPOLATION" equiv-text="remaining&lt;/ng-template&gt;"/> remaining</source>
<target> <x id="INTERPOLATION" equiv-text="remaining&lt;/ng-template&gt;"/> осталось</target> <target><x id="INTERPOLATION" equiv-text="remaining&lt;/ng-template&gt;"/> осталось</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/transactions-list/transactions-list.component.html</context> <context context-type="sourcefile">src/app/components/transactions-list/transactions-list.component.html</context>
<context context-type="linenumber">332,333</context> <context context-type="linenumber">332,333</context>
@@ -5106,7 +5120,7 @@
</trans-unit> </trans-unit>
<trans-unit id="25d58cd5c18fd9c1c89d6062d67dcc2482161410" datatype="html"> <trans-unit id="25d58cd5c18fd9c1c89d6062d67dcc2482161410" datatype="html">
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using native SegWit</source> <source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using native SegWit</source>
<target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/> % на комиссиях за счет использования нативного SegWit.</target> <target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% на комиссиях за счет использования нативного SegWit.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context> <context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
<context context-type="linenumber">2</context> <context context-type="linenumber">2</context>
@@ -5133,7 +5147,7 @@
</trans-unit> </trans-unit>
<trans-unit id="b6a3f6afdac6873e2d261647d834c02c91376893" datatype="html"> <trans-unit id="b6a3f6afdac6873e2d261647d834c02c91376893" datatype="html">
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using SegWit and could save <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% more by fully upgrading to native SegWit</source> <source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using SegWit and could save <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% more by fully upgrading to native SegWit</source>
<target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/> % на комиссиях за счет использования SegWit и может сэкономить еще <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/> % за счет полного перехода на нативный SegWit.</target> <target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% на комиссиях за счет использования SegWit и может сэкономить еще <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% за счет полного перехода на нативный SegWit.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context> <context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
<context context-type="linenumber">4</context> <context context-type="linenumber">4</context>
@@ -5142,7 +5156,7 @@
</trans-unit> </trans-unit>
<trans-unit id="a67530e246368aa7e5d010061fd84c3c4fe755c2" datatype="html"> <trans-unit id="a67530e246368aa7e5d010061fd84c3c4fe755c2" datatype="html">
<source>This transaction could save <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% on fees by upgrading to native SegWit or <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% by upgrading to SegWit-P2SH</source> <source>This transaction could save <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% on fees by upgrading to native SegWit or <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% by upgrading to SegWit-P2SH</source>
<target>Эта транзакция могла сэкономить <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/> % на комиссиях за счет перехода на нативный SegWit или <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/> % за счет обновления до SegWit-P2SH.</target> <target>Эта транзакция могла сэкономить <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% на комиссиях за счет перехода на нативный SegWit или <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% за счет обновления до SegWit-P2SH.</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context> <context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
<context context-type="linenumber">6</context> <context context-type="linenumber">6</context>
@@ -5264,7 +5278,7 @@
</trans-unit> </trans-unit>
<trans-unit id="60601e02e7c1f6c4dbabd0ef0bb8946003db8dec" datatype="html"> <trans-unit id="60601e02e7c1f6c4dbabd0ef0bb8946003db8dec" datatype="html">
<source>Only ~<x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat/vB was needed to get into this block</source> <source>Only ~<x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat/vB was needed to get into this block</source>
<target>Чтобы попасть в этот блок, необходимо всего ~ <x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat / vB</target> <target>Чтобы попасть в этот блок, необходимо всего ~<x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat/vB</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-fee-rating/tx-fee-rating.component.html</context> <context context-type="sourcefile">src/app/components/tx-fee-rating/tx-fee-rating.component.html</context>
<context context-type="linenumber">2</context> <context context-type="linenumber">2</context>
@@ -5277,7 +5291,7 @@
</trans-unit> </trans-unit>
<trans-unit id="0fa66b0c410bef320d3f370d7c98c51754b5f28f" datatype="html"> <trans-unit id="0fa66b0c410bef320d3f370d7c98c51754b5f28f" datatype="html">
<source>Overpaid <x id="INTERPOLATION" equiv-text="{{ overpaidTimes }}"/>x</source> <source>Overpaid <x id="INTERPOLATION" equiv-text="{{ overpaidTimes }}"/>x</source>
<target>Переплачено <x id="INTERPOLATION" equiv-text="{{ overpaidTimes }}"/> x</target> <target>Переплачено <x id="INTERPOLATION" equiv-text="{{ overpaidTimes }}"/>x</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-fee-rating/tx-fee-rating.component.html</context> <context context-type="sourcefile">src/app/components/tx-fee-rating/tx-fee-rating.component.html</context>
<context context-type="linenumber">2</context> <context context-type="linenumber">2</context>
@@ -5564,7 +5578,7 @@
</trans-unit> </trans-unit>
<trans-unit id="205c1b86ac1cc419c4d0cca51fdde418c4ffdc20" datatype="html"> <trans-unit id="205c1b86ac1cc419c4d0cca51fdde418c4ffdc20" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> channels</source> <source><x id="INTERPOLATION" equiv-text="{{ i }}"/> channels</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> каналов</target> <target><x id="INTERPOLATION" equiv-text="{{ i }}"/> каналов</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context> <context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
<context context-type="linenumber">79</context> <context context-type="linenumber">79</context>
@@ -6712,6 +6726,7 @@
</trans-unit> </trans-unit>
<trans-unit id="599038141003770125" datatype="html"> <trans-unit id="599038141003770125" datatype="html">
<source>Clearnet and Darknet</source> <source>Clearnet and Darknet</source>
<target>Clearnet и Darknet</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">164,161</context> <context context-type="linenumber">164,161</context>
@@ -6723,6 +6738,7 @@
</trans-unit> </trans-unit>
<trans-unit id="1282458597026430784" datatype="html"> <trans-unit id="1282458597026430784" datatype="html">
<source>Clearnet Only (IPv4, IPv6)</source> <source>Clearnet Only (IPv4, IPv6)</source>
<target>Только Clearnet (IPv4, IPv6)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">185,182</context> <context context-type="linenumber">185,182</context>
@@ -6734,6 +6750,7 @@
</trans-unit> </trans-unit>
<trans-unit id="2165336009914523952" datatype="html"> <trans-unit id="2165336009914523952" datatype="html">
<source>Darknet Only (Tor, I2P, cjdns)</source> <source>Darknet Only (Tor, I2P, cjdns)</source>
<target>Только Darknet (Tor, I2P, cjdns)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">206,203</context> <context context-type="linenumber">206,203</context>
@@ -6758,6 +6775,7 @@
</trans-unit> </trans-unit>
<trans-unit id="5222540403093176126" datatype="html"> <trans-unit id="5222540403093176126" datatype="html">
<source><x id="PH" equiv-text="nodeCount"/> nodes</source> <source><x id="PH" equiv-text="nodeCount"/> nodes</source>
<target><x id="PH" equiv-text="nodeCount"/> узлов</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
<context context-type="linenumber">104,103</context> <context context-type="linenumber">104,103</context>
@@ -7020,7 +7038,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.year" datatype="html"> <trans-unit id="date-base.year" datatype="html">
<source><x id="DATE" equiv-text="counter"/> year</source> <source><x id="DATE" equiv-text="counter"/> year</source>
<target> <x id="DATE" equiv-text="counter"/> год</target> <target><x id="DATE" equiv-text="counter"/> год</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">3</context> <context context-type="linenumber">3</context>
@@ -7028,7 +7046,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.years" datatype="html"> <trans-unit id="date-base.years" datatype="html">
<source><x id="DATE" equiv-text="counter"/> years</source> <source><x id="DATE" equiv-text="counter"/> years</source>
<target> <x id="DATE" equiv-text="counter"/> лет</target> <target><x id="DATE" equiv-text="counter"/> лет</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">4</context> <context context-type="linenumber">4</context>
@@ -7036,7 +7054,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.month" datatype="html"> <trans-unit id="date-base.month" datatype="html">
<source><x id="DATE" equiv-text="counter"/> month</source> <source><x id="DATE" equiv-text="counter"/> month</source>
<target> <x id="DATE" equiv-text="counter"/> месяц</target> <target><x id="DATE" equiv-text="counter"/> месяц</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>
@@ -7044,7 +7062,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.months" datatype="html"> <trans-unit id="date-base.months" datatype="html">
<source><x id="DATE" equiv-text="counter"/> months</source> <source><x id="DATE" equiv-text="counter"/> months</source>
<target> <x id="DATE" equiv-text="counter"/> месяцев</target> <target><x id="DATE" equiv-text="counter"/> месяцев</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">6</context> <context context-type="linenumber">6</context>
@@ -7052,7 +7070,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.week" datatype="html"> <trans-unit id="date-base.week" datatype="html">
<source><x id="DATE" equiv-text="counter"/> week</source> <source><x id="DATE" equiv-text="counter"/> week</source>
<target> <x id="DATE" equiv-text="counter"/> неделя</target> <target><x id="DATE" equiv-text="counter"/> неделю</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">7</context> <context context-type="linenumber">7</context>
@@ -7060,7 +7078,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.weeks" datatype="html"> <trans-unit id="date-base.weeks" datatype="html">
<source><x id="DATE" equiv-text="counter"/> weeks</source> <source><x id="DATE" equiv-text="counter"/> weeks</source>
<target> <x id="DATE" equiv-text="counter"/> недель</target> <target><x id="DATE" equiv-text="counter"/> недели</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">8</context> <context context-type="linenumber">8</context>
@@ -7068,7 +7086,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.day" datatype="html"> <trans-unit id="date-base.day" datatype="html">
<source><x id="DATE" equiv-text="counter"/> day</source> <source><x id="DATE" equiv-text="counter"/> day</source>
<target> <x id="DATE" equiv-text="counter"/> дней</target> <target><x id="DATE" equiv-text="counter"/> дней</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">9</context> <context context-type="linenumber">9</context>
@@ -7076,7 +7094,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.days" datatype="html"> <trans-unit id="date-base.days" datatype="html">
<source><x id="DATE" equiv-text="counter"/> days</source> <source><x id="DATE" equiv-text="counter"/> days</source>
<target> <x id="DATE" equiv-text="counter"/> дней</target> <target><x id="DATE" equiv-text="counter"/> дней</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">10</context> <context context-type="linenumber">10</context>
@@ -7084,7 +7102,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.hour" datatype="html"> <trans-unit id="date-base.hour" datatype="html">
<source><x id="DATE" equiv-text="counter"/> hour</source> <source><x id="DATE" equiv-text="counter"/> hour</source>
<target> <x id="DATE" equiv-text="counter"/> час</target> <target><x id="DATE" equiv-text="counter"/> час</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">11</context> <context context-type="linenumber">11</context>
@@ -7092,7 +7110,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.hours" datatype="html"> <trans-unit id="date-base.hours" datatype="html">
<source><x id="DATE" equiv-text="counter"/> hours</source> <source><x id="DATE" equiv-text="counter"/> hours</source>
<target> <x id="DATE" equiv-text="counter"/> часов</target> <target><x id="DATE" equiv-text="counter"/> часов</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">12</context> <context context-type="linenumber">12</context>
@@ -7100,7 +7118,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.minute" datatype="html"> <trans-unit id="date-base.minute" datatype="html">
<source><x id="DATE" equiv-text="counter"/> minute</source> <source><x id="DATE" equiv-text="counter"/> minute</source>
<target> <x id="DATE" equiv-text="counter"/> минута</target> <target><x id="DATE" equiv-text="counter"/> минута</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">13</context> <context context-type="linenumber">13</context>
@@ -7108,7 +7126,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.minutes" datatype="html"> <trans-unit id="date-base.minutes" datatype="html">
<source><x id="DATE" equiv-text="counter"/> minutes</source> <source><x id="DATE" equiv-text="counter"/> minutes</source>
<target> <x id="DATE" equiv-text="counter"/> минут</target> <target><x id="DATE" equiv-text="counter"/> минут</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">14</context> <context context-type="linenumber">14</context>
@@ -7116,7 +7134,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.second" datatype="html"> <trans-unit id="date-base.second" datatype="html">
<source><x id="DATE" equiv-text="counter"/> second</source> <source><x id="DATE" equiv-text="counter"/> second</source>
<target> <x id="DATE" equiv-text="counter"/> секунда</target> <target><x id="DATE" equiv-text="counter"/> секунда</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">15</context> <context context-type="linenumber">15</context>
@@ -7124,7 +7142,7 @@
</trans-unit> </trans-unit>
<trans-unit id="date-base.seconds" datatype="html"> <trans-unit id="date-base.seconds" datatype="html">
<source><x id="DATE" equiv-text="counter"/> seconds</source> <source><x id="DATE" equiv-text="counter"/> seconds</source>
<target> <x id="DATE" equiv-text="counter"/> секунд</target> <target><x id="DATE" equiv-text="counter"/> секунд</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context> <context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">16</context> <context context-type="linenumber">16</context>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 31 KiB