Some missing stuff was added

Also Shizuru is gone (((
This commit is contained in:
dan63047 2024-12-12 02:06:12 +03:00
parent f08ebce52c
commit 8ded0aeb34
19 changed files with 397 additions and 2036 deletions

View File

@ -4,9 +4,9 @@
/// To regenerate, run: `dart run slang`
///
/// Locales: 2
/// Strings: 1516 (758 per locale)
/// Strings: 1520 (760 per locale)
///
/// Built on 2024-12-07 at 15:08 UTC
/// Built on 2024-12-11 at 15:09 UTC
// coverage:ignore-file
// ignore_for_file: type=lint
@ -991,6 +991,8 @@ class _StringsFirstTimeViewEn {
String get description => 'Service, that allows you to keep track of various statistics for TETR.IO';
String get nicknameQuestion => 'What\'s your nickname?';
String get inpuntHint => 'Type it here... (3-16 symbols)';
String get emptyInputError => 'Can\'t submit empty string';
String get skip => 'Skip';
}
// Path: aboutView
@ -2522,8 +2524,10 @@ class _StringsFirstTimeViewRuRu implements _StringsFirstTimeViewEn {
// Translations
@override String get welcome => 'Добро пожаловать в Tetra Stats';
@override String get description => 'Сервис, который позволяет просматривать статистику в TETR.IO';
@override String get nicknameQuestion => 'Какой у вас ник?';
@override String get inpuntHint => 'Введите его здесь... (3-16 символов)';
@override String get nicknameQuestion => 'Введите свой ник';
@override String get inpuntHint => '(3-16 символов)';
@override String get emptyInputError => 'Строка пуста';
@override String get skip => 'Пропустить';
}
// Path: aboutView
@ -3530,6 +3534,8 @@ extension on Translations {
case 'firstTimeView.description': return 'Service, that allows you to keep track of various statistics for TETR.IO';
case 'firstTimeView.nicknameQuestion': return 'What\'s your nickname?';
case 'firstTimeView.inpuntHint': return 'Type it here... (3-16 symbols)';
case 'firstTimeView.emptyInputError': return 'Can\'t submit empty string';
case 'firstTimeView.skip': return 'Skip';
case 'aboutView.title': return 'About Tetra Stats';
case 'aboutView.about': return 'Tetra Stats is a service, that works with TETR.IO Tetra Channel API, providing data from it and calculating some addtitional metrics, based on this data. Service allows user to track their progress in Tetra League with "Track" function, which records every Tetra League change into local database (not automatically, you have to visit service from time to time), so these changes could be looked through graphs.\n\nBeanserver blaster is a part of a Tetra Stats, that decoupled into a serverside script. It provides full Tetra League leaderboard, allowing Tetra Stats to sort leaderboard by any metric and build scatter chart, that allows user to analyse Tetra League trends. It also provides history of Tetra League ranks cutoffs, which can be viewed by user via graph as well.\n\nThere is a plans to add replay analysis and tournaments history, so stay tuned!\n\nService is not associated with TETR.IO or osk in any capacity.';
case 'aboutView.appVersion': return 'App Version';
@ -4335,8 +4341,10 @@ extension on _StringsRuRu {
case 'calcNavigation.damage': return 'Калькулятор урона';
case 'firstTimeView.welcome': return 'Добро пожаловать в Tetra Stats';
case 'firstTimeView.description': return 'Сервис, который позволяет просматривать статистику в TETR.IO';
case 'firstTimeView.nicknameQuestion': return 'Какой у вас ник?';
case 'firstTimeView.inpuntHint': return 'Введите его здесь... (3-16 символов)';
case 'firstTimeView.nicknameQuestion': return 'Введите свой ник';
case 'firstTimeView.inpuntHint': return '(3-16 символов)';
case 'firstTimeView.emptyInputError': return 'Строка пуста';
case 'firstTimeView.skip': return 'Пропустить';
case 'aboutView.title': return 'О Tetra Stats';
case 'aboutView.about': return 'Tetra Stats — это сервис, который работает с TETR.IO Tetra Channel API, показывает данные оттуда и считает дополнительную статистику, основанную на этих данных. Сервис позволяет отслеживать прогресс в Тетра Лиге с помощью функции "Отслеживать", которая записывает каждое изменение в Лиге в локальную базу данных (не автоматически, вы должны вручную посещать свой профиль), что позволяет потом просматривать изменения с помощью графиков.\n\nBeanserver blaster — серверная часть Tetra Stats. Она собирает полную таблицу игроков Тетра Лиги, благодаря чему сортировать эту таблицу по любой метрике и строить точечную диаграмму, что позволяет анализировать тренды Лиги. Также она предоставляет историю требований рангов, которую тоже можно посмотреть на графике.\n\nВ будущем планируется добавить анализ повторов и историю турниров, так что оставайтесь на связи.\n\nСервис ни коим образом не ассоциируется с TETR.IO или osk.';
case 'aboutView.appVersion': return 'Версия приложения';

View File

@ -3,6 +3,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:ffi';
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
@ -672,7 +673,7 @@ class TetrioService extends DB {
/// Retrieves Tetra League history from p1nkl0bst3r api for a player with given [id]. Returns a list of states
/// (state = instance of [TetrioPlayer] at some point of time). Can throw an exception if fails to retrieve data.
Future<List<TetraLeague>> fetchAndsaveTLHistory(String id) async {
Future<List<TetraLeague>> fetchAndsaveTLHistory(String id, int season) async {
Uri url;
if (kIsWeb) {
url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "TLHistory", "user": id});

View File

@ -11,6 +11,7 @@ import 'package:tetra_stats/data_objects/record_single.dart';
import 'package:tetra_stats/data_objects/summaries.dart';
import 'package:tetra_stats/data_objects/tetrio_constants.dart';
import 'package:tetra_stats/data_objects/tetrio_player.dart';
import 'package:tetra_stats/data_objects/tetrio_zen.dart';
import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/main.dart' show teto;
import 'package:tetra_stats/utils/numers_formats.dart';
@ -40,6 +41,7 @@ class CompareView extends StatefulWidget {
class CompareState extends State<CompareView> {
late ScrollController _scrollController;
bool tlOnly = false;
List<TetrioPlayer> players = [];
List<Summaries> summaries = [];
List<String> nicknames = [];
@ -513,6 +515,69 @@ class CompareState extends State<CompareView> {
]);
}
addAverages(Summaries s){
rawValues[1].add(
[
s.league.tr,
s.league.glicko,
s.league.rd,
s.league.gxe,
s.league.s1tr,
s.league.standing,
s.league.gamesPlayed,
s.league.gamesWon,
s.league.winrate,
s.league.apm,
s.league.pps,
s.league.vs,
"",
s.league.nerdStats?.app,
s.league.nerdStats?.vsapm,
s.league.nerdStats?.dss,
s.league.nerdStats?.dsp,
s.league.nerdStats?.appdsp,
s.league.nerdStats?.cheese,
s.league.nerdStats?.gbe,
s.league.nerdStats?.nyaapp,
s.league.nerdStats?.area,
"",
s.league.playstyle?.opener,
s.league.playstyle?.plonk,
s.league.playstyle?.stride,
s.league.playstyle?.infds,
]
);
formattedValues[1].add([
Text(s.league.tr.isNegative ? "---" : f4.format(s.league.tr)),
Text(s.league.glicko!.isNegative ? "---" : f4.format(s.league.glicko)),
Text(s.league.rd!.isNegative ? "---" : f4.format(s.league.rd), style: TextStyle(color: s.league.rd!.isNegative ? Colors.grey : Colors.white)),
Text(s.league.gxe.isNegative ? "---" : f4.format(s.league.gxe)),
Text(s.league.s1tr.isNegative ? "---" : f4.format(s.league.s1tr)),
Text(s.league.standing.isNegative ? "---" : ""+intf.format(s.league.standing)),
Text(intf.format(s.league.gamesPlayed)),
Text(intf.format(s.league.gamesWon)),
Text(s.league.winrate.isNaN ? "---" : f4.format(s.league.winrate*100)+"%"),
Text(s.league.apm != null ? f2.format(s.league.apm) : "---"),
Text(s.league.pps != null ? f2.format(s.league.pps) : "---"),
Text(s.league.vs != null ? f2.format(s.league.vs) : "---"),
Text(""),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.app) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.vsapm) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.dss) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.dsp) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.appdsp) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.cheese) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.gbe) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.nyaapp) : "---"),
Text(s.league.nerdStats != null ? f4.format(s.league.nerdStats!.area) : "---"),
Text(""),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.opener) : "---"),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.plonk) : "---"),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.stride) : "---"),
Text(s.league.playstyle != null ? f4.format(s.league.playstyle!.infds) : "---"),
]);
}
List<List<dynamic>> recalculateBestEntries(){
return [
[
@ -674,28 +739,66 @@ class CompareState extends State<CompareView> {
}
void addPlayer(String nickname) async {
players.add(await teto.fetchPlayer(nickname));
summaries.add(await teto.fetchSummaries(players.last.userId));
addvaluesEntrys(players.last, summaries.last);
if (nickname.startsWith("\$avg")){
await addRankAverages(nickname.substring(4).toLowerCase());
}else{
players.add(await teto.fetchPlayer(nickname));
summaries.add(await teto.fetchSummaries(players.last.userId));
addvaluesEntrys(players.last, summaries.last);
nicknames.add(players.last.username);
}
best = recalculateBestEntries();
nicknames.add(players.last.username);
setState(() {
});
}
void removePlayer(String nickname) async {
int id = players.indexWhere((e) => e.username == nickname);
players.removeAt(id);
summaries.removeAt(id);
nicknames.remove(nickname);
Future<void> addRankAverages(String rank) async {
try{
var average = (await teto.fetchTLLeaderboard()).getRankData(rank)[0];
Summaries summary = Summaries("avg${rank.toUpperCase()}", average, TetrioZen(level: 0, score: 0));
players.add(TetrioPlayer(
userId: "avg${rank}",
username: "Avg ${rank.toUpperCase()} rank",
role: "rank",
state: summary.league.timestamp,
registrationTime: summary.league.timestamp,
badges: [],
friendCount: -1,
gamesPlayed: -1,
gamesWon: -1,
gameTime: Duration(seconds: -1),
xp: -1,
supporterTier: 0,
verified: false,
connections: null
));
summaries.add(summary);
nicknames.add("Avg ${rank.toUpperCase()} rank");
addAverages(summary);
return setState(() {tlOnly = true;});
}on Exception {
//if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.snackBarMessages.compareViewWrongValue(value: rank))));
return;
}
}
void removePlayer(String id) async {
int p = players.indexWhere((e) => e.userId == id);
players.removeAt(p);
summaries.removeAt(p);
nicknames.removeAt(p);
if (id.startsWith("avg")){
rawValues[1].removeAt(p);
formattedValues[1].removeAt(p);
}else
for (int i = 0; i < 7; i++){
rawValues[i].removeAt(id);
formattedValues[i].removeAt(id);
rawValues[i].removeAt(p);
formattedValues[i].removeAt(p);
}
if (players.isNotEmpty) best = recalculateBestEntries();
setState(() {
if (players.any((e) => e.userId.startsWith("avg")) == false) tlOnly = false;
});
}
@ -759,7 +862,38 @@ class CompareState extends State<CompareView> {
SizedBox(width: 300, child: AddNewColumnCard(addPlayer))
]
),
for (int i = 0; i < formattedValues.length; i++) SizedBox(
if (tlOnly) SizedBox(
width: 300+300*summaries.length.toDouble(),
child: Column(
children: [
Row(
children: [
SizedBox(
width: 300.0,
child: Card(
child: Column(children: [
for (String title in TitesForStats[TitesForStats.keys.elementAt(1)]!) Text(title),
]),
),
),
for (int k = 0; k < formattedValues[1].length; k++) SizedBox(
width: 300.0,
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (int l = 0; l < formattedValues[1][k].length; l++) Container(decoration: (rawValues[0].length > 1 && rawValues[1][k][l] != null && best[1][l] == rawValues[1][k][l]) ? BoxDecoration(boxShadow: [BoxShadow(color: Colors.cyanAccent.withAlpha(96), spreadRadius: 0, blurRadius: 4)]) : null, child: formattedValues[1][k][l]),
],
),
),
),
]
),
VsGraphs(stats: [for (var s in summaries) if (s.league.nerdStats != null) AggregateStats.precalculated(s.league.apm!, s.league.pps!, s.league.vs!, s.league.nerdStats!, s.league.playstyle!)], nicknames: [for (int i = 0; i < summaries.length; i++) if (summaries[i].league.nerdStats != null) nicknames[i]]),
],
),
)
else for (int i = 0; i < formattedValues.length; i++) SizedBox(
width: 300+300*summaries.length.toDouble(),
child: ExpansionTile(
title: Text(TitesForStats.keys.elementAt(i), style: _expansionTileTitleTextStyle),
@ -831,7 +965,7 @@ class HeaderCard extends StatelessWidget{
height: 120.0,
fadeInCurve: Easing.standard, fadeInDuration: Durations.long4
)
else SizedBox(height: 120.0),
else SizedBox(height: 120.0, width: 300.0),
Positioned(
top: 20.0,
child: ClipRRect(
@ -847,7 +981,7 @@ class HeaderCard extends StatelessWidget{
Positioned(
right: 0,
child: IconButton(onPressed: (){
removePlayer(player.username);
removePlayer(player.userId);
}, icon: Icon(Icons.close, shadows: textShadow,))
)
],

View File

@ -144,7 +144,7 @@ class _DestinationGraphsState extends State<DestinationGraphs> {
Future<Map<int, Map<Stats, List<_HistoryChartSpot>>>> getHistoryData(bool fetchHistory) async {
if(fetchHistory){
try{
var history = await teto.fetchAndsaveTLHistory(widget.searchFor);
var history = await teto.fetchAndsaveTLHistory(widget.searchFor, 1);
if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.graphsDestination.fetchAndsaveTLHistoryResult(number: history.length))));
}on TetrioHistoryNotExist{
if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.noHistorySaved)));

View File

@ -897,7 +897,18 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
}
Widget getTetraLeagueCard(TetraLeague data, Cutoffs? cutoffs, CutoffTetrio? averages, List<TetraLeague> states, PlayerLeaderboardPosition? lbPos, double width){
TetraLeague? toCompare = states.length >= 2 ? states.elementAtOrNull(states.length-2) : null;
TetraLeague toSee;
TetraLeague? toCompare;
if (currentRangeValues.start.round() == 0){
toSee = data;
}else{
toSee = states[currentRangeValues.start.round()-1];
}
if (currentRangeValues.end.round() == 0){
toCompare = states.length >= 2 ? states.elementAtOrNull(states.length-2) : null;
}else{
toCompare = states[currentRangeValues.end.round()-1];
}
return Column(
children: [
Card(
@ -910,13 +921,36 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(t.gamemodes["league"]!, style: Theme.of(context).textTheme.titleLarge),
//Text("${states.last.timestamp} ${states.last.tr}", textAlign: TextAlign.center)
if (toCompare != null) Text(t.comparingWith(newDate: timestamp(toSee.timestamp), oldDate: timestamp(toCompare.timestamp)), textAlign: TextAlign.center)
],
),
),
),
),
TetraLeagueThingy(league: data, toCompare: toCompare, cutoffs: cutoffs, averages: averages, lbPos: lbPos, width: width),
if (toCompare != null) Card(
child: RangeSlider(values: currentRangeValues, max: states.length.toDouble(),
labels: RangeLabels(
currentRangeValues.start.round().toString(),
currentRangeValues.end.round().toString(),
),
onChanged: (RangeValues values) {
setState(() {
currentRangeValues = values;
});
},
),
),
TetraLeagueThingy(league: toSee, toCompare: toCompare, cutoffs: cutoffs, averages: averages, lbPos: lbPos, width: width),
// Center(
// child: Card(
// child: ElevatedButton.icon(
// onPressed: (){teto.fetchAndsaveTLHistory(data.id, 1).then((_) => setState((){}));},
// icon: const Icon(Icons.query_stats),
// label: Text(t.graphsDestination.fetchAndsaveTLHistory),
// style: const ButtonStyle(shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0)))))
// )
// ),
// ),
if (data.nerdStats != null) Card(
//surfaceTintColor: rankColors[data.rank],
child: Row(
@ -928,8 +962,8 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
],
),
),
if (data.nerdStats != null) NerdStatsThingy(nerdStats: data.nerdStats!, oldNerdStats: toCompare?.nerdStats, averages: averages, lbPos: lbPos, width: width),
if (data.nerdStats != null) Graphs(data.apm!, data.pps!, data.vs!, data.nerdStats!, data.playstyle!)
if (data.nerdStats != null) NerdStatsThingy(nerdStats: toSee.nerdStats!, oldNerdStats: toCompare?.nerdStats, averages: averages, lbPos: lbPos, width: width),
if (data.nerdStats != null) Graphs(toSee.apm!, toSee.pps!, toSee.vs!, toSee.nerdStats!, toSee.playstyle!)
],
);
}
@ -1120,12 +1154,12 @@ class _DestinationHomeState extends State<DestinationHome> with SingleTickerProv
_transition = AnimationController(vsync: this, duration: Durations.long4);
_offsetAnimation = Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.5, 0.0),
).animate(CurvedAnimation(
parent: _transition,
curve: Curves.elasticIn,
));
begin: Offset.zero,
end: const Offset(1.5, 0.0),
).animate(CurvedAnimation(
parent: _transition,
curve: Curves.elasticIn,
));
super.initState();
}

