Updated 40 lines and blitz averages + view to see them

Also very tiny little small bugfix
This commit is contained in:
dan63047 2024-05-29 00:05:01 +03:00
parent 3394605d4a
commit a1a508963c
12 changed files with 239 additions and 64 deletions

View File

@ -141,45 +141,87 @@ const Map<String, Color> rankColors = { // thanks osk for const rankColors at ht
'z': Color(0xFF375433)
};
const Map<String, Duration> sprintAverages = { // based on https://discord.com/channels/673303546107658242/917098364787650590/1214231970259673098
'x': Duration(seconds: 25, milliseconds: 413),
'u': Duration(seconds: 34, milliseconds: 549),
'ss': Duration(seconds: 43, milliseconds: 373),
's+': Duration(seconds: 54, milliseconds: 027),
's': Duration(seconds: 60, milliseconds: 412),
's-': Duration(seconds: 67, milliseconds: 381),
'a+': Duration(seconds: 73, milliseconds: 694),
'a': Duration(seconds: 81, milliseconds: 166),
'a-': Duration(seconds: 88, milliseconds: 334),
'b+': Duration(seconds: 93, milliseconds: 741),
'b': Duration(seconds: 98, milliseconds: 354),
'b-': Duration(seconds: 109, milliseconds: 610),
'c+': Duration(seconds: 124, milliseconds: 641),
'c': Duration(seconds: 126, milliseconds: 104),
'c-': Duration(seconds: 145, milliseconds: 865),
'd+': Duration(seconds: 154, milliseconds: 338),
'd': Duration(seconds: 162, milliseconds: 063),
// const Map<String, Duration> sprintAverages = { // old data, based on https://discord.com/channels/673303546107658242/917098364787650590/1214231970259673098
// 'x': Duration(seconds: 25, milliseconds: 413),
// 'u': Duration(seconds: 34, milliseconds: 549),
// 'ss': Duration(seconds: 43, milliseconds: 373),
// 's+': Duration(seconds: 54, milliseconds: 027),
// 's': Duration(seconds: 60, milliseconds: 412),
// 's-': Duration(seconds: 67, milliseconds: 381),
// 'a+': Duration(seconds: 73, milliseconds: 694),
// 'a': Duration(seconds: 81, milliseconds: 166),
// 'a-': Duration(seconds: 88, milliseconds: 334),
// 'b+': Duration(seconds: 93, milliseconds: 741),
// 'b': Duration(seconds: 98, milliseconds: 354),
// 'b-': Duration(seconds: 109, milliseconds: 610),
// 'c+': Duration(seconds: 124, milliseconds: 641),
// 'c': Duration(seconds: 126, milliseconds: 104),
// 'c-': Duration(seconds: 145, milliseconds: 865),
// 'd+': Duration(seconds: 154, milliseconds: 338),
// 'd': Duration(seconds: 162, milliseconds: 063),
// //'z': Duration(seconds: 66, milliseconds: 802)
// };
// const Map<String, int> blitzAverages = {
// 'x': 626494,
// 'u': 406059,
// 'ss': 243166,
// 's+': 168636,
// 's': 121594,
// 's-': 107845,
// 'a+': 87142,
// 'a': 73413,
// 'a-': 60799,
// 'b+': 55417,
// 'b': 47608,
// 'b-': 40534,
// 'c+': 34200,
// 'c': 32535,
// 'c-': 25808,
// 'd+': 23345,
// 'd': 23063,
// //'z': 72084
// };
const Map<String, Duration> sprintAverages = { // based on https://discord.com/channels/673303546107658242/674421736162197515/1244287342965952562
'x': Duration(seconds: 25, milliseconds: 144),
'u': Duration(seconds: 36, milliseconds: 115),
'ss': Duration(seconds: 46, milliseconds: 396),
's+': Duration(seconds: 55, milliseconds: 056),
's': Duration(seconds: 61, milliseconds: 892),
's-': Duration(seconds: 68, milliseconds: 918),
'a+': Duration(seconds: 76, milliseconds: 187),
'a': Duration(seconds: 83, milliseconds: 529),
'a-': Duration(seconds: 88, milliseconds: 608),
'b+': Duration(seconds: 97, milliseconds: 626),
'b': Duration(seconds: 104, milliseconds: 687),
'b-': Duration(seconds: 113, milliseconds: 372),
'c+': Duration(seconds: 123, milliseconds: 461),
'c': Duration(seconds: 135, milliseconds: 326),
'c-': Duration(seconds: 147, milliseconds: 056),
'd+': Duration(seconds: 156, milliseconds: 757),
'd': Duration(seconds: 167, milliseconds: 393),
//'z': Duration(seconds: 66, milliseconds: 802)
};
const Map<String, int> blitzAverages = {
'x': 626494,
'u': 406059,
'ss': 243166,
's+': 168636,
's': 121594,
's-': 107845,
'a+': 87142,
'a': 73413,
'a-': 60799,
'b+': 55417,
'b': 47608,
'b-': 40534,
'c+': 34200,
'c': 32535,
'c-': 25808,
'd+': 23345,
'd': 23063,
'x': 600715,
'u': 379418,
'ss': 233740,
's+': 158295,
's': 125164,
's-': 100933,
'a+': 83593,
'a': 68613,
'a-': 60219,
'b+': 51197,
'b': 44171,
'b-': 39045,
'c+': 34130,
'c': 28931,
'c-': 25095,
'd+': 22944,
'd': 20728,
//'z': 72084
};

View File

@ -4,9 +4,9 @@
/// To regenerate, run: `dart run slang`
///
/// Locales: 2
/// Strings: 1138 (569 per locale)
/// Strings: 1144 (572 per locale)
///
/// Built on 2024-05-04 at 19:13 UTC
/// Built on 2024-05-28 at 20:38 UTC
// coverage:ignore-file
// ignore_for_file: type=lint
@ -303,6 +303,9 @@ class Translations implements BaseTranslations<AppLocale, Translations> {
String get calc => 'Calc';
String get calcViewNoValues => 'Enter values to calculate the stats';
String get rankAveragesViewTitle => 'Ranks cutoff and average stats';
String get sprintAndBlitsViewTitle => '40 lines and Blitz averages';
String sprintAndBlitsRelevance({required Object date}) => 'Relevance: ${date}';
String get rank => 'Rank';
String get averages => 'Averages';
String get lbViewZeroEntrys => 'Empty list';
String get lbViewOneEntry => 'There is only one player';
@ -709,7 +712,7 @@ class _StringsStatCellNumEn {
String get nyaappDescription => '(Abbreviated as wAPP) Essentially, a measure of your ability to send cheese while still maintaining a high APP.\nInvented by Wertj.';
String get area => 'Area';
String get areaDescription => 'How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections';
String get estOfTR => 'Est. of TR';
String get estOfTR => 'Estimated TR';
String get estOfTRShort => 'Est. TR';
String get accOfEst => 'Accuracy';
String get accOfEstShort => 'Acc.';
@ -782,16 +785,16 @@ class _StringsErrorsEn {
String forbiddenSub({required Object nickname}) => 'If you are using VPN or Proxy, turn it off. If this does not help, reach out to ${nickname}';
String get tooManyRequests => 'You have been rate limited.';
String get tooManyRequestsSub => 'Wait a few moments and try again';
String get internal => 'Something happend on the tetr.io side';
String get internal => 'Something happened on the tetr.io side';
String get internalSub => 'osk, probably, already aware about it';
String get internalWebVersion => 'Something happend on the tetr.io side (or on oskware_bridge, idk honestly)';
String get internalWebVersion => 'Something happened on the tetr.io side (or on oskware_bridge, idk honestly)';
String get internalWebVersionSub => 'If osk status page says that everything is ok, let dan63047 know about this issue';
String get oskwareBridge => 'Something happend with oskware_bridge';
String get oskwareBridge => 'Something happened with oskware_bridge';
String get oskwareBridgeSub => 'Let dan63047 know';
String get p1nkl0bst3rForbidden => 'Third party API blocked your IP address';
String get p1nkl0bst3rTooManyRequests => 'Too many requests to third party API. Try again later';
String get p1nkl0bst3rinternal => 'Something happend on the p1nkl0bst3r side';
String get p1nkl0bst3rinternalWebVersion => 'Something happend on the p1nkl0bst3r side (or on oskware_bridge, idk honestly)';
String get p1nkl0bst3rinternal => 'Something happened on the p1nkl0bst3r side';
String get p1nkl0bst3rinternalWebVersion => 'Something happened on the p1nkl0bst3r side (or on oskware_bridge, idk honestly)';
String get replayAlreadySaved => 'Replay already saved';
String get replayExpired => 'Replay expired and not available anymore';
String get replayRejected => 'Third party API blocked your IP address';
@ -976,6 +979,9 @@ class _StringsRu implements Translations {
@override String get calc => 'Считать';
@override String get calcViewNoValues => 'Введите значения, чтобы посчитать статистику';
@override String get rankAveragesViewTitle => 'Требования рангов и средние значения';
@override String get sprintAndBlitsViewTitle => 'Средние результаты 40 линий и блица';
@override String sprintAndBlitsRelevance({required Object date}) => 'Актуальность: ${date}';
@override String get rank => 'Ранг';
@override String get averages => 'Средние значения';
@override String get lbViewZeroEntrys => 'Рейтинговая таблица пуста';
@override String get lbViewOneEntry => 'В рейтинговой таблице всего один игрок';
@ -1641,6 +1647,9 @@ extension on Translations {
case 'calc': return 'Calc';
case 'calcViewNoValues': return 'Enter values to calculate the stats';
case 'rankAveragesViewTitle': return 'Ranks cutoff and average stats';
case 'sprintAndBlitsViewTitle': return '40 lines and Blitz averages';
case 'sprintAndBlitsRelevance': return ({required Object date}) => 'Relevance: ${date}';
case 'rank': return 'Rank';
case 'averages': return 'Averages';
case 'lbViewZeroEntrys': return 'Empty list';
case 'lbViewOneEntry': return 'There is only one player';
@ -1731,7 +1740,7 @@ extension on Translations {
case 'statCellNum.nyaappDescription': return '(Abbreviated as wAPP) Essentially, a measure of your ability to send cheese while still maintaining a high APP.\nInvented by Wertj.';
case 'statCellNum.area': return 'Area';
case 'statCellNum.areaDescription': return 'How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections';
case 'statCellNum.estOfTR': return 'Est. of TR';
case 'statCellNum.estOfTR': return 'Estimated TR';
case 'statCellNum.estOfTRShort': return 'Est. TR';
case 'statCellNum.accOfEst': return 'Accuracy';
case 'statCellNum.accOfEstShort': return 'Acc.';
@ -1785,16 +1794,16 @@ extension on Translations {
case 'errors.forbiddenSub': return ({required Object nickname}) => 'If you are using VPN or Proxy, turn it off. If this does not help, reach out to ${nickname}';
case 'errors.tooManyRequests': return 'You have been rate limited.';
case 'errors.tooManyRequestsSub': return 'Wait a few moments and try again';
case 'errors.internal': return 'Something happend on the tetr.io side';
case 'errors.internal': return 'Something happened on the tetr.io side';
case 'errors.internalSub': return 'osk, probably, already aware about it';
case 'errors.internalWebVersion': return 'Something happend on the tetr.io side (or on oskware_bridge, idk honestly)';
case 'errors.internalWebVersion': return 'Something happened on the tetr.io side (or on oskware_bridge, idk honestly)';
case 'errors.internalWebVersionSub': return 'If osk status page says that everything is ok, let dan63047 know about this issue';
case 'errors.oskwareBridge': return 'Something happend with oskware_bridge';
case 'errors.oskwareBridge': return 'Something happened with oskware_bridge';
case 'errors.oskwareBridgeSub': return 'Let dan63047 know';
case 'errors.p1nkl0bst3rForbidden': return 'Third party API blocked your IP address';
case 'errors.p1nkl0bst3rTooManyRequests': return 'Too many requests to third party API. Try again later';
case 'errors.p1nkl0bst3rinternal': return 'Something happend on the p1nkl0bst3r side';
case 'errors.p1nkl0bst3rinternalWebVersion': return 'Something happend on the p1nkl0bst3r side (or on oskware_bridge, idk honestly)';
case 'errors.p1nkl0bst3rinternal': return 'Something happened on the p1nkl0bst3r side';
case 'errors.p1nkl0bst3rinternalWebVersion': return 'Something happened on the p1nkl0bst3r side (or on oskware_bridge, idk honestly)';
case 'errors.replayAlreadySaved': return 'Replay already saved';
case 'errors.replayExpired': return 'Replay expired and not available anymore';
case 'errors.replayRejected': return 'Third party API blocked your IP address';
@ -2230,6 +2239,9 @@ extension on _StringsRu {
case 'calc': return 'Считать';
case 'calcViewNoValues': return 'Введите значения, чтобы посчитать статистику';
case 'rankAveragesViewTitle': return 'Требования рангов и средние значения';
case 'sprintAndBlitsViewTitle': return 'Средние результаты 40 линий и блица';
case 'sprintAndBlitsRelevance': return ({required Object date}) => 'Актуальность: ${date}';
case 'rank': return 'Ранг';
case 'averages': return 'Средние значения';
case 'lbViewZeroEntrys': return 'Рейтинговая таблица пуста';
case 'lbViewOneEntry': return 'В рейтинговой таблице всего один игрок';

View File

@ -23,14 +23,12 @@ class CalcView extends StatefulWidget {
}
class CalcState extends State<CalcView> {
late ScrollController _scrollController;
TextEditingController ppsController = TextEditingController();
TextEditingController apmController = TextEditingController();
TextEditingController vsController = TextEditingController();
@override
void initState() {
_scrollController = ScrollController();
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS){
windowManager.getTitle().then((value) => oldWindowTitle = value);
windowManager.setTitle("Tetra Stats: ${t.statsCalc}");

View File

@ -18,6 +18,7 @@ import 'package:tetra_stats/services/crud_exceptions.dart';
import 'package:tetra_stats/utils/numers_formats.dart';
import 'package:tetra_stats/utils/text_shadow.dart';
import 'package:tetra_stats/views/ranks_averages_view.dart' show RankAveragesView;
import 'package:tetra_stats/views/sprint_and_blitz_averages.dart';
import 'package:tetra_stats/views/tl_leaderboard_view.dart' show TLLeaderboardView;
import 'package:tetra_stats/views/tl_match_view.dart' show TlMatchResultView;
import 'package:tetra_stats/widgets/finesse_thingy.dart';
@ -665,6 +666,20 @@ class _NavDrawerState extends State<NavDrawer> {
},
),
),
SliverToBoxAdapter(
child: ListTile( // Rank averages button
leading: const Icon(Icons.bar_chart),
title: Text(t.sprintAndBlitsViewTitle),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SprintAndBlitzView(),
),
);
},
),
),
const SliverToBoxAdapter(child: Divider())
];
},

View File

@ -276,7 +276,7 @@ class SettingsState extends State<SettingsView> {
onTap: (){
launchInBrowser(Uri.https("github.com", "dan63047/TetraStats"));
},
title: Text(t.aboutApp, style: TextStyle(fontWeight: FontWeight.w500),),
title: Text(t.aboutApp, style: const TextStyle(fontWeight: FontWeight.w500),),
subtitle: Text(t.aboutAppText(appName: packageInfo.appName, packageName: packageInfo.packageName, version: packageInfo.version, buildNumber: packageInfo.buildNumber)),
trailing: const Icon(Icons.arrow_right)
),

View File

@ -0,0 +1,102 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:tetra_stats/data_objects/tetrio.dart';
import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/utils/text_shadow.dart';
import 'package:tetra_stats/views/main_view.dart';
import 'package:window_manager/window_manager.dart';
late String oldWindowTitle;
final DateFormat dateFormat = DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode);
class SprintAndBlitzView extends StatefulWidget {
const SprintAndBlitzView({super.key});
@override
State<StatefulWidget> createState() => SprintAndBlitzState();
}
class SprintAndBlitzState extends State<SprintAndBlitzView> {
@override
void initState() {
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS){
windowManager.getTitle().then((value) => oldWindowTitle = value);
windowManager.setTitle("Tetra Stats: ${t.settings}");
}
super.initState();
}
@override
void dispose(){
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) windowManager.setTitle(oldWindowTitle);
super.dispose();
}
@override
Widget build(BuildContext context) {
final t = Translations.of(context);
return Scaffold(
appBar: AppBar(
title: Text(t.sprintAndBlitsViewTitle),
),
backgroundColor: Colors.black,
body: SafeArea(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
alignment: Alignment.center,
constraints: const BoxConstraints(maxWidth: 600),
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
border: TableBorder.all(color: Colors.grey.shade900),
columnWidths: {0: const FixedColumnWidth(48)},
children: [
TableRow(
children: [
Text(t.rank, textAlign: TextAlign.center, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white)),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Text(t.sprint, textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, fontWeight: FontWeight.w500, color: Colors.white)),
),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Text(t.blitz, textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, fontWeight: FontWeight.w500, color: Colors.white)),
),
]
),
for (MapEntry<String, Duration> sprintEntry in sprintAverages.entries) TableRow(
decoration: BoxDecoration(gradient: LinearGradient(colors: [rankColors[sprintEntry.key]!.withAlpha(100), rankColors[sprintEntry.key]!.withAlpha(200)])),
children: [
Container(decoration: BoxDecoration(boxShadow: [BoxShadow(color: Colors.black.withAlpha(132), blurRadius: 32.0, blurStyle: BlurStyle.inner)]), child: Image.asset("res/tetrio_tl_alpha_ranks/${sprintEntry.key}.png", height: 48)),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Text(get40lTime(sprintEntry.value.inMicroseconds), textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, fontWeight: FontWeight.w500, color: Colors.white, shadows: textShadow)),
),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Text(NumberFormat.decimalPattern().format(blitzAverages[sprintEntry.key]), textAlign: TextAlign.right, style: const TextStyle(fontFamily: "Eurostile Round", fontSize: 28, fontWeight: FontWeight.w500, color: Colors.white, shadows: textShadow)),
),
]
)
],
),
Text(t.sprintAndBlitsRelevance(date: dateFormat.format(DateTime(2024, 5, 26))))
],
),
),
),
],
)),
);
}
}

