[i18n] add language changing at runtime in webconsole

Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
R4SAS 2021-06-27 17:14:45 +03:00
parent 6d2c9e367b
commit 12d6f03dc9
No known key found for this signature in database
GPG Key ID: 66F6C87B98EBCFE2
9 changed files with 396 additions and 354 deletions

View File

@ -26,548 +26,554 @@ msgstr ""
msgid "Enabled"
msgstr ""
#: daemon/HTTPServer.cpp:141
#: daemon/HTTPServer.cpp:147
msgid "day"
msgid_plural "days"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:145
#: daemon/HTTPServer.cpp:151
msgid "hour"
msgid_plural "hours"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:149
#: daemon/HTTPServer.cpp:155
msgid "minute"
msgid_plural "minutes"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:152
#: daemon/HTTPServer.cpp:158
msgid "second"
msgid_plural "seconds"
msgstr[0] ""
msgstr[1] ""
#: daemon/HTTPServer.cpp:160 daemon/HTTPServer.cpp:188
#: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194
msgid "KiB"
msgstr ""
#: daemon/HTTPServer.cpp:162
#: daemon/HTTPServer.cpp:168
msgid "MiB"
msgstr ""
#: daemon/HTTPServer.cpp:164
#: daemon/HTTPServer.cpp:170
msgid "GiB"
msgstr ""
#: daemon/HTTPServer.cpp:181
#: daemon/HTTPServer.cpp:187
msgid "building"
msgstr ""
#: daemon/HTTPServer.cpp:182
#: daemon/HTTPServer.cpp:188
msgid "failed"
msgstr ""
#: daemon/HTTPServer.cpp:183
#: daemon/HTTPServer.cpp:189
msgid "expiring"
msgstr ""
#: daemon/HTTPServer.cpp:184
#: daemon/HTTPServer.cpp:190
msgid "established"
msgstr ""
#: daemon/HTTPServer.cpp:185
#: daemon/HTTPServer.cpp:191
msgid "unknown"
msgstr ""
#: daemon/HTTPServer.cpp:187
#: daemon/HTTPServer.cpp:193
msgid "exploratory"
msgstr ""
#: daemon/HTTPServer.cpp:223
#: daemon/HTTPServer.cpp:229
msgid "<b>i2pd</b> webconsole"
msgstr ""
#: daemon/HTTPServer.cpp:226
#: daemon/HTTPServer.cpp:232
msgid "Main page"
msgstr ""
#: daemon/HTTPServer.cpp:227 daemon/HTTPServer.cpp:683
#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:689
msgid "Router commands"
msgstr ""
#: daemon/HTTPServer.cpp:228
#: daemon/HTTPServer.cpp:234
msgid "Local destinations"
msgstr ""
#: daemon/HTTPServer.cpp:230 daemon/HTTPServer.cpp:382
#: daemon/HTTPServer.cpp:463 daemon/HTTPServer.cpp:469
#: daemon/HTTPServer.cpp:599 daemon/HTTPServer.cpp:642
#: daemon/HTTPServer.cpp:646
#: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388
#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475
#: daemon/HTTPServer.cpp:605 daemon/HTTPServer.cpp:648
#: daemon/HTTPServer.cpp:652
msgid "LeaseSets"
msgstr ""
#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:652
#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:658
msgid "Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:727
#: daemon/HTTPServer.cpp:743
#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:746
#: daemon/HTTPServer.cpp:762
msgid "Transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:792
#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:811
msgid "Transports"
msgstr ""
#: daemon/HTTPServer.cpp:235
#: daemon/HTTPServer.cpp:241
msgid "I2P tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:237 daemon/HTTPServer.cpp:854
#: daemon/HTTPServer.cpp:864
#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:873
#: daemon/HTTPServer.cpp:883
msgid "SAM sessions"
msgstr ""
#: daemon/HTTPServer.cpp:253 daemon/HTTPServer.cpp:1254
#: daemon/HTTPServer.cpp:1257 daemon/HTTPServer.cpp:1260
#: daemon/HTTPServer.cpp:1274 daemon/HTTPServer.cpp:1319
#: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1325
#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1273
#: daemon/HTTPServer.cpp:1276 daemon/HTTPServer.cpp:1279
#: daemon/HTTPServer.cpp:1293 daemon/HTTPServer.cpp:1338
#: daemon/HTTPServer.cpp:1341 daemon/HTTPServer.cpp:1344
msgid "ERROR"
msgstr ""
#: daemon/HTTPServer.cpp:260
#: daemon/HTTPServer.cpp:266
msgid "OK"
msgstr ""
#: daemon/HTTPServer.cpp:261
#: daemon/HTTPServer.cpp:267
msgid "Testing"
msgstr ""
#: daemon/HTTPServer.cpp:262
#: daemon/HTTPServer.cpp:268
msgid "Firewalled"
msgstr ""
#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:284
#: daemon/HTTPServer.cpp:370
#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:290
#: daemon/HTTPServer.cpp:376
msgid "Unknown"
msgstr ""
#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:394
#: daemon/HTTPServer.cpp:395 daemon/HTTPServer.cpp:922
#: daemon/HTTPServer.cpp:931
#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400
#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:941
#: daemon/HTTPServer.cpp:950
msgid "Proxy"
msgstr ""
#: daemon/HTTPServer.cpp:265
#: daemon/HTTPServer.cpp:271
msgid "Mesh"
msgstr ""
#: daemon/HTTPServer.cpp:268
#: daemon/HTTPServer.cpp:274
msgid "Error"
msgstr ""
#: daemon/HTTPServer.cpp:272
#: daemon/HTTPServer.cpp:278
msgid "Clock skew"
msgstr ""
#: daemon/HTTPServer.cpp:275
#: daemon/HTTPServer.cpp:281
msgid "Offline"
msgstr ""
#: daemon/HTTPServer.cpp:278
#: daemon/HTTPServer.cpp:284
msgid "Symmetric NAT"
msgstr ""
#: daemon/HTTPServer.cpp:290
#: daemon/HTTPServer.cpp:296
msgid "Uptime"
msgstr ""
#: daemon/HTTPServer.cpp:293
#: daemon/HTTPServer.cpp:299
msgid "Network status"
msgstr ""
#: daemon/HTTPServer.cpp:298
#: daemon/HTTPServer.cpp:304
msgid "Network status v6"
msgstr ""
#: daemon/HTTPServer.cpp:304 daemon/HTTPServer.cpp:311
#: daemon/HTTPServer.cpp:310 daemon/HTTPServer.cpp:317
msgid "Stopping in"
msgstr ""
#: daemon/HTTPServer.cpp:318
#: daemon/HTTPServer.cpp:324
msgid "Family"
msgstr ""
#: daemon/HTTPServer.cpp:319
#: daemon/HTTPServer.cpp:325
msgid "Tunnel creation success rate"
msgstr ""
#: daemon/HTTPServer.cpp:320
#: daemon/HTTPServer.cpp:326
msgid "Received"
msgstr ""
#: daemon/HTTPServer.cpp:322 daemon/HTTPServer.cpp:325
#: daemon/HTTPServer.cpp:328
#: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331
#: daemon/HTTPServer.cpp:334
msgid "KiB/s"
msgstr ""
#: daemon/HTTPServer.cpp:323
#: daemon/HTTPServer.cpp:329
msgid "Sent"
msgstr ""
#: daemon/HTTPServer.cpp:326
#: daemon/HTTPServer.cpp:332
msgid "Transit"
msgstr ""
#: daemon/HTTPServer.cpp:329
#: daemon/HTTPServer.cpp:335
msgid "Data path"
msgstr ""
#: daemon/HTTPServer.cpp:332
#: daemon/HTTPServer.cpp:338
msgid "Hidden content. Press on text to see."
msgstr ""
#: daemon/HTTPServer.cpp:335
#: daemon/HTTPServer.cpp:341
msgid "Router Ident"
msgstr ""
#: daemon/HTTPServer.cpp:337
#: daemon/HTTPServer.cpp:343
msgid "Router Family"
msgstr ""
#: daemon/HTTPServer.cpp:338
#: daemon/HTTPServer.cpp:344
msgid "Router Caps"
msgstr ""
#: daemon/HTTPServer.cpp:339
#: daemon/HTTPServer.cpp:345
msgid "Version"
msgstr ""
#: daemon/HTTPServer.cpp:340
#: daemon/HTTPServer.cpp:346
msgid "Our external address"
msgstr ""
#: daemon/HTTPServer.cpp:348
#: daemon/HTTPServer.cpp:354
msgid "supported"
msgstr ""
#: daemon/HTTPServer.cpp:380
#: daemon/HTTPServer.cpp:386
msgid "Routers"
msgstr ""
#: daemon/HTTPServer.cpp:381
#: daemon/HTTPServer.cpp:387
msgid "Floodfills"
msgstr ""
#: daemon/HTTPServer.cpp:388 daemon/HTTPServer.cpp:908
#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:927
msgid "Client Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:389
#: daemon/HTTPServer.cpp:395
msgid "Transit Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:393
#: daemon/HTTPServer.cpp:399
msgid "Services"
msgstr ""
#: daemon/HTTPServer.cpp:407 daemon/HTTPServer.cpp:419
#: daemon/HTTPServer.cpp:413 daemon/HTTPServer.cpp:425
msgid "Local Destinations"
msgstr ""
#: daemon/HTTPServer.cpp:442
#: daemon/HTTPServer.cpp:448
msgid "Encrypted B33 address"
msgstr ""
#: daemon/HTTPServer.cpp:451
#: daemon/HTTPServer.cpp:457
msgid "Address registration line"
msgstr ""
#: daemon/HTTPServer.cpp:456
#: daemon/HTTPServer.cpp:462
msgid "Domain"
msgstr ""
#: daemon/HTTPServer.cpp:457
#: daemon/HTTPServer.cpp:463
msgid "Generate"
msgstr ""
#: daemon/HTTPServer.cpp:458
#: daemon/HTTPServer.cpp:464
msgid ""
"<b>Note:</b> result string can be used only for registering 2LD domains "
"(example.i2p). For registering subdomains please use i2pd-tools."
msgstr ""
#: daemon/HTTPServer.cpp:464
#: daemon/HTTPServer.cpp:470
msgid "Address"
msgstr ""
#: daemon/HTTPServer.cpp:464
#: daemon/HTTPServer.cpp:470
msgid "Type"
msgstr ""
#: daemon/HTTPServer.cpp:464
#: daemon/HTTPServer.cpp:470
msgid "EncType"
msgstr ""
#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:657
#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:663
msgid "Inbound tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:489
#: daemon/HTTPServer.cpp:662 daemon/HTTPServer.cpp:672
#: Means milliseconds
#. Milliseconds
#: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495
#: daemon/HTTPServer.cpp:668 daemon/HTTPServer.cpp:678
msgid "ms"
msgstr ""
#: daemon/HTTPServer.cpp:484 daemon/HTTPServer.cpp:667
#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:673
msgid "Outbound tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:496
#: daemon/HTTPServer.cpp:502
msgid "Tags"
msgstr ""
#: daemon/HTTPServer.cpp:496
#: daemon/HTTPServer.cpp:502
msgid "Incoming"
msgstr ""
#: daemon/HTTPServer.cpp:503 daemon/HTTPServer.cpp:506
#: daemon/HTTPServer.cpp:509 daemon/HTTPServer.cpp:512
msgid "Outgoing"
msgstr ""
#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:520
#: daemon/HTTPServer.cpp:510 daemon/HTTPServer.cpp:526
msgid "Destination"
msgstr ""
#: daemon/HTTPServer.cpp:504
#: daemon/HTTPServer.cpp:510
msgid "Amount"
msgstr ""
#: daemon/HTTPServer.cpp:511
#: daemon/HTTPServer.cpp:517
msgid "Incoming Tags"
msgstr ""
#: daemon/HTTPServer.cpp:519 daemon/HTTPServer.cpp:522
#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:528
msgid "Tags sessions"
msgstr ""
#: daemon/HTTPServer.cpp:520
#: daemon/HTTPServer.cpp:526
msgid "Status"
msgstr ""
#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:584
#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:590
msgid "Local Destination"
msgstr ""
#: daemon/HTTPServer.cpp:538 daemon/HTTPServer.cpp:887
#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:906
msgid "Streams"
msgstr ""
#: daemon/HTTPServer.cpp:560
#: daemon/HTTPServer.cpp:566
msgid "Close stream"
msgstr ""
#: daemon/HTTPServer.cpp:589
#: daemon/HTTPServer.cpp:595
msgid "I2CP session not found"
msgstr ""
#: daemon/HTTPServer.cpp:592
#: daemon/HTTPServer.cpp:598
msgid "I2CP is not enabled"
msgstr ""
#: daemon/HTTPServer.cpp:618
#: daemon/HTTPServer.cpp:624
msgid "Invalid"
msgstr ""
#: daemon/HTTPServer.cpp:621
#: daemon/HTTPServer.cpp:627
msgid "Store type"
msgstr ""
#: daemon/HTTPServer.cpp:622
#: daemon/HTTPServer.cpp:628
msgid "Expires"
msgstr ""
#: daemon/HTTPServer.cpp:627
#: daemon/HTTPServer.cpp:633
msgid "Non Expired Leases"
msgstr ""
#: daemon/HTTPServer.cpp:630
#: daemon/HTTPServer.cpp:636
msgid "Gateway"
msgstr ""
#: daemon/HTTPServer.cpp:631
#: daemon/HTTPServer.cpp:637
msgid "TunnelID"
msgstr ""
#: daemon/HTTPServer.cpp:632
#: daemon/HTTPServer.cpp:638
msgid "EndDate"
msgstr ""
#: daemon/HTTPServer.cpp:642
#: daemon/HTTPServer.cpp:648
msgid "not floodfill"
msgstr ""
#: daemon/HTTPServer.cpp:653
#: daemon/HTTPServer.cpp:659
msgid "Queue size"
msgstr ""
#: daemon/HTTPServer.cpp:684
#: daemon/HTTPServer.cpp:690
msgid "Run peer test"
msgstr ""
#: daemon/HTTPServer.cpp:687
#: daemon/HTTPServer.cpp:693
msgid "Decline transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:689
#: daemon/HTTPServer.cpp:695
msgid "Accept transit tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:692 daemon/HTTPServer.cpp:697
#: daemon/HTTPServer.cpp:698 daemon/HTTPServer.cpp:703
msgid "Cancel graceful shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:694 daemon/HTTPServer.cpp:699
#: daemon/HTTPServer.cpp:700 daemon/HTTPServer.cpp:705
msgid "Start graceful shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:701
#: daemon/HTTPServer.cpp:707
msgid "Force shutdown"
msgstr ""
#: daemon/HTTPServer.cpp:704
#: daemon/HTTPServer.cpp:710
msgid ""
"<b>Note:</b> any action done here are not persistent and not changes your "
"config files."
msgstr ""
#: daemon/HTTPServer.cpp:706
#: daemon/HTTPServer.cpp:712
msgid "Logging level"
msgstr ""
#: daemon/HTTPServer.cpp:714
#: daemon/HTTPServer.cpp:720
msgid "Transit tunnels limit"
msgstr ""
#: daemon/HTTPServer.cpp:719
#: daemon/HTTPServer.cpp:725 daemon/HTTPServer.cpp:737
msgid "Change"
msgstr ""
#: daemon/HTTPServer.cpp:743
#: daemon/HTTPServer.cpp:729
msgid "Change language"
msgstr ""
#: daemon/HTTPServer.cpp:762
msgid "no transit tunnels currently built"
msgstr ""
#: daemon/HTTPServer.cpp:848 daemon/HTTPServer.cpp:871
#: daemon/HTTPServer.cpp:867 daemon/HTTPServer.cpp:890
msgid "SAM disabled"
msgstr ""
#: daemon/HTTPServer.cpp:864
#: daemon/HTTPServer.cpp:883
msgid "no sessions currently running"
msgstr ""
#: daemon/HTTPServer.cpp:877
#: daemon/HTTPServer.cpp:896
msgid "SAM session not found"
msgstr ""
#: daemon/HTTPServer.cpp:882
#: daemon/HTTPServer.cpp:901
msgid "SAM Session"
msgstr ""
#: daemon/HTTPServer.cpp:939
#: daemon/HTTPServer.cpp:958
msgid "Server Tunnels"
msgstr ""
#: daemon/HTTPServer.cpp:955
#: daemon/HTTPServer.cpp:974
msgid "Client Forwards"
msgstr ""
#: daemon/HTTPServer.cpp:969
#: daemon/HTTPServer.cpp:988
msgid "Server Forwards"
msgstr ""
#: daemon/HTTPServer.cpp:1175
#: daemon/HTTPServer.cpp:1194
msgid "Unknown page"
msgstr ""
#: daemon/HTTPServer.cpp:1194
#: daemon/HTTPServer.cpp:1213
msgid "Invalid token"
msgstr ""
#: daemon/HTTPServer.cpp:1252 daemon/HTTPServer.cpp:1309
#: daemon/HTTPServer.cpp:1337
#: daemon/HTTPServer.cpp:1271 daemon/HTTPServer.cpp:1328
#: daemon/HTTPServer.cpp:1364
msgid "SUCCESS"
msgstr ""
#: daemon/HTTPServer.cpp:1252
#: daemon/HTTPServer.cpp:1271
msgid "Stream closed"
msgstr ""
#: daemon/HTTPServer.cpp:1254
#: daemon/HTTPServer.cpp:1273
msgid "Stream not found or already was closed"
msgstr ""
#: daemon/HTTPServer.cpp:1257
#: daemon/HTTPServer.cpp:1276
msgid "Destination not found"
msgstr ""
#: daemon/HTTPServer.cpp:1260
#: daemon/HTTPServer.cpp:1279
msgid "StreamID can't be null"
msgstr ""
#: daemon/HTTPServer.cpp:1262 daemon/HTTPServer.cpp:1327
#: daemon/HTTPServer.cpp:1281 daemon/HTTPServer.cpp:1346
msgid "Return to destination page"
msgstr ""
#: daemon/HTTPServer.cpp:1263 daemon/HTTPServer.cpp:1276
#: daemon/HTTPServer.cpp:1282 daemon/HTTPServer.cpp:1295
msgid "You will be redirected back in 5 seconds"
msgstr ""
#: daemon/HTTPServer.cpp:1274
#: daemon/HTTPServer.cpp:1293
msgid "Transit tunnels count must not exceed 65535"
msgstr ""
#: daemon/HTTPServer.cpp:1275 daemon/HTTPServer.cpp:1338
#: daemon/HTTPServer.cpp:1294 daemon/HTTPServer.cpp:1365
msgid "Back to commands list"
msgstr ""
#: daemon/HTTPServer.cpp:1311
#: daemon/HTTPServer.cpp:1330
msgid "Register at reg.i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1312
#: daemon/HTTPServer.cpp:1331
msgid "Description"
msgstr ""
#: daemon/HTTPServer.cpp:1312
#: daemon/HTTPServer.cpp:1331
msgid "A bit information about service on domain"
msgstr ""
#: daemon/HTTPServer.cpp:1313
#: daemon/HTTPServer.cpp:1332
msgid "Submit"
msgstr ""
#: daemon/HTTPServer.cpp:1319
#: daemon/HTTPServer.cpp:1338
msgid "Domain can't end with .b32.i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1322
#: daemon/HTTPServer.cpp:1341
msgid "Domain must end with .i2p"
msgstr ""
#: daemon/HTTPServer.cpp:1325
#: daemon/HTTPServer.cpp:1344
msgid "Such destination is not found"
msgstr ""
#: daemon/HTTPServer.cpp:1333
#: daemon/HTTPServer.cpp:1360
msgid "Unknown command"
msgstr ""
#: daemon/HTTPServer.cpp:1337
#: daemon/HTTPServer.cpp:1364
msgid "Command accepted"
msgstr ""
#: daemon/HTTPServer.cpp:1339
#: daemon/HTTPServer.cpp:1366
msgid "You will be redirected in 5 seconds"
msgstr ""