View File

@ -77,7 +77,7 @@ class _DestinationInfo extends State<DestinationInfo> {
InfoCard(
height: widget.constraints.maxHeight - 77,
viewportWidth: widget.constraints.maxWidth,
assetLink: "res/images/info card 1 focus.png",
assetLink: "res/images/info card 1.png",
title: t.infoDestination.sprintAndBlitzAverages,
description: "${t.infoDestination.sprintAndBlitzAveragesDescription}\n\n${t.sprintAndBlitsRelevance(date: DateFormat.yMMMd(LocaleSettings.currentLocale.languageCode).format(sprintAndBlitzRelevance))}",
onPressed: (){
@ -89,7 +89,7 @@ class _DestinationInfo extends State<DestinationInfo> {
InfoCard(
height: widget.constraints.maxHeight - 77,
viewportWidth: widget.constraints.maxWidth,
assetLink: "res/images/Снимок экрана_2023-11-06_01-00-50.png",
assetLink: "res/images/info card 2.png",
title: t.infoDestination.tetraStatsWiki,
description: t.infoDestination.tetraStatsWikiDescription,
onPressed: (){
@ -99,7 +99,7 @@ class _DestinationInfo extends State<DestinationInfo> {
InfoCard(
height: widget.constraints.maxHeight - 77,
viewportWidth: widget.constraints.maxWidth,
assetLink: "res/images/Снимок экрана_2023-11-06_01-00-50.png",
assetLink: "res/images/info card 3.png",
title: t.infoDestination.about,
description: t.infoDestination.aboutDescription,
onPressed: (){

View File

@ -1,5 +1,8 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:tetra_stats/data_objects/tetrio_player.dart';
import 'package:tetra_stats/gen/strings.g.dart';
import 'package:tetra_stats/main.dart';
class FirstTimeView extends StatefulWidget {
/// The very first view, that user see when he launch this programm.
@ -10,28 +13,148 @@ class FirstTimeView extends StatefulWidget {
}
class _FirstTimeState extends State<FirstTimeView> with SingleTickerProviderStateMixin {
late AnimationController _transition;
late final Animation<Offset> _offsetAnimation;
late AnimationController _animController;
late final Animation<double> _spinAnimation;
late Animation<double> _opacity;
late Animation<double> _enterNicknameOpacity;
late Animation<double> _transform;
late Animation<Color?> _badNicknameAnim;
late TextEditingController _controller;
String helperText = "";
String nickname = "";
double helperTextOpacity = 0;
bool userSet = false;
@override
void initState() {
_transition = AnimationController(vsync: this, duration: Durations.long4);
_offsetAnimation = Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.5, 0.0),
).animate(CurvedAnimation(
parent: _transition,
curve: Curves.elasticIn,
));
_animController = AnimationController(
vsync: this,
// value: 0,
// lowerBound: 0.0,
// upperBound: 2.0,
duration: Durations.extralong2
);
_spinAnimation = Tween<double>(
begin: -0.3,
end: 0.0000,
).animate(CurvedAnimation(
parent: _animController,
curve: Interval(
0.0,
0.5,
curve: Curves.linearToEaseOut,
)
));
_badNicknameAnim = new ColorTween(
begin: Colors.redAccent,
end: Colors.grey,
).animate(new CurvedAnimation(
parent: _animController,
curve: const Interval(
0.5,
0.75,
curve: Easing.emphasizedAccelerate
),
));
_opacity = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: _animController,
curve: const Interval(
0.0,
0.5,
curve: Curves.linear,
),
),
);
_enterNicknameOpacity = Tween<double>(
begin: 1.0,
end: 0.0
).animate(
CurvedAnimation(
parent: _animController,
curve: const Interval(
0.75,
1.0,
curve: Curves.ease,
),
),
);
_transform = Tween<double>(
begin: 0.0,
end: 40.0
).animate(
CurvedAnimation(
parent: _animController,
curve: const Interval(
0.75,
1.0,
curve: Curves.easeInOut,
),
),
);
_controller = TextEditingController();
super.initState();
}
@override
void dispose(){
_animController.dispose();
_controller.dispose();
super.dispose();
}
Future<bool> _setDefaultNickname(String n) async {
setState((){
helperTextOpacity = 1;
_animController.value = 0.75;
helperText = t.settingsDestination.checking;
});
if (n.isNotEmpty) {
try {
if (n.length > 16){
nickname = await teto.getNicknameByID(n);
await prefs.setString('playerID', n);
}else{
TetrioPlayer player = await teto.fetchPlayer(n);
nickname = player.username;
await prefs.setString('playerID', player.userId);
}
await prefs.setString('player', nickname);
helperText = "";
_animController.forward();
setState((){
userSet = true;
});
return true;
} catch (e) {
_animController.value = 0.5;
_animController.animateTo(1.0, duration: Durations.long1);
setState((){
helperText = t.settingsDestination.noSuchAccount;
});
return false;
}
} else {
_animController.value = 0.5;
_animController.animateTo(1.0, duration: Durations.long1);
setState((){
helperText = t.firstTimeView.emptyInputError;
});
return false;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: TweenAnimationBuilder(
onEnd: (){
_animController.animateTo(0.75);
},
duration: Durations.long4,
tween: Tween<double>(begin: 0, end: 1),
curve: Easing.standard,
@ -44,9 +167,18 @@ class _FirstTimeState extends State<FirstTimeView> with SingleTickerProviderStat
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Spacer(),
Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: RotationTransition(
turns: _spinAnimation,
child: Image.asset("res/icons/app.png", height: 128, opacity: _opacity)
),
),
Text(t.firstTimeView.welcome, style: Theme.of(context).textTheme.titleLarge),
Text(t.firstTimeView.description),
Text(t.firstTimeView.description, style: TextStyle(color: Colors.grey)),
Padding(
padding: const EdgeInsets.only(top: 24.0),
child: Card(
@ -58,23 +190,39 @@ class _FirstTimeState extends State<FirstTimeView> with SingleTickerProviderStat
Text(t.firstTimeView.nicknameQuestion, style: Theme.of(context).textTheme.titleSmall),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: SizedBox(width: 400.0, child: TextField(
maxLength: 16,
decoration: InputDecoration(
hintText: t.firstTimeView.inpuntHint,
counter: const Offstage()
child: SizedBox(width: 400.0, child: Focus(
onFocusChange: (value) {
setState((){if (value) helperTextOpacity = 0;});
},
child: TextField(
controller: _controller,
maxLength: 16,
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: t.firstTimeView.inpuntHint,
helper: AnimatedOpacity(
opacity: helperTextOpacity,
duration: Durations.long1,
curve: Easing.standardDecelerate,
child: AnimatedDefaultTextStyle(child: Text(helperText), style: TextStyle(fontFamily: "Eurostile Round", color: _badNicknameAnim.value, height: 0.5), duration: Durations.long1)
),
counter: const Offstage()
),
onSubmitted: (value) => _setDefaultNickname(value),
),
)),
),
ElevatedButton.icon(onPressed: (){}, icon: Icon(Icons.subdirectory_arrow_left), label: Text("Submit"))
ElevatedButton.icon(onPressed: () => _setDefaultNickname(_controller.value.text), icon: Icon(Icons.subdirectory_arrow_left), label: Text(t.actions.submit))
],
),
),
),
)
),
Spacer(flex: 2),
TextButton(onPressed: (){ context.replace("/"); }, child: Text(t.firstTimeView.skip))
],
)
)
),
)
),
),
);

View File