View File

@ -21,16 +21,17 @@ class FinesseThingy extends StatelessWidget{
return Stack(
alignment: AlignmentDirectional.bottomStart,
children: [
Text("f", style: TextStyle(
const Text("f", style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 65,
height: 1.2,
)),
Positioned(child: Text("inesse", style: TextStyle(fontFamily: "Eurostile Round Extended")), left: 25, top: 20),
const Positioned(left: 25, top: 20, child: Text("inesse", style: TextStyle(fontFamily: "Eurostile Round Extended"))),
Positioned(
right: 0, top: 20,
child: Text("${finesse != null ? finesse!.faults : "---"}F", style: TextStyle(
color: getFinesseColor()
)), right: 0, top: 20),
))),
Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text("${finesse != null ? f2.format(finessePercentage! * 100) : "---.--"}%", style: TextStyle(

View File

@ -4,7 +4,6 @@ import 'package:tetra_stats/data_objects/tetrio.dart';
import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/utils/colors_functions.dart';
import 'package:tetra_stats/utils/numers_formats.dart';
import 'package:tetra_stats/widgets/tl_thingy.dart';
class GaugetNum extends StatelessWidget {
final num playerStat;

View File

@ -318,7 +318,7 @@ class _TLThingyState extends State<TLThingy> {
if (oldTl?.estTr?.esttr != null) TextSpan(text: comparef.format(currentTl.estTr!.esttr - oldTl!.estTr!.esttr), style: TextStyle(
color: oldTl!.estTr!.esttr > currentTl.estTr!.esttr ? Colors.redAccent : Colors.greenAccent
),),
if (oldTl?.estTr?.esttr != null) const TextSpan(text: ""),
if (oldTl?.estTr?.esttr != null && widget.lbPositions?.estTr != null) const TextSpan(text: ""),
if (widget.lbPositions?.estTr != null) TextSpan(text: widget.lbPositions!.estTr!.position >= 1000 ? "${t.top} ${f2.format(widget.lbPositions!.estTr!.percentage*100)}%" : "${widget.lbPositions!.estTr!.position}", style: TextStyle(color: getColorOfRank(widget.lbPositions!.estTr!.position))),
if (widget.lbPositions?.estTr != null || oldTl?.estTr?.esttr != null) const TextSpan(text: ""),
TextSpan(text: "Glicko: ${f2.format(currentTl.estTr!.estglicko)}")

View File

@ -2,7 +2,7 @@ name: tetra_stats
description: Track your and other player stats in TETR.IO
publish_to: 'none'
version: 1.5.2+18
version: 1.5.3+19
environment:
sdk: '>=3.0.0'

View File

@ -168,6 +168,9 @@
"calc": "Calc",
"calcViewNoValues": "Enter values to calculate the stats",
"rankAveragesViewTitle": "Ranks cutoff and average stats",
"sprintAndBlitsViewTitle": "40 lines and Blitz averages",
"sprintAndBlitsRelevance": "Relevance: ${date}",
"rank": "Rank",
"averages": "Averages",
"lbViewZeroEntrys": "Empty list",
"lbViewOneEntry": "There is only one player",
@ -261,7 +264,7 @@
"nyaappDescription": "(Abbreviated as wAPP) Essentially, a measure of your ability to send cheese while still maintaining a high APP.\nInvented by Wertj.",
"area": "Area",
"areaDescription": "How much space your shape takes up on the graph, if you exclude the cheese and vs/apm sections",
"estOfTR": "Est. of TR",
"estOfTR": "Estimated TR",
"estOfTRShort": "Est. TR",
"accOfEst": "Accuracy",
"accOfEstShort": "Acc."
@ -323,16 +326,16 @@
"forbiddenSub": "If you are using VPN or Proxy, turn it off. If this does not help, reach out to $nickname",
"tooManyRequests": "You have been rate limited.",
"tooManyRequestsSub": "Wait a few moments and try again",
"internal": "Something happend on the tetr.io side",
"internal": "Something happened on the tetr.io side",
"internalSub": "osk, probably, already aware about it",
"internalWebVersion": "Something happend on the tetr.io side (or on oskware_bridge, idk honestly)",
"internalWebVersion": "Something happened on the tetr.io side (or on oskware_bridge, idk honestly)",
"internalWebVersionSub": "If osk status page says that everything is ok, let dan63047 know about this issue",
"oskwareBridge": "Something happend with oskware_bridge",
"oskwareBridge": "Something happened with oskware_bridge",
"oskwareBridgeSub": "Let dan63047 know",
"p1nkl0bst3rForbidden": "Third party API blocked your IP address",
"p1nkl0bst3rTooManyRequests": "Too many requests to third party API. Try again later",
"p1nkl0bst3rinternal": "Something happend on the p1nkl0bst3r side",
"p1nkl0bst3rinternalWebVersion": "Something happend on the p1nkl0bst3r side (or on oskware_bridge, idk honestly)",
"p1nkl0bst3rinternal": "Something happened on the p1nkl0bst3r side",
"p1nkl0bst3rinternalWebVersion": "Something happened on the p1nkl0bst3r side (or on oskware_bridge, idk honestly)",
"replayAlreadySaved": "Replay already saved",
"replayExpired": "Replay expired and not available anymore",
"replayRejected": "Third party API blocked your IP address"

View File

@ -168,6 +168,9 @@
"calc": "Считать",
"calcViewNoValues": "Введите значения, чтобы посчитать статистику",
"rankAveragesViewTitle": "Требования рангов и средние значения",
"sprintAndBlitsViewTitle": "Средние результаты 40 линий и блица",
"sprintAndBlitsRelevance": "Актуальность: ${date}",
"rank": "Ранг",
"averages": "Средние значения",
"lbViewZeroEntrys": "Рейтинговая таблица пуста",
"lbViewOneEntry": "В рейтинговой таблице всего один игрок",