View File

@ -68,11 +68,11 @@ namespace http {
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
<< " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n"
<< " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n"
<< " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n"
<< " .menu { float: left; } .menu a, .commands a { display: block; }\r\n"
<< " .wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n"
<< " .menu { display: block; float: left; overflow: hidden; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; }\r\n"
<< " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
<< " .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
<< " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; overflow: auto; }\r\n"
<< " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 48em; overflow: auto; }\r\n"
<< " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n"
<< " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n"
<< " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
@ -84,19 +84,24 @@ namespace http {
<< " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n"
<< " .disabled:after { color: #D33F3F; content: \"" << tr("Disabled") << "\" }\r\n"
<< " .enabled:after { color: #56B734; content: \"" << tr("Enabled") << "\" }\r\n"
<< " @media screen and (max-width: 980px) {\r\n" /* adaptive style */
<< " @media screen and (max-width: 1150px) {\r\n" /* adaptive style */
<< " .wrapper { max-width: 58em; } .menu { max-width: 10em; }\r\n"
<< " .content { margin-left: 2em; max-width: 42em; }\r\n"
<< " }\r\n"
<< " @media screen and (max-width: 980px) {\r\n"
<< " body { padding: 1.5em 0 0 0; }\r\n"
<< " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n"
<< " .menu { width: 100%; max-width: unset; display: block; float: none; position: unset; font-size: 16px;\r\n"
<< " text-align: center; }\r\n"
<< " .menu a, .commands a { padding: 2px; }\r\n"
<< " .menu a, .commands a { display: inline-block; padding: 4px; }\r\n"
<< " .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n"
<< " text-align: center; }\r\n"
<< " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n"
<< " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n"
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
<< " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n"
<< " input { width: 35%; text-align: center; padding: 5px;\r\n"
<< " input, select { width: 35%; text-align: center; padding: 5px;\r\n"
<< " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n"
<< " table.extaddr { margin: auto; text-align: unset; }\r\n"
<< " textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n"
<< " -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n"
<< " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n"
@ -127,6 +132,7 @@ namespace http {
const char HTTP_COMMAND_KILLSTREAM[] = "closestream";
const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit";
const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string";
const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage";
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
const char HTTP_PARAM_ADDRESS[] = "address";
@ -223,18 +229,18 @@ namespace http {
"<div class=\"header\">" << tr("<b>i2pd</b> webconsole") << "</div>\r\n"
"<div class=\"wrapper\">\r\n"
"<div class=\"menu\">\r\n"
" <a href=\"" << webroot << "\">" << tr("Main page") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">" << tr("Router commands") << "</a>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">" << tr("Local destinations") << "</a>\r\n";
" <a href=\"" << webroot << "\">" << tr("Main page") << "</a><br><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">" << tr("Router commands") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">" << tr("Local destinations") << "</a><br>\r\n";
if (i2p::context.IsFloodfill ())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">" << tr("LeaseSets") << "</a>\r\n";
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">" << tr("LeaseSets") << "</a><br>\r\n";
s <<
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">" << tr("Tunnels") << "</a>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit tunnels") << "</a>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a>\r\n";
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">" << tr("Tunnels") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit tunnels") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a><br>\r\n"
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a><br>\r\n";
if (i2p::client::context.GetSAMBridge ())
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a>\r\n";
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a><br>\r\n";
s <<
"</div>\r\n"
"<div class=\"content\">";
@ -476,7 +482,7 @@ namespace http {
s << "<div class=\"listitem\">";
it->Print(s);
if(it->LatencyIsKnown())
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
s << " ( " << it->GetMeanLatency() << tr(/* Milliseconds */ "ms") << " )";
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
s << "</div>\r\n";
}
@ -681,22 +687,22 @@ namespace http {
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
/* commands */
s << "<b>" << tr("Router commands") << "</b><br>\r\n<br>\r\n<div class=\"commands\">\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">" << tr("Run peer test") << "</a>\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">" << tr("Run peer test") << "</a><br>\r\n";
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
if (i2p::context.AcceptsTunnels ())
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">" << tr("Decline transit tunnels") << "</a>\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">" << tr("Decline transit tunnels") << "</a><br>\r\n";
else
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">" << tr("Accept transit tunnels") << "</a>\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">" << tr("Accept transit tunnels") << "</a><br>\r\n";
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
if (Daemon.gracefulShutdownInterval)
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
else
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a>\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
#elif defined(WIN32_APP)
if (i2p::util::DaemonWin32::Instance().isGraceful)
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a><br>\r\n";
else
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a>\r\n";
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
#endif
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">" << tr("Force shutdown") << "</a>\r\n";
s << "</div>";
@ -718,6 +724,19 @@ namespace http {
s << " <input type=\"number\" min=\"0\" max=\"65535\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
s << "</form>\r\n<br>\r\n";
std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language
s << "<b>" << tr("Change language") << "</b><br>\r\n";
s << "<form method=\"get\" action=\"" << webroot << "\">\r\n";
s << " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_SETLANGUAGE << "\">\r\n";
s << " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n";
s << " <select name=\"lang\" id=\"lang\">\r\n";
for (const auto& it: i2p::i18n::languages)
s << " <option value=\"" << it.first << "\"" << ((it.first.compare(currLang) == 0) ? " selected" : "") << ">" << it.second.LocaleName << "</option>\r\n";
s << " </select>\r\n";
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
s << "</form>\r\n<br>\r\n";
}
void ShowTransitTunnels (std::stringstream& s)
@ -1327,6 +1346,14 @@ namespace http {
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a>\r\n";
return;
}
else if (cmd == HTTP_COMMAND_SETLANGUAGE)
{
std::string lang = params["lang"];
std::string currLang = i2p::context.GetLanguage ()->GetLanguage();
if (currLang.compare(lang) != 0)
i2p::i18n::SetLanguage(lang);
}
else
{
res.code = 400;

View File

@ -18,8 +18,11 @@ namespace i2p
{
namespace i18n
{
namespace afrikaans // language
namespace afrikaans // language namespace
{
// language name in lowercase
static std::string language = "afrikaans";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
@ -65,7 +68,7 @@ namespace afrikaans // language
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language

View File

@ -19,8 +19,11 @@ namespace i2p
{
namespace i18n
{
namespace english // language
namespace english // language namespace
{
// language name in lowercase
static std::string language = "english";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
@ -39,7 +42,7 @@ namespace english // language
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language

View File

@ -17,16 +17,11 @@ namespace i18n
{
inline void SetLanguage(const std::string &lang)
{
if (!lang.compare("afrikaans"))
i2p::context.SetLanguage (i2p::i18n::afrikaans::GetLocale());
else if (!lang.compare("russian"))
i2p::context.SetLanguage (i2p::i18n::russian::GetLocale());
else if (!lang.compare("turkmen"))
i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale());
else if (!lang.compare("ukrainian"))
i2p::context.SetLanguage (i2p::i18n::ukrainian::GetLocale());
else // fallback
const auto it = i2p::i18n::languages.find(lang);
if (it == i2p::i18n::languages.end()) // fallback
i2p::context.SetLanguage (i2p::i18n::english::GetLocale());
else
i2p::context.SetLanguage (it->second.LocaleFunc());
}
inline std::string translate (const std::string& arg)

View File

@ -17,10 +17,17 @@ namespace i18n
{
public:
Locale (
const std::string& language,
const std::map<std::string, std::string>& strings,
const std::map<std::string, std::vector<std::string>>& plurals,
std::function<int(int)> formula
): m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { };
): m_Language (language), m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { };
// Get activated language name for webconsole
std::string GetLanguage() const
{
return m_Language;
}
std::string GetString (const std::string& arg) const
{
@ -50,11 +57,18 @@ namespace i18n
}
private:
const std::string m_Language;
const std::map<std::string, std::string> m_Strings;
const std::map<std::string, std::vector<std::string>> m_Plurals;
std::function<int(int)> m_Formula;
};
struct langData
{
std::string LocaleName; //localized name
std::function<std::shared_ptr<const i2p::i18n::Locale> (void)> LocaleFunc;
};
// Add localization here with language name as namespace
namespace afrikaans { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace english { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
@ -62,6 +76,18 @@ namespace i18n
namespace turkmen { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
namespace ukrainian { std::shared_ptr<const i2p::i18n::Locale> GetLocale (); }
/**
* That map contains international language name lower-case and name in it's language
*/
static std::map<std::string, langData> languages
{
{ "afrikaans", {"Afrikaans", i2p::i18n::afrikaans::GetLocale} },
{ "english", {"English", i2p::i18n::english::GetLocale} },
{ "russian", {"русский язык", i2p::i18n::russian::GetLocale} },
{ "turkmen", {"türkmen dili", i2p::i18n::turkmen::GetLocale} },
{ "ukrainian", {"украї́нська мо́ва", i2p::i18n::ukrainian::GetLocale} },
};
} // i18n
} // i2p

View File

@ -18,8 +18,11 @@ namespace i2p
{
namespace i18n
{
namespace russian // language
namespace russian // language namespace
{
// language name in lowercase
static std::string language = "russian";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
@ -28,23 +31,152 @@ namespace russian // language
static std::map<std::string, std::string> strings
{
// HTTP Proxy
{"Disabled", "Выключено"},
{"Enabled", "Включено"},
{"KiB", "КиБ"},
{"MiB", "МиБ"},
{"GiB", "ГиБ"},
{"building", "строится"},
{"failed", "неудачный"},
{"expiring", "истекает"},
{"established", "работает"},
{"unknown", "неизвестно"},
{"exploratory", "исследовательский"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
{"Main page", "Главная"},
{"Router commands", "Команды роутера"},
{"Local destinations", "Локальные назначения"},
{"LeaseSets", "Лизсеты"},
{"Tunnels", "Туннели"},
{"Transit tunnels", "Транзитные туннели"},
{"Transports", "Транспорты"},
{"I2P tunnels", "I2P туннели"},
{"SAM sessions", "SAM сессии"},
{"ERROR", "ОШИБКА"},
{"OK", "OK"},
{"Testing", "Тестирование"},
{"Firewalled", "Заблокировано извне"},
{"Unknown", "Неизвестно"},
{"Proxy", "Прокси"},
{"Mesh", "MESH-сеть"},
{"Error", "Ошибка"},
{"Clock skew", "Не точное время"},
{"Offline", "Оффлайн"},
{"Symmetric NAT", "Симметричный NAT"},
{"Uptime", "В сети"},
{"Network status", "Сетевой статус"},
{"Network status v6", "Сетевой статус v6"},
{"Stopping in", "Остановка через"},
{"Family", "Семейство"},
{"Tunnel creation success rate", "Успешно построенных туннелей"},
{"Received", "Получено"},
{"KiB/s", "КиБ/с"},
{"Sent", "Отправлено"},
{"Transit", "Транзит"},
{"Data path", "Путь к данным"},
{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
{"Router Ident", "Идентификатор роутера"},
{"Router Family", "Семейство роутера"},
{"Router Caps", "Флаги роутера"},
{"Version", "Версия"},
{"Our external address", "Наш внешний адрес"},
{"supported", "поддерживается"},
{"Routers", "Роутеры"},
{"Floodfills", "Флудфилы"},
{"Client Tunnels", "Клиентские туннели"},
{"Transit Tunnels", "Транзитные туннели"},
{"Services", "Сервисы"},
{"Local Destinations", "Локальные назначения"},
{"Encrypted B33 address", "Шифрованные B33 адреса"},
{"Address registration line", "Строка регистрации адреса"},
{"Domain", "Домен"},
{"Generate", "Сгенерировать"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "<b>Примечание:</b> полученная строка может быть использована только для регистрации доменов второго уровня (example.i2p). Для регистрации поддоменов используйте i2pd-tools."},
{"Address", "Адрес"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Inbound tunnels", "Входящие туннели"},
{"ms", "мс"},
{"Outbound tunnels", "Исходящие туннели"},
{"Tags", "Теги"},
{"Incoming", "Входящие"},
{"Outgoing", "Исходящие"},
{"Destination", "Назначение"},
{"Amount", "Количество"},
{"Incoming Tags", "Входящие Теги"},
{"Tags sessions", "Сессии Тегов"},
{"Status", "Статус"},
{"Local Destination", "Локальное назначение"},
{"Streams", "Стримы"},
{"Close stream", "Закрыть стрим"},
{"I2CP session not found", "I2CP сессия не найдена"},
{"I2CP is not enabled", "I2CP не включен"},
{"Invalid", "Некорректный"},
{"Store type", "Тип хранилища"},
{"Expires", "Истекает"},
{"Non Expired Leases", "Не истекшие Lease-ы"},
{"Gateway", "Шлюз"},
{"TunnelID", "ID туннеля"},
{"EndDate", "Заканчивается"},
{"not floodfill", "не флудфил"},
{"Queue size", "Размер очереди"},
{"Run peer test", "Запустить тестирование"},
{"Decline transit tunnels", "Отклонять транзитные туннели"},
{"Accept transit tunnels", "Принимать транзитные туннели"},
{"Cancel graceful shutdown", "Отменить плавную остановку"},
{"Start graceful shutdown", "Запустить плавную остановку"},
{"Force shutdown", "Принудительная остановка"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.", "<b>Примечание:</b> любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
{"Logging level", "Уровень логирования"},
{"Transit tunnels limit", "Лимит транзитных туннелей"},
{"Change", "Изменить"},
{"Change language", "Изменение языка"},
{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
{"SAM disabled", "SAM выключен"},
{"no sessions currently running", "нет запущенных сессий"},
{"SAM session not found", "SAM сессия не найдена"},
{"SAM Session", "SAM сессия"},
{"Server Tunnels", "Серверные туннели"},
{"Client Forwards", "Клиентские перенаправления"},
{"Server Forwards", "Серверные перенаправления"},
{"Unknown page", "Неизвестная страница"},
{"Invalid token", "Неверный токен"},
{"SUCCESS", "УСПЕШНО"},
{"Stream closed", "Стрим закрыт"},
{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
{"Destination not found", "Точка назначения не найдена"},
{"StreamID can't be null", "StreamID не может быть пустым"},
{"Return to destination page", "Вернуться на страницу точки назначения"},
{"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"},
{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
{"Back to commands list", "Вернуться к списку команд"},
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
{"Description", "Описание"},
{"A bit information about service on domain", "Немного информации о сервисе на домене"},
{"Submit", "Отправить"},
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
{"Such destination is not found", "Такая точка назначения не найдена"},
{"Unknown command", "Неизвестная команда"},
{"Command accepted", "Команда принята"},
{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
{"Proxy error", "Ошибка прокси"},
{"Proxy info", "Информация прокси"},
{"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"},
{"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"},
{"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"},
{"Proxy error: Host not found", "Ошибка прокси: Узел не найден"},
{"Remote host not found in router's addressbook", "Запрошенный узел не найден в адресной книге роутера"},
{"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"},
{"Invalid request", "Некорректный запрос"},
{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
{"addresshelper is not supported", "addresshelper не поддерживается"},
{"Host", "Адрес"},
{"Host", "Узел"},
{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
{"already in router's addressbook", "уже в адресной книге роутера"},
{"Click", "Нажмите"},
{"here", "здесь"},
{"to proceed", "чтобы продолжить"},
{"to update record", "чтобы обновить запись"},
{"Addresshelper found", "Найден addresshelper"},
{"already in router's addressbook", "уже в адресной книге роутера"},
{"to update record", "чтобы обновить запись"},
{"Invalid Request", "неверный запрос"},
{"invalid request uri", "некорректный URI запроса"},
{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
{"Outproxy failure", "Ошибка внешнего прокси"},
@ -63,169 +195,13 @@ namespace russian // language
{"cannot connect", "не удалось подключиться"},
{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
{"Host is down", "Адрес недоступен"},
{"Can't create connection to requested host, it may be down. Please try again later.",
"Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."},
// Webconsole //
// cssStyles
{"Disabled", "Выключено"},
{"Enabled", "Включено"},
// ShowTraffic
{"KiB", "КиБ"},
{"MiB", "МиБ"},
{"GiB", "ГиБ"},
// ShowTunnelDetails
{"building", "строится"},
{"failed", "неудачный"},
{"expiring", "истекает"},
{"established", "работает"},
{"exploratory", "исследовательский"},
{"unknown", "неизвестно"},
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
// ShowPageHead
{"Main page", "Главная"},
{"Router commands", "Команды роутера"},
{"Local destinations", "Локальные назнач."},
{"LeaseSets", "Лизсеты"},
{"Tunnels", "Туннели"},
{"Transit tunnels", "Транзит. туннели"},
{"Transports", "Транспорты"},
{"I2P tunnels", "I2P туннели"},
{"SAM sessions", "SAM сессии"},
// Network Status
{"OK", "OK"},
{"Testing", "Тестирование"},
{"Firewalled", "Заблокировано извне"},
{"Unknown", "Неизвестно"},
{"Proxy", "Прокси"},
{"Mesh", "MESH-сеть"},
{"Error", "Ошибка"},
{"Clock skew", "Не точное время"},
{"Offline", "Оффлайн"},
{"Symmetric NAT", "Симметричный NAT"},
// Status
{"Uptime", "В сети"},
{"Network status", "Сетевой статус"},
{"Network status v6", "Сетевой статус v6"},
{"Stopping in", "Остановка через"},
{"Family", "Семейство"},
{"Tunnel creation success rate", "Успешно построенных туннелей"},
{"Received", "Получено"},
{"Sent", "Отправлено"},
{"Transit", "Транзит"},
{"KiB/s", "КиБ/с"},
{"Data path", "Путь к данным"},
{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
{"Router Ident", "Идентификатор роутера"},
{"Router Family", "Семейство роутера"},
{"Router Caps", "Флаги роутера"},
{"Version", "Версия"},
{"Our external address", "Наш внешний адрес"},
{"supported", "поддерживается"},
{"Routers", "Роутеры"},
{"Floodfills", "Флудфилы"},
{"LeaseSets", "Лизсеты"},
{"Client Tunnels", "Клиентские туннели"},
{"Transit Tunnels", "Транзитные туннели"},
{"Services", "Сервисы"},
// ShowLocalDestinations
{"Local Destinations", "Локальные назначения"},
// ShowLeaseSetDestination
{"Encrypted B33 address", "Шифрованные B33 адреса"},
{"Address registration line", "Строка регистрации адреса"},
{"Domain", "Домен"},
{"Generate", "Сгенерировать"},
{"<b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.",
"<b>Примечание:</b> полученная строка может быть использована только для регистрации доменов второго уровня. Для регистрации поддоменов используйте i2pd-tools."},
{"Address", "Адрес"},
{"Type", "Тип"},
{"EncType", "ТипШифр"},
{"Inbound tunnels", "Входящие туннели"},
{"Outbound tunnels", "Исходящие туннели"},
{"ms", "мс"}, // milliseconds
{"Tags", "Теги"},
{"Incoming", "Входящие"},
{"Outgoing", "Исходящие"},
{"Destination", "Назначение"},
{"Amount", "Количество"},
{"Incoming Tags", "Входящие Теги"},
{"Tags sessions", "Сессии Тегов"},
{"Status", "Статус"},
// ShowLocalDestination
{"Local Destination", "Локальное назначение"},
{"Streams", "Стримы"},
{"Close stream", "Закрыть стрим"},
// ShowI2CPLocalDestination
{"I2CP session not found", "I2CP сессия не найдена"},
{"I2CP is not enabled", "I2CP не включен"},
// ShowLeasesSets
{"Invalid", "Некорректный"},
{"Store type", "Тип хранилища"},
{"Expires", "Истекает"},
{"Non Expired Leases", "Не истекшие Lease-ы"},
{"Gateway", "Шлюз"},
{"TunnelID", "ID туннеля"},
{"EndDate", "Заканчивается"},
{"not floodfill", "не флудфил"},
// ShowTunnels
{"Queue size", "Размер очереди"},
// ShowCommands
{"Run peer test", "Запустить тестирование"},
{"Decline transit tunnels", "Отклонять транзитные туннели"},
{"Accept transit tunnels", "Принимать транзитные туннели"},
{"Cancel graceful shutdown", "Отменить плавную остановку"},
{"Start graceful shutdown", "Запустить плавную остановку"},
{"Force shutdown", "Принудительная остановка"},
{"<b>Note:</b> any action done here are not persistent and not changes your config files.",
"<b>Примечание:</b> любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
{"Logging level", "Уровень логирования"},
{"Transit tunnels limit", "Лимит транзитных туннелей"},
{"Change", "Изменить"},
// ShowTransitTunnels
{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
// ShowSAMSessions/ShowSAMSession
{"SAM disabled", "SAM выключен"},
{"SAM session not found", "SAM сессия не найдена"},
{"no sessions currently running", "нет запущенных сессий"},
{"SAM Session", "SAM сессия"},
// ShowI2PTunnels
{"Server Tunnels", "Серверные туннели"},
{"Client Forwards", "Клиентские перенаправления"},
{"Server Forwards", "Серверные перенаправления"},
// HandlePage
{"Unknown page", "Неизвестная страница"},
// HandleCommand, ShowError
{"Invalid token", "Неверный токен"},
{"SUCCESS", "УСПЕШНО"},
{"ERROR", "ОШИБКА"},
{"Unknown command", "Неизвестная команда"},
{"Command accepted", "Команда принята"},
{"Back to commands list", "Вернуться к списку команд"},
{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
// HTTP_COMMAND_KILLSTREAM
{"Stream closed", "Стрим закрыт"},
{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
{"Destination not found", "Точка назначения не найдена"},
{"StreamID can't be null", "StreamID не может быть пустым"},
{"Return to destination page", "Вернуться на страницу точки назначения"},
{"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"},
// HTTP_COMMAND_LIMITTRANSIT
{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
// HTTP_COMMAND_GET_REG_STRING
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
{"Description", "Описание"},
{"A bit information about service on domain", "Немного информации о сервисе на домене"},
{"Submit", "Отправить"},
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
{"Such destination is not found", "Такая точка назначения не найдена"},
{"Host is down", "Узел недоступен"},
{"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."},
{"", ""},
};
static std::map<std::string, std::vector<std::string>> plurals
{
// ShowUptime
{"days", {"день", "дня", "дней"}},
{"hours", {"час", "часа", "часов"}},
{"minutes", {"минуту", "минуты", "минут"}},
@ -235,7 +211,7 @@ namespace russian // language
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language

View File

@ -18,8 +18,11 @@ namespace i2p
{
namespace i18n
{
namespace turkmen // language
namespace turkmen // language namespace
{
// language name in lowercase
static std::string language = "turkmen";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
@ -234,7 +237,7 @@ namespace turkmen // language
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language

View File

@ -18,8 +18,11 @@ namespace i2p
{
namespace i18n
{
namespace ukrainian // language
namespace ukrainian // language namespace
{
// language name in lowercase
static std::string language = "ukrainian";
// See for language plural forms here:
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
static int plural (int n) {
@ -207,7 +210,7 @@ namespace ukrainian // language
std::shared_ptr<const i2p::i18n::Locale> GetLocale()
{
return std::make_shared<i2p::i18n::Locale>(strings, plurals, [] (int n)->int { return plural(n); });
return std::make_shared<i2p::i18n::Locale>(language, strings, plurals, [] (int n)->int { return plural(n); });
}
} // language