@ -25,6 +25,7 @@ import 'package:tetra_stats/main.dart';
late Future<FetchResults> _data;
TetrioPlayersLeaderboard? _everyone;
late RangeValues currentRangeValues;
int destination = 0;
// TODO: Redesign some widgets, so they could look nice on mobile view
@ -32,7 +33,7 @@ int destination = 0;
// - APP and VS/APM gadget
// - different design for radar graphs
// - i should put tooltips everywhere
Future<FetchResults> getData(String searchFor) async {
Future<FetchResults> getData(String searchFor, {bool withHistory = false}) async {
TetrioPlayer player;
try{
if (searchFor.startsWith("ds:")){
@ -60,6 +61,8 @@ Future<FetchResults> getData(String searchFor) async {
news = requests[1];
cutoffs = requests.elementAtOrNull(2);
averages = requests.elementAtOrNull(3);
if(withHistory) await teto.fetchAndsaveTLHistory(player.userId, 1); // Retrieve if needed
} on Exception catch (e) {
return FetchResults(false, null, [], null, null, null, null, null, false, e);
}
@ -80,7 +83,7 @@ Future<FetchResults> getData(String searchFor) async {
await teto.storeState(summaries.league);
}
return FetchResults(true, player, states, summaries, news, cutoffs, averages, _meAmongEveryone, isTracking, null);
return FetchResults(true, player, states.reversed.toList(), summaries, news, cutoffs, averages, _meAmongEveryone, isTracking, null);
}
class MainView extends StatefulWidget {
@ -131,6 +134,7 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
void changePlayer(String player) {
setState(() {
currentRangeValues = const RangeValues(0, 1);
_searchFor = player;
_data = getData(_searchFor);
});

View File

@ -29,7 +29,7 @@ class TLRecords extends StatelessWidget {
],
);
}
if (snapshot.hasError){ return FutureError(snapshot); }
if (snapshot.hasError){ return SizedBox(height: 500, child: Center(child: FutureError(snapshot))); }
}
return const Text("what?");
},

View File

@ -1,666 +0,0 @@
{
"locales(map)": {
"en": "English",
"ru": "Russian (Русский)",
"zh-CN": "Simplified Chinese (简体中文)"
},
"tetraLeague": "Tetra League",
"tlRecords": "TL Records",
"history": "History",
"sprint": "40 Lines",
"blitz": "Blitz",
"recent": "Recent",
"recentRuns": "Recent runs",
"blitzScore": "$p points",
"openSPreplay": "Open replay in TETR.IO",
"downloadSPreplay": "Download replay",
"other": "Other",
"distinguishment": "Distinguishment",
"zen": "Zen",
"bio": "Bio",
"news": "News",
"newsParts":{
"leaderboardStart": "Got ",
"leaderboardMiddle": "on ",
"personalbest": "Got a new PB in ",
"personalbestMiddle": "of ",
"badgeStart": "Obtained a ",
"badgeEnd": "badge",
"rankupStart": "Obtained ",
"rankupMiddle": "${r} rank ",
"rankupEnd": "in Tetra League",
"tetoSupporter": "TETR.IO supporter",
"supporterStart": "Become a ",
"supporterGiftStart": "Received the gift of ",
"unknownNews": "Unknown news of type ${type}"
},
"openSearch": "Search player",
"closeSearch": "Close search",
"searchHint": "Nickname, ID or Discord userID (with \"ds:\" prefix)",
"refresh": "Refresh",
"fetchAndsaveTLHistory": "Get player history",
"fetchAndSaveOldTLmatches": "Get Tetra League matches history",
"fetchAndsaveTLHistoryResult": "${number} states was found",
"fetchAndSaveOldTLmatchesResult": "${number} matches was found",
"showStoredData": "Show stored data",
"statsCalc": "Stats Calculator",
"settings": "Settings",
"track": "Track",
"stopTracking": "Stop\ntracking",
"becameTracked": "Added to tracking list!",
"compare": "Compare",
"stoppedBeingTracked": "Removed from tracking list!",
"tlLeaderboard": "Tetra League leaderboard",
"noRecords": "No records",
"noOldRecords": {
"zero": "No records",
"one": "Only $n record",
"two": "Only $n records",
"few": "Only $n records",
"many": "Only $n records",
"other": "Only $n records"
},
"noRecord": "No record",
"botRecord": "Bots are not allowed to set records",
"anonRecord": "Guests are not allowed to set records",
"notEnoughData": "Not enough data",
"noHistorySaved": "No history saved",
"pseudoTooltipHeaderInit": "Hover over point",
"pseudoTooltipFooterInit": "to see detailed data",
"obtainDate": "Obtained ${date}",
"fetchDate": "Fetched ${date}",
"exactGametime": "Exact gametime",
"bigRedBanned": "BANNED",
"normalBanned": "Banned",
"bigRedBadStanding": "BAD STANDING",
"copiedToClipboard": "Copied to clipboard!",
"playerRoleAccount": " account ",
"wasFromBeginning": "that was from very beginning",
"created": "created",
"botCreatedBy": "by",
"notSupporter": "Not a supporter",
"assignedManualy": "That badge was assigned manualy by TETR.IO admins",
"supporter": "Supporter tier ${tier}",
"comparingWith": "Data from ${newDate} comparing with ${oldDate}",
"top": "Top",
"topRank": "Top rank",
"verdictGeneral": "$n $verdict $rank rank avg",
"verdictBetter": "better",
"verdictWorse": "worse",
"smooth": "Smooth",
"postSeason": "Off-season",
"seasonStarts": "Season starts in:",
"nanow": "Not avaliable for now...",
"seasonEnds": "Season ends in ${countdown}",
"seasonEnded": "Season has ended",
"gamesUntilRanked": "${left} games until being ranked",
"numOfVictories": "~${wins} victories",
"promotionOnNextWin": "Promotion on next win",
"numOfdefeats": "~${losses} defeats",
"demotionOnNextLoss": "Demotion on next loss",
"nerdStats": "Nerd Stats",
"playersYouTrack": "Players you track",
"formula": "Formula",
"exactValue": "Exact value",
"neverPlayedTL": "That user never played Tetra League",
"botTL": "Bots are not allowed to play Tetra League",
"anonTL": "Guests are not allowed to play Tetra League",
"quickPlay": "Quick Play",
"expert": "Expert",
"withMods": "With mods",
"withModsPlural":{
"zero": "with $n mods",
"one": "with $n mod",
"two": "with $n mods",
"few": "with $n mods",
"many": "with $n mods",
"other": "with $n mods"
},
"exportDB": "Export local database",
"exportDBDescription": "It contains states and Tetra League records of the tracked players and list of tracked players.",
"desktopExportAlertTitle": "Desktop export",
"desktopExportText": "It seems like you using this app on desktop. Check your documents folder, you should find \"TetraStats.db\". Copy it somewhere",
"androidExportAlertTitle": "Android export",
"androidExportText": "Exported.\n${exportedDB}",
"importDB": "Import local database",
"importDBDescription": "Restore your backup. Notice that already stored database will be overwritten.",
"importWrongFileType": "Wrong file type",
"importCancelled": "Operation was cancelled",
"importSuccess": "Import successful",
"yourID": "Your TETR.IO account",
"yourIDAlertTitle": "Your nickname in TETR.IO",
"yourIDText": "When app loads, it will retrieve data for this account",
"language": "Language",
"updateInBackground": "Update stats in the background",
"updateInBackgroundDescription": "While Tetra Stats is running, it can update stats of the current player when cache expires",
"customization": "Customization",
"customizationDescription": "Change appearance of different things in Tetra Stats UI",
"oskKagari": "Osk Kagari gimmick",
"oskKagariDescription": "If on, osk's rank on main view will be rendered as :kagari:",
"AccentColor": "Accent color",
"AccentColorDescription": "Almost all interactive UI elements highlighted with this color",
"timestamps": "Timestamps",
"timestampsDescription": "You can choose, in which way timestamps shows time",
"timestampsAbsoluteGMT": "Absolute (GMT)",
"timestampsAbsoluteLocalTime": "Absolute (Your timezone)",
"timestampsRelative": "Relative",
"rating": "Main representation of rating",
"ratingDescription": "TR is not linear, while Glicko does not have boundaries and percentile is volatile",
"ratingLBposition": "LB position",
"sheetbotGraphs": "Sheetbot-like behavior for radar graphs",
"sheetbotGraphsDescription": "If on, points on the graphs can appear on the opposite half of the graph if value is negative",
"lbStats": "Show leaderboard based stats",
"lbStatsDescription": "That will impact on loading times, but will allow you to see position on LB by stats and comparison with average values",
"aboutApp": "About app",
"aboutAppText": "${appName} (${packageName}) Version ${version} Build ${buildNumber}\n\nDeveloped by dan63047\nFormulas provided by kerrmunism\nHistory provided by p1nkl0bst3r\nTETR.IO replay grabber API by szy",
"stateViewTitle": "${nickname} account on ${date}",
"statesViewTitle": "${number} states of ${nickname} account",
"matchesViewTitle": "${nickname} TL matches",
"statesViewEntry": "${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно",
"stateRemoved": "${date} state was removed from database!",
"matchRemoved": "${date} match was removed from database!",
"viewAllMatches": "View all matches",
"trackedPlayersViewTitle": "Stored data",
"trackedPlayersZeroEntrys": "Empty list. Press \"Track\" button in previous view to add current player here",
"trackedPlayersOneEntry": "There is only one player",
"trackedPlayersManyEntrys": "There are ${numberOfPlayers} players",
"trackedPlayersEntry": "${nickname}: ${numberOfStates} states",
"trackedPlayersDescription": "From ${firstStateDate} until ${lastStateDate}",
"trackedPlayersStatesDeleted": "${nickname} states was removed from database!",
"duplicatedFix": "Remove duplicated TL mathces",
"compressDB": "Compress DB",
"SpaceSaved": "Space saved: ${size}",
"averageXrank": "Average ${rankLetter} rank",
"vs": "vs",
"inTLmatch": "in TL match",
"downloadReplay": "Download .ttrm replay",
"openReplay": "Open replay in TETR.IO",
"replaySaved": "Replay saved to ${path}",
"match": "Match",
"timeWeightedmatch": "Match (time-weighted)",
"roundNumber": "Round $n",
"statsFor": "Stats for",
"numberOfRounds": "Number of rounds",
"matchLength": "Match Length",
"roundLength": "Round Length",
"matchStats": "Match stats",
"timeWeightedmatchStats": "Time-weighted match stats",
"replayIssue": "Can't process replay",
"matchIsTooOld": "Replay is not available",
"winner": "Winner",
"registred": "Registred",
"playedTL": "Played Tetra League",
"winChance": "Win Chance",
"byGlicko": "By Glicko",
"byEstTR": "By Est. TR",
"compareViewNoValues": "Please, enter username, user ID, APM-PPS-VS values (divider doesn't matter, only order matter) or $avgR (where R is rank) to both fields",
"compareViewWrongValue": "Falied to assign ${value}",
"mostRecentOne": "Most recent one",
"yes": "Yes",
"no": "No",
"daysLater": "days later",
"dayseBefore": "days before",
"fromBeginning": "From beginning",
"calc": "Calc",
"calcViewNoValues": "Enter values to calculate the stats",
"rankAveragesViewTitle": "Ranks cutoffs",
"sprintAndBlitsViewTitle": "40 lines and Blitz averages",
"sprintAndBlitsRelevance": "Relevance: ${date}",
"rank": "Rank",
"averages": "Averages",
"lbViewZeroEntrys": "Empty list",
"lbViewOneEntry": "There is only one player",
"lbViewManyEntrys": "There are ${numberOfPlayers}",
"everyoneAverages": "Values for leaderboard",
"sortBy": "Sort by",
"reversed": "Reversed",
"country": "Country",
"rankAverages": "Values for $rank rank",
"players":{
"zero": "$n players",
"one": "$n player",
"two": "$n players",
"few": "$n players",
"many": "$n players",
"other": "$n players"
},
"games": {
"zero": "$n games",
"one": "$n game",
"two": "$n games",
"few": "$n games",
"many": "$n games",
"other": "$n games"
},
"gamesPlayed": "$games played",
"chart": "Chart",
"entries": "Entries",
"minimums": "Minimums",
"maximums": "Maximums",
"lowestValues": "Lowest Values",
"averageValues": "Average Values",
"highestValues": "Highest Values",
"forPlayer": "for player $username",
"currentAxis": "$axis axis:",
"p1nkl0bst3rAlert": "That data was retrived from third party API maintained by p1nkl0bst3r",
"notForWeb": "Function is not available for web version",
"graphs": {
"attack": "Attack",
"speed": "Speed",
"defense": "Defense",
"cheese": "Cheese"
},
"statCellNum":{
"xpLevel": "XP Level",
"xpProgress": "Progress to next level",
"xpFrom0ToLevel": "Progress from 0 XP to level $n",
"xpLeft": "XP left",
"hoursPlayed": "Hours\nPlayed",
"onlineGames": "Online\nGames",
"gamesWon": "Games\nWon",
"totalGames": "Total Games Played",
"totalWon": "Total Games Won",
"friends": "Friends",
"apm": "Attack\nPer Minute",
"vs": "Versus\nScore",
"recordLB": "Leaderboard placement",
"lbp": "Leaderboard\nplacement",
"lbpShort": "№ in LB",
"lbpc": "Country LB\nplacement",
"lbpcShort": "№ in local LB",
"gamesPlayed": "Games\nplayed",
"gamesWonTL": "Games\nWon",
"winrate": "Winrate",
"level": "Level",
"score": "Score",
"spp": "Score\nPer Piece",
"pieces": "Pieces\nPlaced",
"pps": "Pieces\nPer Second",
"finesseFaults": "Finesse\nFaults",
"finessePercentage": "Finesse\nPercentage",
"keys": "Key\nPresses",
"kpp": "KP Per\nPiece",
"kps": "KP Per\nSecond",
"tr": "Tetra Rating",
"rd": "Rating Deviation",
"app": "Attack Per Piece",
"appDescription": "(Abbreviated as APP) Main efficiency metric. Tells how many attack you producing per piece",
"vsapmDescription": "Basically, tells how much and how efficient you using garbage in your attacks",
"dss": "Downstack\nPer Second",
"dssDescription": "(Abbreviated as DS/S) Downstack per Second measures how many garbage lines you clear in a second.",
"dsp": "Downstack\nPer Piece",
"dspDescription": "(Abbreviated as DS/P) Downstack per Piece measures how many garbage lines you clear per piece.",
"appdsp": "APP + DS/P",
"appdspDescription": "Just a sum of Attack per Piece and Downstack per Piece.",
"cheese": "Cheese\nIndex",
"cheeseDescription": "(Abbreviated as Cheese) Cheese Index is an approximation how much clean / cheese garbage player sends. Lower = more clean. Higher = more cheese.\nInvented by kerrmunism",
"gbe": "Garbage\nEfficiency",
"gbeDescription": "(Abbreviated as Gb Eff.) Garbage Efficiency measures how well player uses their garbage. Higher = better or they use their garbage more. Lower = they mostly send their garbage back at cheese or rarely clear garbage.\nInvented by Zepheniah and Dragonboy.",
"nyaapp": "Weighted\nAPP",
"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": "Estimated TR",
"estOfTRShort": "Est. TR",
"accOfEst": "Accuracy",
"accOfEstShort": "Acc."
},
"playerRole(map)": {
"user": "User",
"banned": "Banned",
"bot": "Bot",
"sysop": "System operator",
"admin": "Admin",
"mod": "Moderator",
"halfmod": "Community moderator",
"anon": "Anonymous"
},
"numOfGameActions":{
"pc": "All Clears",
"hold": "Holds",
"inputs": {
"zero": "$n key presses",
"one": "$n key press",
"two": "$n key presses",
"few": "$n key presses",
"many": "$n key presses",
"other": "$n key presses"
},
"tspinsTotal": {
"zero": "$n T-spins total",
"one": "$n T-spin total",
"two": "$n T-spins total",
"few": "$n T-spins total",
"many": "$n T-spins total",
"other": "$n T-spins total"
},
"lineClears": {
"zero": "$n lines cleared",
"one": "$n line cleared",
"two": "$n lines cleared",
"few": "$n lines cleared",
"many": "$n lines cleared",
"other": "$n lines cleared"
}
},
"popupActions":{
"cancel": "Cancel",
"submit": "Submit",
"ok": "OK"
},
"errors":{
"connection": "Some issue with connection: ${code} ${message}",
"noSuchUser": "No such user",
"noSuchUserSub": "Either you mistyped something, or the account no longer exists",
"discordNotAssigned": "No user assigned to given Discord ID",
"discordNotAssignedSub": "Make sure you provided valid ID",
"history": "History for that player is missing",
"actionSuggestion": "Perhaps, you want to",
"p1nkl0bst3rTLmatches": "No Tetra League matches was found",
"clientException": "No internet connection",
"forbidden": "Your IP address is blocked",
"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 happened on the tetr.io side",
"internalSub": "osk, probably, already aware about it",
"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 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 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"
},
"countries(map)": {
"": "Worldwide",
"AF": "Afghanistan",
"AX": "\u00c5land Islands",
"AL": "Albania",
"DZ": "Algeria",
"AS": "American Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarctica",
"AG": "Antigua and Barbuda",
"AR": "Argentina",
"AM": "Armenia",
"AW": "Aruba",
"AU": "Australia",
"AT": "Austria",
"AZ": "Azerbaijan",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados",
"BY": "Belarus",
"BE": "Belgium",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivia, Plurinational State of",
"BA": "Bosnia and Herzegovina",
"BW": "Botswana",
"BV": "Bouvet Island",
"BR": "Brazil",
"IO": "British Indian Ocean Territory",
"BN": "Brunei Darussalam",
"BG": "Bulgaria",
"BF": "Burkina Faso",
"BI": "Burundi",
"KH": "Cambodia",
"CM": "Cameroon",
"CA": "Canada",
"CV": "Cape Verde",
"BQ": "Caribbean Netherlands",
"KY": "Cayman Islands",
"CF": "Central African Republic",
"TD": "Chad",
"CL": "Chile",
"CN": "China",
"CX": "Christmas Island",
"CC": "Cocos (Keeling) Islands",
"CO": "Colombia",
"KM": "Comoros",
"CG": "Congo",
"CD": "Congo, the Democratic Republic of the",
"CK": "Cook Islands",
"CR": "Costa Rica",
"CI": "C\u00f4te d'Ivoire",
"HR": "Croatia",
"CU": "Cuba",
"CW": "Cura\u00e7ao",
"CY": "Cyprus",
"CZ": "Czech Republic",
"DK": "Denmark",
"DJ": "Djibouti",
"DM": "Dominica",
"DO": "Dominican Republic",
"EC": "Ecuador",
"EG": "Egypt",
"SV": "El Salvador",
"GB-ENG": "England",
"GQ": "Equatorial Guinea",
"ER": "Eritrea",
"EE": "Estonia",
"ET": "Ethiopia",
"EU": "Europe",
"FK": "Falkland Islands (Malvinas)",
"FO": "Faroe Islands",
"FJ": "Fiji",
"FI": "Finland",
"FR": "France",
"GF": "French Guiana",
"PF": "French Polynesia",
"TF": "French Southern Territories",
"GA": "Gabon",
"GM": "Gambia",
"GE": "Georgia",
"DE": "Germany",
"GH": "Ghana",
"GI": "Gibraltar",
"GR": "Greece",
"GL": "Greenland",
"GD": "Grenada",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard Island and McDonald Islands",
"VA": "Holy See (Vatican City State)",
"HN": "Honduras",
"HK": "Hong Kong",
"HU": "Hungary",
"IS": "Iceland",
"IN": "India",
"ID": "Indonesia",
"IR": "Iran, Islamic Republic of",
"IQ": "Iraq",
"IE": "Ireland",
"IM": "Isle of Man",
"IL": "Israel",
"IT": "Italy",
"JM": "Jamaica",
"JP": "Japan",
"JE": "Jersey",
"JO": "Jordan",
"KZ": "Kazakhstan",
"KE": "Kenya",
"KI": "Kiribati",
"KP": "Korea, Democratic People's Republic of",
"KR": "Korea, Republic of",
"XK": "Kosovo",
"KW": "Kuwait",
"KG": "Kyrgyzstan",
"LA": "Lao People's Democratic Republic",
"LV": "Latvia",
"LB": "Lebanon",
"LS": "Lesotho",
"LR": "Liberia",
"LY": "Libya",
"LI": "Liechtenstein",
"LT": "Lithuania",
"LU": "Luxembourg",
"MO": "Macao",
"MK": "Macedonia, the former Yugoslav Republic of",
"MG": "Madagascar",
"MW": "Malawi",
"MY": "Malaysia",
"MV": "Maldives",
"ML": "Mali",
"MT": "Malta",
"MH": "Marshall Islands",
"MQ": "Martinique",
"MR": "Mauritania",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Mexico",
"FM": "Micronesia, Federated States of",
"MD": "Moldova, Republic of",
"MC": "Monaco",
"ME": "Montenegro",
"MA": "Morocco",
"MN": "Mongolia",
"MS": "Montserrat",
"MZ": "Mozambique",
"MM": "Myanmar",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NL": "Netherlands",
"AN": "Netherlands Antilles",
"NC": "New Caledonia",
"NZ": "New Zealand",
"NI": "Nicaragua",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"NF": "Norfolk Island",
"GB-NIR": "Northern Ireland",
"MP": "Northern Mariana Islands",
"NO": "Norway",
"OM": "Oman",
"PK": "Pakistan",
"PW": "Palau",
"PS": "Palestine",
"PA": "Panama",
"PG": "Papua New Guinea",
"PY": "Paraguay",
"PE": "Peru",
"PH": "Philippines",
"PN": "Pitcairn",
"PL": "Poland",
"PT": "Portugal",
"PR": "Puerto Rico",
"QA": "Qatar",
"RE": "Réunion",
"RO": "Romania",
"RU": "Russian Federation",
"RW": "Rwanda",
"BL": "Saint Barthélemy",
"SH": "Saint Helena, Ascension and Tristan da Cunha",
"KN": "Saint Kitts and Nevis",
"LC": "Saint Lucia",
"MF": "Saint Martin",
"PM": "Saint Pierre and Miquelon",
"VC": "Saint Vincent and the Grenadines",
"WS": "Samoa",
"SM": "San Marino",
"ST": "Sao Tome and Principe",
"SA": "Saudi Arabia",
"GB-SCT": "Scotland",
"SN": "Senegal",
"RS": "Serbia",
"SC": "Seychelles",
"SL": "Sierra Leone",
"SG": "Singapore",
"SX": "Sint Maarten (Dutch part)",
"SK": "Slovakia",
"SI": "Slovenia",
"SB": "Solomon Islands",
"SO": "Somalia",
"ZA": "South Africa",
"GS": "South Georgia and the South Sandwich Islands",
"SS": "South Sudan",
"ES": "Spain",
"LK": "Sri Lanka",
"SD": "Sudan",
"SR": "Suriname",
"SJ": "Svalbard and Jan Mayen Islands",
"SZ": "Swaziland",
"SE": "Sweden",
"CH": "Switzerland",
"SY": "Syrian Arab Republic",
"TW": "Taiwan",
"TJ": "Tajikistan",
"TZ": "Tanzania, United Republic of",
"TH": "Thailand",
"TL": "Timor-Leste",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad and Tobago",
"TN": "Tunisia",
"TR": "Turkey",
"TM": "Turkmenistan",
"TC": "Turks and Caicos Islands",
"TV": "Tuvalu",
"UG": "Uganda",
"UA": "Ukraine",
"AE": "United Arab Emirates",
"GB": "United Kingdom",
"US": "United States",
"UY": "Uruguay",
"UM": "US Minor Outlying Islands",
"UZ": "Uzbekistan",
"VU": "Vanuatu",
"VE": "Venezuela, Bolivarian Republic of",
"VN": "Vietnam",
"VG": "Virgin Islands, British",
"VI": "Virgin Islands, U.S.",
"GB-WLS": "Wales",
"WF": "Wallis and Futuna Islands",
"EH": "Western Sahara",
"YE": "Yemen",
"ZM": "Zambia",
"ZW": "Zimbabwe",
"XX": "Unknown",
"XM": "The Moon"
}
}

View File

@ -1,666 +0,0 @@
{
"locales(map)": {
"en": "Английский (English)",
"ru": "Русский",
"zh-CN": "Упрощенный Китайский (简体中文)"
},
"tetraLeague": "Тетра Лига",
"tlRecords": "Матчи ТЛ",
"history": "История",
"sprint": "40 линий",
"blitz": "Блиц",
"recent": "Недавно",
"recentRuns": "Недавние",
"blitzScore": "$p очков",
"openSPreplay": "Открыть повтор в TETR.IO",
"downloadSPreplay": "Скачать повтор",
"other": "Другое",
"distinguishment": "Заслуга",
"zen": "Дзен",
"bio": "Биография",
"news": "Новости",
"newsParts":{
"leaderboardStart": "Взял ",
"leaderboardMiddle": "в таблице ",
"personalbest": "Поставил новый ЛР в ",
"personalbestMiddle": "с результатом в ",
"badgeStart": "Заработал значок ",
"badgeEnd": "",
"rankupStart": "Заработал ",
"rankupMiddle": "${r} ранг ",
"rankupEnd": "в Тетра Лиге",
"tetoSupporter": "TETR.IO supporter",
"supporterStart": "Стал обладателем ",
"supporterGiftStart": "Получил подарок в виде ",
"unknownNews": "Неизвестная новость типа ${type}"
},
"openSearch": "Искать игрока",
"closeSearch": "Закрыть поиск",
"searchHint": "Ник, ID или ID в Discord (с префиксом \"ds:\")",
"refresh": "Обновить",
"fetchAndsaveTLHistory": "Получить историю игрока",
"fetchAndSaveOldTLmatches": "Получить старые матчи Тетра Лиги",
"fetchAndsaveTLHistoryResult": "${number} состояний было найдено",
"fetchAndSaveOldTLmatchesResult": "${number} старых матчей было найдено",
"showStoredData": "Показать сохранённые данные",
"statsCalc": "Калькулятор статистики",
"settings": "Настройки",
"track": "Отслеживать",
"stopTracking": "Перестать\nотслеживать",
"becameTracked": "Добавлен в список отслеживания!",
"stoppedBeingTracked": "Удалён из списка отслеживания!",
"compare": "Сравнить",
"tlLeaderboard": "Рейтинговая таблица",
"noRecords": "Нет записей",
"noOldRecords": {
"zero": "Нет записей",
"one": "Всего один матч",
"two": "Всего $n матча",
"few": "Всего $n матча",
"many": "Всего $n матчей",
"other": "$n матчей"
},
"noRecord": "Нет рекорда",
"botRecord": "Ботам нельзя ставить рекорды",
"anonRecord": "Гостям нельзя ставить рекорды",
"notEnoughData": "Недостаточно данных",
"noHistorySaved": "Нет сохранённой истории",
"pseudoTooltipHeaderInit": "Наведите курсор на точку",
"pseudoTooltipFooterInit": "чтобы узнать подробности",
"obtainDate": "Получено ${date}",
"fetchDate": "На момент ${date}",
"exactGametime": "Время, проведённое в игре",
"bigRedBanned": "ЗАБАНЕН",
"normalBanned": "Забанен",
"bigRedBadStanding": "ПЛОХАЯ РЕПУТАЦИЯ",
"copiedToClipboard": "Скопировано в буфер обмена!",
"playerRoleAccount": ", аккаунт которого ",
"wasFromBeginning": "существовал с самого начала",
"created": "создан",
"botCreatedBy": "игроком",
"notSupporter": "Нет саппортерки",
"supporter": "Саппортерка ${tier} уровня",
"assignedManualy": "Этот значок был присвоен вручную администрацией TETR.IO",
"comparingWith": "Данные от ${newDate} в сравнении с данными от ${oldDate}",
"top": "Топ",
"topRank": "Топ ранг",
"verdictGeneral": "$verdict среднего $rank ранга на $n",
"verdictBetter": "Лучше",
"verdictWorse": "Хуже",
"smooth": "Гладкий",
"postSeason": "Внесезонье",
"seasonStarts": "Сезон начнётся через:",
"nanow": "Пока недоступно...",
"seasonEnds": "Сезон закончится через ${countdown}",
"seasonEnded": "Сезон закончился",
"gamesUntilRanked": "${left} матчей до получения рейтинга",
"numOfVictories": "~${wins} побед",
"promotionOnNextWin": "Повышение после следующей победы",
"numOfdefeats": "~${losses} поражений",
"demotionOnNextLoss": "Понижение после следующего поражения",
"nerdStats": "Для задротов",
"playersYouTrack": "Отслеживаемые игроки",
"formula": "Формула",
"exactValue": "Точное значение",
"neverPlayedTL": "Этот игрок никогда не играл в Тетра Лигу",
"botTL": "Ботам нельзя играть в Тетра Лигу",
"anonTL": "Гостям нельзя играть в Тетра Лигу",
"quickPlay": "Быстрая Игра",
"expert": "Эксперт",
"withMods": "С модами",
"withModsPlural":{
"zero": "с $n модами",
"one": "с $n модом",
"two": "с $n модами",
"few": "с $n модами",
"many": "с $n модами",
"other": "с $n модами"
},
"exportDB": "Экспортировать локальную базу данных",
"exportDBDescription": "Она содержит состояния аккаунтов и их матчей в Тетра Лиге для отслеживаемых игроков и список таких игроков.",
"desktopExportAlertTitle": "Экспорт на десктопе",
"desktopExportText": "Похоже, вы используете десктопную версию. Проверьте папку \"Документы\", там вы должны найти файл \"TetraStats.db\". Скопируйте его куда-нибудь",
"androidExportAlertTitle": "Экспорт на Android",
"androidExportText": "Экспортировано.\n${exportedDB}",
"importDB": "Импортировать локальную базу данных",
"importDBDescription": "Восстановите свою резеврную копию. Обратите внимание, что текущая база данных будет перезаписана.",
"importWrongFileType": "Неверный тип файла",
"importCancelled": "Операция была отменена",
"importSuccess": "Успешно импортировано",
"yourID": "Ваш аккаунт в TETR.IO",
"yourIDAlertTitle": "Ваш ник в TETR.IO",
"yourIDText": "При запуске приложения оно будет получать статистику этого игрока.",
"language": "Язык (Language)",
"updateInBackground": "Обновлять статистику в фоне",
"updateInBackgroundDescription": "Пока Tetra Stats работает, он может обновлять статистику самостоятельно когда кеш истекает",
"customization": "Кастомизация",
"customizationDescription": "Измените внешний вид пользовательского интерфейса Tetra Stats",
"oskKagari": "\"Оск Кагари\" прикол",
"oskKagariDescription": "Если включено, вместо настоящего ранга оска будет рендерится :kagari:",
"AccentColor": "Цветовой акцент",
"AccentColorDescription": "Почти все интерактивные элементы пользовательского интерфейса окрашены в этот цвет",
"timestamps": "Метки времени",
"timestampsDescription": "Вы можете выбрать, каким образом метки времени показывают время",
"timestampsAbsoluteGMT": "Абсолютные (GMT)",
"timestampsAbsoluteLocalTime": "Абсолютные (Ваш часовой пояс)",
"timestampsRelative": "Относительные",
"rating": "Основное представление рейтинга",
"ratingDescription": "TR нелинеен, тогда как Glicko не имеет границ, а положение в таблице лидеров волатильно",
"ratingLBposition": "Позиция в рейтинге",
"sheetbotGraphs": "Графики-радары как у sheetBot",
"sheetbotGraphsDescription": "Если включено, точки на графике могут появляться на противоположной стороне графика если значение отрицательное",
"lbStats": "Показывать статистику, основанную на рейтинговой таблице",
"lbStatsDescription": "Это повлияет на время загрузки, но позволит видеть положение в рейтинге и сравнение со средними значениями по рангу по каждой стате",
"aboutApp": "О приложении",
"aboutAppText": "${appName} (${packageName}) Версия ${version} Сборка ${buildNumber}\n\nРазработал dan63047\nФормулы предоставил kerrmunism\nИсторию предоставляет p1nkl0bst3r\nВозможность скачивать повторы из TETR.IO предоставляет szy",
"stateViewTitle": "Аккаунт ${nickname} ${date}",
"statesViewTitle": "${number} состояний аккаунта ${nickname}",
"matchesViewTitle": "Матчи аккаунта ${nickname}",
"statesViewEntry": "${level} TR, ${glicko}±${rd} Glicko, ${games} игр сыграно",
"stateRemoved": "Состояние от ${date} было удалено из локальной базы данных!",
"matchRemoved": "Матч от ${date} был удален из локальной базы данных!",
"viewAllMatches": "Все матчи",
"trackedPlayersViewTitle": "Сохранённые данные",
"trackedPlayersZeroEntrys": "Пустой список. Вернитесь на предыдущий экран и нажмите кнопку \"Отслеживать\", чтобы текущий игрок появился здесь",
"trackedPlayersOneEntry": "В списке только один игрок",
"trackedPlayersManyEntrys": "В списке ${numberOfPlayers} игроков",
"trackedPlayersEntry": "${nickname}: ${numberOfStates} состояний",
"trackedPlayersDescription": "Начиная с ${firstStateDate} и заканчивая ${lastStateDate}",
"trackedPlayersStatesDeleted": "Состояния аккаунта ${nickname} были удалены из локальной базы данных!",
"duplicatedFix": "Удалить дубликаты матчей в Тетра Лиге",
"compressDB": "Сжать базу данных",
"SpaceSaved": "Места освобождено: ${size}",
"averageXrank": "Средний ${rankLetter} ранг",
"vs": "против",
"inTLmatch": "в матче ТЛ",
"downloadReplay": "Скачать .ttrm повтор",
"openReplay": "Открыть повтор в TETR.IO",
"replaySaved": "Повтор сохранён по пути ${path}",
"match": "Матч",
"timeWeightedmatch": "Матч (взвешенная по времени)",
"roundNumber": "Раунд $n",
"statsFor": "Статистика за",
"numberOfRounds": "Количество раундов",
"matchLength": "Продолжительность матча",
"roundLength": "Продолжительность раунда",
"matchStats": "Статистика матча",
"timeWeightedmatchStats": "Взвешенная по времени cтатистика матча",
"replayIssue": "Ошибка обработки повтора",
"matchIsTooOld": "Информация о повторе недоступна",
"winner": "Победитель",
"registred": "Зарегистрирован",
"playedTL": "Играл в Тетра Лигу",
"winChance": "Шансы на победу",
"byGlicko": "По Glicko",
"byEstTR": "По расч. TR",
"compareViewNoValues": "Пожалуйста, введите никнейм, ID, APM-PPS-VS (неважно, какой разделитель, важен порядок) или $avgR (где R это ранг), в оба поля",
"compareViewWrongValue": "Не удалось получить ${value}",
"mostRecentOne": "Самый последний",
"yes": "Да",
"no": "Нет",
"daysLater": "дней позже",
"dayseBefore": "дней раньше",
"fromBeginning": "С начала",
"calc": "Считать",
"calcViewNoValues": "Введите значения, чтобы посчитать статистику",
"rankAveragesViewTitle": "Требования рангов",
"sprintAndBlitsViewTitle": "Средние результаты 40 линий и блица",
"sprintAndBlitsRelevance": "Актуальность: ${date}",
"rank": "Ранг",
"averages": "Средние значения",
"lbViewZeroEntrys": "Рейтинговая таблица пуста",
"lbViewOneEntry": "В рейтинговой таблице всего один игрок",
"lbViewManyEntrys": "В рейтинговой таблице находится ${numberOfPlayers}",
"everyoneAverages": "Значения таблицы",
"sortBy": "Cортировать по",
"reversed": "Наоборот",
"country": "Страна",
"rankAverages": "Значения для $rank ранга",
"players":{
"zero": "$n игроков",
"one": "$n игрок",
"two": "$n игрока",
"few": "$n игрока",
"many": "$n игроков",
"other": "$n игроков"
},
"games": {
"zero": "$n игр",
"one": "$n игра",
"two": "$n игры",
"few": "$n игры",
"many": "$n игр",
"other": "$n игр"
},
"gamesPlayed": "$games сыграно",
"chart": "График",
"entries": "Список",
"minimums": "Минимумы",
"maximums": "Максимумы",
"lowestValues": "Самые низкие показатели",
"averageValues": "Средние значения показателей",
"highestValues": "Самые высокие показатели",
"forPlayer": "для игрока $username",
"currentAxis": "Ось $axis:",
"p1nkl0bst3rAlert": "Эти данные были получены из стороннего API, который поддерживается p1nkl0bst3r",
"notForWeb": "Функция недоступна для веб версии",
"graphs": {
"attack": "Атака",
"speed": "Скорость",
"defense": "Защита",
"cheese": "Сыр"
},
"statCellNum": {
"xpLevel": "Уровень\nопыта",
"xpProgress": "Прогресс до следующего уровня",
"xpFrom0ToLevel": "Прогресс от 0 XP до $n уровня",
"xpLeft": "XP осталось",
"hoursPlayed": "Часов\nСыграно",
"onlineGames": "Онлайн\nИгр",
"gamesWon": "Онлайн\nПобед",
"totalGames": "Всего матчей",
"totalWon": "Всего побед",
"friends": "Друзей",
"apm": "Атака в\nМинуту",
"vs": "Показатель\nVersus",
"recordLB": "Место в таблице",
"lbp": "Положение\nв рейтинге",
"lbpShort": "№ в рейтинге",
"lbpc": "Положение\nв рейтинге страны",
"lbpcShort": "№ по стране",
"gamesPlayed": "Игр\nСыграно",
"gamesWonTL": "Побед",
"winrate": "Процент\nпобед",
"level": "Уровень",
"score": "Счёт",
"spp": "Очков\nна Фигуру",
"pieces": "Фигур\nУстановлено",
"pps": "Фигур в\nСекунду",
"finesseFaults": "Ошибок\nТехники",
"finessePercentage": "% Качества\nТехники",
"keys": "Нажатий\nКлавиш",
"kpp": "Нажатий\nна Фигуру",
"kps": "Нажатий\nв Секунду",
"tr": "Тетра Рейтинг",
"rd": "Отклонение рейтинга",
"app": "Атака на Фигуру",
"appDescription": "(Сокращенно APP) Главный показатель эффективности. Показывает, сколько атаки приходится на одну фигуру",
"vsapmDescription": "В основном, показывает как много мусора игрок использует в своих атаках и насколько эффективно.",
"dss": "Downstack\nв Секунду",
"dssDescription": "(Сокращенно DS/S) Downstack (спуск вниз) в Секунду показывает как много мусорных линий в среднем игрок убирает за одну секунду.",
"dsp": "Downstack\nна Фигуру",
"dspDescription": "(Сокращенно DS/P) Downstack (спуск вниз) на Фигуру показывает как много мусорных линий в среднем игрок убирает одну фигуру.",
"appdsp": "APP + DS/P",
"appdspDescription": "Просто сумма Атаки на Фигуру и Downstack на Фигуру.",
"cheese": "Индекс сыра",
"cheeseDescription": "(Сокращенно Cheese) Индекс сыра является аппроксимацией того, насколько чистый / дырявый мусор игрок отправляет. Меньше = более чистый. Больше = более дырявый.\nПридумал kerrmunism",
"gbe": "Garbage\nEfficiency",
"gbeDescription": "(Сокращенно Gb Eff.) Garbage Efficiency показывает насколько хорошо игрок использует свой мусор. Больше = лучше (или он использует больше мусора). Меньше = в основном отправляют сыр (или он редко чистит мусор).\nПридумали Zepheniah и Dragonboy.",
"nyaapp": "Взвешенный\nAPP",
"nyaappDescription": "(Сокращенно wAPP) По сути, показывает способность отправлять сыр, сохраняя при этом высокую эффективность.\nПридумал Wertj.",
"area": "Area",
"areaDescription": "Какую площадь занимает диаграмма, если не брать в расчёт индекс сыра и VS/APM",
"estOfTR": "Расчётный TR",
"estOfTRShort": "Расч. TR",
"accOfEst": "Точность расчёта",
"accOfEstShort": "Точность"
},
"playerRole(map)": {
"user": "Пользователь",
"banned": "Заблокированный пользователь",
"bot": "Бот",
"sysop": "Системный оператор",
"admin": "Администратор",
"mod": "Модератор",
"halfmod": "Модератор сообщества",
"anon": "Аноним"
},
"numOfGameActions":{
"pc": "Все чисто",
"hold": "В запас",
"inputs": {
"zero": "$n нажатий клавиш",
"one": "$n нажатие на клавишу",
"two": "$n нажатия на клавишы",
"few": "$n нажатия на клавишы",
"many": "$n нажатий на клавиш",
"other": "$n нажатий на клавиш"
},
"tspinsTotal": {
"zero": "$n T-спинов всего",
"one": "Всего $n T-спин",
"two": "$n T-спина всего",
"few": "$n T-спина всего",
"many": "$n T-спинов всего",
"other": "$n T-спинов всего"
},
"lineClears": {
"zero": "$n линий очищено",
"one": "$n линия очищена",
"two": "$n линии очищено",
"few": "$n линии очищено",
"many": "$n линий очищено",
"other": "$n линий очищено"
}
},
"popupActions":{
"cancel": "Отменить",
"submit": "Подтвердить",
"ok": "OK"
},
"errors":{
"connection": "Проблема с подключением: ${code} ${message}",
"noSuchUser": "Нет такого пользователя",
"noSuchUserSub": "Либо вы ошиблись при вводе, либо аккаунта больше не существует",
"discordNotAssigned": "К данному Discord ID не привязан аккаунт",
"discordNotAssignedSub": "Убедитесь в том, что вы вставили правильный ID",
"history": "История данного игрока отсутствует",
"actionSuggestion": "Возможно, вы хотите",
"p1nkl0bst3rTLmatches": "Старых матчей Тетра Лиги не было найдено",
"clientException": "Нет соединения с интернетом",
"forbidden": "Ваш IP адрес заблокирован",
"forbiddenSub": "Если у вас работает VPN или прокси, выключите его. Если это не помогло, свяжитесь с $nickname",
"tooManyRequests": "Слишком много запросов",
"tooManyRequestsSub": "Подождите немного и попробуйте снова",
"internal": "Что-то случилось на стороне tetr.io",
"internalSub": "Скорее всего, osk уже в курсе об этом",
"internalWebVersion": "Что-то случилось на стороне tetr.io (или на стороне oskware_bridge, я хз если честно)",
"internalWebVersionSub": "Если статус страница osk-а говорит, что всё ок - свяжитесь с dan63047",
"oskwareBridge": "Что-то случилось с oskware_bridge",
"oskwareBridgeSub": "Дайте dan63047 знать",
"p1nkl0bst3rForbidden": "Стороннее API заблокировало ваш IP адрес",
"p1nkl0bst3rTooManyRequests": "Слишком много запросов к стороннему API. Попробуйте позже",
"p1nkl0bst3rinternal": "Что-то случилось на стороне p1nkl0bst3r-а",
"p1nkl0bst3rinternalWebVersion": "Что-то случилось на стороне p1nkl0bst3r-а (или на стороне oskware_bridge, я хз если честно)",
"replayAlreadySaved": "Повтор уже сохранён",
"replayExpired": "Повтор истёк и больше недоступен",
"replayRejected": "Стороннее API заблокировало ваш IP адрес"
},
"countries(map)": {
"": "Во всём мире",
"AF": "Афганистан",
"AX": "Аландские острова",
"AL": "Албания",
"DZ": "Алжир",
"AS": "Американское Самоа",
"AD": "Андорра",
"AO": "Ангола",
"AI": "Ангилья",
"AQ": "Антарктида",
"AG": "Антигуа и Барбуда",
"AR": "Аргентина",
"AM": "Армения",
"AW": "Аруба",
"AU": "Австралия",
"AT": "Австрия",
"AZ": "Азербайджан",
"BS": "Багамские острова",
"BH": "Бахрейн",
"BD": "Бангладеш",
"BB": "Барбадос",
"BY": "Беларусь",
"BE": "Бельгия",
"BZ": "Белиз",
"BJ": "Бенин",
"BM": "Бермуды",
"BT": "Бутан",
"BO": "Боливия, Многонациональное Государство",
"BA": "Босния и Герцеговина",
"BW": "Ботсвана",
"BV": "Остров Буве",
"BR": "Бразилия",
"IO": "Британская территория в Индийском океане",
"BN": "Бруней-Даруссалам",
"BG": "Болгария",
"BF": "Буркина-Фасо",
"BI": "Бурунди",
"KH": "Камбоджа",
"CM": "Камерун",
"CA": "Канада",
"CV": "Кабо-Верде",
"BQ": "Карибские Нидерланды",
"KY": "Каймановы острова",
"CF": "Центральноафриканская Республика",
"TD": "Чад",
"CL": "Чили",
"CN": "Китай",
"CX": "Остров Рождества",
"CC": "Кокосовые острова",
"CO": "Колумбия",
"KM": "Коморские острова",
"CG": "Конго",
"CD": "Конго, Демократическая Республика",
"CK": "Острова Кука",
"CR": "Коста-Рика",
"CI": "Берег Слоновой Кости",
"HR": "Хорватия",
"CU": "Куба",
"CW": "Кюрасао",
"CY": "Кипр",
"CZ": "Чешская Республика",
"DK": "Дания",
"DJ": "Джибути",
"DM": "Доминика",
"DO": "Доминиканская Республика",
"EC": "Эквадор",
"EG": "Египет",
"SV": "Сальвадор",
"GB-ENG": "Англия",
"GQ": "Экваториальная Гвинея",
"ER": "Эритрея",
"EE": "Эстония",
"ET": "Эфиопия",
"EU": "Европа",
"FK": "Фолклендские (Мальвинские) острова",
"FO": "Фарерские острова",
"FJ": "Фиджи",
"FI": "Финляндия",
"FR": "Франция",
"GF": "Французская Гвиана",
"PF": "Французская Полинезия",
"TF": "Южные территории Франции",
"GA": "Габон",
"GM": "Гамбия",
"GE": "Грузия",
"DE": "Германия",
"GH": "Гана",
"GI": "Гибралтар",
"GR": "Греция",
"GL": "Гренландия",
"GD": "Гренада",
"GP": "Гваделупа",
"GU": "Гуам",
"GT": "Гватемала",
"GG": "Гернси",
"GN": "Гвинея",
"GW": "Гвинея-Бисау",
"GY": "Гайана",
"HT": "Гаити",
"HM": "Остров Херд и острова Макдональд",
"VA": "Святой Престол (государство-городок Ватикан)",
"HN": "Гондурас",
"HK": "Гонконг",
"HU": "Венгрия",
"IS": "Исландия",
"IN": "Индия",
"ID": "Индонезия",
"IR": "Иран, Исламская Республика",
"IQ": "Ирак",
"IE": "Ирландия",
"IM": "Остров Мэн",
"IL": "Израиль",
"IT": "Италия",
"JM": "Ямайка",
"JP": "Япония",
"JE": "Джерси",
"JO": "Иордания",
"KZ": "Казахстан",
"KE": "Кения",
"KI": "Кирибати",
"KP": "Корея, Народно-Демократическая Республика",
"KR": "Корея, Республика",
"XK": "Косово",
"KW": "Кувейт",
"KG": "Кыргызстан",
"LA": "Лаосская Народно-Демократическая Республика",
"LV": "Латвия",
"LB": "Ливан",
"LS": "Лесото",
"LR": "Либерия",
"LY": "Ливия",
"LI": "Лихтенштейн",
"LT": "Литва",
"LU": "Люксембург",
"MO": "Макао",
"MK": "Македония, бывшая югославская республика",
"MG": "Мадагаскар",
"MW": "Малави",
"MY": "Малайзия",
"MV": "Мальдивы",
"ML": "Мали",
"MT": "Мальта",
"MH": "Маршалловы острова",
"MQ": "Мартиника",
"MR": "Мавритания",
"MU": "Маврикий",
"YT": "Майотта",
"MX": "Мексика",
"FM": "Микронезия, Федеративные Штаты",
"MD": "Молдова, Республика",
"MC": "Монако",
"ME": "Черногория",
"MA": "Марокко",
"MN": "Монголия",
"MS": "Монтсеррат",
"MZ": "Мозамбик",
"MM": "Мьянма",
"NA": "Намибия",
"NR": "Науру",
"NP": "Непал",
"NL": "Нидерланды",
"AN": "Нидерландские Антильские острова",
"NC": "Новая Каледония",
"NZ": "Новая Зеландия",
"NI": "Никарагуа",
"NE": "Нигер",
"NG": "Нигерия",
"NU": "Ниуэ",
"NF": "Остров Норфолк",
"GB-NIR": "Северная Ирландия",
"MP": "Северные Марианские острова",
"NO": "Норвегия",
"OM": "Оман",
"PK": "Пакистан",
"PW": "Палау",
"PS": "Палестина",
"PA": "Панама",
"PG": "Папуа-Новая Гвинея",
"PY": "Парагвай",
"PE": "Перу",
"PH": "Филиппины",
"PN": "Питкэрн",
"PL": "Польша",
"PT": "Португалия",
"PR": "Пуэрто-Рико",
"QA": "Катар",
"RE": "Реюньон",
"RO": "Румыния",
"RU": "Российская Федерация",
"RW": "Руанда",
"BL": "Сен-Бартелеми",
"SH": "Острова Святой Елены, Вознесения и Тристан-да-Кунья",
"KN": "Сент-Китс и Невис",
"LC": "Сент-Люсия",
"MF": "Сен-Мартен",
"PM": "Сен-Пьер и Микелон",
"VC": "Сент-Винсент и Гренадины",
"WS": "Самоа",
"SM": "Сан-Марино",
"ST": "Сан-Томе и Принсипи",
"SA": "Саудовская Аравия",
"GB-SCT": "Шотландия",
"SN": "Сенегал",
"RS": "Сербия",
"SC": "Сейшельские острова",
"SL": "Сьерра-Леоне",
"SG": "Сингапур",
"SX": "Синт-Мартен (голландская часть)",
"SK": "Словакия",
"SI": "Словения",
"SB": "Соломоновы острова",
"SO": "Сомали",
"ZA": "ЮАР",
"GS": "Южная Георгия и Южные Сандвичевы острова",
"SS": "Южный Судан",
"ES": "Испания",
"LK": "Шри-Ланка",
"SD": "Судан",
"SR": "Суринам",
"SJ": "Острова Шпицберген и Ян-Майен",
"SZ": "Свазиленд",
"SE": "Швеция",
"CH": "Швейцария",
"SY": "Сирийская Арабская Республика",
"TW": "Тайвань",
"TJ": "Таджикистан",
"TZ": "Танзания, Объединенная Республика",
"TH": "Таиланд",
"TL": "Тимор-Лешти",
"TG": "Того",
"TK": "Токелау",
"TO": "Tonga",
"TT": "Тринидад и Тобаго",
"TN": "Тунис",
"TR": "Турция",
"TM": "Туркменистан",
"TC": "Острова Теркс и Кайкос",
"ТВ": "Тувалу",
"UG": "Уганда",
"UA": "Украина",
"AE": "Объединенные Арабские Эмираты",
"GB": "Великобритания",
"US": "Соединенные Штаты",
"UY": "Уругвай",
"UM": "Малые периферийные острова США",
"UZ": "Узбекистан",
"VU": "Вануату",
"VE": "Венесуэла, Боливарианская Республика",
"VN": "Вьетнам",
"VG": "Виргинские острова, Британские",
"VI": "Виргинские острова, США",
"GB-WLS": "Уэльс",
"WF": "Острова Уоллис и Футуна",
"EH": "Западная Сахара",
"YE": "Йемен",
"ZM": "Замбия",
"ZW": "Зимбабве",
"XX": "Неизвестно",
"XM": "Луна"
}
}

View File

@ -1,640 +0,0 @@
{
"locales(map)": {
"en": "英语 (English)",
"ru": "俄语 (Русский)",
"zh-CN": "简体中文"
},
"tetraLeague": "Tetra联赛",
"tlRecords": "Tetra联赛记录",
"history": "历史",
"sprint": "40行竞速",
"blitz": "闪电战",
"recent": "最近",
"recentRuns": "最近游玩局数",
"blitzScore": "$p 分",
"openSPreplay": "在TETR.IO打开回放",
"downloadSPreplay": "下载回放",
"other": "其他",
"distinguishment": "区别",
"zen": "禅意模式",
"bio": "个人简介",
"news": "新闻",
"newsParts": {
"leaderboardStart": "取得 ",
"leaderboardMiddle": "于 ",
"personalbest": "在 ",
"personalbestMiddle": " 中取得了新的个人最好成绩 ",
"badgeStart": "获得勋章 ",
"badgeEnd": "",
"rankupStart": "达成 ",
"rankupMiddle": "${r} 段位 ",
"rankupEnd": "",
"tetoSupporter": "TETR.IO 会员",
"supporterStart": "成为了 ",
"supporterGiftStart": "被赠送了 ",
"unknownNews": "未知新闻 ${type}"
},
"openSearch": "搜索玩家",
"closeSearch": "关闭搜索",
"searchHint": "昵称ID或Discord用户ID需要 \"ds:\" 前缀)",
"refresh": "刷新",
"fetchAndsaveTLHistory": "获取玩家历史",
"fetchAndSaveOldTLmatches": "获取玩家Tetra联赛历史",
"fetchAndsaveTLHistoryResult": "找到 ${number} 个状态",
"fetchAndSaveOldTLmatchesResult": "找到 ${number} 场Tetra联赛比赛",
"showStoredData": "显示获得的数据",
"statsCalc": "统计计算器",
"settings": "设置",
"track": "添加到\n跟踪列表",
"stopTracking": "从跟踪列表\n中移除",
"becameTracked": "已添加到跟踪列表!",
"compare": "对比",
"stoppedBeingTracked": "已从跟踪列表中移除!",
"tlLeaderboard": "Tetra联赛排行榜",
"noRecords": "无记录",
"noOldRecords": {
"zero": "无记录",
"one": "只有 $n 个记录",
"two": "只有 $n 个记录",
"few": "只有 $n 个记录",
"many": "只有 $n 个记录",
"other": "只有 $n 个记录"
},
"noRecord": "没有记录",
"botRecord": "机器人不予参加排位赛",
"anonRecord": "匿名用户不予参加排位赛",
"notEnoughData": "没有足够的数据",
"noHistorySaved": "没有保存历史",
"pseudoTooltipHeaderInit": "将鼠标放在点上",
"pseudoTooltipFooterInit": "以查看详细信息",
"obtainDate": "在 ${date} 获得",
"fetchDate": "Fetched ${date}",
"exactGametime": "实际游玩时长",
"bigRedBanned": "该账号封禁中",
"normalBanned": "封禁",
"bigRedBadStanding": "信誉不佳",
"copiedToClipboard": "已复制",
"playerRoleAccount": "账号",
"wasFromBeginning": "在很久很久以前",
"created": "创建于",
"botCreatedBy": "",
"notSupporter": "非会员",
"assignedManualy": "该勋章由 TETR.IO 管理员手动分配",
"supporter": "会员等级 ${tier}",
"comparingWith": "${newDate} 时的数据与 ${oldDate} 比较",
"top": "前",
"topRank": "最高段位",
"verdictGeneral": "比 $rank 段平均数据$verdict $n",
"verdictBetter": "好",
"verdictWorse": "差",
"smooth": "平滑",
"postSeason": "淡季",
"seasonStarts": "下一赛即将开始于:",
"nanow": "暂未完成,敬请等待!",
"seasonEnds": "赛季将会在 ${countdown} 后结束",
"seasonEnded": "Season has ended",
"gamesUntilRanked": "还有 ${left} 场比赛获取段位",
"numOfVictories": "~${wins} 场胜局",
"promotionOnNextWin": "下一次胜利即可升段",
"numOfdefeats": "~${losses} 场败局",
"demotionOnNextLoss": "下一次失败即可掉段",
"nerdStats": "详细信息",
"playersYouTrack": "跟踪",
"formula": "公式",
"exactValue": "实际值",
"neverPlayedTL": "此用户没有参与Tetra联赛",
"botTL": "机器人不予参加Tetra联赛",
"anonTL": "匿名用户不予参加Tetra联赛",
"quickPlay": "快速游戏",
"expert": "专家",
"withMods": "带着模组",
"withModsPlural": {
"zero": "带着 $n 个模组",
"one": "带着 $n 个模组",
"two": "带着 $n 个模组",
"few": "带着 $n 个模组",
"many": "带着 $n 个模组",
"other": "带着 $n 个模组"
},
"exportDB": "导出本地数据",
"exportDBDescription": "它包含跟踪的玩家的状态和Tetra联赛记录和跟踪列表。",
"desktopExportAlertTitle": "桌面导出",
"desktopExportText": "您好像在使用桌面版。请查看你的“文档”文件夹你应该能找到“TetraStats.db”。把它复制到一个地方",
"androidExportAlertTitle": "安卓导出",
"androidExportText": "导出成功\n${exportedDB}",
"importDB": "导入本地数据",
"importDBDescription": "恢复您的备份。请注意,已存储的数据库将被覆盖。",
"importWrongFileType": "文件类型错误",
"importCancelled": "已取消",
"importSuccess": "导入成功",
"yourID": "你的 TETR.IO 用户",
"yourIDAlertTitle": "你的 TETR.IO 昵称",
"yourIDText": "当程序加载,它将显示此用户的数据",
"language": "语言",
"updateInBackground": "自动升级数据",
"updateInBackgroundDescription": "当 Tetra Stats 运行时,它可以在缓存过期时更新当前玩家的统计数据",
"customization": "自定义",
"customizationDescription": "更改 Tetra Stats UI 中不同事物的外观",
"oskKagari": "osk 特有的 Kagari 段位",
"oskKagariDescription": "如果打开,主视图上的 osk 段位将显示为 :kagari:",
"AccentColor": "主题色",
"AccentColorDescription": "几乎所有交互式 UI 元素都用此颜色突出显示",
"timestamps": "时间",
"timestampsDescription": "您可以选择显示时间的方式",
"timestampsAbsoluteGMT": "绝对 (GMT)",
"timestampsAbsoluteLocalTime": "绝对 (你的时区)",
"timestampsRelative": "相对",
"rating": "评级主要表现",
"ratingDescription": "TR 不是线性的,而 Glicko 没有边界,百分位数易挥发",
"ratingLBposition": "LB 位置",
"sheetbotGraphs": "Sheetbot式雷达图",
"sheetbotGraphsDescription": "若开启,雷达图上的点为负时可以出现在对面",
"lbStats": "显示基于排行榜的数据",
"lbStatsDescription": "这会影响加载时间,但允许您通过统计数据查看排行榜上的位置并与平均值进行比较",
"aboutApp": "关于",
"aboutAppText": "${appName} (${packageName}) ${version} 版 Build ${buildNumber}\n\n由 dan63047 制作\n由 kerrmunism 提供公式\n由 p1nkl0bst3r 提供历史\nTETR.IO 回放抓取器 API 由 szy 制作",
"stateViewTitle": "${nickname} 在 ${date}",
"statesViewTitle": "${nickname} 的 ${number} 个状态",
"matchesViewTitle": "${nickname} 的Tetra联赛历史",
"statesViewEntry": "${level} TR, ${glicko}±${rd} Glicko, ${games} 次游戏",
"stateRemoved": "成功移除 ${date} 的状态!",
"matchRemoved": "成功移除 ${date} 的比赛!",
"viewAllMatches": "查看所有比赛",
"trackedPlayersViewTitle": "获取的数据",
"trackedPlayersZeroEntrys": "列表为空。 点击 “添加到跟踪列表” 可以将玩家放在这里",
"trackedPlayersOneEntry": "只有 1 个玩家",
"trackedPlayersManyEntrys": "${numberOfPlayers} 个玩家",
"trackedPlayersEntry": "${nickname}${numberOfStates} 个状态",
"trackedPlayersDescription": "从 ${firstStateDate} 到 ${lastStateDate}",
"trackedPlayersStatesDeleted": "成功从数据库中移除 ${nickname} 个状态!",
"duplicatedFix": "删除重复的 TL 匹配项",
"compressDB": "压缩数据库",
"SpaceSaved": "保存空白:${size}",
"averageXrank": "平均 ${rankLetter} 段",
"vs": "vs",
"inTLmatch": "在Tetra联赛中",
"downloadReplay": "下载 .ttrm 回放",
"openReplay": "在 TETR.IO 打开回放",
"replaySaved": "已保存回放至 ${path}",
"match": "比赛",
"timeWeightedmatch": "比赛(时间加权)",
"roundNumber": "第 $n 回合",
"statsFor": "数据:",
"numberOfRounds": "回合数",
"matchLength": "比赛时长",
"roundLength": "回合时长",
"matchStats": "比赛数据",
"timeWeightedmatchStats": "时间加权比赛数据",
"replayIssue": "无法处理回放",
"matchIsTooOld": "无回放",
"winner": "赢家",
"registred": "注册日期",
"playedTL": "游玩过Tetra联赛",
"winChance": "胜利机会",
"byGlicko": "靠Glicko",
"byEstTR": "靠预测TR",
"compareViewNoValues": "请输入用户名用户IOAPM-PPS-VS值 (分隔符不重要,只需要顺序)或者$avgRR是一个段位到两个字段",
"compareViewWrongValue": "获取 ${value} 失败",
"mostRecentOne": "最接近的",
"yes": "是",
"no": "否",
"daysLater": "天后",
"dayseBefore": "天前",
"fromBeginning": "开服",
"calc": "计算器",
"calcViewNoValues": "输入值以计算数据",
"rankAveragesViewTitle": "段位分隔符",
"sprintAndBlitsViewTitle": "竞速与闪电战平均数据",
"sprintAndBlitsRelevance": "数据来自${date}",
"rank": "段位",
"averages": "平均",
"lbViewZeroEntrys": "空",
"lbViewOneEntry": "只有一个玩家",
"lbViewManyEntrys": "有 ${numberOfPlayers}",
"everyoneAverages": "Tetra联赛散点图",
"sortBy": "排序依据",
"reversed": "反向",
"country": "地区",
"rankAverages": "$rank段位散点图",
"players": {
"zero": "$n 个玩家",
"one": "$n 个玩家",
"two": "$n 个玩家",
"few": "$n 个玩家",
"many": "$n 个玩家",
"other": "$n 个玩家"
},
"games": {
"zero": "$n 场游戏",
"one": "$n 场游戏",
"two": "$n 场游戏",
"few": "$n 场游戏",
"many": "$n 场游戏",
"other": "$n 场游戏"
},
"gamesPlayed": "$games 场游戏",
"chart": "列表",
"entries": "条目",
"minimums": "最小值",
"maximums": "最大值",
"lowestValues": "最小值",
"averageValues": "平均值",
"highestValues": "最大值",
"forPlayer": "来自用户 $username",
"currentAxis": "$axis 轴:",
"p1nkl0bst3rAlert": "该数据是从 p1nkl0bst3r 维护的第三方 API 中检索的",
"notForWeb": "浏览器版本暂不支持函数",
"graphs": {
"attack": "攻击",
"speed": "速度",
"defense": "防御",
"cheese": "奶酪层"
},
"statCellNum": {
"xpLevel": "XP等级",
"xpProgress": "到下一等级的进度",
"xpFrom0ToLevel": "从 0 到 $n 等级的进度",
"xpLeft": "XP 还有",
"hoursPlayed": "小时游玩",
"onlineGames": "在线游戏场次",
"gamesWon": "获胜场次",
"totalGames": "总在线游戏场次",
"totalWon": "总在线游戏获胜场次",
"friends": "好友",
"apm": "每分\n发送垃圾行",
"vs": "VS\n分数",
"recordLB": "名次",
"lbp": "名次",
"lbpShort": "名次",
"lbpc": "地区\n名次",
"lbpcShort": "地区名次",
"gamesPlayed": "游戏\n场次",
"gamesWonTL": "获胜\n场次",
"winrate": "胜率",
"level": "等级",
"score": "分数",
"spp": "每块\n得分",
"pieces": "放置\n块数",
"pps": "每秒\n放置块数",
"finesseFaults": "非极简\n操作",
"finessePercentage": "极简率",
"keys": "按键",
"kpp": "每块\n按键",
"kps": "每秒\n按键",
"tr": "Tetra分数",
"rd": "偏移值",
"app": "每块发送垃圾行数",
"appDescription": "(Attack per Piece, 简称APP) 主要效率指标。表示玩家每块可以发动多少次攻击",
"vsapmDescription": "基本上可以告诉你在攻击中利用垃圾行的效率",
"dss": "每秒\n挖掘",
"dssDescription": "(Downstack per Second, 简称 DS/S) 测量一秒钟内清除多少条垃圾行。",
"dsp": "每块\n挖掘",
"dspDescription": "(Downstack per Piece, 简称 DS/P) 测量每一块清除多少条垃圾行。",
"appdsp": "APP + DS/P",
"appdspDescription": "只是每块发送垃圾行数与每块挖掘之和。",
"cheese": "垃圾行\n混乱指数",
"cheeseDescription": "(Cheese Index, 简称Cheese) 是玩家发出的垃圾行有多整齐/混乱的近似值。低数据代表整齐,高数据代表混乱。\n由 kerrmunism 发明",
"gbe": "垃圾行\n效率",
"gbeDescription": "(Garbage Efficity, 简称Gb Eff.) 测量玩家如何很好地利用他们收到的垃圾行。高数据代表更好或者他们更多地用TA的垃圾行低数据代表TA大多将垃圾行送回奶酪层或者很少清理垃圾行。\n由 Zepheniah 与 Dragonboy 发明。",
"nyaapp": "加权\nAPP",
"nyaappDescription": "(Weighted APP, 简称wAPP) 在本质上是在衡量您在保持高 APP 的同时发送奶酪的能力。\n由 Wertj 发明。",
"area": "面积",
"areaDescription": "如果排除 Cheese 和 vs/apm 部分,您的形状在图表上占据了多少空间",
"estOfTR": "预测 TR",
"estOfTRShort": "预测 TR",
"accOfEst": "预测实际差量",
"accOfEstShort": "预测实际差量"
},
"playerRole(map)": {
"user": "用户",
"banned": "封禁",
"bot": "机器人",
"sysop": "系统管理员",
"admin": "管理员",
"mod": "管理员",
"halfmod": "社区管理员",
"anon": "匿名"
},
"numOfGameActions": {
"pc": "全消数",
"hold": "暂存数",
"inputs": {
"zero": "$n 次按键",
"one": "$n 次按键",
"two": "$n 次按键",
"few": "$n 次按键",
"many": "$n 次按键",
"other": "$n 次按键"
},
"tspinsTotal": {
"zero": "共 $n 次T旋",
"one": "共 $n 次T旋",
"two": "共 $n 次T旋",
"few": "共 $n 次T旋",
"many": "共 $n 次T旋",
"other": "共 $n 次T旋"
},
"lineClears": {
"zero": "清除了 $n 行",
"one": "清除了 $n 行",
"two": "清除了 $n 行",
"few": "清除了 $n 行",
"many": "清除了 $n 行",
"other": "清除了 $n 行"
}
},
"popupActions": {
"cancel": "取消",
"submit": "确定",
"ok": "彳亍"
},
"errors": {
"connection": "连接错误: ${code} ${message}",
"noSuchUser": "没有这样的用户",
"noSuchUserSub": "检查用户名的拼写是否错误,也许用户不存在",
"discordNotAssigned": "没有用户绑定到该Discord ID",
"discordNotAssignedSub": "您必须输入合法的ID",
"history": "此玩家没有历史",
"actionSuggestion": "你也许想",
"p1nkl0bst3rTLmatches": "没有比赛",
"clientException": "连接不到网络",
"forbidden": "你的IP地址被封禁",
"forbiddenSub": "请关闭您的VPN。若问题仍然存在请联系 $nickname",
"tooManyRequests": "您申请的请求过多",
"tooManyRequestsSub": "等一会再试吧",
"internal": "tetr.io 似乎出错了",
"internalSub": "osk也许要被",
"internalWebVersion": "tetr.io 或者 oskware_bridge 似乎出错了",
"internalWebVersionSub": "如果 osk 说没有什么问题请让dan63047知道",
"oskwareBridge": "oskware_bridge 似乎出错了",
"oskwareBridgeSub": "请让 dan63047 知道",
"p1nkl0bst3rForbidden": "第三方API封禁了你的IP地址",
"p1nkl0bst3rTooManyRequests": "第三方API……太多请求了。",
"p1nkl0bst3rinternal": "p1nkl0bst3r 那边似乎出错了",
"p1nkl0bst3rinternalWebVersion": "p1nkl0bst3r (或 on oskware_bridge, 其实我并不知道) 那边似乎出错了",
"replayAlreadySaved": "你已保存此回放",
"replayExpired": "回放已过期",
"replayRejected": "第三方API封禁了你的IP地址"
},
"countries(map)": {
"": "无",
"AF": "阿富汗",
"AX": "奥兰群岛",
"AL": "阿尔巴尼亚",
"DZ": "阿尔及利亚",
"AS": "美属萨摩亚",
"AD": "安道尔",
"AO": "安哥拉",
"AI": "安圭拉",
"AQ": "南极洲",
"AG": "安提瓜和巴布达",
"AR": "阿根廷",
"AM": "亚美尼亚",
"AW": "阿鲁巴",
"AU": "澳大利亚",
"AT": "奥地利",
"AZ": "阿塞拜疆",
"BS": "巴哈马",
"BH": "巴林",
"BD": "孟加拉国",
"BB": "巴巴多斯",
"BY": "白俄罗斯",
"BE": "比利时",
"BZ": "伯利兹",
"BJ": "贝宁",
"BM": "百慕大",
"BT": "不丹",
"BO": "玻利维亚多民族国",
"BA": "波斯尼亚和黑塞哥维那",
"BW": "博茨瓦纳",
"BV": "布韦岛",
"BR": "巴西",
"IO": "英属印度洋领地",
"BN": "文莱达鲁萨兰国",
"BG": "保加利亚",
"BF": "布基纳法索",
"BI": "布隆迪",
"KH": "柬埔寨",
"CM": "喀麦隆",
"CA": "加拿大",
"CV": "佛得角",
"BQ": "荷兰加勒比区",
"KY": "开曼群岛",
"CF": "中非",
"TD": "乍得",
"CL": "智利",
"CN": "中国",
"CX": "圣诞岛",
"CC": "科科斯(基林)群岛",
"CO": "哥伦比亚",
"KM": "科摩罗",
"CG": "刚果(布)/刚果共和国",
"CD": "刚果(金)/刚果民主共和国",
"CK": "库克群岛",
"CR": "哥斯达黎加",
"CI": "科特迪瓦",
"HR": "克罗地亚",
"CU": "古巴",
"CW": "库拉索",
"CY": "塞浦路斯",
"CZ": "捷克",
"DK": "丹麦",
"DJ": "吉布提",
"DM": "多米尼加",
"DO": "多米尼加共和国",
"EC": "厄瓜多尔",
"EG": "埃及",
"SV": "萨尔瓦多",
"GB-ENG": "英格兰",
"GQ": "赤道几内亚",
"ER": "厄立特里亚",
"EE": "爱沙尼亚",
"ET": "埃塞俄比亚",
"EU": "欧洲",
"FK": "福克兰群岛/马尔维纳斯群岛",
"FO": "法罗群岛",
"FJ": "斐济",
"FI": "芬兰",
"FR": "法国",
"GF": "法属圭亚那",
"PF": "法属波利尼西亚",
"TF": "法属南部领地",
"GA": "加蓬",
"GM": "冈比亚",
"GE": "格鲁吉亚",
"DE": "德国",
"GH": "加纳",
"GI": "直布罗陀",
"GR": "希腊",
"GL": "格陵兰岛",
"GD": "格林纳达",
"GP": "瓜德罗普岛",
"GU": "关岛",
"GT": "危地马拉",
"GG": "根西岛",
"GN": "几内亚",
"GW": "几内亚比绍",
"GY": "圭亚那",
"HT": "海地",
"HM": "赫德岛和麦克唐纳群岛",
"VA": "梵蒂冈",
"HN": "洪都拉斯",
"HK": "中国香港",
"HU": "匈牙利",
"IS": "冰岛",
"IN": "印度",
"ID": "印度尼西亚",
"IR": "伊朗",
"IQ": "伊拉克",
"IE": "爱尔兰",
"IM": "马恩岛",
"IL": "以色列",
"IT": "意大利",
"JM": "牙买加",
"JP": "日本",
"JE": "Jersey",
"JO": "约旦",
"KZ": "哈萨克斯坦",
"KE": "肯尼亚",
"KI": "基里巴斯",
"KP": "朝鲜",
"KR": "韩国",
"XK": "科索沃",
"KW": "科威特",
"KG": "吉尔吉斯斯坦",
"LA": "老挝",
"LV": "拉脱维亚",
"LB": "黎巴嫩",
"LS": "莱索托",
"LR": "利比里亚",
"LY": "利比亚",
"LI": "列支敦士登",
"LT": "立陶宛",
"LU": "卢森堡",
"MO": "中国澳门",
"MK": "马其顿",
"MG": "马达加斯加",
"MW": "马拉维",
"MY": "马来西亚",
"MV": "马尔代夫",
"ML": "马里",
"MT": "马耳他",
"MH": "马绍尔群岛",
"MQ": "马提尼克岛",
"MR": "毛里塔尼亚",
"MU": "毛里求斯",
"YT": "马约特岛",
"MX": "墨西哥",
"FM": "密克罗尼西亚联邦",
"MD": "摩尔多瓦共和国",
"MC": "摩纳哥",
"ME": "黑山",
"MA": "摩洛哥",
"MN": "蒙古",
"MS": "蒙特塞拉特",
"MZ": "莫桑比克",
"MM": "缅甸",
"NA": "纳米比亚",
"NR": "瑙鲁",
"NP": "尼泊尔",
"NL": "尼德兰",
"AN": "荷属安的列斯",
"NC": "新喀里多尼亚",
"NZ": "新西兰",
"NI": "尼加拉瓜",
"NE": "尼日尔",
"NG": "尼日利亚",
"NU": "纽埃",
"NF": "诺福克岛",
"GB-NIR": "北爱尔兰",
"MP": "北马里亚纳群岛",
"NO": "挪威",
"OM": "阿曼",
"PK": "巴基斯坦",
"PW": "帕劳",
"PS": "巴勒斯坦",
"PA": "巴拿马",
"PG": "巴布亚新几内亚",
"PY": "巴拉圭",
"PE": "秘鲁",
"PH": "菲律宾",
"PN": "皮特凯恩",
"PL": "波兰",
"PT": "葡萄牙",
"PR": "波多黎各",
"QA": "卡塔尔",
"RE": "留尼汪",
"RO": "罗马尼亚",
"RU": "俄罗斯联邦",
"RW": "卢旺达",
"BL": "圣巴泰勒米",
"SH": "圣赫勒拿,阿森松和特里斯坦-达库尼亚",
"KN": "圣基茨和尼维斯",
"LC": "圣卢西亚",
"MF": "圣马丁",
"PM": "圣皮埃尔和密克隆群岛",
"VC": "圣文森特和格林纳丁斯",
"WS": "萨摩亚",
"SM": "圣马力诺",
"ST": "圣多美和普林西比",
"SA": "沙特阿拉伯",
"GB-SCT": "苏格兰",
"SN": "塞内加尔",
"RS": "塞尔维亚",
"SC": "塞舌尔",
"SL": "塞拉利昂",
"SG": "新加坡",
"SX": "荷属圣马丁",
"SK": "斯洛伐克",
"SI": "斯洛文尼亚",
"SB": "所罗门群岛",
"SO": "索马里",
"ZA": "南非",
"GS": "南乔治亚和南桑威奇群岛",
"SS": "南苏丹",
"ES": "西班牙",
"LK": "斯里兰卡",
"SD": "苏丹",
"SR": "苏里南",
"SJ": "斯瓦尔巴和扬马延群岛",
"SZ": "斯威士兰",
"SE": "瑞典",
"CH": "瑞士",
"SY": "叙利亚",
"TW": "中国台湾",
"TJ": "塔吉克斯坦",
"TZ": "坦桑尼亚",
"TH": "泰国",
"TL": "东帝汶",
"TG": "多哥",
"TK": "托克劳",
"TO": "汤加",
"TT": "特立尼达和多巴哥",
"TN": "突尼斯",
"TR": "土耳其",
"TM": "土库曼斯坦",
"TC": "特克斯和凯科斯群岛",
"TV": "图瓦卢",
"UG": "乌干达",
"UA": "乌克兰",
"AE": "阿拉伯联合酋长国",
"GB": "英国",
"US": "美国",
"UY": "乌拉圭",
"UM": "美国小岛屿",
"UZ": "乌兹别克斯坦",
"VU": "瓦努阿图",
"VE": "委内瑞拉玻利瓦尔共和国",
"VN": "越南",
"VG": "英属维尔京群岛",
"VI": "美属维尔京群岛",
"GB-WLS": "威尔士",
"WF": "瓦利斯和富图纳群岛",
"EH": "西撒哈拉",
"YE": "也门",
"ZM": "赞比亚",
"ZW": "津巴布韦",
"XX": "未知",
"XM": "月球"
}
}

View File

@ -358,7 +358,9 @@
"welcome": "Welcome to Tetra Stats",
"description": "Service, that allows you to keep track of various statistics for TETR.IO",
"nicknameQuestion": "What's your nickname?",
"inpuntHint": "Type it here... (3-16 symbols)"
"inpuntHint": "Type it here... (3-16 symbols)",
"emptyInputError": "Can't submit empty string",
"skip": "Skip"
},
"aboutView": {
"title": "About Tetra Stats",

View File

@ -357,8 +357,10 @@
"firstTimeView": {
"welcome": "Добро пожаловать в Tetra Stats",
"description": "Сервис, который позволяет просматривать статистику в TETR.IO",
"nicknameQuestion": "Какой у вас ник?",
"inpuntHint": "Введите его здесь... (3-16 символов)"
"nicknameQuestion": "Введите свой ник",
"inpuntHint": "(3-16 символов)",
"emptyInputError": "Строка пуста",
"skip": "Пропустить"
},
"aboutView": {
"title": "О Tetra Stats",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 81 KiB

BIN
res/images/info card 2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
res/images/info card 3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB