1.7.32 ba_data update

This commit is contained in:
Ayush Saini 2023-12-21 15:55:50 +05:30
parent bf2f252ee5
commit 15393d5461
144 changed files with 4296 additions and 2411 deletions

View file

@ -12,7 +12,7 @@
"Filipino": "Tagalog ", "Filipino": "Tagalog ",
"French": "Français", "French": "Français",
"German": "Deutsch", "German": "Deutsch",
"Gibberish": "Gibberish", "Gibberish": "Abuktarika",
"Greek": "Ελληνικά", "Greek": "Ελληνικά",
"Hindi": "हिंदी", "Hindi": "हिंदी",
"Hungarian": "Magyar", "Hungarian": "Magyar",
@ -42,13 +42,18 @@
"!nobal", "!nobal",
"!ParkuristTurist!", "!ParkuristTurist!",
"\"9۝ÅЇρѺ۝ƬǀGΞЯ", "\"9۝ÅЇρѺ۝ƬǀGΞЯ",
"\"Unknown\"",
"/in/dev/", "/in/dev/",
"1.4.139", "1.4.139",
"11",
"123", "123",
"123123123", "123123123",
"1Platinumpatty",
"1SpaZ",
"228варенье", "228варенье",
"233", "233",
"26885", "26885",
"3alTemp",
"43210", "43210",
"5PH3X", "5PH3X",
"99", "99",
@ -100,6 +105,7 @@
"Carlos Mario Agamez", "Carlos Mario Agamez",
"ageng", "ageng",
"Dimitris Aggelou", "Dimitris Aggelou",
"AGØTI",
"ariyan ahir", "ariyan ahir",
"AHMAD", "AHMAD",
"Aufan Ahmad", "Aufan Ahmad",
@ -113,6 +119,7 @@
"Aki", "Aki",
"Abdullah Akkan", "Abdullah Akkan",
"Berk Akkaya", "Berk Akkaya",
"AkVoN",
"AKYG", "AKYG",
"mohammed al-abri", "mohammed al-abri",
"Ali Al-Gattan", "Ali Al-Gattan",
@ -128,12 +135,14 @@
"Alex", "Alex",
"Alexander", "Alexander",
"Gros Alexandre", "Gros Alexandre",
"AlexBx",
"Alexey", "Alexey",
"Alexgmihai", "Alexgmihai",
"Alexis", "Alexis",
"Alexistb2904", "Alexistb2904",
"Alexyze", "Alexyze",
"Algene123456", "Algene123456",
"Alguien_201",
"ALI", "ALI",
"Mohamed ali", "Mohamed ali",
"Shadiq Ali", "Shadiq Ali",
@ -144,6 +153,7 @@
"Allinol", "Allinol",
"ahmed alomari", "ahmed alomari",
"Alonso", "Alonso",
"Alp",
"Alper", "Alper",
"Alpha", "Alpha",
"AlphaT", "AlphaT",
@ -164,6 +174,7 @@
"amir234", "amir234",
"amir80sas", "amir80sas",
"AmirMahdi.D :P", "AmirMahdi.D :P",
"amirsaman050",
"Amirul", "Amirul",
"Ange Kevin Amlaman", "Ange Kevin Amlaman",
"AMOGUSS85", "AMOGUSS85",
@ -214,6 +225,7 @@
"arjanex", "arjanex",
"Arroz", "Arroz",
"ARSHAD", "ARSHAD",
"Arshia",
"ArshiyDLn", "ArshiyDLn",
"Artem", "Artem",
"Valentino Artizzu", "Valentino Artizzu",
@ -244,6 +256,7 @@
"Azlan", "Azlan",
"Azoz", "Azoz",
"Burak Karadeniz (Myth B)", "Burak Karadeniz (Myth B)",
"Leonan B.",
"Myth B.", "Myth B.",
"B4likeBefore", "B4likeBefore",
"Praveen Babu", "Praveen Babu",
@ -280,6 +293,7 @@
"Wojtek Bałut", "Wojtek Bałut",
"Hi bbbbbbbbb", "Hi bbbbbbbbb",
"Eduardo Beascochea", "Eduardo Beascochea",
"Keyhan Behzadi",
"Eduan Bekker", "Eduan Bekker",
"бравлер Андрей Belarus", "бравлер Андрей Belarus",
"ben", "ben",
@ -302,6 +316,7 @@
"Anton Bang Berner", "Anton Bang Berner",
"Felix Bernhard", "Felix Bernhard",
"Beroudzin", "Beroudzin",
"Abhishek Bhardwaj",
"Davide Bigotto", "Davide Bigotto",
"bilibili@Medic药", "bilibili@Medic药",
"Bima", "Bima",
@ -348,6 +363,8 @@
"bsam", "bsam",
"Bsamhero", "Bsamhero",
"BSODPK", "BSODPK",
"Bub",
"Bubas",
"Marvin Bublitz", "Marvin Bublitz",
"BudaCcm", "BudaCcm",
"Vincent R. Buenaventura", "Vincent R. Buenaventura",
@ -382,6 +399,7 @@
"Arthur Cazes", "Arthur Cazes",
"CerdoGordo", "CerdoGordo",
"Ceren", "Ceren",
"cflagos",
"chang", "chang",
"Charlie", "Charlie",
"kalpesh chauhan", "kalpesh chauhan",
@ -445,6 +463,7 @@
"DarshaN", "DarshaN",
"Shibin das", "Shibin das",
"Dasto", "Dasto",
"Davi",
"David", "David",
"Davide", "Davide",
"DavidPlayzLol", "DavidPlayzLol",
@ -454,16 +473,20 @@
"Die or Dead", "Die or Dead",
"Привет от детей DeadLine", "Привет от детей DeadLine",
"deepjith", "deepjith",
"Defiant",
"dekarl", "dekarl",
"deliciouspudding43", "deliciouspudding43",
"deliplayer",
"delshe", "delshe",
"Denis", "Denis",
"Dennis", "Dennis",
"Dennys", "Dennys",
"Alex Derbenew", "Alex Derbenew",
"Ingegner Devecchi",
"Dr : developer", "Dr : developer",
"df", "df",
"Santanu Dhar", "Santanu Dhar",
"DHRUVIL",
"Guilherme Dias", "Guilherme Dias",
"Diase7en", "Diase7en",
"ferbie Dicen", "ferbie Dicen",
@ -485,11 +508,14 @@
"Dmitriy", "Dmitriy",
"Savchenko Dmitriy", "Savchenko Dmitriy",
"Count Su Doku", "Count Su Doku",
"Giuseppe Valerio Dominici",
"DominikSikora!", "DominikSikora!",
"Kai Dominique", "Kai Dominique",
"Gerardo Doro", "Gerardo Doro",
"DottorMorte", "DottorMorte",
"Doubleknig",
"Dragomir", "Dragomir",
"Dreaming",
"Drellsan", "Drellsan",
"DrGhast", "DrGhast",
"Dron009", "Dron009",
@ -503,6 +529,7 @@
"Emir İslam Dündar", "Emir İslam Dündar",
"E.R.A.L", "E.R.A.L",
"Ebutahapro07tr", "Ebutahapro07tr",
"Eder",
"Edson", "Edson",
"Glen Edwards", "Glen Edwards",
"Amr Wassiem Eessa", "Amr Wassiem Eessa",
@ -533,11 +560,12 @@
"emm", "emm",
"EnderDust123", "EnderDust123",
"EnderKay", "EnderKay",
"Endless_jk",
"EnglandFirst", "EnglandFirst",
"Enrico", "Enrico",
"enzo", "enzo",
"Era", "Era",
"Era0S (Spazton)", "Era0S",
"Erick", "Erick",
"Erkam", "Erkam",
"Jonas Ernst", "Jonas Ernst",
@ -573,6 +601,7 @@
"Shaikh Fazal", "Shaikh Fazal",
"Fea", "Fea",
"FearLessCuBer", "FearLessCuBer",
"Feder-28",
"Feder28", "Feder28",
"Federico", "Federico",
"Fedrigo", "Fedrigo",
@ -591,6 +620,7 @@
"Aldereus Fire", "Aldereus Fire",
"Robert Fischer", "Robert Fischer",
"Kai Fleischmann", "Kai Fleischmann",
"FLOKI",
"Iancu Florin", "Iancu Florin",
"FluffyPal", "FluffyPal",
"FLᎧRᏋᏁTIᏁᎧ", "FLᎧRᏋᏁTIᏁᎧ",
@ -602,6 +632,7 @@
"Andrey Fridholm", "Andrey Fridholm",
"FriskTheHuman303", "FriskTheHuman303",
"Froshlee14", "Froshlee14",
"FrostyXD",
"FuckIndoDick", "FuckIndoDick",
"Lukas Funk", "Lukas Funk",
"Gustavo FunnyGuard28", "Gustavo FunnyGuard28",
@ -615,20 +646,24 @@
"João Gabriel", "João Gabriel",
"Gabriele", "Gabriele",
"Nihar Gajare", "Nihar Gajare",
"GalaxyM4",
"GalaxyNinja2003", "GalaxyNinja2003",
"AP - Pro Gamer", "AP - Pro Gamer",
"Proff Gamer", "Proff Gamer",
"Eduardo Gamer05", "Eduardo Gamer05",
"Gamer2809",
"Taufiq Gamera", "Taufiq Gamera",
"Altangerel Ganbaatar", "Altangerel Ganbaatar",
"Quentin Gangler", "Quentin Gangler",
"RUSLAN ABDUL GANI", "RUSLAN ABDUL GANI",
"Garou",
"Gaspard", "Gaspard",
"krish gator", "krish gator",
"gene.mTs", "gene.mTs",
"GeoMatHeo", "GeoMatHeo",
"Gerry", "Gerry",
"GG (9.2)", "GG (9.2)",
"ggMustaGD0",
"Mohammad gh", "Mohammad gh",
"Onkar Ghagarum", "Onkar Ghagarum",
"GHAIS", "GHAIS",
@ -642,6 +677,7 @@
"Aidan Gil", "Aidan Gil",
"Noe Marley Ginting", "Noe Marley Ginting",
"Giovalli99", "Giovalli99",
"Devecchi Giovanni",
"DEVEGGHI GIOVANNI", "DEVEGGHI GIOVANNI",
"Giovanny", "Giovanny",
"Dc superhero girl", "Dc superhero girl",
@ -671,6 +707,8 @@
"Tódor Gábor", "Tódor Gábor",
"Tymoteusz Górski", "Tymoteusz Górski",
"Thomas Günther", "Thomas Günther",
"Hamza Emin GÜRLER",
"Paşa Güven",
"H.J.N", "H.J.N",
"Haasaani", "Haasaani",
"Hack", "Hack",
@ -725,6 +763,7 @@
"Minh Hoang", "Minh Hoang",
"Robin Hofmann", "Robin Hofmann",
"hola", "hola",
"holasoycuyo",
"Sebasian Varela Holguin", "Sebasian Varela Holguin",
"Holystone", "Holystone",
"Jeremy Horbul", "Jeremy Horbul",
@ -736,6 +775,8 @@
"Hussain", "Hussain",
"Umair Hussain", "Umair Hussain",
"Hussam", "Hussam",
"Huy",
"HYr",
"Adrian Höfer", "Adrian Höfer",
"Davide Iaccarino", "Davide Iaccarino",
"iBearzGaming", "iBearzGaming",
@ -749,6 +790,7 @@
"IL_SERGIO", "IL_SERGIO",
"!YamGila (Syed Ilham)", "!YamGila (Syed Ilham)",
"Iliya_bomB", "Iliya_bomB",
"Iliyafeili",
"illonis", "illonis",
"Syed Ilham Ilman", "Syed Ilham Ilman",
"Ily77788", "Ily77788",
@ -829,8 +871,10 @@
"Rudransh Joshi (FireHead)", "Rudransh Joshi (FireHead)",
"joshuapiper", "joshuapiper",
"Jossiney", "Jossiney",
"Juangame65",
"juanramirez", "juanramirez",
"Jules", "Jules",
"Junior4pro",
"juse", "juse",
"Justine", "Justine",
"JYLE", "JYLE",
@ -883,6 +927,7 @@
"$RICO$ KhevenMito", "$RICO$ KhevenMito",
"Khwezi", "Khwezi",
"kibro", "kibro",
"Kicken07",
"Joop Kiefte", "Joop Kiefte",
"killer", "killer",
"killer313", "killer313",
@ -899,6 +944,7 @@
"komasio", "komasio",
"komasio71", "komasio71",
"KomodoRec", "KomodoRec",
"koolych (Николай)",
"Niko Koren", "Niko Koren",
"Nikolay Korolyov", "Nikolay Korolyov",
"Kostas", "Kostas",
@ -914,6 +960,7 @@
"Krunal", "Krunal",
"kueue", "kueue",
"Alok Kumar", "Alok Kumar",
"Parth Kumar",
"sarath kumar", "sarath kumar",
"Aapeli Kumpulainen", "Aapeli Kumpulainen",
"Aldhiza Kurniawan", "Aldhiza Kurniawan",
@ -925,7 +972,9 @@
"Kyle", "Kyle",
"Jan Kölling", "Jan Kölling",
"L_JK", "L_JK",
"Laaziz",
"Labrador", "Labrador",
"labrosggv",
"John Patrick Lachica", "John Patrick Lachica",
"laikrai", "laikrai",
"m a lakum", "m a lakum",
@ -939,8 +988,10 @@
"Lazydog", "Lazydog",
"Elia Lazzari", "Elia Lazzari",
"이지민 (Ji-Min Lee)", "이지민 (Ji-Min Lee)",
"legended",
"Mick Lemmens", "Mick Lemmens",
"Leo", "Leo",
"Mr. LeoLeo",
"Lester", "Lester",
"Szajkajkó Levente", "Szajkajkó Levente",
"Szajkajó Levente", "Szajkajó Levente",
@ -951,6 +1002,7 @@
"Juan Liao", "Juan Liao",
"LickyBeeYT", "LickyBeeYT",
"Nicola Ligas", "Nicola Ligas",
"Alef costa lima",
"Limak09", "Limak09",
"LimonAga", "LimonAga",
"lin", "lin",
@ -958,11 +1010,14 @@
"Kyle Lin", "Kyle Lin",
"Linus", "Linus",
"Linux44313", "Linux44313",
"LioLioFlo",
"Lionel",
"Lippu", "Lippu",
"Lisavidxxxxxxx5", "Lisavidxxxxxxx5",
"LiteBalt", "LiteBalt",
"LittleNyanCat", "LittleNyanCat",
"Juunhao Liu", "Juunhao Liu",
"Lixar",
"Lizz", "Lizz",
"Lizzetc", "Lizzetc",
"Lkham", "Lkham",
@ -992,6 +1047,7 @@
"Luis(GalaxtM4)", "Luis(GalaxtM4)",
"luislinares", "luislinares",
"luispro25", "luispro25",
"Luiz",
"Luka", "Luka",
"Luke", "Luke",
"Luke994", "Luke994",
@ -999,20 +1055,24 @@
"Hermanni Luosujärvi", "Hermanni Luosujärvi",
"Lurã", "Lurã",
"Luthy", "Luthy",
"Luytaris",
"Geogre Lyu", "Geogre Lyu",
"Be aware that m", "Be aware that m",
"Matias M.",
"M.R.T", "M.R.T",
"M5TF4", "M5TF4",
"Mac 143338", "Mac 143338",
"MaceracıMS", "MaceracıMS",
"Samuel Maciel", "Samuel Maciel",
"Djawad madi", "Djawad madi",
"MadNightr",
"Mads Beier Madsen", "Mads Beier Madsen",
"Mahan", "Mahan",
"Ondřej Mahdalík", "Ondřej Mahdalík",
"mahdi", "mahdi",
"mahdimahabadi", "mahdimahabadi",
"Mahmoud", "Mahmoud",
"Mahziyar",
"maicol", "maicol",
"Majestozão", "Majestozão",
"Makar", "Makar",
@ -1020,6 +1080,7 @@
"Malaysian", "Malaysian",
"EMILIO MALQUIN", "EMILIO MALQUIN",
"MAMAD", "MAMAD",
"Wagdy mamdouh",
"Mani", "Mani",
"Manimutharu", "Manimutharu",
"Ahmed Mansy", "Ahmed Mansy",
@ -1032,6 +1093,7 @@
"Marcolino", "Marcolino",
"Filip Marek", "Filip Marek",
"Marcin Marek", "Marcin Marek",
"Margarrom",
"Mariel", "Mariel",
"Marin", "Marin",
"mariuxoGaming", "mariuxoGaming",
@ -1072,6 +1134,7 @@
"Kevin Mejía", "Kevin Mejía",
"Mell", "Mell",
"MereCrack", "MereCrack",
"Merengue",
"Mert", "Mert",
"Meryu07", "Meryu07",
"Meysam", "Meysam",
@ -1090,6 +1153,7 @@
"Mina", "Mina",
"minh123456789thcsvk", "minh123456789thcsvk",
"MinhAn19203", "MinhAn19203",
"Michael J. Soto Miranda",
"Azfar Ahmed Mirza", "Azfar Ahmed Mirza",
"misael", "misael",
"Deepak Mishra", "Deepak Mishra",
@ -1109,6 +1173,7 @@
"Mohammad11dembele", "Mohammad11dembele",
"MOHAMMADERFAN", "MOHAMMADERFAN",
"Mohammadhosain", "Mohammadhosain",
"Mohammadpl",
"Mohammed", "Mohammed",
"MOHAMMEDTALAL1ST", "MOHAMMEDTALAL1ST",
"1n Mohhaamad", "1n Mohhaamad",
@ -1143,6 +1208,7 @@
"Mwss", "Mwss",
"MYSENIOR", "MYSENIOR",
"mythbrk00@gmail.com", "mythbrk00@gmail.com",
"محمدحسین MZZ",
"Sajti Márk", "Sajti Márk",
"Samuel Mörling", "Samuel Mörling",
"Luca Müller", "Luca Müller",
@ -1198,11 +1264,15 @@
"NofaseCZ", "NofaseCZ",
"Max Noisa", "Max Noisa",
"Noisb", "Noisb",
"NoNameC3698241",
"None", "None",
"NOOBPEDAR",
"Noobslaya101", "Noobslaya101",
"noorjandle1", "noorjandle1",
"Petter Nordlander", "Petter Nordlander",
"Nose",
"NotBrojasAgain", "NotBrojasAgain",
"NotDiegoGD",
"Ntinakos555", "Ntinakos555",
"NullWizard", "NullWizard",
"Dhimas Wildan Nz", "Dhimas Wildan Nz",
@ -1217,6 +1287,7 @@
"omgxd5", "omgxd5",
"On3GaMs", "On3GaMs",
"No one", "No one",
"oneman",
"Adam Oros", "Adam Oros",
"Andrés Ortega", "Andrés Ortega",
"Zangar Orynbetov", "Zangar Orynbetov",
@ -1251,6 +1322,7 @@
"PC432736", "PC432736",
"PC607666", "PC607666",
"PC912334", "PC912334",
"PC979802",
"pebikristia", "pebikristia",
"Pedro", "Pedro",
"Jiren/Juan Pedro", "Jiren/Juan Pedro",
@ -1282,6 +1354,7 @@
"Elian Pj", "Elian Pj",
"Broi PL", "Broi PL",
"Ziomek PL", "Ziomek PL",
"George Play's",
"Anestis Plithos", "Anestis Plithos",
"Pluisbaard", "Pluisbaard",
"Jaideep Kumar PM", "Jaideep Kumar PM",
@ -1334,6 +1407,7 @@
"Rahul Raman", "Rahul Raman",
"Vicente Ramirez", "Vicente Ramirez",
"ramon", "ramon",
"Ramzy",
"Randlator", "Randlator",
"Random_artz__", "Random_artz__",
"Rares", "Rares",
@ -1375,6 +1449,7 @@
"Ridzuan", "Ridzuan",
"Samuel Rieger", "Samuel Rieger",
"RieJoemar", "RieJoemar",
"Rings3467",
"Jeroen Rinzema", "Jeroen Rinzema",
"RioAdir", "RioAdir",
"Max Rios", "Max Rios",
@ -1422,6 +1497,7 @@
"Matteo Salvini", "Matteo Salvini",
"Salvo04", "Salvo04",
"Samen", "Samen",
"Samsep10l",
"San", "San",
"SaNt0RiNiKits577YT", "SaNt0RiNiKits577YT",
"Guilherme Santana", "Guilherme Santana",
@ -1440,6 +1516,8 @@
"Hendrik Schur", "Hendrik Schur",
"SEBASTIAN2059", "SEBASTIAN2059",
"Semen", "Semen",
"semethers",
"JIN SEOWOO",
"Mihai Serbanica", "Mihai Serbanica",
"Daniel Balam Cabrera Serrano", "Daniel Balam Cabrera Serrano",
"Yefta Aditya Setiawan", "Yefta Aditya Setiawan",
@ -1466,6 +1544,7 @@
"Simotoring", "Simotoring",
"Pawan Singh sisodiya", "Pawan Singh sisodiya",
"Skick", "Skick",
"SkillPro",
"sks", "sks",
"Max Sky", "Max Sky",
"SlayTaniK", "SlayTaniK",
@ -1491,6 +1570,7 @@
"speddy16", "speddy16",
"Spielfreake (Garke)", "Spielfreake (Garke)",
"Spielfream", "Spielfream",
"Spooc",
"Spy", "Spy",
"SqdDoom", "SqdDoom",
"sss", "sss",
@ -1500,6 +1580,7 @@
"Bartosz Staniszewski", "Bartosz Staniszewski",
"Stare", "Stare",
"StarFighter", "StarFighter",
"Artem Stasyuk",
"Rz Stazzy", "Rz Stazzy",
"Stealives", "Stealives",
"Steffo", "Steffo",
@ -1512,6 +1593,7 @@
"STPayoube", "STPayoube",
"Stratex", "Stratex",
"SYED EPIC STUDIOS", "SYED EPIC STUDIOS",
"SUBC1PYZH",
"sun.4810", "sun.4810",
"Samet Sunal", "Samet Sunal",
"sundar", "sundar",
@ -1588,6 +1670,7 @@
"Tory", "Tory",
"TozeLeal", "TozeLeal",
"Trung Hieu Le Tran", "Trung Hieu Le Tran",
"Small Translation",
"Translator", "Translator",
"TrialTemp", "TrialTemp",
"Trivago", "Trivago",
@ -1599,6 +1682,7 @@
"Jan Tymll", "Jan Tymll",
"Zacker Tz", "Zacker Tz",
"Zoltán Tóth", "Zoltán Tóth",
"Buğra Türksal",
"uDinnoo", "uDinnoo",
"Cristian Ugalde", "Cristian Ugalde",
"Atchy-Dalama--Ancelly Ulrich", "Atchy-Dalama--Ancelly Ulrich",
@ -1663,9 +1747,11 @@
"Tommy Wong", "Tommy Wong",
"WonkaWoe", "WonkaWoe",
"Moury ji world", "Moury ji world",
"worldbiomusic",
"wsltshh", "wsltshh",
"Wurstkatze", "Wurstkatze",
"WurstSaft", "WurstSaft",
"WynB",
"Xavier", "Xavier",
"Francisco Xavier", "Francisco Xavier",
"xbarix123897", "xbarix123897",
@ -1682,6 +1768,7 @@
"Halil Yarkin", "Halil Yarkin",
"Yaroslav (Spaz1)", "Yaroslav (Spaz1)",
"amr yasser", "amr yasser",
"Yatoku",
"YellowTractor", "YellowTractor",
"Yasin YILMAZ", "Yasin YILMAZ",
"Ymgfr", "Ymgfr",
@ -1717,10 +1804,12 @@
"ZaraMax", "ZaraMax",
"zecharaiah", "zecharaiah",
"Daniele Zennaro", "Daniele Zennaro",
"zFliws",
"zfuw668", "zfuw668",
"Alex Zhao", "Alex Zhao",
"Doge Zhao", "Doge Zhao",
"Riven Zhao", "Riven Zhao",
"Liubomyr Zheltova",
"jim ZHOU", "jim ZHOU",
"Mohammad ziar", "Mohammad ziar",
"ZioFesteeeer", "ZioFesteeeer",
@ -1737,6 +1826,7 @@
"Cristian Țicu", "Cristian Țicu",
"Μπαρλάς Παύλος-Ιάσονας", "Μπαρλάς Παύλος-Ιάσονας",
"Ανέστης Πλήθος", "Ανέστης Πλήθος",
"Яркин Абдулхалил",
"Роман Абрамо", "Роман Абрамо",
"Роман Абрамов", "Роман Абрамов",
"Андрей (Krays)", "Андрей (Krays)",
@ -1751,6 +1841,7 @@
"Дмитрий 228", "Дмитрий 228",
"Евгений(Eugene)", "Евгений(Eugene)",
"Артём Зобков (KoLenka)", "Артём Зобков (KoLenka)",
"Иван",
"Юстин Иглин", "Юстин Иглин",
"Игор", "Игор",
"Кирилл", "Кирилл",
@ -1779,6 +1870,7 @@
"Кирилл Рябцев", "Кирилл Рябцев",
"Ерасыл Фазылов (Paraxilius)", "Ерасыл Фазылов (Paraxilius)",
"ZEPT\"Александр Фартунов\"", "ZEPT\"Александр Фартунов\"",
"!SW сосут мой член!",
"Эмир", "Эмир",
"Өмүрзаков Эрсултан", "Өмүрзаков Эрсултан",
"Ярослав \"Noiseaholic\"", "Ярослав \"Noiseaholic\"",
@ -1807,6 +1899,7 @@
"امید رضازاده", "امید رضازاده",
"فاطمه عباس زاده ۸۴", "فاطمه عباس زاده ۸۴",
"فاطمه عباس زاده۸۴", "فاطمه عباس زاده۸۴",
"زينب",
"ستسپ", "ستسپ",
"سلطان سروش", "سلطان سروش",
"محمد وائل سلطان", "محمد وائل سلطان",
@ -1856,6 +1949,7 @@
"南宫銷子()", "南宫銷子()",
"哔哩哔哩@Medic药", "哔哩哔哩@Medic药",
"夏神(后期汉化修正)", "夏神(后期汉化修正)",
"大笨蛋susu",
"小黑猫", "小黑猫",
"张帅", "张帅",
"徐安博", "徐安博",
@ -1886,6 +1980,7 @@
"넌", "넌",
"먹꾸리", "먹꾸리",
"박건희", "박건희",
"배추",
"김대중 부관참시", "김대중 부관참시",
"붐추", "붐추",
"사람사는 세상", "사람사는 세상",
@ -1896,6 +1991,7 @@
"BombsquadKorea 네이버 카페", "BombsquadKorea 네이버 카페",
"Zona-BombSquad", "Zona-BombSquad",
"CrazySquad", "CrazySquad",
"Stazzy" "Stazzy",
"Slida"
] ]
} }

View file

@ -1,6 +1,6 @@
{ {
"accountSettingsWindow": { "accountSettingsWindow": {
"accountNameRules": "لا يمكن لاسماء الحِسابَات أن تحتوي على رموز تعبيرية أو حروف غير ألفبائية", "accountNameRules": ".لا يمكن لاسماء الحِسابَات أن تحتوي على رموز تعبيرية أو حروف غير ألفبائية",
"accountProfileText": "معلومات اللاعبين", "accountProfileText": "معلومات اللاعبين",
"accountsText": "حسابات", "accountsText": "حسابات",
"achievementProgressText": "${TOTAL} من أصل ${COUNT} إنجازاتك: أنجزت", "achievementProgressText": "${TOTAL} من أصل ${COUNT} إنجازاتك: أنجزت",
@ -28,9 +28,10 @@
"signInWithDeviceInfoText": "الحساب التلقائي متوفر فقط على هذا الجهاز", "signInWithDeviceInfoText": "الحساب التلقائي متوفر فقط على هذا الجهاز",
"signInWithDeviceText": "سجل دخولك بحساب الجهاز", "signInWithDeviceText": "سجل دخولك بحساب الجهاز",
"signInWithGameCircleText": "Game Circle سجل دخولك بواسطة", "signInWithGameCircleText": "Game Circle سجل دخولك بواسطة",
"signInWithGooglePlayText": "Google Play سجل دخولك عبر", "signInWithGooglePlayText": "Google Play سجل دخولك عبر ",
"signInWithTestAccountInfoText": "(حساب موجود على هاتفك; استخدم حساب الهاتف للمتابعة)", "signInWithTestAccountInfoText": "(حساب موجود على هاتفك; استخدم حساب الهاتف للمتابعة)",
"signInWithTestAccountText": "تسجيل الدخول بحساب تجريبي", "signInWithTestAccountText": "تسجيل الدخول بحساب تجريبي",
"signInWithText": "تسجيل دخول مع ${SERVICE}",
"signInWithV2InfoText": "حساب يعمل على جميع المنصات", "signInWithV2InfoText": "حساب يعمل على جميع المنصات",
"signInWithV2Text": "قم بتسجيل الدخول باستخدام حساب BombSquad", "signInWithV2Text": "قم بتسجيل الدخول باستخدام حساب BombSquad",
"signOutText": "تسجيل الخروج", "signOutText": "تسجيل الخروج",
@ -369,6 +370,7 @@
"chatMutedText": "تم اسكات الدردشة", "chatMutedText": "تم اسكات الدردشة",
"chatUnMuteText": "تحرير الدردشة", "chatUnMuteText": "تحرير الدردشة",
"choosingPlayerText": "<يختار لاعب>", "choosingPlayerText": "<يختار لاعب>",
"codesExplainText": "يتم توفير الرموز من قبل المطور\n.لتحليل مشاكل الحساب وتصحيحها",
"completeThisLevelToProceedText": "يجب أن تكمل هذه المرحلة ليتم الاجراء", "completeThisLevelToProceedText": "يجب أن تكمل هذه المرحلة ليتم الاجراء",
"completionBonusText": "علاوة الاكمال", "completionBonusText": "علاوة الاكمال",
"configControllersWindow": { "configControllersWindow": {
@ -449,6 +451,7 @@
"swipeText": "مسحة", "swipeText": "مسحة",
"titleText": "تهيئة شاشة اللمس" "titleText": "تهيئة شاشة اللمس"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} يُمكن تعديله في تطبيق إعدادات النظام.",
"configureItNowText": "هل تريد تهيئته الآن؟", "configureItNowText": "هل تريد تهيئته الآن؟",
"configureText": "تهيئة", "configureText": "تهيئة",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -810,7 +813,7 @@
"youHaveShortText": "لديك ${COUNT}", "youHaveShortText": "لديك ${COUNT}",
"youHaveText": "لديك ${COUNT} تذاكر" "youHaveText": "لديك ${COUNT} تذاكر"
}, },
"googleMultiplayerDiscontinuedText": "عذرًا ، خدمة جوجل متعددة اللاعبين لم تعد متاحة.\n أنا أعمل على بديل بأسرع وقت ممكن.\n حتى ذلك الحين ، يرجى تجربة طريقة اتصال أخرى.\n -إريك", "googleMultiplayerDiscontinuedText": "\nعذرًا ، خدمة جوجل متعددة اللاعبين لم تعد متاحة.\n أنا أعمل على بديل بأسرع وقت ممكن.\n حتى ذلك الحين ، يرجى تجربة طريقة اتصال أخرى.\n -إريك",
"googlePlayPurchasesNotAvailableText": "عمليات شراء جوجل بلاي غير متوفرة.\nقد تحتاج لتحديث تطبيق المتجر.", "googlePlayPurchasesNotAvailableText": "عمليات شراء جوجل بلاي غير متوفرة.\nقد تحتاج لتحديث تطبيق المتجر.",
"googlePlayServicesNotAvailableText": "غوغل بلاي العاب غير متوفر.\nبعض المزايا لن تكون متوفرة.", "googlePlayServicesNotAvailableText": "غوغل بلاي العاب غير متوفر.\nبعض المزايا لن تكون متوفرة.",
"googlePlayText": "جوجل بلاي", "googlePlayText": "جوجل بلاي",
@ -818,10 +821,12 @@
"alwaysText": "دائما", "alwaysText": "دائما",
"fullScreenCmdText": "ملء الشاشة (Cmd-F)", "fullScreenCmdText": "ملء الشاشة (Cmd-F)",
"fullScreenCtrlText": "الشاشه كامله (Ctrl-F)", "fullScreenCtrlText": "الشاشه كامله (Ctrl-F)",
"fullScreenText": "تكبير الشاشة",
"gammaText": "غاما", "gammaText": "غاما",
"highText": "عالي الدقة", "highText": "عالي الدقة",
"higherText": "العالي", "higherText": "العالي",
"lowText": "منخفض", "lowText": "منخفض",
"maxFPSText": "أعلى معدل إطارات",
"mediumText": "متوسط", "mediumText": "متوسط",
"neverText": "أبدا", "neverText": "أبدا",
"resolutionText": "القرار", "resolutionText": "القرار",
@ -1060,6 +1065,7 @@
"noExternalStorageErrorText": "لم يتم العثور على وحدة تخزين خارجية على هذا الجهاز", "noExternalStorageErrorText": "لم يتم العثور على وحدة تخزين خارجية على هذا الجهاز",
"noGameCircleText": "خطأ: لم يتم تسجيل الدخول الئ gamecircle", "noGameCircleText": "خطأ: لم يتم تسجيل الدخول الئ gamecircle",
"noScoresYetText": "لا نقاط حتى الآن.", "noScoresYetText": "لا نقاط حتى الآن.",
"noServersFoundText": "لا توجد اي سيرفرات.",
"noThanksText": "لا شكرا", "noThanksText": "لا شكرا",
"noTournamentsInTestBuildText": "تحذير: سيتم تجاهل نقاط البطولات في النسخة التجريبية", "noTournamentsInTestBuildText": "تحذير: سيتم تجاهل نقاط البطولات في النسخة التجريبية",
"noValidMapsErrorText": "لا خرائط صالحة وجدت لهذا النوع اللعبة.", "noValidMapsErrorText": "لا خرائط صالحة وجدت لهذا النوع اللعبة.",
@ -1269,6 +1275,7 @@
"netTestingText": "اختبار الشبكة", "netTestingText": "اختبار الشبكة",
"resetText": "إعادة تعيين", "resetText": "إعادة تعيين",
"showBombTrajectoriesText": "عرض مسارات القنبلة", "showBombTrajectoriesText": "عرض مسارات القنبلة",
"showDevConsoleButtonText": "إظهار زر وحدة تحكم المطورين",
"showInGamePingText": "عرض التأخير الداخلي للعبة", "showInGamePingText": "عرض التأخير الداخلي للعبة",
"showPlayerNamesText": "إظهار اسماء اللاعبين", "showPlayerNamesText": "إظهار اسماء اللاعبين",
"showUserModsText": "عرض مجلد التعديل", "showUserModsText": "عرض مجلد التعديل",
@ -1360,6 +1367,8 @@
"storeText": "متجر", "storeText": "متجر",
"submitText": "ارسال", "submitText": "ارسال",
"submittingPromoCodeText": "تقديم الكود ...", "submittingPromoCodeText": "تقديم الكود ...",
"successText": "نجحت!",
"supportEmailText": "ايذا لديك اي مشكلة تقنية مع\nالبرنامح, يرجى استخدام البريد إلكتروني للدعم ${EMAIL}.",
"teamNamesColorText": "اسماء/الوان الفرق...", "teamNamesColorText": "اسماء/الوان الفرق...",
"telnetAccessGrantedText": "تم تمكين الوصول تلنيت.", "telnetAccessGrantedText": "تم تمكين الوصول تلنيت.",
"telnetAccessText": "تم الكشف عن الوصول تلنيت. السماح؟", "telnetAccessText": "تم الكشف عن الوصول تلنيت. السماح؟",
@ -1813,6 +1822,7 @@
"unlockThisInTheStoreText": "هذا يجب ان يفتح في المتجر", "unlockThisInTheStoreText": "هذا يجب ان يفتح في المتجر",
"unlockThisProfilesText": "لإنشاء أكثر من ${NUM} من الملفات الشخصية، تحتاج إلى:", "unlockThisProfilesText": "لإنشاء أكثر من ${NUM} من الملفات الشخصية، تحتاج إلى:",
"unlockThisText": ":لفتح هذا, تحتاج إلى", "unlockThisText": ":لفتح هذا, تحتاج إلى",
"unsupportedControllerText": "عذرًا، وحدة التحكم \"${NAME}\" غير مدعومة.",
"unsupportedHardwareText": "عفوا, هذه المعدات غير مدعومة في هذه النسخة من اللعبة", "unsupportedHardwareText": "عفوا, هذه المعدات غير مدعومة في هذه النسخة من اللعبة",
"upFirstText": ":يصل اولا", "upFirstText": ":يصل اولا",
"upNextText": ":${COUNT}التالي في اللعبة", "upNextText": ":${COUNT}التالي في اللعبة",
@ -1824,6 +1834,7 @@
"usingItunesText": "...استخدام تطبيق الموسيقى للموسيقى التصويرية", "usingItunesText": "...استخدام تطبيق الموسيقى للموسيقى التصويرية",
"v2AccountLinkingInfoText": "اذا اردت ربط حسابات V2، قم بالتوجه الى 'ادارة الحساب'.", "v2AccountLinkingInfoText": "اذا اردت ربط حسابات V2، قم بالتوجه الى 'ادارة الحساب'.",
"validatingTestBuildText": "التحقق من صحة البناء", "validatingTestBuildText": "التحقق من صحة البناء",
"viaText": "عبر",
"victoryText": "!النصر", "victoryText": "!النصر",
"voteDelayText": "ثانية ${NUMBER} لا يمكنك التصويت ثانية حتى", "voteDelayText": "ثانية ${NUMBER} لا يمكنك التصويت ثانية حتى",
"voteInProgressText": "التصويت بالفعل في التقدم", "voteInProgressText": "التصويت بالفعل في التقدم",

View file

@ -30,6 +30,7 @@
"signInWithGooglePlayText": "Увайсці з дапамогаю Google Play", "signInWithGooglePlayText": "Увайсці з дапамогаю Google Play",
"signInWithTestAccountInfoText": "(акаўнт, які ўжо існуе; спачатку увайдзіце з прылады)", "signInWithTestAccountInfoText": "(акаўнт, які ўжо існуе; спачатку увайдзіце з прылады)",
"signInWithTestAccountText": "Увайсці з тэст-акаўнта", "signInWithTestAccountText": "Увайсці з тэст-акаўнта",
"signInWithText": "Увайдзіце з дапамогай ${SERVICE}",
"signInWithV2InfoText": "(уліковы запіс, які працуе на ўсіх платформах)", "signInWithV2InfoText": "(уліковы запіс, які працуе на ўсіх платформах)",
"signInWithV2Text": "Увайдзіце з уліковым запісам BombSquad", "signInWithV2Text": "Увайдзіце з уліковым запісам BombSquad",
"signOutText": "Выйсці", "signOutText": "Выйсці",
@ -369,6 +370,7 @@
"chatMutedText": "Чат адключон", "chatMutedText": "Чат адключон",
"chatUnMuteText": "Уключыць гук у чаце", "chatUnMuteText": "Уключыць гук у чаце",
"choosingPlayerText": "<выбар гульца>", "choosingPlayerText": "<выбар гульца>",
"codesExplainText": "Коды прадастаўляюцца распрацоўшчыкам\nдыягностыка і выпраўленне праблем з уліковым запісам.",
"completeThisLevelToProceedText": "Вы павінны прайсці гэты\nўзровень, каб працягнуць!", "completeThisLevelToProceedText": "Вы павінны прайсці гэты\nўзровень, каб працягнуць!",
"completionBonusText": "Бонус за праходжанне", "completionBonusText": "Бонус за праходжанне",
"configControllersWindow": { "configControllersWindow": {
@ -449,6 +451,7 @@
"swipeText": "змахванне", "swipeText": "змахванне",
"titleText": "Налады Экрана" "titleText": "Налады Экрана"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} можна наладзіць у праграме \"Сістэмныя налады\".",
"configureItNowText": "Наладзіць гэта зараз?", "configureItNowText": "Наладзіць гэта зараз?",
"configureText": "Налады", "configureText": "Налады",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -562,6 +565,8 @@
"disableXInputDescriptionText": "Дазваляе больш за 4 кантролераў, але можа таксама не працаваць.", "disableXInputDescriptionText": "Дазваляе больш за 4 кантролераў, але можа таксама не працаваць.",
"disableXInputText": "Адключыць XInput", "disableXInputText": "Адключыць XInput",
"disabledText": "Выключана", "disabledText": "Выключана",
"discordFriendsText": "Хочаце шукаць новых людзей для гульні?\nДалучайцеся да нашага Discord і знайдзіце новых сяброў!",
"discordJoinText": "Далучайцеся да Discord",
"doneText": "Зроблена", "doneText": "Зроблена",
"drawText": "Нічыя", "drawText": "Нічыя",
"duplicateText": "Дублікат", "duplicateText": "Дублікат",
@ -823,10 +828,12 @@
"alwaysText": "Заўсёды", "alwaysText": "Заўсёды",
"fullScreenCmdText": "Поўнаэкранны (Сmd-F)", "fullScreenCmdText": "Поўнаэкранны (Сmd-F)",
"fullScreenCtrlText": "Поўнаэкранны (Ctrl-F)", "fullScreenCtrlText": "Поўнаэкранны (Ctrl-F)",
"fullScreenText": "На ўвесь экран",
"gammaText": "Гама", "gammaText": "Гама",
"highText": "Высокае", "highText": "Высокае",
"higherText": "Найвышэйшае", "higherText": "Найвышэйшае",
"lowText": "Нізкае", "lowText": "Нізкае",
"maxFPSText": "Самы высокі FPS",
"mediumText": "Сярэдняе", "mediumText": "Сярэдняе",
"neverText": "Ніколі", "neverText": "Ніколі",
"resolutionText": "Дазвол", "resolutionText": "Дазвол",
@ -1068,6 +1075,7 @@
"noGameCircleText": "Памылка: вы не ўвайшлі ў GameCircle", "noGameCircleText": "Памылка: вы не ўвайшлі ў GameCircle",
"noProfilesErrorText": "У вас няма ніводнага профіля, таму вас будуць называць '${NAME}'.\nЗайдзіце ў \"Налады -> Профілі\", каб стварыць уласны профіль.", "noProfilesErrorText": "У вас няма ніводнага профіля, таму вас будуць называць '${NAME}'.\nЗайдзіце ў \"Налады -> Профілі\", каб стварыць уласны профіль.",
"noScoresYetText": "Вынікаў пакуль няма.", "noScoresYetText": "Вынікаў пакуль няма.",
"noServersFoundText": "Серверы не знойдзены.",
"noThanksText": "Не, дзякуй", "noThanksText": "Не, дзякуй",
"noTournamentsInTestBuildText": "УВАГА: Ацэнкі турніраў з гэтай тэставай зборкі будуць ігнаравацца.", "noTournamentsInTestBuildText": "УВАГА: Ацэнкі турніраў з гэтай тэставай зборкі будуць ігнаравацца.",
"noValidMapsErrorText": "Не знойдзена мап для гэтага тыпу гульні.", "noValidMapsErrorText": "Не знойдзена мап для гэтага тыпу гульні.",
@ -1279,6 +1287,7 @@
"netTestingText": "Тэсціраванне Сеткі", "netTestingText": "Тэсціраванне Сеткі",
"resetText": "Скінуць", "resetText": "Скінуць",
"showBombTrajectoriesText": "Паказваць Траекторыi Бомб", "showBombTrajectoriesText": "Паказваць Траекторыi Бомб",
"showDevConsoleButtonText": "Паказаць Кнопку Кансолі Распрацоўніка",
"showInGamePingText": "Паказываць Пынг Гульні", "showInGamePingText": "Паказываць Пынг Гульні",
"showPlayerNamesText": "Паказваць Імёны Гульцоў", "showPlayerNamesText": "Паказваць Імёны Гульцоў",
"showUserModsText": "Паказаць Тэчку З Модамі", "showUserModsText": "Паказаць Тэчку З Модамі",
@ -1373,6 +1382,8 @@
"storeText": "Крама", "storeText": "Крама",
"submitText": "Адправіць", "submitText": "Адправіць",
"submittingPromoCodeText": "Адпраўка кода...", "submittingPromoCodeText": "Адпраўка кода...",
"successText": "Паспяхова!",
"supportEmailText": "Калі ў вас узніклі праблемы з\nпрыкладаннем, калі ласка, напішыце ${EMAIL}.",
"teamNamesColorText": "Назвы / колеры каманд ...", "teamNamesColorText": "Назвы / колеры каманд ...",
"telnetAccessGrantedText": "Доступ Telnet уключаны.", "telnetAccessGrantedText": "Доступ Telnet уключаны.",
"telnetAccessText": "Знойдзены доступ Telnet, дазволіць?", "telnetAccessText": "Знойдзены доступ Telnet, дазволіць?",
@ -1438,12 +1449,12 @@
"${GAME} Training": "Падрыхтоўка да гульні ${GAME}", "${GAME} Training": "Падрыхтоўка да гульні ${GAME}",
"Infinite ${GAME}": "Бясконцая ${GAME}", "Infinite ${GAME}": "Бясконцая ${GAME}",
"Infinite Onslaught": "Бясконцая Атака", "Infinite Onslaught": "Бясконцая Атака",
"Infinite Runaround": "Бясконцы Манеўр", "Infinite Runaround": "Бясконцая бегатня",
"Onslaught Training": "Атака: Трэніроўка", "Onslaught Training": "Атака: Трэніроўка",
"Pro ${GAME}": "${GAME} Профі", "Pro ${GAME}": "${GAME} Профі",
"Pro Football": "Футбол Профі", "Pro Football": "Футбол Профі",
"Pro Onslaught": "Атака Профі", "Pro Onslaught": "Атака Профі",
"Pro Runaround": "Манёўр Профі", "Pro Runaround": "Бегатня Профі",
"Rookie ${GAME}": "${GAME} Лёгкі", "Rookie ${GAME}": "${GAME} Лёгкі",
"Rookie Football": "Футбол Лёгкі", "Rookie Football": "Футбол Лёгкі",
"Rookie Onslaught": "Атака Лёгкая", "Rookie Onslaught": "Атака Лёгкая",
@ -1451,7 +1462,7 @@
"Uber ${GAME}": "Убер ${GAME}", "Uber ${GAME}": "Убер ${GAME}",
"Uber Football": "Убер Футбол", "Uber Football": "Убер Футбол",
"Uber Onslaught": "Убер Атака", "Uber Onslaught": "Убер Атака",
"Uber Runaround": "Убер Манёўр" "Uber Runaround": "Убер Бегатня"
}, },
"gameDescriptions": { "gameDescriptions": {
"Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Каб перамагчы, стань абраным на некаторы час.\nКаб стаць абраным, забей мінулага абранага.", "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Каб перамагчы, стань абраным на некаторы час.\nКаб стаць абраным, забей мінулага абранага.",
@ -1829,6 +1840,7 @@
"unlockThisInTheStoreText": "Гэта павінна быць адкрыта ў магазіне.", "unlockThisInTheStoreText": "Гэта павінна быць адкрыта ў магазіне.",
"unlockThisProfilesText": "Каб стварыць больш за ${NUM} профіляў, вам трэба:", "unlockThisProfilesText": "Каб стварыць больш за ${NUM} профіляў, вам трэба:",
"unlockThisText": "Каб адкрыць гэта, вам патрэбна:", "unlockThisText": "Каб адкрыць гэта, вам патрэбна:",
"unsupportedControllerText": "На жаль, кантролер \"${NAME}\" не падтрымліваецца.",
"unsupportedHardwareText": "Прабачце, ваша прылада не падтрымлівае гэтую версію гульні.", "unsupportedHardwareText": "Прабачце, ваша прылада не падтрымлівае гэтую версію гульні.",
"upFirstText": "Спачатку:", "upFirstText": "Спачатку:",
"upNextText": "Далей у гульні ${COUNT}:", "upNextText": "Далей у гульні ${COUNT}:",
@ -1841,6 +1853,7 @@
"usingItunesTurnRepeatAndShuffleOnText": "Калі ласка, праверце, што ператасаванне і паўтор усяго ў iTunes ўключаны. ", "usingItunesTurnRepeatAndShuffleOnText": "Калі ласка, праверце, што ператасаванне і паўтор усяго ў iTunes ўключаны. ",
"v2AccountLinkingInfoText": "Да прывязкі акаўнту V2, Нажміце 'Кіраваць акаўнтамі'.", "v2AccountLinkingInfoText": "Да прывязкі акаўнту V2, Нажміце 'Кіраваць акаўнтамі'.",
"validatingTestBuildText": "Праверка Тэставай Зборкі...", "validatingTestBuildText": "Праверка Тэставай Зборкі...",
"viaText": "праз",
"victoryText": "Перамога!", "victoryText": "Перамога!",
"voteDelayText": "Вы не можаце пачаць яшчэ адно галасаванне на працягу ${NUMBER} секунд", "voteDelayText": "Вы не можаце пачаць яшчэ адно галасаванне на працягу ${NUMBER} секунд",
"voteInProgressText": "Галасаванне ўжо ідзе.", "voteInProgressText": "Галасаванне ўжо ідзе.",

View file

@ -24,16 +24,17 @@
"resetProgressText": "重置游戏进程", "resetProgressText": "重置游戏进程",
"setAccountName": "设置账户名称", "setAccountName": "设置账户名称",
"setAccountNameDesc": "选择要为您的帐户显示的名称。\n您可以从链接的帐户选择\n或创建唯一的自定义名称。", "setAccountNameDesc": "选择要为您的帐户显示的名称。\n您可以从链接的帐户选择\n或创建唯一的自定义名称。",
"signInInfoText": "登以获取点券, 在线竞赛,\n并在不同设备上同步游戏进程。", "signInInfoText": "登以获取点券, 在线竞赛,\n并在不同设备上同步游戏进程。",
"signInText": "登陆", "signInText": "登陆",
"signInWithDeviceInfoText": "(仅适用于此设备的一个自动账户)", "signInWithDeviceInfoText": "(仅适用于此设备的一个自动账户)",
"signInWithDeviceText": "用设备账户来登", "signInWithDeviceText": "用设备账户来登",
"signInWithGameCircleText": "使用 Game Circle 登入", "signInWithGameCircleText": "使用 Game Circle 登入",
"signInWithGooglePlayText": "用 Google Play 来登", "signInWithGooglePlayText": "用 Google Play 来登",
"signInWithTestAccountInfoText": "使用设备上的其他网络帐号登录;不建议选择该项", "signInWithTestAccountInfoText": "使用设备上的其他网络帐号登录;不建议选择该项",
"signInWithTestAccountText": "用测试账户来登陆", "signInWithTestAccountText": "用测试账户来登陆",
"signInWithText": "使用 ${SERVICE} 登录",
"signInWithV2InfoText": "(账户在所有平台都通用)", "signInWithV2InfoText": "(账户在所有平台都通用)",
"signInWithV2Text": "使用炸弹小分队账号登录", "signInWithV2Text": "使用炸V2账号登录",
"signOutText": "登出", "signOutText": "登出",
"signingInText": "登录中...", "signingInText": "登录中...",
"signingOutText": "登出中...", "signingOutText": "登出中...",
@ -42,8 +43,8 @@
"ticketsText": "点券:${COUNT}", "ticketsText": "点券:${COUNT}",
"titleText": "账号", "titleText": "账号",
"unlinkAccountsInstructionsText": "选择要取消关联的帐户", "unlinkAccountsInstructionsText": "选择要取消关联的帐户",
"unlinkAccountsText": "取消连结帐户", "unlinkAccountsText": "取帐户",
"unlinkLegacyV1AccountsText": "取消连接旧版V1账户", "unlinkLegacyV1AccountsText": "取消关联旧版V1账户",
"v2LinkInstructionsText": "扫码或使用链接来登录或注册新账户", "v2LinkInstructionsText": "扫码或使用链接来登录或注册新账户",
"viaAccount": "(不可用名称 ${NAME})", "viaAccount": "(不可用名称 ${NAME})",
"youAreLoggedInAsText": "您已登录为", "youAreLoggedInAsText": "您已登录为",
@ -64,7 +65,7 @@
"descriptionComplete": "没有使用任何炸弹就获胜了", "descriptionComplete": "没有使用任何炸弹就获胜了",
"descriptionFull": "在${LEVEL}中不用炸弹获胜", "descriptionFull": "在${LEVEL}中不用炸弹获胜",
"descriptionFullComplete": "在${LEVEL}中没用炸弹就获胜了", "descriptionFullComplete": "在${LEVEL}中没用炸弹就获胜了",
"name": "拳" "name": "拳"
}, },
"Dual Wielding": { "Dual Wielding": {
"descriptionFull": "连接两个控制手柄(硬件或应用)", "descriptionFull": "连接两个控制手柄(硬件或应用)",
@ -95,7 +96,7 @@
"descriptionComplete": "没有用炸弹或拳头攻击就获胜了", "descriptionComplete": "没有用炸弹或拳头攻击就获胜了",
"descriptionFull": "在${LEVEL}中不用炸弹或拳头攻击就获胜", "descriptionFull": "在${LEVEL}中不用炸弹或拳头攻击就获胜",
"descriptionFullComplete": "在${LEVEL}中没有用炸弹或拳头攻击就获胜了", "descriptionFullComplete": "在${LEVEL}中没有用炸弹或拳头攻击就获胜了",
"name": "位是关键" "name": "位是关键"
}, },
"In Control": { "In Control": {
"descriptionFull": "连接一个控制手柄(硬件或应用)", "descriptionFull": "连接一个控制手柄(硬件或应用)",
@ -371,6 +372,7 @@
"chatMutedText": "聊天静音", "chatMutedText": "聊天静音",
"chatUnMuteText": "取消屏蔽消息", "chatUnMuteText": "取消屏蔽消息",
"choosingPlayerText": "<选择玩家>", "choosingPlayerText": "<选择玩家>",
"codesExplainText": "开发者会提供代码来\n诊断和修复账户问题",
"completeThisLevelToProceedText": "你需要先完成这一关", "completeThisLevelToProceedText": "你需要先完成这一关",
"completionBonusText": "完成奖励", "completionBonusText": "完成奖励",
"configControllersWindow": { "configControllersWindow": {
@ -451,6 +453,7 @@
"swipeText": "滑动", "swipeText": "滑动",
"titleText": "触摸屏配置" "titleText": "触摸屏配置"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} 可以在系统设置中配置捏",
"configureItNowText": "立即配置?", "configureItNowText": "立即配置?",
"configureText": "配置", "configureText": "配置",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -564,6 +567,8 @@
"disableXInputDescriptionText": "允许使用4个以上的控制器但可能不会正常工作", "disableXInputDescriptionText": "允许使用4个以上的控制器但可能不会正常工作",
"disableXInputText": "禁用XInput", "disableXInputText": "禁用XInput",
"disabledText": "禁用", "disabledText": "禁用",
"discordFriendsText": "这是官方Discord群的按钮但是很可惜中国不许你用Discord\n所以来加鲨鱼QQ群902867245吧译者注有问题可改",
"discordJoinText": "我就要加Discord",
"doneText": "完成", "doneText": "完成",
"drawText": "平局", "drawText": "平局",
"duplicateText": "复制", "duplicateText": "复制",
@ -642,7 +647,7 @@
"errorDeviceTimeIncorrectText": "您设备的时间有 ${HOURS} 小时的误差。\n这会导致游戏出现问题。\n请检查您设备的时间和时区设置。", "errorDeviceTimeIncorrectText": "您设备的时间有 ${HOURS} 小时的误差。\n这会导致游戏出现问题。\n请检查您设备的时间和时区设置。",
"errorOutOfDiskSpaceText": "磁盘空间不足", "errorOutOfDiskSpaceText": "磁盘空间不足",
"errorSecureConnectionFailText": "无法建立安全的云链接,网络可能会连接失败", "errorSecureConnectionFailText": "无法建立安全的云链接,网络可能会连接失败",
"errorText": "错误", "errorText": "啊呜,好像出错了喵...",
"errorUnknownText": "未知错误", "errorUnknownText": "未知错误",
"exitGameText": "退出${APP_NAME}", "exitGameText": "退出${APP_NAME}",
"exportSuccessText": "退出'${NAME}'", "exportSuccessText": "退出'${NAME}'",
@ -655,7 +660,7 @@
"titleFolderText": "选择一个文件夹", "titleFolderText": "选择一个文件夹",
"useThisFolderButtonText": "使用此文件夹" "useThisFolderButtonText": "使用此文件夹"
}, },
"filterText": "过滤器", "filterText": "搜索",
"finalScoreText": "最后得分", "finalScoreText": "最后得分",
"finalScoresText": "最后得分", "finalScoresText": "最后得分",
"finalTimeText": "最终时间", "finalTimeText": "最终时间",
@ -733,7 +738,7 @@
"hostingUnavailableText": "主机不可用", "hostingUnavailableText": "主机不可用",
"inDevelopmentWarningText": "注意:\n\n联网模式是一项新的并且还在开发特性\n目前强烈建议所有玩家在同一个\n无线局域网下游戏。", "inDevelopmentWarningText": "注意:\n\n联网模式是一项新的并且还在开发特性\n目前强烈建议所有玩家在同一个\n无线局域网下游戏。",
"internetText": "在线游戏", "internetText": "在线游戏",
"inviteAFriendText": "好友还未加入该游戏?邀请他们\n一起玩新玩家可获得${COUNT}张免费点券。", "inviteAFriendText": "你的朋友还没下载?邀请他们\n一起玩新玩家可获得${COUNT}张免费点券。",
"inviteFriendsText": "邀请朋友", "inviteFriendsText": "邀请朋友",
"joinPublicPartyDescriptionText": "加入一个公开派对", "joinPublicPartyDescriptionText": "加入一个公开派对",
"localNetworkDescriptionText": "加入一个局域网派对(通过wifi蓝牙等各种方式)", "localNetworkDescriptionText": "加入一个局域网派对(通过wifi蓝牙等各种方式)",
@ -825,17 +830,19 @@
"alwaysText": "总是", "alwaysText": "总是",
"fullScreenCmdText": "全屏显示Cmd+F", "fullScreenCmdText": "全屏显示Cmd+F",
"fullScreenCtrlText": "全屏(Ctrl-F)", "fullScreenCtrlText": "全屏(Ctrl-F)",
"fullScreenText": "全屏",
"gammaText": "Gamma", "gammaText": "Gamma",
"highText": "高", "highText": "高",
"higherText": "极高", "higherText": "极高",
"lowText": "低", "lowText": "低",
"maxFPSText": "最高帧数",
"mediumText": "中", "mediumText": "中",
"neverText": "关", "neverText": "关",
"resolutionText": "分辨率", "resolutionText": "分辨率",
"showFPSText": "显示FPS帧数", "showFPSText": "显示FPS帧数",
"texturesText": "材质质量", "texturesText": "材质质量",
"titleText": "图像质量", "titleText": "图像质量",
"tvBorderText": "电视边缘", "tvBorderText": "大广角",
"verticalSyncText": "垂直同步", "verticalSyncText": "垂直同步",
"visualsText": "视觉" "visualsText": "视觉"
}, },
@ -845,15 +852,15 @@
"controllersInfoText": "你可以和好友在同一网络下玩${APP_NAME},或者\n如果你有足够多的手柄那也可以在同一个设备上游戏。\n${APP_NAME}支持各种选择;你甚至可以通过免费的'${REMOTE_APP_NAME}'\n用手机作为游戏手柄。\n更多信息请参见设置->手柄。", "controllersInfoText": "你可以和好友在同一网络下玩${APP_NAME},或者\n如果你有足够多的手柄那也可以在同一个设备上游戏。\n${APP_NAME}支持各种选择;你甚至可以通过免费的'${REMOTE_APP_NAME}'\n用手机作为游戏手柄。\n更多信息请参见设置->手柄。",
"controllersInfoTextRemoteOnly": "你可以通过局域网与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩", "controllersInfoTextRemoteOnly": "你可以通过局域网与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩",
"controllersText": "手柄", "controllersText": "手柄",
"controlsSubtitleText": "你的友好的${APP_NAME}角色具有几个基本动作", "controlsSubtitleText": "${APP_NAME}的角色基本操作如下",
"controlsText": "控制键", "controlsText": "控制键",
"devicesInfoText": "VR版${APP_NAME}可与\n普通版本联网游戏所以掏出你所有的手机、平板电脑\n和电脑大玩一场吧。你甚至还可以将\n普通版本的游戏连接至VR版\n让游戏外的人也能看你玩。", "devicesInfoText": "VR版${APP_NAME}可与\n普通版本联网游戏所以掏出你所有的手机、平板电脑\n和电脑大玩一场吧。你甚至还可以将\n普通版本的游戏连接至VR版\n让游戏外的人也能看你玩。",
"devicesText": "设备", "devicesText": "设备",
"friendsGoodText": "这对你而言都是好事。和三五好友一起玩${APP_NAME}最有趣了,\n最多可以支持8个玩家一起玩进入", "friendsGoodText": "哎,一个人玩?那咋行!${APP_NAME}就是要人多才好玩嘛~\n最多支持8人同时游戏如果你有魔法可以改掉限制喵~快拉你的小伙伴一起玩吧",
"friendsText": "好友", "friendsText": "好友",
"jumpInfoText": "跳跃\n跳跃可以跳过较窄的缝隙,\n或是把炸弹扔的更远,\n或是表达你难以掩盖的喜悦之情。", "jumpInfoText": "跳跃\n跳跃可以跳过小沟,\n或是把炸弹扔得更远,\n或是表达你难以掩盖的喜悦之情。",
"orPunchingSomethingText": "还可以用拳头攻击,或者把敌人举起来然后丢下去,或者更多好玩的...", "orPunchingSomethingText": "还可以用拳头攻击,或者把敌人举起来然后丢下去,或者更多好玩的...",
"pickUpInfoText": "拾起\n你可以拾起旗子敌人\n还有所有没固定在地上的东西\n然后再扔出去吧", "pickUpInfoText": "拾起\n你可以拾起旗子敌人\n还有所有没固定在地上的东西\n然后再扔出去吧~",
"powerupBombDescriptionText": "将炸弹最大投掷数量\n由一个提升为三个", "powerupBombDescriptionText": "将炸弹最大投掷数量\n由一个提升为三个",
"powerupBombNameText": "三连炸弹", "powerupBombNameText": "三连炸弹",
"powerupCurseDescriptionText": "最好不要接触它。\n...或者你想试试?", "powerupCurseDescriptionText": "最好不要接触它。\n...或者你想试试?",
@ -875,7 +882,7 @@
"powerupsSubtitleText": "当然,没有道具的游戏很难通关:", "powerupsSubtitleText": "当然,没有道具的游戏很难通关:",
"powerupsText": "道具", "powerupsText": "道具",
"punchInfoText": "拳击\n跑得越快拳击的伤害\n越高。所以像疯子一样\n旋转跳跃吧", "punchInfoText": "拳击\n跑得越快拳击的伤害\n越高。所以像疯子一样\n旋转跳跃吧",
"runInfoText": "冲刺\n按任意键冲刺,如果你用手柄操作将会容易许多。\n冲刺跑的虽快但会造成转向困难。且冲且珍惜。", "runInfoText": "冲刺\n按住四个键中的一个即可冲刺,如果你用手柄可以将扳机设置为跑\n冲刺跑的虽快但会造成转向困难。且冲且珍惜",
"someDaysText": "当你想攻击别人时,你可以用各种炸弹", "someDaysText": "当你想攻击别人时,你可以用各种炸弹",
"titleText": "${APP_NAME}帮助", "titleText": "${APP_NAME}帮助",
"toGetTheMostText": "要想最痛快地玩这个游戏,你需要:", "toGetTheMostText": "要想最痛快地玩这个游戏,你需要:",
@ -937,7 +944,7 @@
"rejectingInviteAlreadyInPartyText": "拒绝邀请(已经在派对中)。", "rejectingInviteAlreadyInPartyText": "拒绝邀请(已经在派对中)。",
"serverRestartingText": "服务器自动重启中,请重新加入..", "serverRestartingText": "服务器自动重启中,请重新加入..",
"serverShuttingDownText": "服务器正在关机…", "serverShuttingDownText": "服务器正在关机…",
"signInErrorText": "登出错啦~", "signInErrorText": "登出错啦~",
"signInNoConnectionText": "哎呀,无法登陆。(网络连接有故障?)", "signInNoConnectionText": "哎呀,无法登陆。(网络连接有故障?)",
"telnetAccessDeniedText": "错误用户未得到telnet访问授权。", "telnetAccessDeniedText": "错误用户未得到telnet访问授权。",
"timeOutText": "(将在${TIME}秒内超出时限)", "timeOutText": "(将在${TIME}秒内超出时限)",
@ -1036,7 +1043,7 @@
"mapSelectTitleText": "${GAME}地图", "mapSelectTitleText": "${GAME}地图",
"mapText": "地图", "mapText": "地图",
"maxConnectionsText": "最大连接数", "maxConnectionsText": "最大连接数",
"maxPartySizeText": "最大派对规模", "maxPartySizeText": "最大派对人数",
"maxPlayersText": "最多人数", "maxPlayersText": "最多人数",
"merchText": "来买周边吧~", "merchText": "来买周边吧~",
"modeArcadeText": "街机模式", "modeArcadeText": "街机模式",
@ -1059,7 +1066,7 @@
"nameText": "名称", "nameText": "名称",
"nativeText": "本机", "nativeText": "本机",
"newPersonalBestText": "新个人记录!", "newPersonalBestText": "新个人记录!",
"newTestBuildAvailableText": "更新的测试版可供下载了!(${VERSION}生成${BUILD})。\n到${ADDRESS}获取", "newTestBuildAvailableText": "更新的测试版可供下载了!(${VERSION} build${BUILD})。\n到${ADDRESS}获取吧!",
"newText": "新建", "newText": "新建",
"newVersionAvailableText": "更新版本的 ${APP_NAME} 可供下载了! 版本号(${VERSION})", "newVersionAvailableText": "更新版本的 ${APP_NAME} 可供下载了! 版本号(${VERSION})",
"nextAchievementsText": "下一个成就:", "nextAchievementsText": "下一个成就:",
@ -1070,6 +1077,7 @@
"noGameCircleText": "错误未登入GameCircle", "noGameCircleText": "错误未登入GameCircle",
"noProfilesErrorText": "您没有玩家档案,所以还得忍受“${NAME}”这个名字。\n进入设置->玩家档案,为自己创建档案。", "noProfilesErrorText": "您没有玩家档案,所以还得忍受“${NAME}”这个名字。\n进入设置->玩家档案,为自己创建档案。",
"noScoresYetText": "还未有得分记录。", "noScoresYetText": "还未有得分记录。",
"noServersFoundText": "未找到服务器",
"noThanksText": "不,谢谢", "noThanksText": "不,谢谢",
"noTournamentsInTestBuildText": "温馨提示:测试版的锦标赛分数不能计入锦标赛哦!", "noTournamentsInTestBuildText": "温馨提示:测试版的锦标赛分数不能计入锦标赛哦!",
"noValidMapsErrorText": "该比赛类型中未发现有效地图。", "noValidMapsErrorText": "该比赛类型中未发现有效地图。",
@ -1140,7 +1148,7 @@
"pleaseRateText": "如果你喜欢 ${APP_NAME},请考虑花一点时间\n来评价一下它或为它写一篇评论。这将为我们提供\n有用的反馈建议为游戏的未来开发给予支持。\n\n感谢您\n-eric", "pleaseRateText": "如果你喜欢 ${APP_NAME},请考虑花一点时间\n来评价一下它或为它写一篇评论。这将为我们提供\n有用的反馈建议为游戏的未来开发给予支持。\n\n感谢您\n-eric",
"pleaseWaitText": "请稍等...", "pleaseWaitText": "请稍等...",
"pluginClassLoadErrorText": "加载'${PLUGIN}'插件时出错了耶: ${ERROR}", "pluginClassLoadErrorText": "加载'${PLUGIN}'插件时出错了耶: ${ERROR}",
"pluginInitErrorText": "初始化'${PLUGIN}'插件失败了: ${ERROR}", "pluginInitErrorText": "初始化'${PLUGIN}'插件失败了: ${ERROR}",
"pluginSettingsText": "插件设置", "pluginSettingsText": "插件设置",
"pluginsAutoEnableNewText": "自动启用新插件", "pluginsAutoEnableNewText": "自动启用新插件",
"pluginsDetectedText": "新插件安装成功,请重启游戏或在设置中设置它们~", "pluginsDetectedText": "新插件安装成功,请重启游戏或在设置中设置它们~",
@ -1284,6 +1292,7 @@
"netTestingText": "网络测试", "netTestingText": "网络测试",
"resetText": "恢复默认值", "resetText": "恢复默认值",
"showBombTrajectoriesText": "显示炸弹轨迹", "showBombTrajectoriesText": "显示炸弹轨迹",
"showDevConsoleButtonText": "显示开发者控制台按钮",
"showInGamePingText": "显示游戏延迟", "showInGamePingText": "显示游戏延迟",
"showPlayerNamesText": "显示玩家名字", "showPlayerNamesText": "显示玩家名字",
"showUserModsText": "显示Mod文件夹", "showUserModsText": "显示Mod文件夹",
@ -1378,6 +1387,8 @@
"storeText": "商店", "storeText": "商店",
"submitText": "提交", "submitText": "提交",
"submittingPromoCodeText": "正在提交代码...", "submittingPromoCodeText": "正在提交代码...",
"successText": "成功",
"supportEmailText": "如果你在APP遇到任何问题\n请发邮件到${EMAIL}",
"teamNamesColorText": "团队名称/颜色。。。", "teamNamesColorText": "团队名称/颜色。。。",
"telnetAccessGrantedText": "Telnet访问已启用。", "telnetAccessGrantedText": "Telnet访问已启用。",
"telnetAccessText": "检测到Telnet访问是否允许", "telnetAccessText": "检测到Telnet访问是否允许",
@ -1648,7 +1659,7 @@
"Profile \"${NAME}\" upgraded successfully.": "${NAME}档案升级成功。", "Profile \"${NAME}\" upgraded successfully.": "${NAME}档案升级成功。",
"Profile could not be upgraded.": "档案不可升级。", "Profile could not be upgraded.": "档案不可升级。",
"Purchase successful!": "购买成功!", "Purchase successful!": "购买成功!",
"Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "登录成功 获得${COUNT}点券喵~\n明日再来领取${TOMORROW_COUNT}。", "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "今日登录获得${COUNT}点券\n明日再来领取${TOMORROW_COUNT}点券",
"Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "此版本的游戏不再支持服务器功能;\n请更新到较新版本。", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "此版本的游戏不再支持服务器功能;\n请更新到较新版本。",
"Sorry, there are no uses remaining on this code.": "对不起,此代码已经无法继续使用了。", "Sorry, there are no uses remaining on this code.": "对不起,此代码已经无法继续使用了。",
"Sorry, this code has already been used.": "对不起,此代码已被使用。", "Sorry, this code has already been used.": "对不起,此代码已被使用。",
@ -1663,9 +1674,9 @@
"This requires version ${VERSION} or newer.": "这需要版本${VERSION}或更高版本。", "This requires version ${VERSION} or newer.": "这需要版本${VERSION}或更高版本。",
"Tournaments disabled due to rooted device.": "该设备已禁用比赛。", "Tournaments disabled due to rooted device.": "该设备已禁用比赛。",
"Tournaments require ${VERSION} or newer": "比赛需要${VERSION}或更高版本", "Tournaments require ${VERSION} or newer": "比赛需要${VERSION}或更高版本",
"Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "从此帐户取消 ${ACCOUNT} 的连结\n${ACCOUNT}上的所有数据将被重置。\n在某些情况下除成就外", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "从此帐户取消 ${ACCOUNT} 的关联\n${ACCOUNT}上的所有数据将被重置。\n在某些情况下除成就外",
"WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "警告:针对您的帐户发出黑客投诉。\n被盗用的帐户将被禁止。请公平竞技。", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "警告:针对您的帐户发出黑客投诉。\n被盗用的帐户将被禁止。请公平竞技。",
"Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否将您的设备帐户链接到此?\n\n您的设备账户为${ACCOUNT1}\n此帐户为${ACCOUNT2}\n\n您可保存现有进度。\n警告: 此操作不可撤消!", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否将您的设备帐户关联到此?\n\n您的设备账户为${ACCOUNT1}\n此帐户为${ACCOUNT2}\n\n您可保存现有进度。\n警告: 此操作不可撤消!",
"You already own this!": "你已拥有了!", "You already own this!": "你已拥有了!",
"You can join in ${COUNT} seconds.": "你在${COUNT} 秒后可以加入", "You can join in ${COUNT} seconds.": "你在${COUNT} 秒后可以加入",
"You don't have enough tickets for this!": "你的点券不足!", "You don't have enough tickets for this!": "你的点券不足!",
@ -1832,6 +1843,7 @@
"unlockThisInTheStoreText": "这必须在商店中解锁。", "unlockThisInTheStoreText": "这必须在商店中解锁。",
"unlockThisProfilesText": "如需创建超过 ${NUM} 个玩家档案,你需要", "unlockThisProfilesText": "如需创建超过 ${NUM} 个玩家档案,你需要",
"unlockThisText": "你需要这些来解锁", "unlockThisText": "你需要这些来解锁",
"unsupportedControllerText": "抱歉,游戏不兼容你的控制器\"${NAME}\"",
"unsupportedHardwareText": "抱歉,此版本的游戏不支持该硬件。", "unsupportedHardwareText": "抱歉,此版本的游戏不支持该硬件。",
"upFirstText": "进入第一局:", "upFirstText": "进入第一局:",
"upNextText": "进入比赛${COUNT}第二局:", "upNextText": "进入比赛${COUNT}第二局:",
@ -1842,8 +1854,9 @@
"usesExternalControllerText": "该游戏使用外部手柄进行输入。", "usesExternalControllerText": "该游戏使用外部手柄进行输入。",
"usingItunesText": "使用音乐应用设置背景音乐……", "usingItunesText": "使用音乐应用设置背景音乐……",
"usingItunesTurnRepeatAndShuffleOnText": "请确认iTunes中随机播放已开启且重复全部歌曲。", "usingItunesTurnRepeatAndShuffleOnText": "请确认iTunes中随机播放已开启且重复全部歌曲。",
"v2AccountLinkingInfoText": "要连接V2账户请点击“管理账户”~", "v2AccountLinkingInfoText": "要关联V2账户请点击“管理账户”喵~",
"validatingTestBuildText": "测试版验证中……", "validatingTestBuildText": "测试版验证中……",
"viaText": "渠道账户:",
"victoryText": "胜利!", "victoryText": "胜利!",
"voteDelayText": "${NUMBER} 秒内你不能发起另一个投票", "voteDelayText": "${NUMBER} 秒内你不能发起另一个投票",
"voteInProgressText": "已经有一个投票在进行中了", "voteInProgressText": "已经有一个投票在进行中了",

View file

@ -818,6 +818,7 @@
"highText": "高", "highText": "高",
"higherText": "最高", "higherText": "最高",
"lowText": "低", "lowText": "低",
"maxFPSText": "最大FPS",
"mediumText": "中", "mediumText": "中",
"neverText": "關", "neverText": "關",
"resolutionText": "分辨率", "resolutionText": "分辨率",
@ -1265,6 +1266,7 @@
"netTestingText": "網絡連接測試", "netTestingText": "網絡連接測試",
"resetText": "恢復默認", "resetText": "恢復默認",
"showBombTrajectoriesText": "顯示炸彈軌跡", "showBombTrajectoriesText": "顯示炸彈軌跡",
"showDevConsoleButtonText": "顯示開發控制臺按鈕",
"showInGamePingText": "顯示遊戲內延遲", "showInGamePingText": "顯示遊戲內延遲",
"showPlayerNamesText": "顯示玩家名稱", "showPlayerNamesText": "顯示玩家名稱",
"showUserModsText": "顯示MOD安裝文件夾", "showUserModsText": "顯示MOD安裝文件夾",

View file

@ -32,6 +32,7 @@
"signInWithGooglePlayText": "Přihlásit se přes Google Play", "signInWithGooglePlayText": "Přihlásit se přes Google Play",
"signInWithTestAccountInfoText": "(zastaralý typ účtu; použije raději účet zařízení)", "signInWithTestAccountInfoText": "(zastaralý typ účtu; použije raději účet zařízení)",
"signInWithTestAccountText": "Přihlásit se s testovacím účtem", "signInWithTestAccountText": "Přihlásit se s testovacím účtem",
"signInWithText": "Přihlásit se s ${SERVICE}",
"signInWithV2InfoText": "(účet který funguje na všech platformách)", "signInWithV2InfoText": "(účet který funguje na všech platformách)",
"signInWithV2Text": "Přihlášení s BombSquad účtem", "signInWithV2Text": "Přihlášení s BombSquad účtem",
"signOutText": "Odhlásit se", "signOutText": "Odhlásit se",
@ -339,6 +340,8 @@
"getMoreGamesText": "Získat více her...", "getMoreGamesText": "Získat více her...",
"titleText": "Přidat hru" "titleText": "Přidat hru"
}, },
"addToFavoritesText": "Přidáno do Oblíbených",
"addedToFavoritesText": "Přidáno '${NAME}' do Oblíbených.",
"allText": "Vše", "allText": "Vše",
"allowText": "Povolit", "allowText": "Povolit",
"alreadySignedInText": "Tento účet je používán v jiném zařízení;\npřepněte prosím účet nebo v druhém\nzařízení hru zavřete, poté to zkuste znova.", "alreadySignedInText": "Tento účet je používán v jiném zařízení;\npřepněte prosím účet nebo v druhém\nzařízení hru zavřete, poté to zkuste znova.",
@ -375,6 +378,7 @@
"chatMutedText": "Chat ztlumen", "chatMutedText": "Chat ztlumen",
"chatUnMuteText": "Obnovit chat", "chatUnMuteText": "Obnovit chat",
"choosingPlayerText": "<vybírá hráče>", "choosingPlayerText": "<vybírá hráče>",
"codesExplainText": "Kódy jsou zřizovány vývojářem za účelem\ndiagnózy a opravy problémů s účty.",
"completeThisLevelToProceedText": "Musíte dokončit\ntento level, abyste mohli pokračovat!", "completeThisLevelToProceedText": "Musíte dokončit\ntento level, abyste mohli pokračovat!",
"completionBonusText": "Bonus za dokončení", "completionBonusText": "Bonus za dokončení",
"configControllersWindow": { "configControllersWindow": {
@ -455,6 +459,7 @@
"swipeText": "přejíždění", "swipeText": "přejíždění",
"titleText": "Nastavit dotykovou obrazovku" "titleText": "Nastavit dotykovou obrazovku"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} může být nakonfigurováno v Nastavení Systému",
"configureItNowText": "Nastavit teď?", "configureItNowText": "Nastavit teď?",
"configureText": "Nastavit", "configureText": "Nastavit",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -568,6 +573,8 @@
"disableXInputDescriptionText": "Povolí více než 4 ovladače, ale nemusí fungovat tak dobře.", "disableXInputDescriptionText": "Povolí více než 4 ovladače, ale nemusí fungovat tak dobře.",
"disableXInputText": "Vypnout XInput", "disableXInputText": "Vypnout XInput",
"disabledText": "Zakázáno", "disabledText": "Zakázáno",
"discordFriendsText": "Chcete najít nové lidi na hraní?\nPřipojte se k našemu Discordu a najděte nové přátele!",
"discordJoinText": "Připoj se k Discordu",
"doneText": "Hotovo", "doneText": "Hotovo",
"drawText": "Remíza", "drawText": "Remíza",
"duplicateText": "Duplikovat", "duplicateText": "Duplikovat",
@ -756,6 +763,7 @@
"manualYourLocalAddressText": "Vaše lokální adresa:", "manualYourLocalAddressText": "Vaše lokální adresa:",
"nearbyText": "Lokální", "nearbyText": "Lokální",
"noConnectionText": "<žádné připojení>", "noConnectionText": "<žádné připojení>",
"noPartiesAddedText": "Nebyly přidány žádné strany",
"otherVersionsText": "(ostatní verze)", "otherVersionsText": "(ostatní verze)",
"partyCodeText": "Kód Party", "partyCodeText": "Kód Party",
"partyInviteAcceptText": "Potvrdit", "partyInviteAcceptText": "Potvrdit",
@ -828,10 +836,12 @@
"alwaysText": "Vždy", "alwaysText": "Vždy",
"fullScreenCmdText": "Celá obrazovka (Cmd-F)", "fullScreenCmdText": "Celá obrazovka (Cmd-F)",
"fullScreenCtrlText": "Celá obrazovka (Ctrl-F)", "fullScreenCtrlText": "Celá obrazovka (Ctrl-F)",
"fullScreenText": "Na celou obrazovku",
"gammaText": "Gamma", "gammaText": "Gamma",
"highText": "Vysoká", "highText": "Vysoká",
"higherText": "Vyšší", "higherText": "Vyšší",
"lowText": "Nízká", "lowText": "Nízká",
"maxFPSText": "Maximální FPS",
"mediumText": "Střední", "mediumText": "Střední",
"neverText": "Nikdy", "neverText": "Nikdy",
"resolutionText": "Rozlišení", "resolutionText": "Rozlišení",
@ -1071,8 +1081,10 @@
"noContinuesText": "(bez pokračování)", "noContinuesText": "(bez pokračování)",
"noExternalStorageErrorText": "Žádné externí úložiště nebylo na tomto zařízení nalezeno", "noExternalStorageErrorText": "Žádné externí úložiště nebylo na tomto zařízení nalezeno",
"noGameCircleText": "Chyba: nejste přihlášeni do Game Circle", "noGameCircleText": "Chyba: nejste přihlášeni do Game Circle",
"noPluginsInstalledText": "Nenainstalovány žádné pluginy",
"noProfilesErrorText": "Nemáte žádné herní profily, takže Vám bylo podstrčeno jméno '${NAME}'.\nJděte do Nastavení->Herní Profily pro vytvoření svého profilu.", "noProfilesErrorText": "Nemáte žádné herní profily, takže Vám bylo podstrčeno jméno '${NAME}'.\nJděte do Nastavení->Herní Profily pro vytvoření svého profilu.",
"noScoresYetText": "Zatím žádné výsledky.", "noScoresYetText": "Zatím žádné výsledky.",
"noServersFoundText": "Nenalezeny žádné servery.",
"noThanksText": "Ne, děkuji", "noThanksText": "Ne, děkuji",
"noTournamentsInTestBuildText": "VAROVÁNÍ: Skóre z turnajů z tohoto testovacího buildu budou ignorovány.", "noTournamentsInTestBuildText": "VAROVÁNÍ: Skóre z turnajů z tohoto testovacího buildu budou ignorovány.",
"noValidMapsErrorText": "Nebyly nalezeny žádné platné mapy pro tento typ hry.", "noValidMapsErrorText": "Nebyly nalezeny žádné platné mapy pro tento typ hry.",
@ -1285,6 +1297,7 @@
"netTestingText": "Testování sítě", "netTestingText": "Testování sítě",
"resetText": "Obnovit", "resetText": "Obnovit",
"showBombTrajectoriesText": "Ukazovat trajektorii bomb", "showBombTrajectoriesText": "Ukazovat trajektorii bomb",
"showDevConsoleButtonText": "Ukaž tlačítko vývojářské konzoly",
"showInGamePingText": "Ukazovat ping při hře", "showInGamePingText": "Ukazovat ping při hře",
"showPlayerNamesText": "Ukazovat jména hráčů", "showPlayerNamesText": "Ukazovat jména hráčů",
"showUserModsText": "Zobrazit složku s módy", "showUserModsText": "Zobrazit složku s módy",
@ -1379,6 +1392,8 @@
"storeText": "Obchod", "storeText": "Obchod",
"submitText": "Odeslat", "submitText": "Odeslat",
"submittingPromoCodeText": "Odesílám kód...", "submittingPromoCodeText": "Odesílám kód...",
"successText": "Úspěch!",
"supportEmailText": "Pokud máte jakékoliv problémy s aplikací, prosím \nnapište na email ${EMAIL}.",
"teamNamesColorText": "Jména/Barvy týmů...", "teamNamesColorText": "Jména/Barvy týmů...",
"telnetAccessGrantedText": "Přístup k telnetu zapnut.", "telnetAccessGrantedText": "Přístup k telnetu zapnut.",
"telnetAccessText": "Detekován přístup k telnetu; povolit?", "telnetAccessText": "Detekován přístup k telnetu; povolit?",
@ -1833,6 +1848,7 @@
"unlockThisInTheStoreText": "Toto musí být nejdříve odemknuto v obchodě.", "unlockThisInTheStoreText": "Toto musí být nejdříve odemknuto v obchodě.",
"unlockThisProfilesText": "Pro vytvoření více než ${NUM} profilů, potřebujete:", "unlockThisProfilesText": "Pro vytvoření více než ${NUM} profilů, potřebujete:",
"unlockThisText": "Pro odemknutí tohoto potřebujete:", "unlockThisText": "Pro odemknutí tohoto potřebujete:",
"unsupportedControllerText": "Je mi líto, ovladač \"${NAME}\" není podporován.",
"unsupportedHardwareText": "Omlouváme se, ale tento hardware není porporován tímto buildem hry.", "unsupportedHardwareText": "Omlouváme se, ale tento hardware není porporován tímto buildem hry.",
"upFirstText": "První:", "upFirstText": "První:",
"upNextText": "Další, ${COUNT}. hra bude:", "upNextText": "Další, ${COUNT}. hra bude:",
@ -1845,6 +1861,7 @@
"usingItunesTurnRepeatAndShuffleOnText": "Ujistěte se prosím, že je zaplý shuffle, a opakovat VŠE v iTunes,", "usingItunesTurnRepeatAndShuffleOnText": "Ujistěte se prosím, že je zaplý shuffle, a opakovat VŠE v iTunes,",
"v2AccountLinkingInfoText": "Pro propojení V2 účtů stiskněte tlačítko „Spravovat účet“", "v2AccountLinkingInfoText": "Pro propojení V2 účtů stiskněte tlačítko „Spravovat účet“",
"validatingTestBuildText": "Ověřuji testovací build...", "validatingTestBuildText": "Ověřuji testovací build...",
"viaText": "skrze",
"victoryText": "Vítězství!", "victoryText": "Vítězství!",
"voteDelayText": "Nelze spustit další hlas za ${NUMBER} sekund", "voteDelayText": "Nelze spustit další hlas za ${NUMBER} sekund",
"voteInProgressText": "Hlasování již probíhá.", "voteInProgressText": "Hlasování již probíhá.",

View file

@ -25,10 +25,7 @@
"signInText": "Sign In", "signInText": "Sign In",
"signInWithDeviceInfoText": "(an automatic account only available from this device)", "signInWithDeviceInfoText": "(an automatic account only available from this device)",
"signInWithDeviceText": "Sign in with device account", "signInWithDeviceText": "Sign in with device account",
"signInWithGameCircleText": "Sign in with Game Circle", "signInWithText": "Sign in with ${SERVICE}",
"signInWithGooglePlayText": "Sign in with Google Play",
"signInWithTestAccountInfoText": "(legacy account type; use device accounts going forward)",
"signInWithTestAccountText": "Sign in with test account",
"signInWithV2InfoText": "(an account that works on all platforms)", "signInWithV2InfoText": "(an account that works on all platforms)",
"signInWithV2Text": "Sign in with a BombSquad account", "signInWithV2Text": "Sign in with a BombSquad account",
"signOutText": "Sign Out", "signOutText": "Sign Out",
@ -332,6 +329,8 @@
"getMoreGamesText": "Get More Games...", "getMoreGamesText": "Get More Games...",
"titleText": "Add Game" "titleText": "Add Game"
}, },
"addToFavoritesText": "Add to Favorites",
"addedToFavoritesText": "Added '${NAME}' to Favorites.",
"allText": "All", "allText": "All",
"allowText": "Allow", "allowText": "Allow",
"alreadySignedInText": "Your account is signed in from another device;\nplease switch accounts or close the game on your\nother devices and try again.", "alreadySignedInText": "Your account is signed in from another device;\nplease switch accounts or close the game on your\nother devices and try again.",
@ -366,6 +365,7 @@
"chatMutedText": "Chat Muted", "chatMutedText": "Chat Muted",
"chatUnMuteText": "Unmute Chat", "chatUnMuteText": "Unmute Chat",
"choosingPlayerText": "<choosing player>", "choosingPlayerText": "<choosing player>",
"codesExplainText": "Codes are provided by the developer to\ndiagnose and correct account issues.",
"completeThisLevelToProceedText": "You must complete\nthis level to proceed!", "completeThisLevelToProceedText": "You must complete\nthis level to proceed!",
"completionBonusText": "Completion Bonus", "completionBonusText": "Completion Bonus",
"configControllersWindow": { "configControllersWindow": {
@ -446,6 +446,7 @@
"swipeText": "swipe", "swipeText": "swipe",
"titleText": "Configure Touchscreen" "titleText": "Configure Touchscreen"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} can be configured in the System Settings app.",
"configureItNowText": "Configure it now?", "configureItNowText": "Configure it now?",
"configureText": "Configure", "configureText": "Configure",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -560,6 +561,8 @@
"disableXInputDescriptionText": "Allows more than 4 controllers but may not work as well.", "disableXInputDescriptionText": "Allows more than 4 controllers but may not work as well.",
"disableXInputText": "Disable XInput", "disableXInputText": "Disable XInput",
"disabledText": "Disabled", "disabledText": "Disabled",
"discordFriendsText": "Want to look for new people to play with?\nJoin our Discord and find new friends!",
"discordJoinText": "Join the Discord",
"doneText": "Done", "doneText": "Done",
"drawText": "Draw", "drawText": "Draw",
"duplicateText": "Duplicate", "duplicateText": "Duplicate",
@ -661,8 +664,6 @@
"flawlessWaveText": "Flawless Wave!", "flawlessWaveText": "Flawless Wave!",
"fourKillText": "QUAD KILL!!!", "fourKillText": "QUAD KILL!!!",
"friendScoresUnavailableText": "Friend scores unavailable.", "friendScoresUnavailableText": "Friend scores unavailable.",
"gameCenterText": "GameCenter",
"gameCircleText": "GameCircle",
"gameLeadersText": "Game ${COUNT} Leaders", "gameLeadersText": "Game ${COUNT} Leaders",
"gameListWindow": { "gameListWindow": {
"cantDeleteDefaultText": "You can't delete the default playlist.", "cantDeleteDefaultText": "You can't delete the default playlist.",
@ -745,11 +746,11 @@
"manualYourLocalAddressText": "Your local address:", "manualYourLocalAddressText": "Your local address:",
"nearbyText": "Nearby", "nearbyText": "Nearby",
"noConnectionText": "<no connection>", "noConnectionText": "<no connection>",
"noPartiesAddedText": "No Parties Added",
"otherVersionsText": "(other versions)", "otherVersionsText": "(other versions)",
"partyCodeText": "Party Code", "partyCodeText": "Party Code",
"partyInviteAcceptText": "Accept", "partyInviteAcceptText": "Accept",
"partyInviteDeclineText": "Decline", "partyInviteDeclineText": "Decline",
"partyInviteGooglePlayExtraText": "(see the 'Google Play' tab in the 'Gather' window)",
"partyInviteIgnoreText": "Ignore", "partyInviteIgnoreText": "Ignore",
"partyInviteText": "${NAME} has invited\nyou to join their party!", "partyInviteText": "${NAME} has invited\nyou to join their party!",
"partyNameText": "Party Name", "partyNameText": "Party Name",
@ -782,7 +783,6 @@
"wifiDirectOpenWiFiSettingsText": "Open Wi-Fi Settings", "wifiDirectOpenWiFiSettingsText": "Open Wi-Fi Settings",
"wifiDirectText": "Wi-Fi Direct", "wifiDirectText": "Wi-Fi Direct",
"worksBetweenAllPlatformsText": "(works between all platforms)", "worksBetweenAllPlatformsText": "(works between all platforms)",
"worksWithGooglePlayDevicesText": "(works with devices running the Google Play (android) version of the game)",
"youHaveBeenSentAPromoCodeText": "You have been sent a ${APP_NAME} promo code:" "youHaveBeenSentAPromoCodeText": "You have been sent a ${APP_NAME} promo code:"
}, },
"getTicketsWindow": { "getTicketsWindow": {
@ -808,7 +808,6 @@
"youHaveShortText": "you have ${COUNT}", "youHaveShortText": "you have ${COUNT}",
"youHaveText": "you have ${COUNT} tickets" "youHaveText": "you have ${COUNT} tickets"
}, },
"googleMultiplayerDiscontinuedText": "Sorry, Googles multiplayer service is no longer available.\nI am working on a replacement as fast as possible.\nUntil then, please try another connection method.\n-Eric",
"googlePlayPurchasesNotAvailableText": "Google Play purchases are not available.\nYou may need to update your store app.", "googlePlayPurchasesNotAvailableText": "Google Play purchases are not available.\nYou may need to update your store app.",
"googlePlayServicesNotAvailableText": "Google Play Services is not available.\nSome app functionality may be disabled.", "googlePlayServicesNotAvailableText": "Google Play Services is not available.\nSome app functionality may be disabled.",
"googlePlayText": "Google Play", "googlePlayText": "Google Play",
@ -816,10 +815,12 @@
"alwaysText": "Always", "alwaysText": "Always",
"fullScreenCmdText": "Fullscreen (Cmd-F)", "fullScreenCmdText": "Fullscreen (Cmd-F)",
"fullScreenCtrlText": "Fullscreen (Ctrl-F)", "fullScreenCtrlText": "Fullscreen (Ctrl-F)",
"fullScreenText": "Fullscreen",
"gammaText": "Gamma", "gammaText": "Gamma",
"highText": "High", "highText": "High",
"higherText": "Higher", "higherText": "Higher",
"lowText": "Low", "lowText": "Low",
"maxFPSText": "Max FPS",
"mediumText": "Medium", "mediumText": "Medium",
"neverText": "Never", "neverText": "Never",
"resolutionText": "Resolution", "resolutionText": "Resolution",
@ -1065,7 +1066,9 @@
"noContinuesText": "(no continues)", "noContinuesText": "(no continues)",
"noExternalStorageErrorText": "No external storage found on this device", "noExternalStorageErrorText": "No external storage found on this device",
"noGameCircleText": "Error: not logged into GameCircle", "noGameCircleText": "Error: not logged into GameCircle",
"noPluginsInstalledText": "No Plugins Installed",
"noScoresYetText": "No scores yet.", "noScoresYetText": "No scores yet.",
"noServersFoundText": "No servers found.",
"noThanksText": "No Thanks", "noThanksText": "No Thanks",
"noTournamentsInTestBuildText": "WARNING: Tournament scores from this test build will be ignored.", "noTournamentsInTestBuildText": "WARNING: Tournament scores from this test build will be ignored.",
"noValidMapsErrorText": "No valid maps found for this game type.", "noValidMapsErrorText": "No valid maps found for this game type.",
@ -1274,6 +1277,7 @@
"netTestingText": "Network Testing", "netTestingText": "Network Testing",
"resetText": "Reset", "resetText": "Reset",
"showBombTrajectoriesText": "Show Bomb Trajectories", "showBombTrajectoriesText": "Show Bomb Trajectories",
"showDevConsoleButtonText": "Show Dev Console Button",
"showInGamePingText": "Show In-Game Ping", "showInGamePingText": "Show In-Game Ping",
"showPlayerNamesText": "Show Player Names", "showPlayerNamesText": "Show Player Names",
"showUserModsText": "Show Mods Folder", "showUserModsText": "Show Mods Folder",
@ -1290,7 +1294,6 @@
"sharingText": "Sharing...", "sharingText": "Sharing...",
"showText": "Show", "showText": "Show",
"signInForPromoCodeText": "You must sign in to an account for codes to take effect.", "signInForPromoCodeText": "You must sign in to an account for codes to take effect.",
"signInWithGameCenterText": "To use a Game Center account,\nsign in with the Game Center app.",
"singleGamePlaylistNameText": "Just ${GAME}", "singleGamePlaylistNameText": "Just ${GAME}",
"singlePlayerCountText": "1 player", "singlePlayerCountText": "1 player",
"soloNameFilterText": "Solo ${NAME}", "soloNameFilterText": "Solo ${NAME}",
@ -1365,6 +1368,8 @@
"storeText": "Store", "storeText": "Store",
"submitText": "Submit", "submitText": "Submit",
"submittingPromoCodeText": "Submitting Code...", "submittingPromoCodeText": "Submitting Code...",
"successText": "Success!",
"supportEmailText": "If you are experiencing any problems with the\napp, please email ${EMAIL}.",
"teamNamesColorText": "Team Names/Colors...", "teamNamesColorText": "Team Names/Colors...",
"telnetAccessGrantedText": "Telnet access enabled.", "telnetAccessGrantedText": "Telnet access enabled.",
"telnetAccessText": "Telnet access detected; allow?", "telnetAccessText": "Telnet access detected; allow?",
@ -1818,6 +1823,7 @@
"unlockThisInTheStoreText": "This must be unlocked in the store.", "unlockThisInTheStoreText": "This must be unlocked in the store.",
"unlockThisProfilesText": "To create more than ${NUM} profiles, you need:", "unlockThisProfilesText": "To create more than ${NUM} profiles, you need:",
"unlockThisText": "To unlock this, you need:", "unlockThisText": "To unlock this, you need:",
"unsupportedControllerText": "Sorry, controller \"${NAME}\" is not supported.",
"unsupportedHardwareText": "Sorry, this hardware is not supported by this build of the game.", "unsupportedHardwareText": "Sorry, this hardware is not supported by this build of the game.",
"upFirstText": "Up first:", "upFirstText": "Up first:",
"upNextText": "Up next in game ${COUNT}:", "upNextText": "Up next in game ${COUNT}:",
@ -1829,6 +1835,7 @@
"usingItunesText": "Using Music App for soundtrack...", "usingItunesText": "Using Music App for soundtrack...",
"v2AccountLinkingInfoText": "To link V2 accounts, use the 'Manage Account' button.", "v2AccountLinkingInfoText": "To link V2 accounts, use the 'Manage Account' button.",
"validatingTestBuildText": "Validating Test Build...", "validatingTestBuildText": "Validating Test Build...",
"viaText": "via",
"victoryText": "Victory!", "victoryText": "Victory!",
"voteDelayText": "You can't start another vote for ${NUMBER} seconds", "voteDelayText": "You can't start another vote for ${NUMBER} seconds",
"voteInProgressText": "A vote is already in progress.", "voteInProgressText": "A vote is already in progress.",

View file

@ -1,76 +1,77 @@
{ {
"accountSettingsWindow": { "accountSettingsWindow": {
"accountNameRules": "Marapat na ang pangalan ng account na iyon ay walang mga special characters o mga emoji", "accountNameRules": "Hindi pwede ang pangalan na may emoji o mga ibang special characters",
"accountsText": "Mga Account", "accountsText": "Mga Manlalaro",
"achievementProgressText": "Mga Nakamtan: ${COUNT} sa ${TOTAL}", "achievementProgressText": "Mga Nakamtan: ${COUNT} sa ${TOTAL}",
"campaignProgressText": "Ang Progreso sa Laro [Mahirap]: ${PROGRESS}", "campaignProgressText": "Ang Progreso sa Campgain [Mahirap]: ${PROGRESS}",
"changeOncePerSeason": "Mapapalit mo lang ito isa-isa kada season", "changeOncePerSeason": "Mapapalit mo lang ito isang beses kada season",
"changeOncePerSeasonError": "Kailangan mo muna maghintay ng susunod na season para mapalitan ito. (${NUM} araw)", "changeOncePerSeasonError": "Kailangan mo muna maghintay ng susunod na panahon para mapalitan ito. (${NUM} araw)",
"customName": "Custom na Pangalan", "customName": "Kahit-anong Pangalan",
"googlePlayGamesAccountSwitchText": "Kung gusto mong gamitin ang iba ninyong Google Account,\nGumamit ka ng Google Play Games app upang maipalit.", "googlePlayGamesAccountSwitchText": "Kung gusto mong gamitin ang iba ninyong Google Account, \nkailangan mo gamitin ang Google Play Games app upang maipalit ito.",
"linkAccountsEnterCodeText": "Ilagay ang Code", "linkAccountsEnterCodeText": "Ilagay ang Kowd",
"linkAccountsGenerateCodeText": "Gumawa ng Code", "linkAccountsGenerateCodeText": "Gumawa ng Kowd",
"linkAccountsInfoText": "(ibahagi ang pag-usad sa iba't ibang platform)", "linkAccountsInfoText": "(ibahagi ang pag-usad sa ibang mga platform)",
"linkAccountsInstructionsNewText": "Para maiugnay ang dalawang accounts, gumawa ka ng code sa una at ilagay \nyung code sa pangalawa. Data na galing sa pangalawang account ay \nmaibabahagi sa dalawa.\n(Data na nasa unang account ay mawawala)\n\nMaari kang magugnay ng hangang ${COUNT} accounts.\n\nIMPORTANTE: Iugnay lamang ang iyong mga accounts, \ndahil kapag iuugnay mo sa kaibigan mo ang iyong \naccount,hindi kayo makakapaglaro ng sabay.", "linkAccountsInstructionsNewText": "Para maiugnay ang dalawang accounts, gumawa ka ng kowd sa una at ilagay \nyung kowd sa pangalawa. Data na galing sa pangalawang account ay \nmaibabahagi sa dalawa.\n(Data na nasa unang account ay mawawala)\n\nMaari kang mag link ng hangang ${COUNT} accounts.\n\nIMPORTANTE: Iugnay lamang ang iyong mga accounts, \ndahil kapag iuugnay mo sa kaibigan mo ang iyong \naccount,hindi kayo makakapaglaro ng sabay.",
"linkAccountsInstructionsText": "Para mag-ugnay ng dalawang account, gumawa ng code\nsa isa at ilagay ang code na iyon sa kabila.\nAng iyong pag-usad at imbentaryo ay pagsasamahin.\nMaaari mong i-ugnay hanggang sa ${COUNT} accounts.\n\nBabala lang; hindi na ito maibabalik!", "linkAccountsInstructionsText": "Para mag-ugnay ng dalawang account, gumawa ng code\nsa isa at ilagay ang code na iyon sa kabila.\nAng iyong pag-usad at imbentaryo ay pagsasamahin.\nMaaari mong i-ugnay hanggang sa ${COUNT} accounts.\n\nBabala lang; hindi na ito maibabalik!",
"linkAccountsText": "Iugnay ang mga Account", "linkAccountsText": "Ilink ang mga Account",
"linkedAccountsText": "Naka-ugnay na mga Account", "linkedAccountsText": "Naka-link na mga Account",
"manageAccountText": "I-Manage ang Account", "manageAccountText": "I-Pamahalaan ang Account",
"nameChangeConfirm": "Baguhin ang pangalan ng iyong account sa ${NAME}?", "nameChangeConfirm": "Ipalitan ang pangalan ng iyong account sa ${NAME}?",
"resetProgressConfirmNoAchievementsText": "Ibabalik nito sa dati ang iyong pag-usad,\nat lokal na mga high-score (pwera sa ticket).\nHindi na ito maibabalik pa. Ipagpatuloy pa rin?", "resetProgressConfirmNoAchievementsText": "Ibabalik nito sa dati ang iyong pag-usad,\nat lokal na mga high-score (pwera sa mga ticket).\nHindi na ito maibabalik. Ipagpatuloy pa rin?",
"resetProgressConfirmText": "Ibabalik nito sa dati ang iyong pag-usad,\nmga nakamtan, at lokal na mga high-score\n(pwera sa ticket). Hindi na ito maibabalik\npa. Ipagpatuloy pa rin?", "resetProgressConfirmText": "Ibabalik nito sa dati ang iyong pag-usad,\nmga nakamtan, at lokal na mga high-score\n(pwera sa mga ticket). Hindi na ito maibabalik\nulit. Ipagpatuloy pa rin?",
"resetProgressText": "I-reset ang Progreso", "resetProgressText": "I-reset ang Progreso",
"setAccountName": "I-set ang Account name", "setAccountName": "I-set ang pangngalan ng Account",
"setAccountNameDesc": "Piliin ang pangalan na ipapakita para sa iyong account.\nMaaari mong gamitin ang pangalan mula sa isa sa iyong mga naka-link \nna account o lumikha ng isang natatanging pasadyang pangalan.", "setAccountNameDesc": "Piliin ang pangalan na ipapakita para sa iyong account.\nMaaari mong gamitin ang pangalan mula sa isa sa iyong mga naka-link \nna account o lumikha ng isang natatanging pasadyang pangalan.",
"signInInfoText": "Magsign-in para kumolekta ng mga ticket, makipagkompetensya online,\nat makabahagi ng pag-usad sa iba't ibang mga device.", "signInInfoText": "Pumasok o gumawa nang account para kumolekta ng mga ticket, makipagkompetensya online,\nat makabahagi ng pag-usad sa iba't ibang mga device.",
"signInText": "Mag-sign in", "signInText": "Pumasok sa account",
"signInWithDeviceInfoText": "(isang automatic account na magagamit lamang sa device na ito)", "signInWithDeviceInfoText": "(automatic account na magagamit lamang sa device na ito)",
"signInWithDeviceText": "Mag-sign in gamit ang device", "signInWithDeviceText": "Pumasok gamit ang device account",
"signInWithGameCircleText": "Magsign-in gamit ang Game Circle", "signInWithGameCircleText": "Pumasok sa account gamit ang Game Circle",
"signInWithGooglePlayText": "Magsign-in gamit ang Google Play", "signInWithGooglePlayText": "Pumasok sa account gamit ang Google Play",
"signInWithTestAccountInfoText": "(uri ng legacy account; gamitin ang mga account ng device na pasulong)", "signInWithTestAccountInfoText": "(uri ng legacy account; gamitin ang mga account ng device na pasulong)",
"signInWithTestAccountText": "Magsign in gamit ang test account", "signInWithTestAccountText": "Pumasok gamit ang test account",
"signInWithV2InfoText": "(ang account na gumagana sa lahat na platforms)", "signInWithText": "Mag sign in gamit ang ${SERVICE}",
"signInWithV2Text": "Mag sign in gamit ang BombSquad account", "signInWithV2InfoText": "(ang account na gumagana sa lahat ng platforms)",
"signOutText": "Mag-sign out", "signInWithV2Text": "Pumasok gamit ang BombSquad account",
"signingInText": "Nagsasign-in...", "signOutText": "Umalis",
"signingOutText": "Nagsasign-out...", "signingInText": "Pumapasok sa account...",
"signingOutText": "Umaalis sa account...",
"ticketsText": "Mga ticket: ${COUNT}", "ticketsText": "Mga ticket: ${COUNT}",
"titleText": "Account", "titleText": "Manlalaro",
"unlinkAccountsInstructionsText": "Pumili ng account na i-uunlink", "unlinkAccountsInstructionsText": "Pumili ng manlalaro na i-uunlink",
"unlinkAccountsText": "I-unlink ang mga accounts", "unlinkAccountsText": "I-unlink ang mga manlalaro",
"unlinkLegacyV1AccountsText": "I-unlink ang mga Legacy (V1) Account", "unlinkLegacyV1AccountsText": "I-unlink ang mga Legacy (V1) na mga Account",
"v2LinkInstructionsText": "Gamitin ang link na ito para gumawa ng account o mag sign in.", "v2LinkInstructionsText": "Gamitin ang link na ito para gumawa ng account o pumasok sa account.",
"viaAccount": "(sa pamamagitan ng account ${NAME})", "viaAccount": "(sa pamamagitan ng manlalaro ${NAME})",
"youAreSignedInAsText": "Nakasign-in ka bilang:" "youAreSignedInAsText": "Nakasign-in ka bilang si:"
}, },
"achievementChallengesText": "Mga nakamit", "achievementChallengesText": "Mga nakamit na",
"achievementText": "Mga Nakamtan", "achievementText": "Mga Nakamtan",
"achievements": { "achievements": {
"Boom Goes the Dynamite": { "Boom Goes the Dynamite": {
"description": "Mapasabog ang 3 kalaban gamit ang TNT", "description": "Magpasabog nang TNT para mamatay ang 3 na salbahe",
"descriptionComplete": "Napasabog ang 3 kalaban gamit ang TNT", "descriptionComplete": "Napasabog ang 3 salbahe gamit ang TNT",
"descriptionFull": "Mapasabog ang 3 kalaban gamit ang TNT sa ${LEVEL}", "descriptionFull": "Ipasabog and 3 salbahe gamit ang TNT ${LEVEL}",
"descriptionFullComplete": "Napasabog ang 3 kalabangamit ang TNT sa ${LEVEL}", "descriptionFullComplete": "Napasabog ang 3 kalaban gamit ang TNT sa ${LEVEL}",
"name": "Sabog ang Sabi ng Dinamita" "name": "Sabog ang Sabi ng Dinamita"
}, },
"Boxer": { "Boxer": {
"description": "Manalo sa laro ng hindi gumagamit ng bomba", "description": "Manalo sa laro ng hindi gumagamit ng mga bomba",
"descriptionComplete": "Nanalo sa laro ng hindi gumagamit ng bomba", "descriptionComplete": "Manalo sa laro ng hindi gumagamit ng bomba",
"descriptionFull": "Tapusin ang ${LEVEL} na walang gamit na bomba", "descriptionFull": "Tapusin ang ${LEVEL} habang hindi gumagamit nang bomba",
"descriptionFullComplete": "Natapos ang ${LEVEL} na himdi gumagamit ng bomba", "descriptionFullComplete": "Natapos ang ${LEVEL} habang hindi gumagamit nang bomba",
"name": "Boksingero" "name": "Boksingero"
}, },
"Dual Wielding": { "Dual Wielding": {
"descriptionFull": "Ikonekta ang 2 controllers (hardware o app)", "descriptionFull": "Ikonekta ang dalawang mga controllers (hardware o app)",
"descriptionFullComplete": "Konektado ang 2 controllers (hardware o app)", "descriptionFullComplete": "Nakonektado na ang 2 controllers (hardware o app)",
"name": "Dalawang Nangalaro" "name": "Dalawang Manlalaro"
}, },
"Flawless Victory": { "Flawless Victory": {
"description": "Manalo nang hindi natatamaan", "description": "Manalo nang hindi natatamaan ng kalaban",
"descriptionComplete": "Nanalo nang hindi natamaan", "descriptionComplete": "Nanalo nang hindi natamaan ng kalaban",
"descriptionFull": "Manalo sa ${LEVEL} nang hindi makakakuha ng hit", "descriptionFull": "Manalo sa ${LEVEL} nang hindi matatamaan",
"descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi nakakakuha ng hit", "descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi natatamaan",
"name": "Di Mintis Na Pagtagumpay" "name": "Di Mintis Na Pagtagumpay"
}, },
"Free Loader": { "Free Loader": {
@ -283,7 +284,7 @@
"name": "Manlalaro Ng Koponan" "name": "Manlalaro Ng Koponan"
}, },
"The Great Wall": { "The Great Wall": {
"description": "Itigil ang bawat kalaban", "description": "Patayin ang lahat ng salbahe",
"descriptionComplete": "Pinigilan ang bawat kalaban", "descriptionComplete": "Pinigilan ang bawat kalaban",
"descriptionFull": "Itigil ang bawat kalaban sa ${LEVEL}", "descriptionFull": "Itigil ang bawat kalaban sa ${LEVEL}",
"descriptionFullComplete": "Pinigilan ang bawat kalaban sa ${LEVEL}", "descriptionFullComplete": "Pinigilan ang bawat kalaban sa ${LEVEL}",
@ -363,10 +364,11 @@
"cancelText": "Kanselahin", "cancelText": "Kanselahin",
"cantConfigureDeviceText": "Pasensya na, ang ${DEVICE} na ito ay hindi ma-configure.", "cantConfigureDeviceText": "Pasensya na, ang ${DEVICE} na ito ay hindi ma-configure.",
"challengeEndedText": "Natapos na ang challenge na ito.", "challengeEndedText": "Natapos na ang challenge na ito.",
"chatMuteText": "I-mute ang Chat", "chatMuteText": "Tahimikin Ang Chat Mo",
"chatMutedText": "Na-mute ang Chat", "chatMutedText": "Na-mute ang Chat",
"chatUnMuteText": "I-unmute ang Chat", "chatUnMuteText": "I-unmute ang Chat",
"choosingPlayerText": "<pumipili ng manlalaro>", "choosingPlayerText": "<pumipili ng manlalaro>",
"codesExplainText": "Binigay ng developer ang mga codes \npara i-diagnose at i-tama ang mga issues sa account.",
"completeThisLevelToProceedText": "I complete mo muna\nang level na ito bago ka mag-proceed!", "completeThisLevelToProceedText": "I complete mo muna\nang level na ito bago ka mag-proceed!",
"completionBonusText": "Bonus sa Pagkumpleto nito:", "completionBonusText": "Bonus sa Pagkumpleto nito:",
"configControllersWindow": { "configControllersWindow": {
@ -386,16 +388,16 @@
"titleText": "I-configure ang mga Controller" "titleText": "I-configure ang mga Controller"
}, },
"configGamepadWindow": { "configGamepadWindow": {
"advancedText": "Advanced", "advancedText": "Mga Iba Pa",
"advancedTitleText": "Advanced na Setup ng Controller", "advancedTitleText": "Iba Pang Setup ng Controller",
"analogStickDeadZoneDescriptionText": "(itaas ito kapag ang iyong karakter ay nag d-drift kapag binitawan mo ang stick)", "analogStickDeadZoneDescriptionText": "(itaas ito kapag ang iyong karakter ay nag d-drift kapag binitawan mo ang stick)",
"analogStickDeadZoneText": "Analog Stick Dead Zone", "analogStickDeadZoneText": "Analog Stick Dead Zone",
"appliesToAllText": "(nalalapat sa lahat ng controller ng ganitong uri)", "appliesToAllText": "(nalalapat sa lahat ng controller ng ganitong uri)",
"autoRecalibrateDescriptionText": "(paganahin ito kung ang iyong karakter ay hindi gumagalaw ng buong bilis)", "autoRecalibrateDescriptionText": "(paganahin ito kung ang iyong karakter ay hindi gumagalaw ng buong bilis)",
"autoRecalibrateText": "Auto-Recalibrate Analog Stick", "autoRecalibrateText": "Auto-Recalibrate Analog Stick",
"axisText": "aksis", "axisText": "aksis",
"clearText": "alisin", "clearText": "i-bura",
"dpadText": "dpad", "dpadText": "DPAD",
"extraStartButtonText": "Extra na Start Button", "extraStartButtonText": "Extra na Start Button",
"ifNothingHappensTryAnalogText": "Kapag walang gumagana, i-try na i-assign sa analog stick.", "ifNothingHappensTryAnalogText": "Kapag walang gumagana, i-try na i-assign sa analog stick.",
"ifNothingHappensTryDpadText": "Kapag hindi gumana, i-try na i-assign sa d-pad.", "ifNothingHappensTryDpadText": "Kapag hindi gumana, i-try na i-assign sa d-pad.",
@ -447,11 +449,13 @@
"swipeText": "mag-swipe", "swipeText": "mag-swipe",
"titleText": "I-configure ang Touchscreen" "titleText": "I-configure ang Touchscreen"
}, },
"configureDeviceInSystemSettingsText": "Ang ${DEVICE} ay pwede ma-configure sa System Settings app.",
"configureItNowText": "I-configure ngayon?", "configureItNowText": "I-configure ngayon?",
"configureText": "Configure", "configureText": "Configure",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
"amazonText": "Amazon Appstore", "amazonText": "Amazon Appstore",
"appStoreText": "App Store", "appStoreText": "App Store",
"bestResultsScale": 0.6,
"bestResultsText": "Para sa pinakamahusay na mga resulta, kakailanganin mo ng isang lag-free na wifi network. Kaya mo\nbawasan ang wifi lag sa pamamagitan ng pag-off ng iba pang mga wireless na device, sa pamamagitan ng\nnaglalaro malapit sa iyong wifi router, at sa pamamagitan ng pagkonekta sa\ndirektang host ng laro sa network sa pamamagitan ng ethernet.", "bestResultsText": "Para sa pinakamahusay na mga resulta, kakailanganin mo ng isang lag-free na wifi network. Kaya mo\nbawasan ang wifi lag sa pamamagitan ng pag-off ng iba pang mga wireless na device, sa pamamagitan ng\nnaglalaro malapit sa iyong wifi router, at sa pamamagitan ng pagkonekta sa\ndirektang host ng laro sa network sa pamamagitan ng ethernet.",
"explanationText": "Para gumamit ng smart-phone o tablet bilang wireless controller,\ni-install ang \"${REMOTE_APP_NAME}\" na app dito. Anumang bilang ng mga device\nmaaaring kumonekta sa isang larong ${APP_NAME} sa Wi-Fi, at libre ito!", "explanationText": "Para gumamit ng smart-phone o tablet bilang wireless controller,\ni-install ang \"${REMOTE_APP_NAME}\" na app dito. Anumang bilang ng mga device\nmaaaring kumonekta sa isang larong ${APP_NAME} sa Wi-Fi, at libre ito!",
"forAndroidText": "para sa Andriod:", "forAndroidText": "para sa Andriod:",
@ -495,7 +499,7 @@
"skipWaitText": "Lagktawang Paghintay", "skipWaitText": "Lagktawang Paghintay",
"timeRemainingText": "Natitirang Oras", "timeRemainingText": "Natitirang Oras",
"toRankedText": "Sagad Sa Ranggo", "toRankedText": "Sagad Sa Ranggo",
"totalText": "kabuuan", "totalText": "kabuuhan",
"tournamentInfoText": "Makipagkumpitensya para sa matataas na marka sa\nibang mga manlalaro sa iyong liga.\n\nAng mga premyo ay iginagawad sa pinakamataas na iskor\nmga manlalaro kapag nag-expire ang oras ng tournament.", "tournamentInfoText": "Makipagkumpitensya para sa matataas na marka sa\nibang mga manlalaro sa iyong liga.\n\nAng mga premyo ay iginagawad sa pinakamataas na iskor\nmga manlalaro kapag nag-expire ang oras ng tournament.",
"welcome1Text": "Maligayang pagdating sa ${LEAGUE}. Maaari mong pagbutihin ang iyong\nranggo ng liga sa pamamagitan ng pagkamit ng mga star rating, pagkumpleto\nmga tagumpay, at panalong tropeo sa mga paligsahan.", "welcome1Text": "Maligayang pagdating sa ${LEAGUE}. Maaari mong pagbutihin ang iyong\nranggo ng liga sa pamamagitan ng pagkamit ng mga star rating, pagkumpleto\nmga tagumpay, at panalong tropeo sa mga paligsahan.",
"welcome2Text": "Maaari ka ring makakuha ng mga tiket mula sa marami sa parehong mga aktibidad.\nMaaaring gamitin ang mga tiket para i-unlock ang mga bagong character, mapa, at\nmini-games, para makapasok sa mga tournament, at higit pa.", "welcome2Text": "Maaari ka ring makakuha ng mga tiket mula sa marami sa parehong mga aktibidad.\nMaaaring gamitin ang mga tiket para i-unlock ang mga bagong character, mapa, at\nmini-games, para makapasok sa mga tournament, at higit pa.",
@ -541,7 +545,7 @@
"stressTestRoundDurationText": "Pagtagal Ng Round", "stressTestRoundDurationText": "Pagtagal Ng Round",
"stressTestTitleText": "Stress Test", "stressTestTitleText": "Stress Test",
"titleText": "Benchmarks at Stress Test", "titleText": "Benchmarks at Stress Test",
"totalReloadTimeText": "Kabuuang reload time: ${TIME} (tingnan Ang log para sa mga detalye)" "totalReloadTimeText": "Kabuuhang reload time: ${TIME} (tingnan Ang log para sa mga detalye)"
}, },
"defaultGameListNameText": "Default ${PLAYMODE} Playlist", "defaultGameListNameText": "Default ${PLAYMODE} Playlist",
"defaultNewGameListNameText": "Ang aking ${PLAYMODE} Playlist", "defaultNewGameListNameText": "Ang aking ${PLAYMODE} Playlist",
@ -560,9 +564,11 @@
"disableXInputDescriptionText": "Pumayag ng higit sa 4 na controllers ngunit maaaring hindi mabuti ang kalagay", "disableXInputDescriptionText": "Pumayag ng higit sa 4 na controllers ngunit maaaring hindi mabuti ang kalagay",
"disableXInputText": "Disable XInput", "disableXInputText": "Disable XInput",
"disabledText": "Naka-disabled", "disabledText": "Naka-disabled",
"discordFriendsText": "Gusto mong may kalaro kang mga tao na gusto mo?\nSumali sa aming Discord server at hanapin mo ang kaibiganin mo!",
"discordJoinText": "Sumali sa Discord",
"doneText": "Tapos", "doneText": "Tapos",
"drawText": "Patas", "drawText": "Patas",
"duplicateText": "I-duplicate", "duplicateText": "Duplikaduhin",
"editGameListWindow": { "editGameListWindow": {
"addGameText": "Idagdag na\nLaro", "addGameText": "Idagdag na\nLaro",
"cantOverwriteDefaultText": "Hindi ma-overwrite ang default playlist!", "cantOverwriteDefaultText": "Hindi ma-overwrite ang default playlist!",
@ -687,16 +693,16 @@
"aboutText": "Tungkulin", "aboutText": "Tungkulin",
"addressFetchErrorText": "<error sa pagkuha ng mga address>", "addressFetchErrorText": "<error sa pagkuha ng mga address>",
"appInviteMessageText": "Pinadalhan ka ni ${NAME} ng ${COUNT} ticket sa ${APP_NAME}", "appInviteMessageText": "Pinadalhan ka ni ${NAME} ng ${COUNT} ticket sa ${APP_NAME}",
"appInviteSendACodeText": "Mag-send ka sa Kanila ng Code", "appInviteSendACodeText": "Mag-Sent Ka Ng Kowd Sa Kanila",
"appInviteTitleText": "${APP_NAME} App Invite", "appInviteTitleText": "${APP_NAME} App Invite",
"bluetoothAndroidSupportText": "(gumagana sa anumang Android device na mayroong Bluetooth)", "bluetoothAndroidSupportText": "(gumagana sa anumang Android device na mayroong Bluetooth)",
"bluetoothDescriptionText": "Mag-host/sumali sa isang party sa pamamagitan ng Bluetooth:", "bluetoothDescriptionText": "Mag-host/sumali sa isang party sa pamamagitan ng Bluetooth:",
"bluetoothHostText": "Mag-host gamit ang Bluetooth", "bluetoothHostText": "Mag-host gamit ang Bluetooth",
"bluetoothJoinText": "Sumali gamit ang Bluetooth", "bluetoothJoinText": "Sumali gamit ang Bluetooth",
"bluetoothText": "Bluetooth", "bluetoothText": "Bluetooth",
"checkingText": "nag-checking…", "checkingText": "sinusuri...",
"copyCodeConfirmText": "Nakopya ang code sa clipboard.", "copyCodeConfirmText": "Nakopya na ang kowd sa clipboard.",
"copyCodeText": "I-kopya ang Code", "copyCodeText": "Kopyahin ang kowd",
"dedicatedServerInfoText": "Para sa pinakamahusay na mga resulta, mag-set up ng nakalaang server. Tingnan ang bombsquadgame.com/server para malaman kung paano.", "dedicatedServerInfoText": "Para sa pinakamahusay na mga resulta, mag-set up ng nakalaang server. Tingnan ang bombsquadgame.com/server para malaman kung paano.",
"disconnectClientsText": "Ididiskonekta nito ang ${COUNT} (mga) manlalaro\nsa iyong party. Sigurado ka ba?", "disconnectClientsText": "Ididiskonekta nito ang ${COUNT} (mga) manlalaro\nsa iyong party. Sigurado ka ba?",
"earnTicketsForRecommendingAmountText": "Makakatanggap ang mga kaibigan ng ${COUNT} na tiket kung susubukan nila ang laro\n(at makakatanggap ka ng ${YOU_COUNT} para sa bawat gagawa)", "earnTicketsForRecommendingAmountText": "Makakatanggap ang mga kaibigan ng ${COUNT} na tiket kung susubukan nila ang laro\n(at makakatanggap ka ng ${YOU_COUNT} para sa bawat gagawa)",
@ -709,12 +715,12 @@
"freeCloudServerNotAvailableText": "Walang available na libreng cloud server.", "freeCloudServerNotAvailableText": "Walang available na libreng cloud server.",
"friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} na mga tiket mula sa ${NAME}", "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} na mga tiket mula sa ${NAME}",
"friendPromoCodeAwardText": "Makakatanggap ka ng ${COUNT} na tiket sa tuwing ito ay gagamitin.", "friendPromoCodeAwardText": "Makakatanggap ka ng ${COUNT} na tiket sa tuwing ito ay gagamitin.",
"friendPromoCodeExpireText": "Mag-e-expire ang code sa loob ng ${EXPIRE_HOURS} na oras at gagana lang para sa mga bagong manlalaro.", "friendPromoCodeExpireText": "E-expire ang kowd sa loob ng ${EXPIRE_HOURS} na oras at gagana lang para sa mga bagong manlalaro.",
"friendPromoCodeInstructionsText": "Upang gamitin ito, buksan ang ${APP_NAME} at pumunta sa \"Mga Setting->Advanced->Ilagay ang Code\".\nTingnan ang bombsquadgame.com para sa mga link sa pag-download para sa lahat ng sinusuportahang platform.", "friendPromoCodeInstructionsText": "Upang gamitin ito, buksan ang ${APP_NAME} at pumunta sa \"Mga Setting->Mga Iba Pa->Ilagay ang Kowd\".\nTingnan ang bombsquadgame.com para sa mga link sa pag-download para sa lahat ng sinusuportahang platform.",
"friendPromoCodeRedeemLongText": "Maaari itong ma-redem ng ${COUNT} na libreng tiket ng hanggang ${MAX_USES} na tao.", "friendPromoCodeRedeemLongText": "Maaari itong ma-redem ng ${COUNT} na libreng tiket ng hanggang ${MAX_USES} na tao.",
"friendPromoCodeRedeemShortText": "Maaari itong ma-redem ng ${COUNT} na tiket sa larong ito.", "friendPromoCodeRedeemShortText": "Maaari itong ma-redem ng ${COUNT} na tiket sa larong ito.",
"friendPromoCodeWhereToEnterText": "(sa \"Settings->Advanced->Ilagay Ang Code\")", "friendPromoCodeWhereToEnterText": "(sa \"Settings->Mga Iba Pa->Ilagay Ang Kowd\")",
"getFriendInviteCodeText": "Kumuha ng imbitasyon ng code ng kaibigan", "getFriendInviteCodeText": "Kumuha ng imbitasyon ng kowd ng kaibigan",
"googlePlayDescriptionText": "Mag-imbita ng mga manlalaro ng Google Play sa iyong party:", "googlePlayDescriptionText": "Mag-imbita ng mga manlalaro ng Google Play sa iyong party:",
"googlePlayInviteText": "Mag-imbita", "googlePlayInviteText": "Mag-imbita",
"googlePlayReInviteText": "Mayroong ${COUNT} (mga) Google Play na manlalaro sa iyong party \nna madidiskonekta kung magsisimula ka ng bagong imbitasyon.\nIsama sila sa bagong imbitasyon para maibalik mo sila.", "googlePlayReInviteText": "Mayroong ${COUNT} (mga) Google Play na manlalaro sa iyong party \nna madidiskonekta kung magsisimula ka ng bagong imbitasyon.\nIsama sila sa bagong imbitasyon para maibalik mo sila.",
@ -746,11 +752,11 @@
"nearbyText": "Malapit", "nearbyText": "Malapit",
"noConnectionText": "<walang koneksyon>", "noConnectionText": "<walang koneksyon>",
"otherVersionsText": "<iba pang mga bersyon>", "otherVersionsText": "<iba pang mga bersyon>",
"partyCodeText": "Code ng Partido", "partyCodeText": "Kowd ng Partido",
"partyInviteAcceptText": "Tanggapin", "partyInviteAcceptText": "Tanggapin",
"partyInviteDeclineText": "Tanggihan", "partyInviteDeclineText": "Tanggihan",
"partyInviteGooglePlayExtraText": "(tingnan ang 'Google Play' tab sa 'Sumama' window)", "partyInviteGooglePlayExtraText": "(tingnan ang 'Google Play' tab sa 'Sumama' window)",
"partyInviteIgnoreText": "Ignorahin", "partyInviteIgnoreText": "Pabayaan",
"partyInviteText": "Inimbitahan ka ni ${NAME} \nna sumali sa kanilang party", "partyInviteText": "Inimbitahan ka ni ${NAME} \nna sumali sa kanilang party",
"partyNameText": "Pangalan Ng Partido", "partyNameText": "Pangalan Ng Partido",
"partyServerRunningText": "Tumatakbo ang iyong party server.", "partyServerRunningText": "Tumatakbo ang iyong party server.",
@ -768,7 +774,7 @@
"privateText": "Pribado", "privateText": "Pribado",
"publicHostRouterConfigText": "Maaaring mangailangan nito ng pag-configure ng port-forwarding sa iyong router. Para sa mas madaling opsyon, mag-host ng pribadong party.", "publicHostRouterConfigText": "Maaaring mangailangan nito ng pag-configure ng port-forwarding sa iyong router. Para sa mas madaling opsyon, mag-host ng pribadong party.",
"publicText": "Publiko", "publicText": "Publiko",
"requestingAPromoCodeText": "Humihiling ng code...", "requestingAPromoCodeText": "Humihiling ng kowd...",
"sendDirectInvitesText": "I-send ng direktang imbitasyon", "sendDirectInvitesText": "I-send ng direktang imbitasyon",
"shareThisCodeWithFriendsText": "Ibahagi ang code na ito sa iyong mga kaibigan:", "shareThisCodeWithFriendsText": "Ibahagi ang code na ito sa iyong mga kaibigan:",
"showMyAddressText": "Ipakita Ang Address Ko", "showMyAddressText": "Ipakita Ang Address Ko",
@ -816,10 +822,12 @@
"alwaysText": "Palagi", "alwaysText": "Palagi",
"fullScreenCmdText": "Fullscreen (Cmd-F)", "fullScreenCmdText": "Fullscreen (Cmd-F)",
"fullScreenCtrlText": "Fullscreen (Ctrl-F)", "fullScreenCtrlText": "Fullscreen (Ctrl-F)",
"fullScreenText": "Fullscreen",
"gammaText": "Gama", "gammaText": "Gama",
"highText": "Mataas", "highText": "Mataas",
"higherText": "Napakataas", "higherText": "Napakataas",
"lowText": "Mababa", "lowText": "Mababa",
"maxFPSText": "Pinakamataas na FPS",
"mediumText": "Katamtaman", "mediumText": "Katamtaman",
"neverText": "Wala", "neverText": "Wala",
"resolutionText": "Resolusyon", "resolutionText": "Resolusyon",
@ -857,22 +865,23 @@
"powerupIceBombsDescriptionText": "Mas mahina kaysa sa mga normal na bomba\nngunit nagyelo ang iyong mga kalaban\nat partikular na mabasag.", "powerupIceBombsDescriptionText": "Mas mahina kaysa sa mga normal na bomba\nngunit nagyelo ang iyong mga kalaban\nat partikular na mabasag.",
"powerupIceBombsNameText": "Bombang-Yelo", "powerupIceBombsNameText": "Bombang-Yelo",
"powerupImpactBombsDescriptionText": "Medyo mahina kaysa sa regular\nbomba, ngunit sumasabog ito kapag nabagsak.", "powerupImpactBombsDescriptionText": "Medyo mahina kaysa sa regular\nbomba, ngunit sumasabog ito kapag nabagsak.",
"powerupImpactBombsNameText": "Gatilyong-Bomba", "powerupImpactBombsNameText": "Bombang-Gatilyo",
"powerupLandMinesDescriptionText": "Ang mga ito ay dumating sa mga pakete ng 3;\nKapaki-pakinabang para sa base defense o\npaghinto ng mabilis na mga kalaban.", "powerupLandMinesDescriptionText": "Ang mga ito ay dumating sa mga pakete ng 3;\nKapaki-pakinabang para sa base defense o\npaghinto ng mga mabibilis na kalaban.",
"powerupLandMinesNameText": "Mina", "powerupLandMinesNameText": "Mina",
"powerupPunchDescriptionText": "Ang iyong mga suntok ay mas mahirap,\nmas mabilis, mas mahusay, at mas malakas.", "powerupPunchDescriptionText": "Ang iyong mga suntok ay mas mahirap,\nmas mabilis, mas mahusay, at mas malakas.",
"powerupPunchNameText": "Boxing-Gloves", "powerupPunchNameText": "Boxing-Gloves",
"powerupShieldDescriptionText": "Pumigil na pagsakit\nkaya hindi mo kailangan.", "powerupShieldDescriptionText": "Pumigil na pagsakit\nkaya hindi mo kailangan.",
"powerupShieldNameText": "Enrhiyang-Kalasag", "powerupShieldNameText": "Enrhiyang-Kalasag",
"powerupStickyBombsDescriptionText": "Dumikit sa anumang matamaan nila.\nItoy naging pagtawanan.", "powerupStickyBombsDescriptionText": "Dumikit sa anumang matamaan nila.\nItoy naging pagtawanan.",
"powerupStickyBombsNameText": "Malagkit-Bomba", "powerupStickyBombsNameText": "Bombang-Malagkit",
"powerupsSubtitleText": "Siyempre, walang larong kumpleto pag walang powerups:", "powerupsSubtitleText": "Siyempre, 'di kumpleto ang laro kapag walang mga powerups:",
"powerupsText": "Powerups", "powerupsText": "Powerups",
"punchInfoText": "- Suntok -\nAng mga suntok ay mas nakakasakit\nmas mabilis ang paggalaw ng iyong mga kamay, kaya\ntumakbo at umiikot na parang baliw.", "punchInfoText": "- Suntok -\nAng mga suntok ay mas nakakasakit\nmas mabilis ang paggalaw ng iyong mga kamay, kaya\ntumakbo at umiikot na parang baliw.",
"runInfoText": "- Takbo -\nPindutin ang ANY button para tumakbo. Ang mga trigger o mga button sa balikat ay gumagana nang maayos kung mayroon ka ng mga ito.\nAng pagtakbo ay nagpapabilis sa iyo ng mga lugar ngunit nahihirapan kang lumiko, kaya mag-ingat sa mga bangin.", "punchInfoTextScale": 0.4,
"runInfoText": "- Takbo -\nPindutin ang KAHIT ANUMANG button para tumakbo. Ang mga trigger o mga gilid na button ay gumagana nang maayos kung mayroon ka ng mga ito.\nAng pagtakbo ay nagpapabilis sa iyo ng mga lugar ngunit nahihirapan kang lumiko, kaya mag-ingat sa mga bangin.",
"someDaysText": "May mga araw na parang gusto mong sumuntok ng kung ano. O nagpapasabog ng isang bagay.", "someDaysText": "May mga araw na parang gusto mong sumuntok ng kung ano. O nagpapasabog ng isang bagay.",
"titleText": "Tulong ng ${APP_NAME}", "titleText": "Tulong ng ${APP_NAME}",
"toGetTheMostText": "Upang masulit ang larong ito, kakailanganin mo:", "toGetTheMostText": "Upang masulit ang larong ito, kakailanganin mo ng:",
"welcomeText": "Maligayang Pagdating sa ${APP_NAME}" "welcomeText": "Maligayang Pagdating sa ${APP_NAME}"
}, },
"holdAnyButtonText": "<hawakan ang anumang pindutan>", "holdAnyButtonText": "<hawakan ang anumang pindutan>",
@ -961,7 +970,7 @@
"kickVoteText": "Bumoto sa Pagki-kick", "kickVoteText": "Bumoto sa Pagki-kick",
"kickVotingDisabledText": "Naka-disable ang kick voting.", "kickVotingDisabledText": "Naka-disable ang kick voting.",
"kickWithChatText": "I-type ang ${YES} sa chat para sa oo at ${NO} para sa hindi.", "kickWithChatText": "I-type ang ${YES} sa chat para sa oo at ${NO} para sa hindi.",
"killsTallyText": "${COUNT} ang pinatay", "killsTallyText": "${COUNT} pinatay",
"killsText": "Pinatay", "killsText": "Pinatay",
"kioskWindow": { "kioskWindow": {
"easyText": "Madali", "easyText": "Madali",
@ -1022,7 +1031,7 @@
"resumeText": "Ipatuloy", "resumeText": "Ipatuloy",
"settingsText": "Mga Setting" "settingsText": "Mga Setting"
}, },
"makeItSoText": "Gawin itong Kaya", "makeItSoText": "Gawin mo syang parag ganyan",
"mapSelectGetMoreMapsText": "Kumuha ng Higit pang Mapa...", "mapSelectGetMoreMapsText": "Kumuha ng Higit pang Mapa...",
"mapSelectText": "Pumili…", "mapSelectText": "Pumili…",
"mapSelectTitleText": "Mapa ng ${GAME}", "mapSelectTitleText": "Mapa ng ${GAME}",
@ -1041,9 +1050,9 @@
"multiKillText": "${COUNT}-PAGPATAY!!!", "multiKillText": "${COUNT}-PAGPATAY!!!",
"multiPlayerCountText": "${COUNT} na manlalaro", "multiPlayerCountText": "${COUNT} na manlalaro",
"mustInviteFriendsText": "Tandaan: dapat kang mag-imbita ng mga kaibigan\nang panel na \"${GATHER}\" o i-attach\nmga controller para maglaro ng multiplayer.", "mustInviteFriendsText": "Tandaan: dapat kang mag-imbita ng mga kaibigan\nang panel na \"${GATHER}\" o i-attach\nmga controller para maglaro ng multiplayer.",
"nameBetrayedText": "${VICTIM} ay pinagtaksilan ni ${NAME}.", "nameBetrayedText": "Pinagtaksilan ni ${NAME} si ${VICTIM}",
"nameDiedText": "${NAME} ay namatay.", "nameDiedText": "${NAME} ay namatay.",
"nameKilledText": "${VICTIM} ay pinatay ni ${NAME}.", "nameKilledText": "Pinatay ni ${NAME} si ${VICTIM}",
"nameNotEmptyText": "Hindi pwede ang walang pangalan!", "nameNotEmptyText": "Hindi pwede ang walang pangalan!",
"nameScoresText": "${NAME} Naka-score!", "nameScoresText": "${NAME} Naka-score!",
"nameSuicideKidFriendlyText": "Hindi sinasadyang namatay si ${NAME}.", "nameSuicideKidFriendlyText": "Hindi sinasadyang namatay si ${NAME}.",
@ -1061,6 +1070,7 @@
"noExternalStorageErrorText": "Walang nakitang external na storage sa device na ito", "noExternalStorageErrorText": "Walang nakitang external na storage sa device na ito",
"noGameCircleText": "Error: hindi naka-log in sa GameCircle", "noGameCircleText": "Error: hindi naka-log in sa GameCircle",
"noScoresYetText": "Wala pang score.", "noScoresYetText": "Wala pang score.",
"noServersFoundText": "Walang nahanap na servers.",
"noThanksText": "Salamat Nalang", "noThanksText": "Salamat Nalang",
"noTournamentsInTestBuildText": "BABALA: Babalewalain ang mga score sa tournament mula sa test build na ito.", "noTournamentsInTestBuildText": "BABALA: Babalewalain ang mga score sa tournament mula sa test build na ito.",
"noValidMapsErrorText": "Walang nakitang valid na mapa para sa ganitong uri ng laro.", "noValidMapsErrorText": "Walang nakitang valid na mapa para sa ganitong uri ng laro.",
@ -1107,10 +1117,10 @@
"twoToEightPlayersText": "2-8 na manlalaro" "twoToEightPlayersText": "2-8 na manlalaro"
}, },
"playerCountAbbreviatedText": "${COUNT}p", "playerCountAbbreviatedText": "${COUNT}p",
"playerDelayedJoinText": "Papasok si ${PLAYER} sa simula ng susunod na round.", "playerDelayedJoinText": "Papasok si ${PLAYER} sa simula ng susunod na laro.",
"playerInfoText": "Impormasyon ng Manlalaro", "playerInfoText": "Impormasyon ng Manlalaro",
"playerLeftText": "Umalis si ${PLAYER} sa laro.", "playerLeftText": "Umalis si ${PLAYER} sa laro.",
"playerLimitReachedText": "Naabot na ang limitasyon ng manlalaro na ${COUNT}; hindi pinapayagan ang mga ibang sumali.", "playerLimitReachedText": "Naabot na ang limitasyon ng manlalaro na ${COUNT}; hindi pinapayagan ang mga ibang manlalaro sumali.",
"playerProfilesWindow": { "playerProfilesWindow": {
"cantDeleteAccountProfileText": "Hindi mo matatanggal ang profile ng iyong account.", "cantDeleteAccountProfileText": "Hindi mo matatanggal ang profile ng iyong account.",
"deleteButtonText": "Itangal ang\nProfile", "deleteButtonText": "Itangal ang\nProfile",
@ -1129,14 +1139,14 @@
"pleaseWaitText": "Hintay lang…", "pleaseWaitText": "Hintay lang…",
"pluginClassLoadErrorText": "Error sa paglo-load ang '${PLUGIN}' na klaseng plugin : ${ERROR}", "pluginClassLoadErrorText": "Error sa paglo-load ang '${PLUGIN}' na klaseng plugin : ${ERROR}",
"pluginInitErrorText": "Error sa pagsisimula ang '${PLUGIN}' na plugin: ${ERROR}", "pluginInitErrorText": "Error sa pagsisimula ang '${PLUGIN}' na plugin: ${ERROR}",
"pluginSettingsText": "Settings ng mga Plugins", "pluginSettingsText": "Settings ng mga Plugin",
"pluginsAutoEnableNewText": "Paganahin ang Bagong Plugins", "pluginsAutoEnableNewText": "Paganahin ang Bagong Plugins",
"pluginsDetectedText": "May nakitang bagong (mga) plugin. I-restart para i-activate ang mga ito, o i-configure ang mga ito sa mga setting.", "pluginsDetectedText": "May nakitang bagong (mga) plugin. I-restart para i-activate ang mga ito, o i-configure ang mga ito sa mga setting.",
"pluginsDisableAllText": "Di-Paganahin ang mga Plugins", "pluginsDisableAllText": "Salantahin ang mga Plugin",
"pluginsEnableAllText": "Paganahin Lahat ng mga Plugins", "pluginsEnableAllText": "Paganahin Lahat ng mga Plugin",
"pluginsRemovedText": "Hindi na nahanapan ang ${NUM} ng (mga) plugin.", "pluginsRemovedText": "Hindi na nahanapan ang ${NUM} ng (mga) plugin.",
"pluginsText": "Mga Plugin", "pluginsText": "Mga Plugin",
"practiceText": "Pagsasagawa", "practiceText": "Sanayan",
"pressAnyButtonPlayAgainText": "Pindutin ang anumang button para maglaro muli...", "pressAnyButtonPlayAgainText": "Pindutin ang anumang button para maglaro muli...",
"pressAnyButtonText": "Pindutin ang anumang button para magpatuloy...", "pressAnyButtonText": "Pindutin ang anumang button para magpatuloy...",
"pressAnyButtonToJoinText": "pindutin ang anumang button para sumali...", "pressAnyButtonToJoinText": "pindutin ang anumang button para sumali...",
@ -1152,7 +1162,7 @@
"codeText": "Code", "codeText": "Code",
"enterText": "I-enter" "enterText": "I-enter"
}, },
"promoSubmitErrorText": "Error sa pagsusumite ng code; suriin ang iyong koneksyon ng internet", "promoSubmitErrorText": "Error sa pagsusumite ng kowd; suriin ang iyong koneksyon sa internet",
"ps3ControllersWindow": { "ps3ControllersWindow": {
"macInstructionsText": "I-off ang power sa likod ng iyong PS3, siguraduhin\nNaka-enable ang Bluetooth sa iyong Mac, pagkatapos ay ikonekta ang iyong controller\nsa iyong Mac sa pamamagitan ng USB cable upang ipares ang dalawa. Mula noon, ikaw\nmaaaring gamitin ang home button ng controller para ikonekta ito sa iyong Mac\nsa alinman sa wired (USB) o wireless (Bluetooth) mode.\n\nSa ilang mga Mac maaari kang ma-prompt para sa isang passcode kapag nagpapares.\nKung mangyari ito, tingnan ang sumusunod na tutorial o google para sa tulong.\n\n\n\n\nDapat lumabas sa device ang mga PS3 controller na nakakonekta nang wireless\nlistahan sa System Preferences->Bluetooth. Maaaring kailanganin mong alisin ang mga ito\nmula sa listahang iyon kapag gusto mong gamitin muli ang mga ito sa iyong PS3.\n\nTiyakin din na idiskonekta ang mga ito sa Bluetooth kapag hindi naka-in\ngamitin o ang kanilang mga baterya ay patuloy na mauubos.\n\nDapat hawakan ng Bluetooth ang hanggang 7 konektadong device,\nkahit na ang iyong mileage ay maaaring mag-iba.", "macInstructionsText": "I-off ang power sa likod ng iyong PS3, siguraduhin\nNaka-enable ang Bluetooth sa iyong Mac, pagkatapos ay ikonekta ang iyong controller\nsa iyong Mac sa pamamagitan ng USB cable upang ipares ang dalawa. Mula noon, ikaw\nmaaaring gamitin ang home button ng controller para ikonekta ito sa iyong Mac\nsa alinman sa wired (USB) o wireless (Bluetooth) mode.\n\nSa ilang mga Mac maaari kang ma-prompt para sa isang passcode kapag nagpapares.\nKung mangyari ito, tingnan ang sumusunod na tutorial o google para sa tulong.\n\n\n\n\nDapat lumabas sa device ang mga PS3 controller na nakakonekta nang wireless\nlistahan sa System Preferences->Bluetooth. Maaaring kailanganin mong alisin ang mga ito\nmula sa listahang iyon kapag gusto mong gamitin muli ang mga ito sa iyong PS3.\n\nTiyakin din na idiskonekta ang mga ito sa Bluetooth kapag hindi naka-in\ngamitin o ang kanilang mga baterya ay patuloy na mauubos.\n\nDapat hawakan ng Bluetooth ang hanggang 7 konektadong device,\nkahit na ang iyong mileage ay maaaring mag-iba.",
"ouyaInstructionsText": "Para gumamit ng PS3 controller sa iyong OUYA, ikonekta lang ito gamit ang USB cable\nisang beses upang ipares ito. Ang paggawa nito ay maaaring madiskonekta ang iyong iba pang mga controller, kaya\ndapat mong i-restart ang iyong OUYA at i-unplug ang USB cable.\n\nMula noon, magagamit mo na ang HOME button ng controller para\nikonekta ito nang wireless. Kapag tapos ka nang maglaro, pindutin nang matagal ang HOME button\npara sa 10 segundo upang i-off ang controller; kung hindi, maaari itong manatili sa\nat mga basurang baterya.", "ouyaInstructionsText": "Para gumamit ng PS3 controller sa iyong OUYA, ikonekta lang ito gamit ang USB cable\nisang beses upang ipares ito. Ang paggawa nito ay maaaring madiskonekta ang iyong iba pang mga controller, kaya\ndapat mong i-restart ang iyong OUYA at i-unplug ang USB cable.\n\nMula noon, magagamit mo na ang HOME button ng controller para\nikonekta ito nang wireless. Kapag tapos ka nang maglaro, pindutin nang matagal ang HOME button\npara sa 10 segundo upang i-off ang controller; kung hindi, maaari itong manatili sa\nat mga basurang baterya.",
@ -1207,24 +1217,24 @@
"renameText": "I-palitan", "renameText": "I-palitan",
"replayEndText": "Itigil Ang Replay", "replayEndText": "Itigil Ang Replay",
"replayNameDefaultText": "Replay ng Huling Laro", "replayNameDefaultText": "Replay ng Huling Laro",
"replayReadErrorText": "Error sa pagbabasa ng replay file.", "replayReadErrorText": "May kamalian sa pagbabasa ng replay file.",
"replayRenameWarningText": "Palitan ang pangalan ng \"${REPLAY}\" pagkatapos ng isang laro kung gusto mong panatilihin ito; kung hindi, ito ay mapapatungan.", "replayRenameWarningText": "Palitan ang pangalan ng \"${REPLAY}\" pagkatapos ng isang laro kung gusto mong panatilihin ito; kung hindi, ito ay mapapatungan.",
"replayVersionErrorText": "Pasensya na, ginawa ang replay na ito sa ibang paraang\nbersyon ng laro at hindi magagamit.", "replayVersionErrorText": "Pasensya na, ginawa ang replay na ito sa ibang paraang\nbersyon ng laro at hindi magagamit.",
"replayWatchText": "Panoorin ang replay", "replayWatchText": "Panoorin ang replay",
"replayWriteErrorText": "Error sa pagsulat ng replay file.", "replayWriteErrorText": "May kamalian sa pagsulat ng replay file.",
"replaysText": "Mga Replay", "replaysText": "Mga Replay",
"reportPlayerExplanationText": "Gamitin ang email na ito upang mag-ulat ng pagdaya, hindi naaangkop na pananalita, o iba pang masamang gawin.\nPakilarawan sa ibaba:", "reportPlayerExplanationText": "Gamitin ang email na ito upang mag-ulat ng pagdaya, hindi naaangkop na pananalita, o iba pang masamang gawin.\nPakilarawan sa ibaba:",
"reportThisPlayerCheatingText": "Pagdaya", "reportThisPlayerCheatingText": "Dumadaya",
"reportThisPlayerLanguageText": "Hindi Angkop na Salita", "reportThisPlayerLanguageText": "Hindi Angkop na Salita",
"reportThisPlayerReasonText": "Ano ang gusto mong iulat?", "reportThisPlayerReasonText": "Ano ang gusto mong iulat?",
"reportThisPlayerText": "Iulat ang Manlalaro na Ito", "reportThisPlayerText": "Iulat ang Manlalaro na Ito",
"requestingText": "Humihiling", "requestingText": "Humihiling...",
"restartText": "I-restart", "restartText": "Umulit",
"retryText": "I-retry", "retryText": "Ulitin",
"revertText": "Ibalik", "revertText": "Ibalik",
"runText": "Takbo", "runText": "Tumakbo",
"saveText": "I-save", "saveText": "I-save",
"scanScriptsErrorText": "(Mga) error sa pag-scan ng mga script; Tignan ang log para sa mga detalye.", "scanScriptsErrorText": "(Mga) kamalian sa pag-scan ng mga script; Tignan ang log para sa mga detalye.",
"scanScriptsMultipleModulesNeedUpdatesText": "Kailangan maibago para sa API ${API} ang ${PATH} at mga ${NUM} na iba pang modules.", "scanScriptsMultipleModulesNeedUpdatesText": "Kailangan maibago para sa API ${API} ang ${PATH} at mga ${NUM} na iba pang modules.",
"scanScriptsSingleModuleNeedsUpdatesText": "Kailangan maibago para sa api ${API} ang ${PATH}.", "scanScriptsSingleModuleNeedsUpdatesText": "Kailangan maibago para sa api ${API} ang ${PATH}.",
"scoreChallengesText": "Mga Hamon sa Iskor", "scoreChallengesText": "Mga Hamon sa Iskor",
@ -1236,14 +1246,14 @@
"secondsText": "Segundo" "secondsText": "Segundo"
}, },
"scoreWasText": "(ay nasa ${COUNT})", "scoreWasText": "(ay nasa ${COUNT})",
"selectText": "Piliin", "selectText": "Pilihin",
"seriesWinLine1PlayerText": "ANG NANALO SA", "seriesWinLine1PlayerText": "ANG NANALO SA",
"seriesWinLine1TeamText": "ANG NANALO SA", "seriesWinLine1TeamText": "ANG NANALO SA",
"seriesWinLine1Text": "ANG NANALO SA", "seriesWinLine1Text": "ANG NANALO SA",
"seriesWinLine2Text": "SERYE!", "seriesWinLine2Text": "SERYENG NITO!",
"settingsWindow": { "settingsWindow": {
"accountText": "Account", "accountText": "Account",
"advancedText": "Advanced", "advancedText": "Mga Iba Pa",
"audioText": "Audio", "audioText": "Audio",
"controllersText": "Mga Controller", "controllersText": "Mga Controller",
"graphicsText": "Grapika", "graphicsText": "Grapika",
@ -1263,13 +1273,14 @@
"forTestingText": "Tandaan: ang mga value na ito ay para lamang sa pagsubok at mawawala kapag lumabas ang app.", "forTestingText": "Tandaan: ang mga value na ito ay para lamang sa pagsubok at mawawala kapag lumabas ang app.",
"helpTranslateText": "Ang mga pagsasalin na hindi Ingles ng ${APP_NAME} ay isang komunidad\nsuportadong pagsisikap. Kung gusto mong mag-ambag o magtama\nisang pagsasalin, sundan ang link sa ibaba. Salamat!", "helpTranslateText": "Ang mga pagsasalin na hindi Ingles ng ${APP_NAME} ay isang komunidad\nsuportadong pagsisikap. Kung gusto mong mag-ambag o magtama\nisang pagsasalin, sundan ang link sa ibaba. Salamat!",
"kickIdlePlayersText": "I-kick Ang Mga Idle na Manlalaro", "kickIdlePlayersText": "I-kick Ang Mga Idle na Manlalaro",
"kidFriendlyModeText": "Kid-Friendly Mode (binawasan ang karahasan, atbp)", "kidFriendlyModeText": "Pambata na Mode (binawasan ang karahasan, atbp)",
"languageText": "Wika", "languageText": "Wika",
"moddingGuideText": "Gabay sa Modding", "moddingGuideText": "Gabay sa Modding",
"mustRestartText": "Dapat mong i-restart ang laro para magka-epekto ito.", "mustRestartText": "Dapat mong i-restart ang laro para magka-epekto ito.",
"netTestingText": "Pagsusuri ng Network", "netTestingText": "Pagsusuri ng Network",
"resetText": "I-reset", "resetText": "I-reset",
"showBombTrajectoriesText": "Ipakita ang Mga Trajectory ng Bomba", "showBombTrajectoriesText": "Ipakita ang Mga Trajectory ng Bomba",
"showDevConsoleButtonText": "Ipakita ang Dev Console Button",
"showInGamePingText": "Ipakita ang In-Game Ping", "showInGamePingText": "Ipakita ang In-Game Ping",
"showPlayerNamesText": "Ipakita ang Mga Pangalan ng Manlalaro", "showPlayerNamesText": "Ipakita ang Mga Pangalan ng Manlalaro",
"showUserModsText": "Ipakita ang Mods Folder", "showUserModsText": "Ipakita ang Mods Folder",
@ -1294,7 +1305,7 @@
"CharSelect": "Pagpili ng Karakter", "CharSelect": "Pagpili ng Karakter",
"Chosen One": "Napili ng Isa", "Chosen One": "Napili ng Isa",
"Epic": "Larong Epic na Mode", "Epic": "Larong Epic na Mode",
"Epic Race": "Epic na Takbuan", "Epic Race": "Epic na Takbuhan",
"FlagCatcher": "Kunin ang Bandila", "FlagCatcher": "Kunin ang Bandila",
"Flying": "Masayang Isip", "Flying": "Masayang Isip",
"Football": "Rugbi", "Football": "Rugbi",
@ -1305,7 +1316,7 @@
"Marching": "Bantayan", "Marching": "Bantayan",
"Menu": "Pangunahing Menu", "Menu": "Pangunahing Menu",
"Onslaught": "Pagsalakay", "Onslaught": "Pagsalakay",
"Race": "Takbuan", "Race": "Takbuhan",
"Scary": "Hari Ng Burol", "Scary": "Hari Ng Burol",
"Scores": "Screen Ng Iskor", "Scores": "Screen Ng Iskor",
"Survival": "Kaligtasan", "Survival": "Kaligtasan",
@ -1333,7 +1344,7 @@
"loadingText": "Saglit lang…", "loadingText": "Saglit lang…",
"mapsText": "Mga Mapa", "mapsText": "Mga Mapa",
"miniGamesText": "Mga MiniGames", "miniGamesText": "Mga MiniGames",
"oneTimeOnlyText": "(isang beses lamang)", "oneTimeOnlyText": "(isang beses lang)",
"purchaseAlreadyInProgressText": "Ang isang nabilhin ng item na ito ay isinasagawa na.", "purchaseAlreadyInProgressText": "Ang isang nabilhin ng item na ito ay isinasagawa na.",
"purchaseConfirmText": "Ibili ang ${ITEM}?", "purchaseConfirmText": "Ibili ang ${ITEM}?",
"purchaseNotValidError": "Hindi wasto ang nabilhin.\nMakipag-ugnayan kay ${EMAIL} kung ito ay isang error.", "purchaseNotValidError": "Hindi wasto ang nabilhin.\nMakipag-ugnayan kay ${EMAIL} kung ito ay isang error.",
@ -1361,6 +1372,8 @@
"storeText": "Tindahan", "storeText": "Tindahan",
"submitText": "Ipasa", "submitText": "Ipasa",
"submittingPromoCodeText": "Nagsusumite ng Code...", "submittingPromoCodeText": "Nagsusumite ng Code...",
"successText": "Wakas!",
"supportEmailText": "Pag may problema sa app, \npaki-email ang ${EMAIL}.",
"teamNamesColorText": "Mga Pangalan/Kulay ng Team…", "teamNamesColorText": "Mga Pangalan/Kulay ng Team…",
"telnetAccessGrantedText": "Pinagana ang pag-access sa Telnet..", "telnetAccessGrantedText": "Pinagana ang pag-access sa Telnet..",
"telnetAccessText": "Natuklasan ang pag-access sa Telnet; payagan?", "telnetAccessText": "Natuklasan ang pag-access sa Telnet; payagan?",
@ -1370,7 +1383,7 @@
"testBuildValidatedText": "Na-validate ang Test Build; Tamasahin!", "testBuildValidatedText": "Na-validate ang Test Build; Tamasahin!",
"thankYouText": "Salamat sa iyong suporta! Tangkilikin ang laro!!", "thankYouText": "Salamat sa iyong suporta! Tangkilikin ang laro!!",
"threeKillText": "TRIPLENG PAGPATAY!!", "threeKillText": "TRIPLENG PAGPATAY!!",
"timeBonusText": "Bonus Ng Oras", "timeBonusText": "Bonus sa Oras",
"timeElapsedText": "Oras Na Lumipas", "timeElapsedText": "Oras Na Lumipas",
"timeExpiredText": "Nag-expire Na Ang Oras!", "timeExpiredText": "Nag-expire Na Ang Oras!",
"timeSuffixDaysText": "${COUNT}d", "timeSuffixDaysText": "${COUNT}d",
@ -1380,7 +1393,7 @@
"tipText": "Tip", "tipText": "Tip",
"titleText": "BombSquad", "titleText": "BombSquad",
"titleVRText": "BombSquad VR", "titleVRText": "BombSquad VR",
"topFriendsText": "Pangunahing Kaibigan", "topFriendsText": "Pinakamataas na Kaibigan",
"tournamentCheckingStateText": "Sinusuri ang estado ng paligsahan; pakihintay...", "tournamentCheckingStateText": "Sinusuri ang estado ng paligsahan; pakihintay...",
"tournamentEndedText": "Natapos na ang paligsahan na ito. Magsisimula ng bago mamaya.", "tournamentEndedText": "Natapos na ang paligsahan na ito. Magsisimula ng bago mamaya.",
"tournamentEntryText": "Pagpasok sa Paligsahan", "tournamentEntryText": "Pagpasok sa Paligsahan",
@ -1393,12 +1406,12 @@
"translations": { "translations": {
"characterNames": { "characterNames": {
"Agent Johnson": "Ahente Johnson", "Agent Johnson": "Ahente Johnson",
"B-9000": "B-9000", "B-9000": "Makina-9000",
"Bernard": "Oso", "Bernard": "Oso",
"Bones": "Buto", "Bones": "Buto",
"Butch": "Bakero", "Butch": "Bakero",
"Easter Bunny": "Kuneho", "Easter Bunny": "Kuneho",
"Flopsy": "Malambot", "Flopsy": "Magalaw",
"Frosty": "Taong Niyebe", "Frosty": "Taong Niyebe",
"Gretel": "Mag-aawit Na Manananggal", "Gretel": "Mag-aawit Na Manananggal",
"Grumbledorf": "Manggagaway", "Grumbledorf": "Manggagaway",
@ -1414,7 +1427,7 @@
"Sammy Slam": "Mambubuno", "Sammy Slam": "Mambubuno",
"Santa Claus": "Santa Klaus", "Santa Claus": "Santa Klaus",
"Snake Shadow": "Aninong Balatkayo", "Snake Shadow": "Aninong Balatkayo",
"Spaz": "Kawal", "Spaz": "Mandirigma",
"Taobao Mascot": "Taobao Maskot", "Taobao Mascot": "Taobao Maskot",
"Todd McBurton": "Todd McBurton", "Todd McBurton": "Todd McBurton",
"Zoe": "Dalagang Bombero", "Zoe": "Dalagang Bombero",
@ -1430,7 +1443,7 @@
"Pro Football": "Batidong Rugbi", "Pro Football": "Batidong Rugbi",
"Pro Onslaught": "Batidong Pagsalakay", "Pro Onslaught": "Batidong Pagsalakay",
"Pro Runaround": "Batidong Bantayan", "Pro Runaround": "Batidong Bantayan",
"Rookie ${GAME}": "Bagitong ${GAME}", "Rookie ${GAME}": "Pang bago na ${GAME}",
"Rookie Football": "Bagitong Rugbi", "Rookie Football": "Bagitong Rugbi",
"Rookie Onslaught": "Bagitog Pagsalakay", "Rookie Onslaught": "Bagitog Pagsalakay",
"The Last Stand": "Ang Huling Labanan", "The Last Stand": "Ang Huling Labanan",
@ -1446,7 +1459,7 @@
"Carry the flag for a set length of time.": "Hawakan ang bandila para sa isang nakatakdang haba ng oras.", "Carry the flag for a set length of time.": "Hawakan ang bandila para sa isang nakatakdang haba ng oras.",
"Crush ${ARG1} of your enemies.": "Patayin ang ${ARG1} ng iyong mga kalaban", "Crush ${ARG1} of your enemies.": "Patayin ang ${ARG1} ng iyong mga kalaban",
"Defeat all enemies.": "Talunin ang lahat ng iyong mga kalaban", "Defeat all enemies.": "Talunin ang lahat ng iyong mga kalaban",
"Dodge the falling bombs.": "Umiwas sa mga bumabagsak na bomba.", "Dodge the falling bombs.": "Iwasan ang bumabagsak na bomba.",
"Final glorious epic slow motion battle to the death.": "Huling maluwalhating epic slow motion na labanan hanggang kamatayan.", "Final glorious epic slow motion battle to the death.": "Huling maluwalhating epic slow motion na labanan hanggang kamatayan.",
"Gather eggs!": "Ipunin ng mga itlog!", "Gather eggs!": "Ipunin ng mga itlog!",
"Get the flag to the enemy end zone.": "Kunin ang bandila sa end zone ng kalaban.", "Get the flag to the enemy end zone.": "Kunin ang bandila sa end zone ng kalaban.",
@ -1461,7 +1474,7 @@
"Run ${ARG1} laps.": "Tumakbo ng ${ARG1} ikot", "Run ${ARG1} laps.": "Tumakbo ng ${ARG1} ikot",
"Run ${ARG1} laps. Your entire team has to finish.": "Tumakbo ng {ARG1} ikot. Kailangang matapos ang iyong buong team na ito.", "Run ${ARG1} laps. Your entire team has to finish.": "Tumakbo ng {ARG1} ikot. Kailangang matapos ang iyong buong team na ito.",
"Run 1 lap.": "Tumakbo ng 1 ikot.", "Run 1 lap.": "Tumakbo ng 1 ikot.",
"Run 1 lap. Your entire team has to finish.": "Tumakbo ng 1 ikot. Kailangang matapos ang iyong buong team na ito.", "Run 1 lap. Your entire team has to finish.": "Tumakbo ng 1 ikot. Kailangang matapos ang iyong buong grupo.",
"Run real fast!": "Tumakbo ng mabilis!", "Run real fast!": "Tumakbo ng mabilis!",
"Score ${ARG1} goals.": "Makaiskor ng ${ARG1} gol.", "Score ${ARG1} goals.": "Makaiskor ng ${ARG1} gol.",
"Score ${ARG1} touchdowns.": "Makaiskor ng ${ARG1} touchdowns.", "Score ${ARG1} touchdowns.": "Makaiskor ng ${ARG1} touchdowns.",
@ -1480,7 +1493,7 @@
"carry the flag for ${ARG1} seconds": "Hawakan ang bandila ng ${ARG1} segundo", "carry the flag for ${ARG1} seconds": "Hawakan ang bandila ng ${ARG1} segundo",
"kill ${ARG1} enemies": "patayin ang ${ARG1} na mga kalaban.", "kill ${ARG1} enemies": "patayin ang ${ARG1} na mga kalaban.",
"last one standing wins": "kung sino ang huling nakatayo ang siyang mananalo", "last one standing wins": "kung sino ang huling nakatayo ang siyang mananalo",
"last team standing wins": "kung sino ang huling katayuan ng team ang siyang mananalo", "last team standing wins": "ang huling grupo ay mananalo",
"return ${ARG1} flags": "Magnakaw ng ${ARG1} na mga bandera", "return ${ARG1} flags": "Magnakaw ng ${ARG1} na mga bandera",
"return 1 flag": "ibalik ang 1 bandila", "return 1 flag": "ibalik ang 1 bandila",
"run ${ARG1} laps": "Tumakbo ng ${ARG1} ikot", "run ${ARG1} laps": "Tumakbo ng ${ARG1} ikot",
@ -1495,14 +1508,14 @@
"touch 1 flag": "humawak ng 1 bandila" "touch 1 flag": "humawak ng 1 bandila"
}, },
"gameNames": { "gameNames": {
"Assault": "Pag-atake", "Assault": "Pag hawak ng bandila",
"Capture the Flag": "Kunin ang Bandila", "Capture the Flag": "Kunin ang Bandila",
"Chosen One": "Napili ang Isa", "Chosen One": "Napili na Isa",
"Conquest": "Pagsakop", "Conquest": "Pagsakop",
"Death Match": "Laban ng Kamatayan", "Death Match": "Laban ng Kamatayan",
"Easter Egg Hunt": "Paghahanap ng mga Easter Egg", "Easter Egg Hunt": "Paghahanap ng mga Easter Egg",
"Elimination": "Kaligtasan", "Elimination": "Pagbabawas sa away",
"Football": "Rugbi", "Football": "Putbol",
"Hockey": "Hockey", "Hockey": "Hockey",
"Keep Away": "Layuan Mo", "Keep Away": "Layuan Mo",
"King of the Hill": "Hari ng Burol", "King of the Hill": "Hari ng Burol",
@ -1533,7 +1546,7 @@
"Finnish": "Finnish", "Finnish": "Finnish",
"French": "Pranses", "French": "Pranses",
"German": "Aleman", "German": "Aleman",
"Gibberish": "Walang Kwentang Linguahe", "Gibberish": "Hindi Naiitindihan na Linguahe",
"Greek": "Griyego", "Greek": "Griyego",
"Hindi": "Indiyano", "Hindi": "Indiyano",
"Hungarian": "Hanggaryan", "Hungarian": "Hanggaryan",
@ -1571,7 +1584,7 @@
"Crag Castle": "Kastilyong Bangin", "Crag Castle": "Kastilyong Bangin",
"Doom Shroom": "Itim na Kabute", "Doom Shroom": "Itim na Kabute",
"Football Stadium": "Istadyum", "Football Stadium": "Istadyum",
"Happy Thoughts": "Masayang Isip", "Happy Thoughts": "Masayan na mga Isip",
"Hockey Stadium": "Istadyum ng Hockey", "Hockey Stadium": "Istadyum ng Hockey",
"Lake Frigid": "Yelong Lawa", "Lake Frigid": "Yelong Lawa",
"Monkey Face": "Mukha ng Unggoy", "Monkey Face": "Mukha ng Unggoy",
@ -1593,7 +1606,7 @@
"Score": "Iskor", "Score": "Iskor",
"Survived": "Nakaligtas", "Survived": "Nakaligtas",
"Time": "Oras", "Time": "Oras",
"Time Held": "Oras na Gaganapin" "Time Held": "Oras na Nahawak"
}, },
"serverResponses": { "serverResponses": {
"A code has already been used on this account.": "Nagamit na ang isang code sa account na ito.", "A code has already been used on this account.": "Nagamit na ang isang code sa account na ito.",
@ -1675,7 +1688,7 @@
"5 Minutes": "5 minuto", "5 Minutes": "5 minuto",
"8 Seconds": "8 segundo", "8 Seconds": "8 segundo",
"Allow Negative Scores": "Payagan ang Mga Negatibong Iskor", "Allow Negative Scores": "Payagan ang Mga Negatibong Iskor",
"Balance Total Lives": "Balansehin ang Kabuuang Buhay", "Balance Total Lives": "Balansehin ang Kabuuhang Buhay",
"Bomb Spawning": "Paglitaw ng Bomba", "Bomb Spawning": "Paglitaw ng Bomba",
"Chosen One Gets Gloves": "Ang Isa Sa Napili Ay Makukuha Ng Gloves", "Chosen One Gets Gloves": "Ang Isa Sa Napili Ay Makukuha Ng Gloves",
"Chosen One Gets Shield": "Ang Isa Sa Napili Ay Makukuha Ng Kalasag", "Chosen One Gets Shield": "Ang Isa Sa Napili Ay Makukuha Ng Kalasag",
@ -1814,6 +1827,7 @@
"unlockThisInTheStoreText": "Ito ay dapat na naka-unlock sa tindahan.", "unlockThisInTheStoreText": "Ito ay dapat na naka-unlock sa tindahan.",
"unlockThisProfilesText": "Upang lumikha ng higit sa ${NUM} na mga profile, kailangan mo:", "unlockThisProfilesText": "Upang lumikha ng higit sa ${NUM} na mga profile, kailangan mo:",
"unlockThisText": "Upang i-unlock ito, kailangan mo ng:", "unlockThisText": "Upang i-unlock ito, kailangan mo ng:",
"unsupportedControllerText": "Sorry, ang pangalan na \"${NAME}\" ay hindi pa supported.",
"unsupportedHardwareText": "Pasensya na, ang hardware na ito ay hindi suportado ng build na ito ng laro.", "unsupportedHardwareText": "Pasensya na, ang hardware na ito ay hindi suportado ng build na ito ng laro.",
"upFirstText": "Bumangon muna:", "upFirstText": "Bumangon muna:",
"upNextText": "Susunod sa larong ${COUNT}:", "upNextText": "Susunod sa larong ${COUNT}:",
@ -1825,6 +1839,7 @@
"usingItunesText": "Paggamit ng Music App para sa soundtrack...", "usingItunesText": "Paggamit ng Music App para sa soundtrack...",
"v2AccountLinkingInfoText": "Upang ma-link ang mga V2 account mo, dumeretso ka sa “I-Manage ang Account“.", "v2AccountLinkingInfoText": "Upang ma-link ang mga V2 account mo, dumeretso ka sa “I-Manage ang Account“.",
"validatingTestBuildText": "Pinapatunayan ang Test Build...", "validatingTestBuildText": "Pinapatunayan ang Test Build...",
"viaText": "via",
"victoryText": "Panalo!", "victoryText": "Panalo!",
"voteDelayText": "Hindi ka makapagsimula ng bagong botohan sa ${NUMBER} segundo", "voteDelayText": "Hindi ka makapagsimula ng bagong botohan sa ${NUMBER} segundo",
"voteInProgressText": "Ang pagboboto ay isinasagawa na.", "voteInProgressText": "Ang pagboboto ay isinasagawa na.",
@ -1858,7 +1873,7 @@
"wellSureText": "Oo Syempre!", "wellSureText": "Oo Syempre!",
"whatIsThisText": "Ano ito?", "whatIsThisText": "Ano ito?",
"wiimoteLicenseWindow": { "wiimoteLicenseWindow": {
"titleText": "Copyright ni DarwiinRemote" "titleText": "Copyright ng DarwiinRemote"
}, },
"wiimoteListenWindow": { "wiimoteListenWindow": {
"listeningText": "Nakikinig sa Wiimote...", "listeningText": "Nakikinig sa Wiimote...",

View file

@ -32,6 +32,7 @@
"signInWithGooglePlayText": "Connectez-vous avec Google Play", "signInWithGooglePlayText": "Connectez-vous avec Google Play",
"signInWithTestAccountInfoText": "(ancien compte; utilisez les comptes de cet appareil pour les prochaines fois)", "signInWithTestAccountInfoText": "(ancien compte; utilisez les comptes de cet appareil pour les prochaines fois)",
"signInWithTestAccountText": "Connectez-vous avec un compte test", "signInWithTestAccountText": "Connectez-vous avec un compte test",
"signInWithText": "Connectez-vous avec ${SERVICE}",
"signInWithV2InfoText": "(un compte qui fonctionne sur toutes les plateformes)", "signInWithV2InfoText": "(un compte qui fonctionne sur toutes les plateformes)",
"signInWithV2Text": "Connectez-vous avec un compte Bombsquad", "signInWithV2Text": "Connectez-vous avec un compte Bombsquad",
"signOutText": "Se déconnecter", "signOutText": "Se déconnecter",
@ -339,6 +340,7 @@
"getMoreGamesText": "Obtenir plus de jeux...", "getMoreGamesText": "Obtenir plus de jeux...",
"titleText": "Ajouter un Jeu" "titleText": "Ajouter un Jeu"
}, },
"allText": "Tous",
"allowText": "Autoriser", "allowText": "Autoriser",
"alreadySignedInText": "Votre compte est connecté sur un autre appareil;\nveuillez changer de compte ou fermez le jeu sur \nles autres appareils et réessayez.", "alreadySignedInText": "Votre compte est connecté sur un autre appareil;\nveuillez changer de compte ou fermez le jeu sur \nles autres appareils et réessayez.",
"apiVersionErrorText": "Impossible de charger le jeu ${NAME}; sa version api est ${VERSION_USED}; nous demandons la version ${VERSION_REQUIRED}.", "apiVersionErrorText": "Impossible de charger le jeu ${NAME}; sa version api est ${VERSION_USED}; nous demandons la version ${VERSION_REQUIRED}.",
@ -375,6 +377,7 @@
"chatMutedText": "Tchat muet", "chatMutedText": "Tchat muet",
"chatUnMuteText": "Réactiver tchat", "chatUnMuteText": "Réactiver tchat",
"choosingPlayerText": "<choix du joueur>", "choosingPlayerText": "<choix du joueur>",
"codesExplainText": "Les codes sont fournis par le développeur pour \ndiagnostiquer et corriger les problèmes de compte.",
"completeThisLevelToProceedText": "Vous devez compléter ce \nniveau pour continuer!", "completeThisLevelToProceedText": "Vous devez compléter ce \nniveau pour continuer!",
"completionBonusText": "Bonus de fin", "completionBonusText": "Bonus de fin",
"configControllersWindow": { "configControllersWindow": {
@ -458,6 +461,7 @@
"titleText": "Configurer l'Écran Tactile", "titleText": "Configurer l'Écran Tactile",
"touchControlsScaleText": "Taille des boutons tactiles" "touchControlsScaleText": "Taille des boutons tactiles"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} peut être configuré dans Paramètres Système.",
"configureItNowText": "Configurer maintenant?", "configureItNowText": "Configurer maintenant?",
"configureText": "Configurer", "configureText": "Configurer",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -578,6 +582,9 @@
"disableRemoteAppConnectionsText": "Désactiver les connexions d'applications-manettes", "disableRemoteAppConnectionsText": "Désactiver les connexions d'applications-manettes",
"disableXInputDescriptionText": "Permet plus que 4 manettes mais risque de malfonctionner.", "disableXInputDescriptionText": "Permet plus que 4 manettes mais risque de malfonctionner.",
"disableXInputText": "Désactiver XInput", "disableXInputText": "Désactiver XInput",
"disabledText": "Désactivé",
"discordFriendsText": "Vous voulez chercher de nouvelles personnes avec qui jouer ? \nRejoignez notre Discord et trouvez de nouveaux amis !",
"discordJoinText": "Rejoignez le Discord",
"doneText": "Terminé", "doneText": "Terminé",
"drawText": "Égalité", "drawText": "Égalité",
"duplicateText": "Dupliquer", "duplicateText": "Dupliquer",
@ -651,6 +658,7 @@
"useMusicFolderText": "Dossier de Fichiers Musicaux" "useMusicFolderText": "Dossier de Fichiers Musicaux"
}, },
"editText": "Éditer", "editText": "Éditer",
"enabledText": "Activé",
"endText": "Terminé", "endText": "Terminé",
"enjoyText": "Amusez-vous Bien!", "enjoyText": "Amusez-vous Bien!",
"epicDescriptionFilterText": "${DESCRIPTION} Dans un \"slow-motion\" épique.", "epicDescriptionFilterText": "${DESCRIPTION} Dans un \"slow-motion\" épique.",
@ -854,10 +862,12 @@
"alwaysText": "Toujours", "alwaysText": "Toujours",
"fullScreenCmdText": "Plein Écran (Cmd-F)", "fullScreenCmdText": "Plein Écran (Cmd-F)",
"fullScreenCtrlText": "Plein Écran (Ctrl-F)", "fullScreenCtrlText": "Plein Écran (Ctrl-F)",
"fullScreenText": "plein écran",
"gammaText": "Gamma", "gammaText": "Gamma",
"highText": "Élevé", "highText": "Élevé",
"higherText": "Très élevé", "higherText": "Très élevé",
"lowText": "Bas", "lowText": "Bas",
"maxFPSText": "FPS maximum",
"mediumText": "Moyen", "mediumText": "Moyen",
"neverText": "Jamais", "neverText": "Jamais",
"resolutionText": "Résolution", "resolutionText": "Résolution",
@ -1116,6 +1126,7 @@
"noJoinCoopMidwayText": "Vous ne pouvez pas rejoindre une partie co-cop en plein milieu.", "noJoinCoopMidwayText": "Vous ne pouvez pas rejoindre une partie co-cop en plein milieu.",
"noProfilesErrorText": "Vous avez aucun profil de joueur, vous êtes donc coincés avec '${NAME}'.\nAllez à Paramètres->Profils des Joueurs pour vous créer un profil.", "noProfilesErrorText": "Vous avez aucun profil de joueur, vous êtes donc coincés avec '${NAME}'.\nAllez à Paramètres->Profils des Joueurs pour vous créer un profil.",
"noScoresYetText": "Aucun score pour le moment.", "noScoresYetText": "Aucun score pour le moment.",
"noServersFoundText": "Aucun serveur trouvé.",
"noThanksText": "Non Merci", "noThanksText": "Non Merci",
"noTournamentsInTestBuildText": "AVERTISSEMENT: les scores de tournoi de cette version de test seront ignorés.", "noTournamentsInTestBuildText": "AVERTISSEMENT: les scores de tournoi de cette version de test seront ignorés.",
"noValidMapsErrorText": "Aucune carte valide a été trouvée pour ce type de jeu.", "noValidMapsErrorText": "Aucune carte valide a été trouvée pour ce type de jeu.",
@ -1290,6 +1301,8 @@
"runText": "Courir", "runText": "Courir",
"saveText": "Sauvegarder", "saveText": "Sauvegarder",
"scanScriptsErrorText": "Erreur(s) dans les scripts. Consulter le journal pour plus de détails.", "scanScriptsErrorText": "Erreur(s) dans les scripts. Consulter le journal pour plus de détails.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} et ${NUM} autre(s) module(s) doivent être mis à jour pour l'API ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} doit être mis à jour pour l'API ${API}.",
"scoreChallengesText": "Défis de Score", "scoreChallengesText": "Défis de Score",
"scoreListUnavailableText": "Liste des scores indisponible.", "scoreListUnavailableText": "Liste des scores indisponible.",
"scoreText": "Score", "scoreText": "Score",
@ -1335,6 +1348,7 @@
"netTestingText": "Tester Votre Réseau", "netTestingText": "Tester Votre Réseau",
"resetText": "Réinitialiser", "resetText": "Réinitialiser",
"showBombTrajectoriesText": "Montrer les trajectoires de bombe", "showBombTrajectoriesText": "Montrer les trajectoires de bombe",
"showDevConsoleButtonText": "Afficher le Bouton de la Console de Développeur",
"showInGamePingText": "Afficher La Latence En Jeu", "showInGamePingText": "Afficher La Latence En Jeu",
"showPlayerNamesText": "Montrer les Noms des Joueurs", "showPlayerNamesText": "Montrer les Noms des Joueurs",
"showUserModsText": "Montrer le Dossier des Mods", "showUserModsText": "Montrer le Dossier des Mods",
@ -1430,6 +1444,8 @@
"storeText": "Magasin", "storeText": "Magasin",
"submitText": "Soumettre", "submitText": "Soumettre",
"submittingPromoCodeText": "Envoi du code...", "submittingPromoCodeText": "Envoi du code...",
"successText": "Succès!",
"supportEmailText": "Si vous rencontrez des problèmes avec \nl'application, veuillez envoyer un e-mail à ${EMAIL}.",
"teamNamesColorText": "Noms d'équipe/Couleurs...", "teamNamesColorText": "Noms d'équipe/Couleurs...",
"teamsText": "Équipes", "teamsText": "Équipes",
"telnetAccessGrantedText": "L'accès Telnet est activé.", "telnetAccessGrantedText": "L'accès Telnet est activé.",
@ -1911,6 +1927,7 @@
"unlockThisInTheStoreText": "Cela doit être débloqué dans le magasin.", "unlockThisInTheStoreText": "Cela doit être débloqué dans le magasin.",
"unlockThisProfilesText": "Pour créer plus de ${NUM} profiles, vous avez besoin de:", "unlockThisProfilesText": "Pour créer plus de ${NUM} profiles, vous avez besoin de:",
"unlockThisText": "Pour débloquer ceci, vous avez besoin:", "unlockThisText": "Pour débloquer ceci, vous avez besoin:",
"unsupportedControllerText": "Désolé, contrôleur \"${NAME}\" pas pris en charge.",
"unsupportedHardwareText": "Désolé, ce hardware n'est pas supporté par cette version du jeu.", "unsupportedHardwareText": "Désolé, ce hardware n'est pas supporté par cette version du jeu.",
"upFirstText": "En premier:", "upFirstText": "En premier:",
"upNextText": "Le jeu ${COUNT} sera:", "upNextText": "Le jeu ${COUNT} sera:",
@ -1924,6 +1941,7 @@
"v2AccountLinkingInfoText": "Pour lier des comptes V2, utilisez le bouton 'Gérer compte'.", "v2AccountLinkingInfoText": "Pour lier des comptes V2, utilisez le bouton 'Gérer compte'.",
"validatingBetaText": "Validation de la beta...", "validatingBetaText": "Validation de la beta...",
"validatingTestBuildText": "Validation de la Version Test...", "validatingTestBuildText": "Validation de la Version Test...",
"viaText": "via",
"victoryText": "Victoire!", "victoryText": "Victoire!",
"voteDelayText": "Vous ne pouvez commencer un autre vote que dans ${NUMBER} secondes", "voteDelayText": "Vous ne pouvez commencer un autre vote que dans ${NUMBER} secondes",
"voteInProgressText": "Un vote est déjà en cours.", "voteInProgressText": "Un vote est déjà en cours.",

View file

@ -871,6 +871,7 @@
"highText": "Hoch", "highText": "Hoch",
"higherText": "Höher", "higherText": "Höher",
"lowText": "Niedrig", "lowText": "Niedrig",
"maxFPSText": "Max FPS",
"mediumText": "Mittel", "mediumText": "Mittel",
"neverText": "Niemals", "neverText": "Niemals",
"resolutionText": "Auflösung", "resolutionText": "Auflösung",

View file

@ -1,7 +1,7 @@
{ {
"accountRejectedText": "You ac woefije obj acwoew. Aj cowier wore cs?", "accountRejectedText": "You ac woefije obj acwoew. Aj cowier wore cs?",
"accountSettingsWindow": { "accountSettingsWindow": {
"accountNameRules": "Acoief coej. c woejf. cwoef ocoweofwjfj c wjefowfowef wocjowefffz", "accountNameRules": "Acoief coej. \n woejf. cwoef ocoweofwjfj c wjefowfowef wocjowefffz",
"accountProfileText": "(acczntl prfflzlf)", "accountProfileText": "(acczntl prfflzlf)",
"accountsText": "Acctntzz", "accountsText": "Acctntzz",
"achievementProgressText": "Achilfjasdflz: ${COUNT} ouzt of ${TOTAL}", "achievementProgressText": "Achilfjasdflz: ${COUNT} ouzt of ${TOTAL}",
@ -34,6 +34,7 @@
"signInWithGooglePlayText": "Snf ocj weo fGOofl Plfl", "signInWithGooglePlayText": "Snf ocj weo fGOofl Plfl",
"signInWithTestAccountInfoText": "(lgjo cac cojef ot; oeco doic w eofjw oero )", "signInWithTestAccountInfoText": "(lgjo cac cojef ot; oeco doic w eofjw oero )",
"signInWithTestAccountText": "Sjc weo fwtjwoefj cowefwf", "signInWithTestAccountText": "Sjc weo fwtjwoefj cowefwf",
"signInWithText": "Sign fit cweof ${SERVICE}",
"signInWithV2InfoText": "(an zofj c woof woke wo Eire wf ofjjowg)", "signInWithV2InfoText": "(an zofj c woof woke wo Eire wf ofjjowg)",
"signInWithV2Text": "Sngo cow erwoj CBombSOudds acorjds.", "signInWithV2Text": "Sngo cow erwoj CBombSOudds acorjds.",
"signOutText": "Sgngz Ozt", "signOutText": "Sgngz Ozt",
@ -342,6 +343,8 @@
"titleText": "Ádzd Gámzé", "titleText": "Ádzd Gámzé",
"titleTextScale": 1.01 "titleTextScale": 1.01
}, },
"addToFavoritesText": "Add owej owjwffwfwe",
"addedToFavoritesText": "Added '${NAME}' for cow jowdif.",
"allText": "Alcllwerf", "allText": "Alcllwerf",
"allowText": "Alzéow", "allowText": "Alzéow",
"alreadySignedInText": "Yr co wcowief woeijo wife ewf;\norc woeful oj ceofjwoejfowief\nocjwoef weofwocijweofw.", "alreadySignedInText": "Yr co wcowief woeijo wife ewf;\norc woeful oj ceofjwoejfowief\nocjwoef weofwocijweofw.",
@ -378,6 +381,7 @@
"chatMutedText": "Chad mamba", "chatMutedText": "Chad mamba",
"chatUnMuteText": "Unobiaje Chafb", "chatUnMuteText": "Unobiaje Chafb",
"choosingPlayerText": "<chflzf plzlflr>", "choosingPlayerText": "<chflzf plzlflr>",
"codesExplainText": "Cody wc woeir wcpwep oijwoeifj\nwoe wefjwe ofiwjeocijwoerer.",
"completeThisLevelToProceedText": "Yóz múst cómplítz\nthís lével tú próceed!", "completeThisLevelToProceedText": "Yóz múst cómplítz\nthís lével tú próceed!",
"completionBonusText": "Cúmplezión Búnís", "completionBonusText": "Cúmplezión Búnís",
"configControllersWindow": { "configControllersWindow": {
@ -467,6 +471,7 @@
"titleText": "Cónfígúre Tóuchszreen", "titleText": "Cónfígúre Tóuchszreen",
"touchControlsScaleText": "Tóuch Cóntróls Scále" "touchControlsScaleText": "Tóuch Cóntróls Scále"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} otic w ejowei fajowe cjwoei woeirj dfwf.",
"configureItNowText": "Cónfígzre ít nów?", "configureItNowText": "Cónfígzre ít nów?",
"configureText": "Cónfúgzre", "configureText": "Cónfúgzre",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -591,6 +596,8 @@
"disableXInputDescriptionText": "Allow mor wow ejo4 cow oeicjwo cobu oaf woejfowie jowrj", "disableXInputDescriptionText": "Allow mor wow ejo4 cow oeicjwo cobu oaf woejfowie jowrj",
"disableXInputText": "Dio cow eofwije", "disableXInputText": "Dio cow eofwije",
"disabledText": "Dfewfczfwef", "disabledText": "Dfewfczfwef",
"discordFriendsText": "Weor owe fwjeowi cow fowijfowjdfdf?\nJJowjef c jewel dODIj c jdjfosijfdfs!",
"discordJoinText": "JWeoj wc c wwdofijsd",
"doneText": "Dónz", "doneText": "Dónz",
"drawText": "Drawz", "drawText": "Drawz",
"duplicateText": "DSFcoiwjef", "duplicateText": "DSFcoiwjef",
@ -790,6 +797,7 @@
"manualYourLocalAddressText": "Yrrz lcl addratrz:", "manualYourLocalAddressText": "Yrrz lcl addratrz:",
"nearbyText": "Woiwjefd", "nearbyText": "Woiwjefd",
"noConnectionText": "<nz cnnectars>", "noConnectionText": "<nz cnnectars>",
"noPartiesAddedText": "Not cower wo cowdj fwd",
"otherVersionsText": "(otco verosfjso)", "otherVersionsText": "(otco verosfjso)",
"partyCodeText": "Prewjr Cdfew", "partyCodeText": "Prewjr Cdfew",
"partyInviteAcceptText": "Acczlfp", "partyInviteAcceptText": "Acczlfp",
@ -873,10 +881,12 @@
"autoText": "Aúto", "autoText": "Aúto",
"fullScreenCmdText": "Fúllézreen (Cmd-F)", "fullScreenCmdText": "Fúllézreen (Cmd-F)",
"fullScreenCtrlText": "Fúlzcréen (Ctrl-F)", "fullScreenCtrlText": "Fúlzcréen (Ctrl-F)",
"fullScreenText": "Ffjoefzlefw",
"gammaText": "Gámza", "gammaText": "Gámza",
"highText": "Hígh", "highText": "Hígh",
"higherText": "Híghrz", "higherText": "Híghrz",
"lowText": "Lózw", "lowText": "Lózw",
"maxFPSText": "Mxf cWEf",
"mediumText": "Mzdíum", "mediumText": "Mzdíum",
"neverText": "Névzer", "neverText": "Névzer",
"resolutionText": "Résólution", "resolutionText": "Résólution",
@ -1142,8 +1152,10 @@
"noExternalStorageErrorText": "Nz xtenrlf stlfsdf fnff onf thz dfvfojfzz", "noExternalStorageErrorText": "Nz xtenrlf stlfsdf fnff onf thz dfvfojfzz",
"noGameCircleText": "Errór: nút lúggzd íntó Góme Cúrclz", "noGameCircleText": "Errór: nút lúggzd íntó Góme Cúrclz",
"noJoinCoopMidwayText": "Có-óp gúmzs cán't bz jóinzd mídwáy.", "noJoinCoopMidwayText": "Có-óp gúmzs cán't bz jóinzd mídwáy.",
"noPluginsInstalledText": "No Plugiwue sowiej fwdf",
"noProfilesErrorText": "Yoú hávz nó pláyerz prófilzs, só yóu're stzck wíth '${NAME}'.\nGó tz Sétzings->Pláyerz Prófiles tú mzke yóurszlf á prófile.", "noProfilesErrorText": "Yoú hávz nó pláyerz prófilzs, só yóu're stzck wíth '${NAME}'.\nGó tz Sétzings->Pláyerz Prófiles tú mzke yóurszlf á prófile.",
"noScoresYetText": "Nz scrrlz ytz.", "noScoresYetText": "Nz scrrlz ytz.",
"noServersFoundText": "Neo c who wj wo eij.",
"noThanksText": "Nó Thánkz", "noThanksText": "Nó Thánkz",
"noTournamentsInTestBuildText": "WOREwr: WOTo cwoefw coif wefiidfjdf cow ekfwoejowijerwdifwdf.", "noTournamentsInTestBuildText": "WOREwr: WOTo cwoefw coif wefiidfjdf cow ekfwoejowijerwdifwdf.",
"noValidMapsErrorText": "Nó válíd máps fóund fúr thzs gáme typz.", "noValidMapsErrorText": "Nó válíd máps fóund fúr thzs gáme typz.",
@ -1373,6 +1385,7 @@
"netTestingText": "Ntwkrz Tsstcg", "netTestingText": "Ntwkrz Tsstcg",
"resetText": "Rsttz", "resetText": "Rsttz",
"showBombTrajectoriesText": "Shzlz Bomf Tfwoejcwoefz", "showBombTrajectoriesText": "Shzlz Bomf Tfwoejcwoefz",
"showDevConsoleButtonText": "Sho c weroiw c wo cwoije fwois",
"showInGamePingText": "Shoe o co fowl Png", "showInGamePingText": "Shoe o co fowl Png",
"showPlayerNamesText": "SHzlfjl Plzlrr Nmzlzlls", "showPlayerNamesText": "SHzlfjl Plzlrr Nmzlzlls",
"showUserModsText": "Shzl Mdsz Fldlrz", "showUserModsText": "Shzl Mdsz Fldlrz",
@ -1468,6 +1481,8 @@
"storeText": "Stzlrle", "storeText": "Stzlrle",
"submitText": "Scowiejfwef", "submitText": "Scowiejfwef",
"submittingPromoCodeText": "Subjfoif Cdssz...", "submittingPromoCodeText": "Subjfoif Cdssz...",
"successText": "Sensded!",
"supportEmailText": "IF wc weoif joweij c woeifjowiejorwer\nc who we fweofiwjefo ${EMAIL}.",
"teamNamesColorText": "Tmcoj Conor/ Coarle...", "teamNamesColorText": "Tmcoj Conor/ Coarle...",
"teamsText": "Tééáémés", "teamsText": "Tééáémés",
"telnetAccessGrantedText": "Tzélnt acczzss énazledz.", "telnetAccessGrantedText": "Tzélnt acczzss énazledz.",
@ -1653,21 +1668,21 @@
"ChineseTraditional": "Cheifwoefjw Trwwefsdfs", "ChineseTraditional": "Cheifwoefjw Trwwefsdfs",
"Croatian": "Crrlzlrrs", "Croatian": "Crrlzlrrs",
"Czech": "Czffef", "Czech": "Czffef",
"Danish": "Dnishsdl", "Danish": "Dnailöş",
"Dutch": "Dtchjdflz", "Dutch": "Dtchjdflz",
"English": "Englfjlzjsh", "English": "Enfizikik",
"Esperanto": "Esprorjjzlz", "Esperanto": "Esprorjjzlz",
"Filipino": "Fefjwoeifj", "Filipino": "Fefjwoeifj",
"Finnish": "Fnnizhsh", "Finnish": "Fnnizhsh",
"French": "Frnzhfhn", "French": "Froktury",
"German": "Grmmzndn", "German": "Deutgwiz",
"Gibberish": "Gibberish", "Gibberish": "Abuktarika",
"Greek": "Gaofwef", "Greek": "Gaofwef",
"Hindi": "Hfjofz", "Hindi": "Panokallas",
"Hungarian": "Hngjgozf", "Hungarian": "Hngjgozf",
"Indonesian": "Inofiqdson", "Indonesian": "Inofiqdson",
"Italian": "Itzllfjssnn", "Italian": "Itzllfjssnn",
"Japanese": "Jpndjsjzes", "Japanese": "Capnokas",
"Korean": "Kornesnzn", "Korean": "Kornesnzn",
"Malay": "FJwoerjjdf", "Malay": "FJwoerjjdf",
"Persian": "Psdfsdf", "Persian": "Psdfsdf",
@ -1676,12 +1691,12 @@
"Romanian": "Rmrfoijfzf", "Romanian": "Rmrfoijfzf",
"Russian": "Rzznrsn", "Russian": "Rzznrsn",
"Serbian": "Socowiejf", "Serbian": "Socowiejf",
"Slovak": "Slihdtbjoy", "Slovak": "Zokkis",
"Spanish": "Snsdnsh", "Spanish": "Snaddies",
"Swedish": "Swdiiszh", "Swedish": "Swdiiszh",
"Tamil": "Tmfiewf", "Tamil": "Tmfiewf",
"Thai": "Thzff", "Thai": "Thzff",
"Turkish": "Twfoijwef", "Turkish": "Turiyako",
"Ukrainian": "Ukckwef", "Ukrainian": "Ukckwef",
"Venetian": "Vwvowefdf", "Venetian": "Vwvowefdf",
"Vietnamese": "Vjefowiewer" "Vietnamese": "Vjefowiewer"
@ -1735,16 +1750,16 @@
"Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "And foci wej fowif ijcowjer.\nPle eocj w jocose fowl jeowijeo few fj cijwoiejr. fofofifjow e ciweocywe.", "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "And foci wej fowif ijcowjer.\nPle eocj w jocose fowl jeowijeo few fj cijwoiejr. fofofifjow e ciweocywe.",
"An error has occurred; (${ERROR})": "An cow fc woof wcef; (${ERROR})", "An error has occurred; (${ERROR})": "An cow fc woof wcef; (${ERROR})",
"An error has occurred; please contact support. (${ERROR})": "An cowed c woefj wcoi woof weiojrwe rj goije ${ERROR})", "An error has occurred; please contact support. (${ERROR})": "An cowed c woefj wcoi woof weiojrwe rj goije ${ERROR})",
"An error has occurred; please contact support@froemling.net.": "An f oco ao ocio wj ; pocj oco woei fsuupo co co ifoiwnet", "An error has occurred; please contact support@froemling.net.": "An f oco ao ocio wj ; pocj oco woei fsuupo co co ifoiwnet support@froemling.net gwizing patüköç.",
"An error has occurred; please try again later.": "An cowjef win woes owe p apowejrowjers.", "An error has occurred; please try again later.": "An cowjef win woes owe p apowejrowjers.",
"Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Ac woef oi eowic woiej fowije foijcwe?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nTHci weo woi efoiw ojo ij!!", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Ac woef oi eowic woiej fowije foijcwe?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nTHci weo woi efoiw ojo ij!!",
"BombSquad Pro unlocked!": "Boijfdfsjef pon occoijfs!", "BombSquad Pro unlocked!": "Boijfdfsjef pon occoijfs!",
"Can't link 2 accounts of this type.": "Cnoj' oi n aoco i ot oaifftz.", "Can't link 2 accounts of this type.": "Cnoj' oi n aoco i ot oaifftz.",
"Can't link 2 diamond league accounts.": "Cnoi' oin koci o2 doi co fla cairjrs.", "Can't link 2 diamond league accounts.": "Cnoi' oin koci o2 doi co fla cairjrs.",
"Can't link; would surpass maximum of ${COUNT} linked accounts.": "Cn't coi oi; could up vo io ${COUNT} oi c ioicoicuors.", "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Cn't coi oi; could up vo io möaksokato ${COUNT} oi c ioicoicuors.",
"Cheating detected; scores and prizes suspended for ${COUNT} days.": "Chowcj eof weoc jco; oe jwoeijf wojcwjeowfj woejf o${COUNT} dzf.", "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Chowcj eof weoc jco; oe jwoeijf wojcwjeowfj woejf o${COUNT} dzf.",
"Could not establish a secure connection.": "Cjfoi cn ooi a tac c oweocoicoinr.", "Could not establish a secure connection.": "Cjfoi cn ooi a tac c oweocoicoinr.",
"Daily maximum reached.": "Dfilaf mciwfjiwf rechced.", "Daily maximum reached.": "Dfilaf möaksokato ravhgedök.",
"Entering tournament...": "Ernwoefijweo jfowjefw...", "Entering tournament...": "Ernwoefijweo jfowjefw...",
"Invalid code.": "Invflijf cddz.", "Invalid code.": "Invflijf cddz.",
"Invalid payment; purchase canceled.": "Info ejcwpeopwer; purwup cowefjwef.", "Invalid payment; purchase canceled.": "Info ejcwpeopwer; purwup cowefjwef.",
@ -1754,9 +1769,9 @@
"Item unlocked!": "Iwerw cowefjwoeijwer!", "Item unlocked!": "Iwerw cowefjwoeijwer!",
"LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LINKING FOFJWEF. ${ACCOUNT} o iwjof\nowe oijwe c woeoijwf oAL FJOEJI OCJW.\nYou off leojwoer wcowe foiwjefojweoiwf\n(a c owfw oefjTHIS c weoojw oesf)", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LINKING FOFJWEF. ${ACCOUNT} o iwjof\nowe oijwe c woeoijwf oAL FJOEJI OCJW.\nYou off leojwoer wcowe foiwjefojweoiwf\n(a c owfw oefjTHIS c weoojw oesf)",
"Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Lcjwe fwofj o ${ACCOUNT} to cowejfweof?\nAll wefoiwejtthosjic w ${ACCOUNT} cowiejf tjsl.\nThis wefowondot onsof. Aojr tyocu wsure?", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Lcjwe fwofj o ${ACCOUNT} to cowejfweof?\nAll wefoiwejtthosjic w ${ACCOUNT} cowiejf tjsl.\nThis wefowondot onsof. Aojr tyocu wsure?",
"Max number of playlists reached.": "Mx nfmow oijeplyalfaf rcnoahfd.", "Max number of playlists reached.": "Möaks nfmow oijeplyalfaf rcnoahfd.",
"Max number of profiles reached.": "Mc fjpasdofj c owiejfowe oiwjefsd.", "Max number of profiles reached.": "Möks fresadora c owiejfowe rafgexed.",
"Maximum friend code rewards reached.": "Cmwoe oc wo Ego wel jacoweij weer.", "Maximum friend code rewards reached.": "Cmwoe oc wo Ego wel jacoweij weer möaksiöas.",
"Message is too long.": "CMew ociwje owe el.", "Message is too long.": "CMew ociwje owe el.",
"No servers are available. Please try again soon.": "Ns seroiejwc wefjwoe wj. Ple wer wfwef ewfowes.", "No servers are available. Please try again soon.": "Ns seroiejwc wefjwoe wj. Ple wer wfwef ewfowes.",
"Profile \"${NAME}\" upgraded successfully.": "Profjojf \"${NAME}\" oupfuap coj woijsfsf.", "Profile \"${NAME}\" upgraded successfully.": "Profjojf \"${NAME}\" oupfuap coj woijsfsf.",
@ -1818,12 +1833,12 @@
"Flag Idle Return Time": "Flág Ídle Rétúrn Tímz", "Flag Idle Return Time": "Flág Ídle Rétúrn Tímz",
"Flag Touch Return Time": "Flág Tzch Rétúrn Tímz", "Flag Touch Return Time": "Flág Tzch Rétúrn Tímz",
"Hold Time": "Hólz Tímz", "Hold Time": "Hólz Tímz",
"Kills to Win Per Player": "Kílls tó Wín Pér Plzáyer", "Kills to Win Per Player": "Gebertzerto tórku Wenn Piérko Plzáyer",
"Laps": "Lápz", "Laps": "Ląkzl",
"Lives Per Player": "Lívz Pérz Pláyrr", "Lives Per Player": "Lívz Pérz Pláyrr",
"Long": "Lónggz", "Long": "Lónggz",
"Longer": "Lóngrzz", "Longer": "Lóngrzz",
"Mine Spawning": "Míne Spáwning", "Mine Spawning": "Mõvn okmalako",
"No Mines": "Nz Mfjfnzl", "No Mines": "Nz Mfjfnzl",
"None": "Núnz", "None": "Núnz",
"Normal": "Nórmzll", "Normal": "Nórmzll",
@ -1842,10 +1857,10 @@
"Warning to ${NAME}: turbo / button-spamming knocks you out.": "Wjocief cwf ${NAME}: jojwo / ocjo efoiwefj wcoweok owerjoijdof." "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Wjocief cwf ${NAME}: jojwo / ocjo efoiwefj wcoweok owerjoijdof."
}, },
"teamNames": { "teamNames": {
"Bad Guys": "Bázd Gúyzs", "Bad Guys": "Juardz gùårdz'n",
"Blue": "Blzúe", "Blue": "Blzúe",
"Good Guys": "Gzóod Gúys", "Good Guys": "Gzóod Gùårdz'n",
"Red": "Réd" "Red": "Vegco"
}, },
"tips": { "tips": {
"A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Á perfectly timed running-jumping-zpin-punch cán kill in á zingle hit\nánd eárn yóu lifelóng rezpect fróm yóur friendz.", "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Á perfectly timed running-jumping-zpin-punch cán kill in á zingle hit\nánd eárn yóu lifelóng rezpect fróm yóur friendz.",
@ -1950,6 +1965,7 @@
"unlockThisInTheStoreText": "Thz mf voi eunlcoef owef joiefsfrwe.", "unlockThisInTheStoreText": "Thz mf voi eunlcoef owef joiefsfrwe.",
"unlockThisProfilesText": "To cowier co we ${NUM} pcoer, cow oicoj:", "unlockThisProfilesText": "To cowier co we ${NUM} pcoer, cow oicoj:",
"unlockThisText": "Tz ncowifj ocje, ycon fneeds:", "unlockThisText": "Tz ncowifj ocje, ycon fneeds:",
"unsupportedControllerText": "Sorwfw, contorlwef \"${NAME}\" oweifj wcjwoeir.",
"unsupportedHardwareText": "Srrz, thz hardwrz isz nt spprted bz thz vejerelr dlzl gmpzz.", "unsupportedHardwareText": "Srrz, thz hardwrz isz nt spprted bz thz vejerelr dlzl gmpzz.",
"upFirstText": "Uzp férzt:", "upFirstText": "Uzp férzt:",
"upNextText": "Úp nézt ín gámz ${COUNT}:", "upNextText": "Úp nézt ín gámz ${COUNT}:",
@ -1963,6 +1979,7 @@
"v2AccountLinkingInfoText": "To ljeowirj V2 sojowe, use fo 'Mnawefw Acoiwo' bons.", "v2AccountLinkingInfoText": "To ljeowirj V2 sojowe, use fo 'Mnawefw Acoiwo' bons.",
"validatingBetaText": "Válúdztíng Bztá...", "validatingBetaText": "Válúdztíng Bztá...",
"validatingTestBuildText": "Vldfjdfoi jtese-bsdfasfd...", "validatingTestBuildText": "Vldfjdfoi jtese-bsdfasfd...",
"viaText": "sdf",
"victoryText": "Vúctzry!", "victoryText": "Vúctzry!",
"voteDelayText": "You caecowe oefo wocj woeiwo ${NUMBER} wocijwoef.", "voteDelayText": "You caecowe oefo wocj woeiwo ${NUMBER} wocijwoef.",
"voteInProgressText": "A voiajf coiwje fwooeio wcwer.", "voteInProgressText": "A voiajf coiwje fwooeio wcwer.",

View file

@ -817,6 +817,7 @@
"highText": "Υψηλό", "highText": "Υψηλό",
"higherText": "Υψηλότερο", "higherText": "Υψηλότερο",
"lowText": "Χαμηλό", "lowText": "Χαμηλό",
"maxFPSText": "Όριο FPS",
"mediumText": "Μέτριο", "mediumText": "Μέτριο",
"neverText": "Ποτέ", "neverText": "Ποτέ",
"resolutionText": "Ανάλυση", "resolutionText": "Ανάλυση",
@ -1225,6 +1226,7 @@
"runText": "Τρέξιμο", "runText": "Τρέξιμο",
"saveText": "Αποθήκευση", "saveText": "Αποθήκευση",
"scanScriptsErrorText": "Σφάλμα(α) κατά τη σάρωση σεναρίων. Δείτε το αρχείο καταγραφής για λεπτομέρειες.", "scanScriptsErrorText": "Σφάλμα(α) κατά τη σάρωση σεναρίων. Δείτε το αρχείο καταγραφής για λεπτομέρειες.",
"scanScriptsSingleModuleNeedsUpdatesText": "Το ${PATH} χρειάζεται να αναβαθμιστεί για το api ${API}",
"scoreChallengesText": "Προκλήσεις Βαθμολογίας", "scoreChallengesText": "Προκλήσεις Βαθμολογίας",
"scoreListUnavailableText": "Λίστα βαθμολογίας μη διαθέσιμη.", "scoreListUnavailableText": "Λίστα βαθμολογίας μη διαθέσιμη.",
"scoreText": "Βαθμολογία", "scoreText": "Βαθμολογία",
@ -1268,6 +1270,7 @@
"netTestingText": "Έλεγχος Δικτύου", "netTestingText": "Έλεγχος Δικτύου",
"resetText": "Επαναφορά", "resetText": "Επαναφορά",
"showBombTrajectoriesText": "Εμφάνιση Πορείας Βόμβας", "showBombTrajectoriesText": "Εμφάνιση Πορείας Βόμβας",
"showDevConsoleButtonText": "Εμφάνιση κονσόλας προγραμματιστών",
"showInGamePingText": "Εμφάνιση Καθυστέρησης Εντός-Παιχνιδιού", "showInGamePingText": "Εμφάνιση Καθυστέρησης Εντός-Παιχνιδιού",
"showPlayerNamesText": "Προβολή Ονομάτων Παικτών", "showPlayerNamesText": "Προβολή Ονομάτων Παικτών",
"showUserModsText": "Προβολή Φακέλου Πακέτων Τροποποίησης", "showUserModsText": "Προβολή Φακέλου Πακέτων Τροποποίησης",

View file

@ -337,6 +337,7 @@
"getMoreGamesText": "और गेम्स कि जानकारी पायें", "getMoreGamesText": "और गेम्स कि जानकारी पायें",
"titleText": "गेम जोड़ें" "titleText": "गेम जोड़ें"
}, },
"allText": "सभी",
"allowText": "अनुमति दें", "allowText": "अनुमति दें",
"alreadySignedInText": "आपका खाता किसी अन्य डिवाइस से साइन किया गया है; \nकृपया खातों को स्विच करें या अपने गेम को अन्य डिवाइस \nपर बंद करें और फिर से प्रयास करें", "alreadySignedInText": "आपका खाता किसी अन्य डिवाइस से साइन किया गया है; \nकृपया खातों को स्विच करें या अपने गेम को अन्य डिवाइस \nपर बंद करें और फिर से प्रयास करें",
"apiVersionErrorText": "${NAME} मौड्यूल लोड नहीं हो पाया ; यह एपीआई - संस्करण ${VERSION_USED} पे काम करने का प्रयास कर रहा है ; हमें संस्करण ${VERSION_REQUIRED} चाहिए |", "apiVersionErrorText": "${NAME} मौड्यूल लोड नहीं हो पाया ; यह एपीआई - संस्करण ${VERSION_USED} पे काम करने का प्रयास कर रहा है ; हमें संस्करण ${VERSION_REQUIRED} चाहिए |",
@ -561,6 +562,7 @@
"disableRemoteAppConnectionsText": "रिमोट के ऐप्प कनेक्शन्स को बंद करे", "disableRemoteAppConnectionsText": "रिमोट के ऐप्प कनेक्शन्स को बंद करे",
"disableXInputDescriptionText": "4 नियंत्रकों से अधिक की अनुमति देता है लेकिन साथ ही साथ काम नहीं कर सकते", "disableXInputDescriptionText": "4 नियंत्रकों से अधिक की अनुमति देता है लेकिन साथ ही साथ काम नहीं कर सकते",
"disableXInputText": "Xinput अक्षम करें", "disableXInputText": "Xinput अक्षम करें",
"disabledText": "डिसेबल्ड",
"doneText": "हो गया", "doneText": "हो गया",
"drawText": "बराबर", "drawText": "बराबर",
"duplicateText": "प्रतिलिपि", "duplicateText": "प्रतिलिपि",
@ -629,6 +631,7 @@
"useMusicFolderText": "गाने कि फाइल्स का फोल्डर" "useMusicFolderText": "गाने कि फाइल्स का फोल्डर"
}, },
"editText": "संपादित करें", "editText": "संपादित करें",
"enabledText": "इनेब्ल",
"endText": "समाप्त", "endText": "समाप्त",
"enjoyText": "मज़ा लें !", "enjoyText": "मज़ा लें !",
"epicDescriptionFilterText": "${DESCRIPTION} उत्कृष्ट धीमे गति में।", "epicDescriptionFilterText": "${DESCRIPTION} उत्कृष्ट धीमे गति में।",
@ -819,10 +822,12 @@
"alwaysText": "हमेशा", "alwaysText": "हमेशा",
"fullScreenCmdText": "संपूर्ण स्क्रीन में चलायें (सी-एम्-डी + ऍफ़)", "fullScreenCmdText": "संपूर्ण स्क्रीन में चलायें (सी-एम्-डी + ऍफ़)",
"fullScreenCtrlText": "संपूर्ण स्क्रीन में चलायें (सी-टी-आर-एल + ऍफ़)", "fullScreenCtrlText": "संपूर्ण स्क्रीन में चलायें (सी-टी-आर-एल + ऍफ़)",
"fullScreenText": "पूर्ण स्क्रीन",
"gammaText": "चमक", "gammaText": "चमक",
"highText": "ज्यादा", "highText": "ज्यादा",
"higherText": "और ज्यादा", "higherText": "और ज्यादा",
"lowText": "कम", "lowText": "कम",
"maxFPSText": "अधिकतम एफ.पी.एस.",
"mediumText": "ठीक ठाक", "mediumText": "ठीक ठाक",
"neverText": "कभी नहीं", "neverText": "कभी नहीं",
"resolutionText": "रेज़ोल्यूशन", "resolutionText": "रेज़ोल्यूशन",
@ -1064,6 +1069,7 @@
"noGameCircleText": "त्रुटी: गेम-सर्किल में लॉग-इन नहीं हैं |", "noGameCircleText": "त्रुटी: गेम-सर्किल में लॉग-इन नहीं हैं |",
"noProfilesErrorText": "आपकी कोई खिलाड़ी पार्श्वचित्र नहीं है, इसलिए आप '${NAME}' नाम के साथ फंसे हैं |\nसेटिंग -> खिलाड़ी पार्श्वचित्र में जाके अपने लिए पार्श्वचित्र बनायें |", "noProfilesErrorText": "आपकी कोई खिलाड़ी पार्श्वचित्र नहीं है, इसलिए आप '${NAME}' नाम के साथ फंसे हैं |\nसेटिंग -> खिलाड़ी पार्श्वचित्र में जाके अपने लिए पार्श्वचित्र बनायें |",
"noScoresYetText": "अभी तक कोई स्कोर नहीं है |", "noScoresYetText": "अभी तक कोई स्कोर नहीं है |",
"noServersFoundText": "कोई सरवर्स नहीं मिलें।",
"noThanksText": "नहीं धन्यवाद", "noThanksText": "नहीं धन्यवाद",
"noTournamentsInTestBuildText": "चेतावनी: इस टेस्ट बिल्ड से खेलकूद-प्रतियोगिता के खेल के अंकों को नजरअंदाज कर दिया जाएगा।", "noTournamentsInTestBuildText": "चेतावनी: इस टेस्ट बिल्ड से खेलकूद-प्रतियोगिता के खेल के अंकों को नजरअंदाज कर दिया जाएगा।",
"noValidMapsErrorText": "इस गेम ढंग के लिए कोई नक्शा नहीं मिला", "noValidMapsErrorText": "इस गेम ढंग के लिए कोई नक्शा नहीं मिला",
@ -1229,6 +1235,8 @@
"runText": "दोडें", "runText": "दोडें",
"saveText": "सुरक्षित करें", "saveText": "सुरक्षित करें",
"scanScriptsErrorText": "स्क्रिप्ट्स स्कैन करने में गलती; विवरण के लिए लॉग देखें।", "scanScriptsErrorText": "स्क्रिप्ट्स स्कैन करने में गलती; विवरण के लिए लॉग देखें।",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} और ${NUM} अन्य मॉड्यूल को ए.पी.आई. ${API} के लिए अद्यतन करने की आवश्यकता है।",
"scanScriptsSingleModuleNeedsUpdatesText": "एपीआई ${API} के लिए ${PATH} को अद्यतन करने की आवश्यकता है।",
"scoreChallengesText": "अंकों कि चुनौतियाँ", "scoreChallengesText": "अंकों कि चुनौतियाँ",
"scoreListUnavailableText": "अंकों कि सूचि अभी उपस्थित नहीं है", "scoreListUnavailableText": "अंकों कि सूचि अभी उपस्थित नहीं है",
"scoreText": "अंक", "scoreText": "अंक",
@ -1272,6 +1280,7 @@
"netTestingText": "नेटवर्क पर परीक्षण", "netTestingText": "नेटवर्क पर परीक्षण",
"resetText": "रीसेट", "resetText": "रीसेट",
"showBombTrajectoriesText": "बोम्ब का पथ दिखाएँ", "showBombTrajectoriesText": "बोम्ब का पथ दिखाएँ",
"showDevConsoleButtonText": "डेव कंसोल बटन दिखाएँ",
"showInGamePingText": "गेम पिंग में दिखाएं", "showInGamePingText": "गेम पिंग में दिखाएं",
"showPlayerNamesText": "खिलाड़ी का नाम दिखाएँ", "showPlayerNamesText": "खिलाड़ी का नाम दिखाएँ",
"showUserModsText": "परिवर्तनों का फोल्डर दिखाएँ", "showUserModsText": "परिवर्तनों का फोल्डर दिखाएँ",
@ -1363,6 +1372,7 @@
"storeText": "दुकान", "storeText": "दुकान",
"submitText": "जमा करें", "submitText": "जमा करें",
"submittingPromoCodeText": "संहिता जमा कर रहा है ...", "submittingPromoCodeText": "संहिता जमा कर रहा है ...",
"successText": "सफल!",
"teamNamesColorText": "टीम के नाम / रंग ...", "teamNamesColorText": "टीम के नाम / रंग ...",
"telnetAccessGrantedText": "टेलनेट एक्सेस सक्षम है", "telnetAccessGrantedText": "टेलनेट एक्सेस सक्षम है",
"telnetAccessText": "टेलनेट पहुंच का पता चला; अनुमति देते हैं?", "telnetAccessText": "टेलनेट पहुंच का पता चला; अनुमति देते हैं?",

View file

@ -31,6 +31,7 @@
"signInWithGooglePlayText": "Masuk menggunakan Google Play", "signInWithGooglePlayText": "Masuk menggunakan Google Play",
"signInWithTestAccountInfoText": "(akun tipe lama; gunakan akun device untuk kedepannya)", "signInWithTestAccountInfoText": "(akun tipe lama; gunakan akun device untuk kedepannya)",
"signInWithTestAccountText": "Masuk menggunakan akun percobaan", "signInWithTestAccountText": "Masuk menggunakan akun percobaan",
"signInWithText": "Masuk dengan ${SERVICE}",
"signInWithV2InfoText": "(Akun yang berfungsi di semua akun)", "signInWithV2InfoText": "(Akun yang berfungsi di semua akun)",
"signInWithV2Text": "Daftar dengan akun bombsquad", "signInWithV2Text": "Daftar dengan akun bombsquad",
"signOutText": "Keluar", "signOutText": "Keluar",
@ -367,6 +368,7 @@
"chatMutedText": "Percakapan Diabaikan", "chatMutedText": "Percakapan Diabaikan",
"chatUnMuteText": "Menampilkan kembali percakapan", "chatUnMuteText": "Menampilkan kembali percakapan",
"choosingPlayerText": "<memilih pemain>", "choosingPlayerText": "<memilih pemain>",
"codesExplainText": "Kode telah disediakan oleh pengembang\nuntuk didiagnosa dan memperbaiki isu akun.",
"completeThisLevelToProceedText": "Kamu harus menyelesaikan\nlevel ini untuk dapat lanjut!", "completeThisLevelToProceedText": "Kamu harus menyelesaikan\nlevel ini untuk dapat lanjut!",
"completionBonusText": "Bonus Kelengkapan", "completionBonusText": "Bonus Kelengkapan",
"configControllersWindow": { "configControllersWindow": {
@ -447,6 +449,7 @@
"swipeText": "geser", "swipeText": "geser",
"titleText": "Atur layar sentuh" "titleText": "Atur layar sentuh"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} dapat dikonfigurasikan pada aplikasi Pengaturan Sistem.",
"configureItNowText": "Atur sekarang?", "configureItNowText": "Atur sekarang?",
"configureText": "Konfigurasi", "configureText": "Konfigurasi",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -782,7 +785,7 @@
"wifiDirectOpenWiFiSettingsText": "Buka Pengaturan Wi-Fi", "wifiDirectOpenWiFiSettingsText": "Buka Pengaturan Wi-Fi",
"wifiDirectText": "Wi-Fi Direct", "wifiDirectText": "Wi-Fi Direct",
"worksBetweenAllPlatformsText": "(bekerja antar platform)", "worksBetweenAllPlatformsText": "(bekerja antar platform)",
"worksWithGooglePlayDevicesText": "(bekerja antar perangkat yang menggunakan versi Android)", "worksWithGooglePlayDevicesText": "(bekerja antar perangkat yang menggunakan versi Android) ",
"youHaveBeenSentAPromoCodeText": "Kamu telah mengirim sebuah kode promo ${APP_NAME}!" "youHaveBeenSentAPromoCodeText": "Kamu telah mengirim sebuah kode promo ${APP_NAME}!"
}, },
"getTicketsWindow": { "getTicketsWindow": {
@ -816,10 +819,12 @@
"alwaysText": "Selalu", "alwaysText": "Selalu",
"fullScreenCmdText": "Layar Penuh (Cmd-F)", "fullScreenCmdText": "Layar Penuh (Cmd-F)",
"fullScreenCtrlText": "Layar Penuh (Ctrl+F)", "fullScreenCtrlText": "Layar Penuh (Ctrl+F)",
"fullScreenText": "Layar Penuh",
"gammaText": "Gamma", "gammaText": "Gamma",
"highText": "Tinggi", "highText": "Tinggi",
"higherText": "Tertinggi", "higherText": "Tertinggi",
"lowText": "Rendah", "lowText": "Rendah",
"maxFPSText": "FPS Maks",
"mediumText": "Sedang", "mediumText": "Sedang",
"neverText": "Tak Pernah", "neverText": "Tak Pernah",
"resolutionText": "Resolusi", "resolutionText": "Resolusi",
@ -1061,6 +1066,7 @@
"noGameCircleText": "Kesalahan: tidak masuk ke LingkaranGame", "noGameCircleText": "Kesalahan: tidak masuk ke LingkaranGame",
"noProfilesErrorText": "Kamu tidak punya profil pemain, jadi '${NAME}' dipakai. \nMasuk Pengaturan->Profil Pemain untuk membuat profil. ", "noProfilesErrorText": "Kamu tidak punya profil pemain, jadi '${NAME}' dipakai. \nMasuk Pengaturan->Profil Pemain untuk membuat profil. ",
"noScoresYetText": "Belum ada skor.", "noScoresYetText": "Belum ada skor.",
"noServersFoundText": "Server tidak ditemukan.",
"noThanksText": "Tidak, Terima kasih", "noThanksText": "Tidak, Terima kasih",
"noTournamentsInTestBuildText": "PERHATIAN: Skor turnamen dari build tes ini akan di abaikan", "noTournamentsInTestBuildText": "PERHATIAN: Skor turnamen dari build tes ini akan di abaikan",
"noValidMapsErrorText": "Tidak ada arena valid untuk game ini.", "noValidMapsErrorText": "Tidak ada arena valid untuk game ini.",
@ -1271,6 +1277,7 @@
"netTestingText": "Tes Jaringan", "netTestingText": "Tes Jaringan",
"resetText": "Atur ulang", "resetText": "Atur ulang",
"showBombTrajectoriesText": "Lihat Lintasan Bom", "showBombTrajectoriesText": "Lihat Lintasan Bom",
"showDevConsoleButtonText": "Tampilkan tombol Dev Console",
"showInGamePingText": "Tampilkan Ping dalam permainan", "showInGamePingText": "Tampilkan Ping dalam permainan",
"showPlayerNamesText": "Tunjukkan Nama Pemain", "showPlayerNamesText": "Tunjukkan Nama Pemain",
"showUserModsText": "Lihat Folder Mod", "showUserModsText": "Lihat Folder Mod",
@ -1362,6 +1369,8 @@
"storeText": "Toko", "storeText": "Toko",
"submitText": "Serahkan", "submitText": "Serahkan",
"submittingPromoCodeText": "Menyerahkan Kode ...", "submittingPromoCodeText": "Menyerahkan Kode ...",
"successText": "Sukses!",
"supportEmailText": "Jika kamu mengalami masalah apa pun pada\naplikasi, mohon segera kirim email ${EMAIL}.",
"teamNamesColorText": "Nama Tim / Warna ...", "teamNamesColorText": "Nama Tim / Warna ...",
"telnetAccessGrantedText": "Akses telnet aktif.", "telnetAccessGrantedText": "Akses telnet aktif.",
"telnetAccessText": "Akses telnet terdekteksi; izinkan?", "telnetAccessText": "Akses telnet terdekteksi; izinkan?",
@ -1817,6 +1826,7 @@
"unlockThisInTheStoreText": "Tersedia di toko terdekat.", "unlockThisInTheStoreText": "Tersedia di toko terdekat.",
"unlockThisProfilesText": "Untuk membuat lebih dari ${NUM} profil, Kamu memerlukan:", "unlockThisProfilesText": "Untuk membuat lebih dari ${NUM} profil, Kamu memerlukan:",
"unlockThisText": "Untuk buka ini,kamu membutuhkan:", "unlockThisText": "Untuk buka ini,kamu membutuhkan:",
"unsupportedControllerText": "Maaf, kontroler \"${NAME}\" tidak mendukung.",
"unsupportedHardwareText": "Maaf, perangkat ini tidak mendukung build permainan ini.", "unsupportedHardwareText": "Maaf, perangkat ini tidak mendukung build permainan ini.",
"upFirstText": "Game pertama:", "upFirstText": "Game pertama:",
"upNextText": "${COUNT} game berikutnya:", "upNextText": "${COUNT} game berikutnya:",
@ -1829,6 +1839,7 @@
"usingItunesTurnRepeatAndShuffleOnText": "Tolong pastikan lagu diacak dan diulang di iTunes. ", "usingItunesTurnRepeatAndShuffleOnText": "Tolong pastikan lagu diacak dan diulang di iTunes. ",
"v2AccountLinkingInfoText": "Untuk menautkan akun V2, gunakan tombol 'Manajemen Akun'.", "v2AccountLinkingInfoText": "Untuk menautkan akun V2, gunakan tombol 'Manajemen Akun'.",
"validatingTestBuildText": "Memvalidasi Bangunan Tes...", "validatingTestBuildText": "Memvalidasi Bangunan Tes...",
"viaText": "melalui",
"victoryText": "Menang!", "victoryText": "Menang!",
"voteDelayText": "Kamu tidak dapat memulai pemilihan suara dalam ${NUMBER} detik", "voteDelayText": "Kamu tidak dapat memulai pemilihan suara dalam ${NUMBER} detik",
"voteInProgressText": "Pemilihan suara sedang dalam proses.", "voteInProgressText": "Pemilihan suara sedang dalam proses.",

View file

@ -17,7 +17,7 @@
"linkAccountsInstructionsText": "Per collegare due account, crea un codice su uno\ndei dispositivi e inserisci quel codice negli altri. \nProgressi e inventario verranno combinati.\nPuoi collegare fino a ${COUNT} account.\n\nIMPORTANTE: Collega solo account che possiedi!\nSe colleghi un account con un tuo amico non potrete\ngiocare allo stesso momento!\n \nInoltre: questa operazione non può essere annullata, quindi stai attento!", "linkAccountsInstructionsText": "Per collegare due account, crea un codice su uno\ndei dispositivi e inserisci quel codice negli altri. \nProgressi e inventario verranno combinati.\nPuoi collegare fino a ${COUNT} account.\n\nIMPORTANTE: Collega solo account che possiedi!\nSe colleghi un account con un tuo amico non potrete\ngiocare allo stesso momento!\n \nInoltre: questa operazione non può essere annullata, quindi stai attento!",
"linkAccountsText": "Collega account", "linkAccountsText": "Collega account",
"linkedAccountsText": "Account Collegati:", "linkedAccountsText": "Account Collegati:",
"manageAccountText": "Gestisci account", "manageAccountText": "Gestisci Account",
"nameChangeConfirm": "Confermi di voler modificare il tuo nome in ${NAME}?", "nameChangeConfirm": "Confermi di voler modificare il tuo nome in ${NAME}?",
"notLoggedInText": "<accesso non effettuato>", "notLoggedInText": "<accesso non effettuato>",
"resetProgressConfirmNoAchievementsText": "Stai per cancellare i tuoi progressi in\nmodalità cooperativa, i tuoi obbiettivi, i tuoi punteggi\nlocali (ma non i tuoi biglietti). \n\nL'operazione è irreversibile: continuare?", "resetProgressConfirmNoAchievementsText": "Stai per cancellare i tuoi progressi in\nmodalità cooperativa, i tuoi obbiettivi, i tuoi punteggi\nlocali (ma non i tuoi biglietti). \n\nL'operazione è irreversibile: continuare?",
@ -33,6 +33,7 @@
"signInWithGooglePlayText": "Accedi con Google Play", "signInWithGooglePlayText": "Accedi con Google Play",
"signInWithTestAccountInfoText": "(tipo di account obsoleto; usa gli account dispositivo d'ora in poi)", "signInWithTestAccountInfoText": "(tipo di account obsoleto; usa gli account dispositivo d'ora in poi)",
"signInWithTestAccountText": "Accedi con un account di prova", "signInWithTestAccountText": "Accedi con un account di prova",
"signInWithText": "Accedi con ${SERVICE}",
"signInWithV2InfoText": "(un account che funziona su tutte le piattaforme)", "signInWithV2InfoText": "(un account che funziona su tutte le piattaforme)",
"signInWithV2Text": "Effettua l'accesso con un account di BombSquad", "signInWithV2Text": "Effettua l'accesso con un account di BombSquad",
"signOutText": "Esci", "signOutText": "Esci",
@ -340,6 +341,8 @@
"getMoreGamesText": "Ottieni Giochi...", "getMoreGamesText": "Ottieni Giochi...",
"titleText": "Aggiungi Partita" "titleText": "Aggiungi Partita"
}, },
"addToFavoritesText": "Aggiungi ai Preferiti",
"addedToFavoritesText": "'${NAME}' aggiunto ai Preferiti",
"allText": "Tutto", "allText": "Tutto",
"allowText": "Consenti", "allowText": "Consenti",
"alreadySignedInText": "Il tuo account è collegato da un altro dispositivo;\ncambia account o chiudi il gioco nel tuo altro\ndispositivo e riprova.", "alreadySignedInText": "Il tuo account è collegato da un altro dispositivo;\ncambia account o chiudi il gioco nel tuo altro\ndispositivo e riprova.",
@ -376,6 +379,7 @@
"chatMutedText": "Chat Silenziata", "chatMutedText": "Chat Silenziata",
"chatUnMuteText": "Smuta Chat", "chatUnMuteText": "Smuta Chat",
"choosingPlayerText": "<scelta giocatore>", "choosingPlayerText": "<scelta giocatore>",
"codesExplainText": "i codici sono forniti dallo sviluppatore per\nscoprire e correggere problemi all'account.",
"completeThisLevelToProceedText": "Devi completare questo\nlivello per procedere!", "completeThisLevelToProceedText": "Devi completare questo\nlivello per procedere!",
"completionBonusText": "Competizione bonus", "completionBonusText": "Competizione bonus",
"configControllersWindow": { "configControllersWindow": {
@ -459,6 +463,7 @@
"titleText": "Configura il Touchscreen", "titleText": "Configura il Touchscreen",
"touchControlsScaleText": "Scala dei Comandi Touch" "touchControlsScaleText": "Scala dei Comandi Touch"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} può essere configurato nelle Impostazioni di Sistema.",
"configureItNowText": "Configurarlo adesso?", "configureItNowText": "Configurarlo adesso?",
"configureText": "Configura", "configureText": "Configura",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -580,6 +585,8 @@
"disableXInputDescriptionText": "Permette l'uso di più di 4 pulsantiere, ma potrebbe anche non funzionare.", "disableXInputDescriptionText": "Permette l'uso di più di 4 pulsantiere, ma potrebbe anche non funzionare.",
"disableXInputText": "Disabilita XInput", "disableXInputText": "Disabilita XInput",
"disabledText": "DISABILITATO", "disabledText": "DISABILITATO",
"discordFriendsText": "Cerchi altri con cui giocare?\nEntra nel nostro server Discord e fatti nuovi amici!",
"discordJoinText": "Entra nel server Discord",
"doneText": "Fatto", "doneText": "Fatto",
"drawText": "Pareggio", "drawText": "Pareggio",
"duplicateText": "Duplicato", "duplicateText": "Duplicato",
@ -776,11 +783,12 @@
"manualYourLocalAddressText": "Indirizzo locale:", "manualYourLocalAddressText": "Indirizzo locale:",
"nearbyText": "Locale", "nearbyText": "Locale",
"noConnectionText": "<nessuna connessione>", "noConnectionText": "<nessuna connessione>",
"noPartiesAddedText": "Nessun Party Aggiunto",
"otherVersionsText": "(altre versioni)", "otherVersionsText": "(altre versioni)",
"partyCodeText": "Codice del Party", "partyCodeText": "Codice del Party",
"partyInviteAcceptText": "Accetta", "partyInviteAcceptText": "Accetta",
"partyInviteDeclineText": "Rifiuta", "partyInviteDeclineText": "Rifiuta",
"partyInviteGooglePlayExtraText": "(vedi la scheda 'Google Play' nella finestra 'Raduna')", "partyInviteGooglePlayExtraText": "(vedi la scheda 'Google Play' nella finestra 'Raduna') ",
"partyInviteIgnoreText": "Ignora", "partyInviteIgnoreText": "Ignora",
"partyInviteText": "${NAME} ti ha invitato\nad unirsi al suo party!", "partyInviteText": "${NAME} ti ha invitato\nad unirsi al suo party!",
"partyNameText": "Nome Party", "partyNameText": "Nome Party",
@ -856,16 +864,18 @@
"autoText": "Automatico", "autoText": "Automatico",
"fullScreenCmdText": "Schermo intero (Cmd-F)", "fullScreenCmdText": "Schermo intero (Cmd-F)",
"fullScreenCtrlText": "Schermo intero (Ctrl-F)", "fullScreenCtrlText": "Schermo intero (Ctrl-F)",
"fullScreenText": "Schermo intero",
"gammaText": "Gamma", "gammaText": "Gamma",
"highText": "Alto", "highText": "Alto",
"higherText": "Più alto", "higherText": "Più alto",
"lowText": "Basso", "lowText": "Basso",
"maxFPSText": "FPS massimi",
"mediumText": "Medio", "mediumText": "Medio",
"neverText": "Mai", "neverText": "Mai",
"resolutionText": "Risoluzione", "resolutionText": "Risoluzione",
"showFPSText": "Mostra FPS", "showFPSText": "Mostra FPS",
"texturesText": "Textures", "texturesText": "Textures",
"titleText": "Grafiche", "titleText": "Grafica",
"tvBorderText": "Bordo della TV", "tvBorderText": "Bordo della TV",
"verticalSyncText": "Sincronizzazione verticale", "verticalSyncText": "Sincronizzazione verticale",
"visualsText": "Visuali" "visualsText": "Visuali"
@ -1106,8 +1116,10 @@
"noExternalStorageErrorText": "Nessun archiviatore esterno trovato su questo dispositivo", "noExternalStorageErrorText": "Nessun archiviatore esterno trovato su questo dispositivo",
"noGameCircleText": "Errore: non hai effettuato il login su GameCircle", "noGameCircleText": "Errore: non hai effettuato il login su GameCircle",
"noJoinCoopMidwayText": "Non puoi entrare in una partita cooperativa già iniziata.", "noJoinCoopMidwayText": "Non puoi entrare in una partita cooperativa già iniziata.",
"noPluginsInstalledText": "Nessun Plugin Installato",
"noProfilesErrorText": "Non hai un profilo giocatore, quindi sei bloccato con '${NAME}'.\nVai su Impostazioni > Profili giocatore per creare un profilo personale.", "noProfilesErrorText": "Non hai un profilo giocatore, quindi sei bloccato con '${NAME}'.\nVai su Impostazioni > Profili giocatore per creare un profilo personale.",
"noScoresYetText": "Ancora nessun punteggio.", "noScoresYetText": "Ancora nessun punteggio.",
"noServersFoundText": "Nessun server individuato.",
"noThanksText": "No Grazie", "noThanksText": "No Grazie",
"noTournamentsInTestBuildText": "I punteggi del torneo di questo test build verranno ignorati", "noTournamentsInTestBuildText": "I punteggi del torneo di questo test build verranno ignorati",
"noValidMapsErrorText": "Non sono state trovate mappe valide per questo tipo di gioco.", "noValidMapsErrorText": "Non sono state trovate mappe valide per questo tipo di gioco.",
@ -1313,7 +1325,7 @@
"benchmarksText": "Benchmarks & Prove Di Stress", "benchmarksText": "Benchmarks & Prove Di Stress",
"disableCameraGyroscopeMotionText": "Disabilita il movimento della visuale tramite giroscopio", "disableCameraGyroscopeMotionText": "Disabilita il movimento della visuale tramite giroscopio",
"disableCameraShakeText": "Disabilita il tremolio della visuale", "disableCameraShakeText": "Disabilita il tremolio della visuale",
"disableThisNotice": "(puoi disattivare questo messaggio su Impostazioni>Avanzate)", "disableThisNotice": "(puoi disattivare questo messaggio su Impostazioni > Avanzate)",
"enablePackageModsDescriptionText": "(abilita la possibilità di modding aggiuntivo ma disabilita il gioco in rete)", "enablePackageModsDescriptionText": "(abilita la possibilità di modding aggiuntivo ma disabilita il gioco in rete)",
"enablePackageModsText": "Abilita Mod Dei Pacchetti Locali", "enablePackageModsText": "Abilita Mod Dei Pacchetti Locali",
"enterPromoCodeText": "Inserisci il Codice", "enterPromoCodeText": "Inserisci il Codice",
@ -1327,6 +1339,7 @@
"netTestingText": "Collaudo Rete", "netTestingText": "Collaudo Rete",
"resetText": "Reset", "resetText": "Reset",
"showBombTrajectoriesText": "Mostra le traiettorie delle bombe", "showBombTrajectoriesText": "Mostra le traiettorie delle bombe",
"showDevConsoleButtonText": "mostra tasto console sviluppatore",
"showInGamePingText": "Mostra il Ping in gioco", "showInGamePingText": "Mostra il Ping in gioco",
"showPlayerNamesText": "Mostra i nomi dei giocatori", "showPlayerNamesText": "Mostra i nomi dei giocatori",
"showUserModsText": "Apri cartella personalizzazioni", "showUserModsText": "Apri cartella personalizzazioni",
@ -1422,6 +1435,8 @@
"storeText": "Negozio", "storeText": "Negozio",
"submitText": "Inoltra", "submitText": "Inoltra",
"submittingPromoCodeText": "Inoltrando il Codice...", "submittingPromoCodeText": "Inoltrando il Codice...",
"successText": "Fatto!",
"supportEmailText": "Se riscontri problemi con l'app,\nper favore scrivi a ${EMAIL}.",
"teamNamesColorText": "Colore/Nome Team", "teamNamesColorText": "Colore/Nome Team",
"teamsText": "Squadre", "teamsText": "Squadre",
"telnetAccessGrantedText": "Accesso a telnet abilitato", "telnetAccessGrantedText": "Accesso a telnet abilitato",
@ -1715,7 +1730,7 @@
"Profile \"${NAME}\" upgraded successfully.": "Il profilo \"${NAME}\" è stato aggiornato con successo.", "Profile \"${NAME}\" upgraded successfully.": "Il profilo \"${NAME}\" è stato aggiornato con successo.",
"Profile could not be upgraded.": "Il profilo non è potuto essere aggiornato.", "Profile could not be upgraded.": "Il profilo non è potuto essere aggiornato.",
"Purchase successful!": "Acquistato con successo!", "Purchase successful!": "Acquistato con successo!",
"Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Ricevi ${COUNT} biglietti accedendo.\nTorna domani per ricevere ${TOMORROW_COUNT}.", "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Ricevi ${COUNT} biglietti accedendo.\nTorna domani per riceverne ${TOMORROW_COUNT}.",
"Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funzionalità server non è più supportata in questa versione del gioco;\nAggiornalo ad una nuova versione.", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funzionalità server non è più supportata in questa versione del gioco;\nAggiornalo ad una nuova versione.",
"Sorry, there are no uses remaining on this code.": "Spiacente, non ci sono altri utilizzi rimasti su questo codice.", "Sorry, there are no uses remaining on this code.": "Spiacente, non ci sono altri utilizzi rimasti su questo codice.",
"Sorry, this code has already been used.": "Spiacente, questo codice è già stato usato.", "Sorry, this code has already been used.": "Spiacente, questo codice è già stato usato.",
@ -1903,6 +1918,7 @@
"unlockThisInTheStoreText": "Deve essere sbloccato nel negozio", "unlockThisInTheStoreText": "Deve essere sbloccato nel negozio",
"unlockThisProfilesText": "Per creare più di ${NUM} profili, ti serve:", "unlockThisProfilesText": "Per creare più di ${NUM} profili, ti serve:",
"unlockThisText": "Per sbloccare questo, hai bisogno di:", "unlockThisText": "Per sbloccare questo, hai bisogno di:",
"unsupportedControllerText": "Spiacente, il controller \"${NAME}\" non è supportato.",
"unsupportedHardwareText": "Purtroppo, questo hardware non è supportato da questa versione del gioco.", "unsupportedHardwareText": "Purtroppo, questo hardware non è supportato da questa versione del gioco.",
"upFirstText": "Per primo:", "upFirstText": "Per primo:",
"upNextText": "Fra poco nel ${COUNT}:", "upNextText": "Fra poco nel ${COUNT}:",
@ -1916,6 +1932,7 @@
"v2AccountLinkingInfoText": "Per collegare degli account V2, usa il tasto 'Gestisci Account'.", "v2AccountLinkingInfoText": "Per collegare degli account V2, usa il tasto 'Gestisci Account'.",
"validatingBetaText": "Sto convalidando la beta...", "validatingBetaText": "Sto convalidando la beta...",
"validatingTestBuildText": "Convalida Build Di Prova...", "validatingTestBuildText": "Convalida Build Di Prova...",
"viaText": "utilizzando",
"victoryText": "Vittoria!", "victoryText": "Vittoria!",
"voteDelayText": "Non puoi cominciare un'altra votazione per ${NUMBER} secondi", "voteDelayText": "Non puoi cominciare un'altra votazione per ${NUMBER} secondi",
"voteInProgressText": "C'è già una votazione in corso.", "voteInProgressText": "C'è già una votazione in corso.",

View file

@ -31,6 +31,7 @@
"signInWithGooglePlayText": "Google Play로 로그인", "signInWithGooglePlayText": "Google Play로 로그인",
"signInWithTestAccountInfoText": "(이전 계정 유형, 앞의 기기 계정을 이용하세요)", "signInWithTestAccountInfoText": "(이전 계정 유형, 앞의 기기 계정을 이용하세요)",
"signInWithTestAccountText": "테스트 계정으로 로그인", "signInWithTestAccountText": "테스트 계정으로 로그인",
"signInWithText": "${SERVICE}로 로그인하기",
"signInWithV2InfoText": "(모든 플랫폼에서 작동하는 계정입니다)", "signInWithV2InfoText": "(모든 플랫폼에서 작동하는 계정입니다)",
"signInWithV2Text": "BombSquad 계정으로 로그인", "signInWithV2Text": "BombSquad 계정으로 로그인",
"signOutText": "로그아웃", "signOutText": "로그아웃",
@ -335,6 +336,7 @@
"getMoreGamesText": "다른 게임 보기...", "getMoreGamesText": "다른 게임 보기...",
"titleText": "게임 추가" "titleText": "게임 추가"
}, },
"allText": "모두",
"allowText": "허용", "allowText": "허용",
"alreadySignedInText": "귀하의 계정은 다른 기기에서 로그인되었습니다. \n계정을 전환하거나 다른 기기에서 게임을 종료하고 \n다시 시도하십시오.", "alreadySignedInText": "귀하의 계정은 다른 기기에서 로그인되었습니다. \n계정을 전환하거나 다른 기기에서 게임을 종료하고 \n다시 시도하십시오.",
"apiVersionErrorText": "${NAME} 모듈을 불러올 수 없습니다; ${VERSION_USED} api 버전입니다; ${VERSION_REQUIRED} 버전이 필요합니다.", "apiVersionErrorText": "${NAME} 모듈을 불러올 수 없습니다; ${VERSION_USED} api 버전입니다; ${VERSION_REQUIRED} 버전이 필요합니다.",
@ -367,6 +369,7 @@
"chatMutedText": "채팅 음소거됨.", "chatMutedText": "채팅 음소거됨.",
"chatUnMuteText": "채팅 음소거 해제", "chatUnMuteText": "채팅 음소거 해제",
"choosingPlayerText": "<플레이어 선택>", "choosingPlayerText": "<플레이어 선택>",
"codesExplainText": "계정 문제를 진단하고 수정하기 위해\n개발자가 코드를 제공합니다.",
"completeThisLevelToProceedText": "계속 진행하려면 이 레벨을\n완료해야 합니다!", "completeThisLevelToProceedText": "계속 진행하려면 이 레벨을\n완료해야 합니다!",
"completionBonusText": "완료 보너스", "completionBonusText": "완료 보너스",
"configControllersWindow": { "configControllersWindow": {
@ -447,6 +450,7 @@
"swipeText": "스와이프", "swipeText": "스와이프",
"titleText": "터치스크린 구성" "titleText": "터치스크린 구성"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE}는 시스템 설정 앱에서 구성할 수 있습니다.",
"configureItNowText": "지금 구성하시겠습니까?", "configureItNowText": "지금 구성하시겠습니까?",
"configureText": "구성", "configureText": "구성",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -559,6 +563,9 @@
"disableRemoteAppConnectionsText": "리모트 앱 연결 비활성화", "disableRemoteAppConnectionsText": "리모트 앱 연결 비활성화",
"disableXInputDescriptionText": "4개 이상의 컨트롤러를 허용하지만 아마 잘 작동하지 않을 것입니다.", "disableXInputDescriptionText": "4개 이상의 컨트롤러를 허용하지만 아마 잘 작동하지 않을 것입니다.",
"disableXInputText": "엑스인풋 컨트롤러 비활성화", "disableXInputText": "엑스인풋 컨트롤러 비활성화",
"disabledText": "비활성화만",
"discordFriendsText": "함께 플레이할 새로운 친구를 찾고 싶으신가요?\n디스코드에 가입하여 새로운 친구를 찾아보세요!",
"discordJoinText": "디스코드 가입",
"doneText": "완료", "doneText": "완료",
"drawText": "무승부", "drawText": "무승부",
"duplicateText": "복사", "duplicateText": "복사",
@ -626,6 +633,7 @@
"useMusicFolderText": "음악 파일 폴더" "useMusicFolderText": "음악 파일 폴더"
}, },
"editText": "편집", "editText": "편집",
"enabledText": "활성화만",
"endText": "종료", "endText": "종료",
"enjoyText": "즐기세요!", "enjoyText": "즐기세요!",
"epicDescriptionFilterText": "(에픽 슬로 모션) ${DESCRIPTION}.", "epicDescriptionFilterText": "(에픽 슬로 모션) ${DESCRIPTION}.",
@ -814,10 +822,12 @@
"alwaysText": "언제나", "alwaysText": "언제나",
"fullScreenCmdText": "전체 화면 (Cmd-F)", "fullScreenCmdText": "전체 화면 (Cmd-F)",
"fullScreenCtrlText": "전체 화면 (Ctrl-F)", "fullScreenCtrlText": "전체 화면 (Ctrl-F)",
"fullScreenText": "전체화면",
"gammaText": "감마", "gammaText": "감마",
"highText": "높음", "highText": "높음",
"higherText": "매우 높음", "higherText": "매우 높음",
"lowText": "낮음", "lowText": "낮음",
"maxFPSText": "최대 FPS",
"mediumText": "중간", "mediumText": "중간",
"neverText": "안 함", "neverText": "안 함",
"resolutionText": "해상도", "resolutionText": "해상도",
@ -1056,6 +1066,7 @@
"noExternalStorageErrorText": "이 기기에서 외부 저장소를 찾지 못했습니다.", "noExternalStorageErrorText": "이 기기에서 외부 저장소를 찾지 못했습니다.",
"noGameCircleText": "오류: GameCircle에 로그인되지 않았습니다", "noGameCircleText": "오류: GameCircle에 로그인되지 않았습니다",
"noScoresYetText": "아직 점수 없음.", "noScoresYetText": "아직 점수 없음.",
"noServersFoundText": "서버를 찾을수 없음.",
"noThanksText": "아니요", "noThanksText": "아니요",
"noTournamentsInTestBuildText": "경고: 이 테스트 빌드의 토너먼트 점수는 기록되지 않습니다.", "noTournamentsInTestBuildText": "경고: 이 테스트 빌드의 토너먼트 점수는 기록되지 않습니다.",
"noValidMapsErrorText": "이 게임 유형에 유효한 지도를 찾지 못했습니다.", "noValidMapsErrorText": "이 게임 유형에 유효한 지도를 찾지 못했습니다.",
@ -1220,6 +1231,8 @@
"runText": "달리기", "runText": "달리기",
"saveText": "저장", "saveText": "저장",
"scanScriptsErrorText": "스크립트(들)을 검색하는 중 오류가 발생하였습니다. 자세한 내용은 로그를 확인하십시오.", "scanScriptsErrorText": "스크립트(들)을 검색하는 중 오류가 발생하였습니다. 자세한 내용은 로그를 확인하십시오.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} 및 ${NUM}개의 기타 모듈을 ${API} API에 대해 업데이트를 해야 합니다.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH}는 api ${API}에 대해 업데이트해야 합니다.",
"scoreChallengesText": "점수 챌린지", "scoreChallengesText": "점수 챌린지",
"scoreListUnavailableText": "점수 목록을 이용할 수 없습니다.", "scoreListUnavailableText": "점수 목록을 이용할 수 없습니다.",
"scoreText": "점수", "scoreText": "점수",
@ -1263,6 +1276,7 @@
"netTestingText": "네트워크 테스트", "netTestingText": "네트워크 테스트",
"resetText": "재설정", "resetText": "재설정",
"showBombTrajectoriesText": "폭탄 궤적 표시", "showBombTrajectoriesText": "폭탄 궤적 표시",
"showDevConsoleButtonText": "개발자 콘솔 버튼 보이기",
"showInGamePingText": "인게임 핑 보이기", "showInGamePingText": "인게임 핑 보이기",
"showPlayerNamesText": "플레이어 이름 표시", "showPlayerNamesText": "플레이어 이름 표시",
"showUserModsText": "모드 폴더 표시", "showUserModsText": "모드 폴더 표시",
@ -1355,6 +1369,8 @@
"storeText": "상점", "storeText": "상점",
"submitText": "제출", "submitText": "제출",
"submittingPromoCodeText": "코드 제출 중...", "submittingPromoCodeText": "코드 제출 중...",
"successText": "성공!",
"supportEmailText": "만약 앱에서 문제를 겪고있을경우,\n${EMAIL}로 연락해주세요",
"teamNamesColorText": "팀 이름/색상...", "teamNamesColorText": "팀 이름/색상...",
"telnetAccessGrantedText": "텔넷 액세스가 활성화됨.", "telnetAccessGrantedText": "텔넷 액세스가 활성화됨.",
"telnetAccessText": "텔넷 액세스가 검색됨, 허용하시겠습니까?", "telnetAccessText": "텔넷 액세스가 검색됨, 허용하시겠습니까?",
@ -1808,6 +1824,7 @@
"unlockThisInTheStoreText": "상점에서 잠금 해제해야 합니다.", "unlockThisInTheStoreText": "상점에서 잠금 해제해야 합니다.",
"unlockThisProfilesText": "${NUM}개 이상의 프로필을 만들기 위해, 다음 사항이 필요합니다. :", "unlockThisProfilesText": "${NUM}개 이상의 프로필을 만들기 위해, 다음 사항이 필요합니다. :",
"unlockThisText": "잠금 해제 필요 사항:", "unlockThisText": "잠금 해제 필요 사항:",
"unsupportedControllerText": "죄송합니다, 컨트롤러 \"${NAME}\" 은 지원되지 않습니다.",
"unsupportedHardwareText": "죄송합니다만 이 하드웨어는 본 게임 빌드에 의해 지원되지 않습니다.", "unsupportedHardwareText": "죄송합니다만 이 하드웨어는 본 게임 빌드에 의해 지원되지 않습니다.",
"upFirstText": "첫 번째:", "upFirstText": "첫 번째:",
"upNextText": "게임 ${COUNT}의 다음:", "upNextText": "게임 ${COUNT}의 다음:",
@ -1820,6 +1837,7 @@
"usingItunesTurnRepeatAndShuffleOnText": "iTunes에서 임의 재생이 켜져있고 반복은 모두로 되어 있는지 확인해주십시오.", "usingItunesTurnRepeatAndShuffleOnText": "iTunes에서 임의 재생이 켜져있고 반복은 모두로 되어 있는지 확인해주십시오.",
"v2AccountLinkingInfoText": "V2 계정을 연결하려면 '계정 관리' 버튼을 누르세요.", "v2AccountLinkingInfoText": "V2 계정을 연결하려면 '계정 관리' 버튼을 누르세요.",
"validatingTestBuildText": "테스트 빌드 확인 중...", "validatingTestBuildText": "테스트 빌드 확인 중...",
"viaText": "통하여 로그인 함",
"victoryText": "승리!", "victoryText": "승리!",
"voteDelayText": "${NUMBER} 초 동안 다른 투표를 시작할 수 없습니다.", "voteDelayText": "${NUMBER} 초 동안 다른 투표를 시작할 수 없습니다.",
"voteInProgressText": "투표가 이미 진행 중입니다.", "voteInProgressText": "투표가 이미 진행 중입니다.",

View file

@ -31,6 +31,7 @@
"signInWithGooglePlayText": "ورود با اکانت گوگل پلی", "signInWithGooglePlayText": "ورود با اکانت گوگل پلی",
"signInWithTestAccountInfoText": "(حساب میراثی؛ از حساب‌های دستگاه برای پیشروی استفاده می‌کند)", "signInWithTestAccountInfoText": "(حساب میراثی؛ از حساب‌های دستگاه برای پیشروی استفاده می‌کند)",
"signInWithTestAccountText": "ورود با حساب آزمایشی", "signInWithTestAccountText": "ورود با حساب آزمایشی",
"signInWithText": "با ${SERVICE} وارد شوید",
"signInWithV2InfoText": "یک اکانت که روی همه سیستم عامل ها کار میکنه", "signInWithV2InfoText": "یک اکانت که روی همه سیستم عامل ها کار میکنه",
"signInWithV2Text": "ورود به سیستم با حساب بمب اسکواد", "signInWithV2Text": "ورود به سیستم با حساب بمب اسکواد",
"signOutText": "خروج از حساب", "signOutText": "خروج از حساب",
@ -60,7 +61,7 @@
"descriptionComplete": "بدون استفاده از بمب برنده شدی", "descriptionComplete": "بدون استفاده از بمب برنده شدی",
"descriptionFull": "را بدون استفاده از هیچ بمبی کامل کن ${LEVEL} مرحلهٔ", "descriptionFull": "را بدون استفاده از هیچ بمبی کامل کن ${LEVEL} مرحلهٔ",
"descriptionFullComplete": "را بدون استفاده از بمب کامل کردی ${LEVEL} مرحلهٔ", "descriptionFullComplete": "را بدون استفاده از بمب کامل کردی ${LEVEL} مرحلهٔ",
"name": "بوکسر" "name": "بوکسور!"
}, },
"Dual Wielding": { "Dual Wielding": {
"descriptionFull": "(‏دو دستهٔ به بازی وصل کن (سخت‌افزاری یا نرم‌افزاری", "descriptionFull": "(‏دو دستهٔ به بازی وصل کن (سخت‌افزاری یا نرم‌افزاری",
@ -124,7 +125,7 @@
"descriptionComplete": "سه حریف را با مین زمینی از بین بردی", "descriptionComplete": "سه حریف را با مین زمینی از بین بردی",
"descriptionFull": "با مین از بین ببر ${LEVEL} سه حریف را در مرحلهٔ", "descriptionFull": "با مین از بین ببر ${LEVEL} سه حریف را در مرحلهٔ",
"descriptionFullComplete": "با مین از بین بردی ${LEVEL} سه حریف را در مرحلهٔ", "descriptionFullComplete": "با مین از بین بردی ${LEVEL} سه حریف را در مرحلهٔ",
"name": "بازی مین" "name": "مین بازی"
}, },
"Off You Go Then": { "Off You Go Then": {
"description": "سه تا حریف از نقشه بنداز بیرون", "description": "سه تا حریف از نقشه بنداز بیرون",
@ -262,7 +263,7 @@
"descriptionComplete": "فقط با یک مشت، یه نفرو کشتی", "descriptionComplete": "فقط با یک مشت، یه نفرو کشتی",
"descriptionFull": "فقط با یک مشت، یه نفر رو نابود کن ${LEVEL} در مرحله", "descriptionFull": "فقط با یک مشت، یه نفر رو نابود کن ${LEVEL} در مرحله",
"descriptionFullComplete": "فقط با یک مشت، یه نفر رو کشتی ${LEVEL} در مرحله", "descriptionFullComplete": "فقط با یک مشت، یه نفر رو کشتی ${LEVEL} در مرحله",
"name": "مشت فوق‌العاده" "name": "مشت خیلی فوق‌العاده"
}, },
"Super Punch": { "Super Punch": {
"description": "با یک مشت، نصف جون یه نفر رو ببر", "description": "با یک مشت، نصف جون یه نفر رو ببر",
@ -334,12 +335,14 @@
"getMoreGamesText": "...بازی های بیشتر", "getMoreGamesText": "...بازی های بیشتر",
"titleText": "افزودن بازی" "titleText": "افزودن بازی"
}, },
"addToFavoritesText": "اضافه کردن به مورد علاقه ها",
"addedToFavoritesText": "اضافه شد '${NAME}' به مورد علاقه ها",
"allText": "همه", "allText": "همه",
"allowText": "اجازه دادن", "allowText": "اجازه دادن",
"alreadySignedInText": "این حساب کاربری توسط یک دستگاه دیگر در حال استفاده می باشد.\nلطفا از حساب کاربری دیگری استفاده کنید یا بازی را \nدر بقیه دستگاه هایتان ببندید و دوباره امتحان کنید.", "alreadySignedInText": "این حساب کاربری توسط یک دستگاه دیگر در حال استفاده می باشد.\nلطفا از حساب کاربری دیگری استفاده کنید یا بازی را \nدر بقیه دستگاه هایتان ببندید و دوباره امتحان کنید.",
"apiVersionErrorText": "نیاز داریم ${VERSION_REQUIRED} است. به ورژن ${VERSION_USED} بالا نمی آید. هدفش ${NAME} مدل", "apiVersionErrorText": "نیاز داریم ${VERSION_REQUIRED} است. به ورژن ${VERSION_USED} بالا نمی آید. هدفش ${NAME} مدل",
"audioSettingsWindow": { "audioSettingsWindow": {
"headRelativeVRAudioInfoText": "(به صورت اتوماتیک فعال شود وقتی که هدفون متصل است)", "headRelativeVRAudioInfoText": "(به صورت خودکار فعال شود وقتی که هدفون متصل است)",
"headRelativeVRAudioText": "(صدای واقعیت مجازی(مخصوص هدفون", "headRelativeVRAudioText": "(صدای واقعیت مجازی(مخصوص هدفون",
"musicVolumeText": "صدای موسیقی", "musicVolumeText": "صدای موسیقی",
"soundVolumeText": "صدای بازی", "soundVolumeText": "صدای بازی",
@ -367,6 +370,7 @@
"chatMutedText": "گفتگو بیصدا شد", "chatMutedText": "گفتگو بیصدا شد",
"chatUnMuteText": "گفتگو رو صدادار کن", "chatUnMuteText": "گفتگو رو صدادار کن",
"choosingPlayerText": "<انتخاب بازیکن>", "choosingPlayerText": "<انتخاب بازیکن>",
"codesExplainText": "کدها توسط توسعه دهنده ارائه می شوند\n مشکلات حساب را تشخیص و تصحیح کنید.",
"completeThisLevelToProceedText": "برای ادامه باید این مرحله را تمام کنید", "completeThisLevelToProceedText": "برای ادامه باید این مرحله را تمام کنید",
"completionBonusText": "پاداش به اتمام رساندن", "completionBonusText": "پاداش به اتمام رساندن",
"configControllersWindow": { "configControllersWindow": {
@ -448,6 +452,7 @@
"swipeText": "حرکت جاروبی", "swipeText": "حرکت جاروبی",
"titleText": "پیکربندی صفحه لمسی" "titleText": "پیکربندی صفحه لمسی"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} می‌تواند در سیستم تنظیمات برنامه پیکربندی شود.",
"configureItNowText": "همین الآن تنظیم شود ؟", "configureItNowText": "همین الآن تنظیم شود ؟",
"configureText": "پیکربندی", "configureText": "پیکربندی",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -562,6 +567,8 @@
"disableXInputDescriptionText": "اجازه می‌دهد به بیش از 4 کنترل کننده اما ممکن است کار نکند.", "disableXInputDescriptionText": "اجازه می‌دهد به بیش از 4 کنترل کننده اما ممکن است کار نکند.",
"disableXInputText": "غیرفعال کردن ورودی ایکس", "disableXInputText": "غیرفعال کردن ورودی ایکس",
"disabledText": "غیر فعال شده", "disabledText": "غیر فعال شده",
"discordFriendsText": "دنبال آدم‌های جدید می‌گردید تا با آنها بازی کنید؟\nبه دیسکورد ما بپیوندید و دوستان جدید پیدا کنید!",
"discordJoinText": "پیوستن به دیسکورد",
"doneText": "انجام شد", "doneText": "انجام شد",
"drawText": "برابر", "drawText": "برابر",
"duplicateText": "تکراری", "duplicateText": "تکراری",
@ -747,6 +754,7 @@
"manualYourLocalAddressText": ":آدرس محلی شما", "manualYourLocalAddressText": ":آدرس محلی شما",
"nearbyText": "افراد نزدیک", "nearbyText": "افراد نزدیک",
"noConnectionText": "<اتصال برقرار نیست>", "noConnectionText": "<اتصال برقرار نیست>",
"noPartiesAddedText": "هیچ مهمانی ای اضافه نشده است",
"otherVersionsText": "(نسخه های دیگر)", "otherVersionsText": "(نسخه های دیگر)",
"partyCodeText": "کد گروه", "partyCodeText": "کد گروه",
"partyInviteAcceptText": "پذیرفتن", "partyInviteAcceptText": "پذیرفتن",
@ -818,10 +826,12 @@
"alwaysText": "همیشه", "alwaysText": "همیشه",
"fullScreenCmdText": "تمام صفحه (Cmd-F)", "fullScreenCmdText": "تمام صفحه (Cmd-F)",
"fullScreenCtrlText": "تمام صفحه (Ctrl-F)", "fullScreenCtrlText": "تمام صفحه (Ctrl-F)",
"fullScreenText": "تمام‌صفحه",
"gammaText": "گاما", "gammaText": "گاما",
"highText": "زیاد", "highText": "زیاد",
"higherText": "بالاتر", "higherText": "بالاتر",
"lowText": "کم", "lowText": "کم",
"maxFPSText": "حداکثر FPS",
"mediumText": "معمولی", "mediumText": "معمولی",
"neverText": "هرگز", "neverText": "هرگز",
"resolutionText": "رزولوشن", "resolutionText": "رزولوشن",
@ -1059,7 +1069,9 @@
"noContinuesText": "(ادامه ندارد)", "noContinuesText": "(ادامه ندارد)",
"noExternalStorageErrorText": "محل ذخیره سازی در این دستگاه یافت نشد", "noExternalStorageErrorText": "محل ذخیره سازی در این دستگاه یافت نشد",
"noGameCircleText": "GameCircleخطا: وارد نشدید به", "noGameCircleText": "GameCircleخطا: وارد نشدید به",
"noPluginsInstalledText": "متاسفانه پلاگین ها نصب نشده",
"noScoresYetText": "هیچ امتیازی نیست", "noScoresYetText": "هیچ امتیازی نیست",
"noServersFoundText": "سروری (شبکه ای) یافت نشد",
"noThanksText": "نه مرسی", "noThanksText": "نه مرسی",
"noTournamentsInTestBuildText": ".هشدار: امتیازات مسابقه از این نسخهٔ آزمایشی نادیده گرفته می‌شوند", "noTournamentsInTestBuildText": ".هشدار: امتیازات مسابقه از این نسخهٔ آزمایشی نادیده گرفته می‌شوند",
"noValidMapsErrorText": "هیچ نقشه معتبری برای این نوع بازی یافت نشد.", "noValidMapsErrorText": "هیچ نقشه معتبری برای این نوع بازی یافت نشد.",
@ -1269,6 +1281,7 @@
"netTestingText": "تست شبکه", "netTestingText": "تست شبکه",
"resetText": "باز گرداندن", "resetText": "باز گرداندن",
"showBombTrajectoriesText": "نمایش خط سیر بمب", "showBombTrajectoriesText": "نمایش خط سیر بمب",
"showDevConsoleButtonText": "نشان دادن دکمه توسعه دهنده کنسول",
"showInGamePingText": "نمایش پینگ در بازی", "showInGamePingText": "نمایش پینگ در بازی",
"showPlayerNamesText": "نمایش نام بازیکنان", "showPlayerNamesText": "نمایش نام بازیکنان",
"showUserModsText": "نمایش پوشهٔ سبک بازی‌ها", "showUserModsText": "نمایش پوشهٔ سبک بازی‌ها",
@ -1361,6 +1374,8 @@
"storeText": "فروشگاه", "storeText": "فروشگاه",
"submitText": "ثبت", "submitText": "ثبت",
"submittingPromoCodeText": "...ثبت کردن کد", "submittingPromoCodeText": "...ثبت کردن کد",
"successText": "!موفقیت آمیز بود",
"supportEmailText": "اگر با هر گونه مشکلی مواجه هستید\n برنامه، لطفاً به ${EMAIL} ایمیل بزنید.",
"teamNamesColorText": "نام/رنگ تیم...", "teamNamesColorText": "نام/رنگ تیم...",
"telnetAccessGrantedText": "شبکه ی در دسترس فعال", "telnetAccessGrantedText": "شبکه ی در دسترس فعال",
"telnetAccessText": "شبکه راه دور دردسترس است اجازه میدید؟", "telnetAccessText": "شبکه راه دور دردسترس است اجازه میدید؟",
@ -1371,7 +1386,7 @@
"thankYouText": "تشکر بخاطر حمایت از ما ! از بازی لذت ببرید", "thankYouText": "تشکر بخاطر حمایت از ما ! از بازی لذت ببرید",
"threeKillText": "نابود کردن همزمان سه نفر", "threeKillText": "نابود کردن همزمان سه نفر",
"timeBonusText": "پاداش سرعت عمل", "timeBonusText": "پاداش سرعت عمل",
"timeElapsedText": "زمان سپری شده", "timeElapsedText": "زمان گذشته",
"timeExpiredText": "زمان تمام شده", "timeExpiredText": "زمان تمام شده",
"timeSuffixDaysText": "روز ${COUNT}", "timeSuffixDaysText": "روز ${COUNT}",
"timeSuffixHoursText": "ساعت ${COUNT}", "timeSuffixHoursText": "ساعت ${COUNT}",
@ -1737,7 +1752,7 @@
"If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "اگه یه جعبه نابودگر رو به اشتباه گرفتین کارتون تمومه مگه اینکه ظرف چند\nثانیه یه جعبه ی درمان گیر بیارید", "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "اگه یه جعبه نابودگر رو به اشتباه گرفتین کارتون تمومه مگه اینکه ظرف چند\nثانیه یه جعبه ی درمان گیر بیارید",
"If you stay in one place, you're toast. Run and dodge to survive..": "اگه فقط توی یه مکان ثابت بمونید کباب میشید پس بهتره مرتب توی زمین تحرک داشته باشی", "If you stay in one place, you're toast. Run and dodge to survive..": "اگه فقط توی یه مکان ثابت بمونید کباب میشید پس بهتره مرتب توی زمین تحرک داشته باشی",
"If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "اگر تعداد زیادی از بازیکنان در حال رفت و آمد هستند، بازیکنان \"بیروت انداختن بازیکنان غیرفعال\" را روشن کنید\nتحت تنظیمات در صورتی که کسی فراموش می‌کندپیش از خروج از بازی ترک بازی را بزند.", "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "اگر تعداد زیادی از بازیکنان در حال رفت و آمد هستند، بازیکنان \"بیروت انداختن بازیکنان غیرفعال\" را روشن کنید\nتحت تنظیمات در صورتی که کسی فراموش می‌کندپیش از خروج از بازی ترک بازی را بزند.",
"If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "اگر دستگاه شما بیش از حد گرم می شود یا شما می خواهید برای حفظ قدرت باتری،\nکم کنید \"کیفیت\" یا \"وضوح تصویر\" رو در تنظیمات> گرافیک", "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "اگر دستگاه شما بیش از حد گرم می شود یا شما می خواهید برای حفظ قدرت باتری،\n\"کیفیت\" یا \"وضوح تصویر\" رو در تنظیمات> گرافیک\nکم کنید",
"If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "اگر دیدید که نرخ فریم تصویر کمی متلاطم است کاهش بدید رزولوشن \nیا کیفیت تصویر رو در تنظیمات گرافیک بازی", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "اگر دیدید که نرخ فریم تصویر کمی متلاطم است کاهش بدید رزولوشن \nیا کیفیت تصویر رو در تنظیمات گرافیک بازی",
"In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "توی بازی رساندن پرچم ، باید پرچم تیم شما همون جا باقی بمونه\nاگه تیم حریف پرچم تیم شما رو برداشت باید از دستش کش بری", "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "توی بازی رساندن پرچم ، باید پرچم تیم شما همون جا باقی بمونه\nاگه تیم حریف پرچم تیم شما رو برداشت باید از دستش کش بری",
"In hockey, you'll maintain more speed if you turn gradually.": "روی زمین های یخی ، یه دفعه چرخیدن خیلی از سرعت بازیکن کم میکنه", "In hockey, you'll maintain more speed if you turn gradually.": "روی زمین های یخی ، یه دفعه چرخیدن خیلی از سرعت بازیکن کم میکنه",
@ -1816,6 +1831,7 @@
"unlockThisInTheStoreText": ". این مورد باید در فروشگاه باز شود", "unlockThisInTheStoreText": ". این مورد باید در فروشگاه باز شود",
"unlockThisProfilesText": "برای ایجاد بیش از ${NUM} پروفال٫ احتیاج به این موارد دارید:", "unlockThisProfilesText": "برای ایجاد بیش از ${NUM} پروفال٫ احتیاج به این موارد دارید:",
"unlockThisText": ": برا باز کردن قفل این شما نیاز دارید که", "unlockThisText": ": برا باز کردن قفل این شما نیاز دارید که",
"unsupportedControllerText": "متاسفانه کنترلر \"${NAME}\" پشتیبانی نمی‌شود.",
"unsupportedHardwareText": "با عرض پوزش، این سخت افزار توسط این ساخت بازی پشتیبانی نمی شود.", "unsupportedHardwareText": "با عرض پوزش، این سخت افزار توسط این ساخت بازی پشتیبانی نمی شود.",
"upFirstText": "برای بار اول:", "upFirstText": "برای بار اول:",
"upNextText": "${COUNT} بعدی در بازی", "upNextText": "${COUNT} بعدی در بازی",
@ -1828,6 +1844,7 @@
"usingItunesTurnRepeatAndShuffleOnText": "مطمین شید که شافل روشن است و تکرار کنید همه رو در آیتونز", "usingItunesTurnRepeatAndShuffleOnText": "مطمین شید که شافل روشن است و تکرار کنید همه رو در آیتونز",
"v2AccountLinkingInfoText": "برای پیوند دادن حساب‌های V2، از دکمه «مدیریت حساب» استفاده کنید.", "v2AccountLinkingInfoText": "برای پیوند دادن حساب‌های V2، از دکمه «مدیریت حساب» استفاده کنید.",
"validatingTestBuildText": "... در حال بررسی حالت آزمایشی", "validatingTestBuildText": "... در حال بررسی حالت آزمایشی",
"viaText": "از طریق",
"victoryText": "پیروز شدی!", "victoryText": "پیروز شدی!",
"voteDelayText": ".ثانیه رای گیری کنید ${NUMBER} شما نمیتوانید به مدت", "voteDelayText": ".ثانیه رای گیری کنید ${NUMBER} شما نمیتوانید به مدت",
"voteInProgressText": ".یک رای گیری در حال انجام است", "voteInProgressText": ".یک رای گیری در حال انجام است",

View file

@ -1,18 +1,18 @@
{ {
"accountSettingsWindow": { "accountSettingsWindow": {
"accountNameRules": "Nazwy kont nie mogą zawierać emotikonków ani innych znaków specjalnych", "accountNameRules": "Nazwy kont nie mogą zawierać emotikonów ani innych znaków specjalnych",
"accountProfileText": "(profil konta)", "accountProfileText": "(profil konta)",
"accountsText": "Konta", "accountsText": "Konta",
"achievementProgressText": "Osiągnięcia: ${COUNT} z ${TOTAL}", "achievementProgressText": "Osiągnięcia: ${COUNT} z ${TOTAL}",
"campaignProgressText": "Postęp Kampanii [Trudny]: ${PROGRESS}", "campaignProgressText": "Postęp Kampanii [Trudny]: ${PROGRESS}",
"changeOncePerSeason": "Możesz to zmienić tylko raz na sezon.", "changeOncePerSeason": "Możesz to zmienić tylko raz na sezon.",
"changeOncePerSeasonError": "Musisz poczekać do następnego sezonu by znowu to zmienić (${NUM} dni)", "changeOncePerSeasonError": "Musisz poczekać do następnego sezonu, by znowu to zmienić (${NUM} dni)",
"customName": "Losowa Nazwa", "customName": "Własna Nazwa",
"googlePlayGamesAccountSwitchText": "Jeśli chcesz użyć innego konta Google,\nużyj aplikacji Gry Google Play, aby przełączyć się na to konto.", "googlePlayGamesAccountSwitchText": "Jeśli chcesz użyć innego konta Google,\nużyj aplikacji Gry Google Play, aby przełączyć się na to konto.",
"linkAccountsEnterCodeText": "Wpisz Kod", "linkAccountsEnterCodeText": "Wpisz Kod",
"linkAccountsGenerateCodeText": "Wygeneruj Kod", "linkAccountsGenerateCodeText": "Wygeneruj Kod",
"linkAccountsInfoText": "(przenoś postęp między różnymi platformami)", "linkAccountsInfoText": "(przenoś postęp między różnymi platformami)",
"linkAccountsInstructionsNewText": "Aby połączyć dwa konta, wygeneruj kod na pierwszym,\ni wpisz ten kod na drugim. Postęp z drugiego\nbędzie podzielony między oba konta.\n(Postęp z pierwszego zostanie utracony)\n\nMożesz połączyć do ${COUNT} kont.\n\nWAŻNE: łącz tylko swoje własne konta;\nJeśli łączysz konto ze znajomym, nie będziecie\nmogli grać przez internet w tym samym czasie.", "linkAccountsInstructionsNewText": "Aby połączyć dwa konta, wygeneruj kod na pierwszym\ni wpisz ten kod na drugim. Postęp z drugiego\nbędzie podzielony między oba konta.\n(Postęp z pierwszego konta zostanie utracony)\n\nMożesz połączyć do ${COUNT} kont.\n\nWAŻNE: łącz tylko swoje własne konta;\nJeśli łączysz konto ze znajomym, nie będziecie\nmogli grać przez internet w tym samym czasie.",
"linkAccountsInstructionsText": "By połączyć dwa konta, wygeneruj kod\nna jednym z nich i wpisz na drugim.\nPostęp i ekwipunek zostaną połączone.\nMożesz połączyć do ${COUNT} kont.\n\nUWAGA: Łącz tylko konta, które należą do Ciebie!\nJeśli połączysz konto z przyjacielem,\nnie będziecie mogli grać w tym samym czasie!\n\nAktualnie nie można tego cofnąć, więc uważaj!", "linkAccountsInstructionsText": "By połączyć dwa konta, wygeneruj kod\nna jednym z nich i wpisz na drugim.\nPostęp i ekwipunek zostaną połączone.\nMożesz połączyć do ${COUNT} kont.\n\nUWAGA: Łącz tylko konta, które należą do Ciebie!\nJeśli połączysz konto z przyjacielem,\nnie będziecie mogli grać w tym samym czasie!\n\nAktualnie nie można tego cofnąć, więc uważaj!",
"linkAccountsText": "Połącz Konta", "linkAccountsText": "Połącz Konta",
"linkedAccountsText": "Połączone Konta:", "linkedAccountsText": "Połączone Konta:",
@ -24,19 +24,20 @@
"resetProgressText": "Wyczyść postęp", "resetProgressText": "Wyczyść postęp",
"setAccountName": "Wybierz nazwę konta", "setAccountName": "Wybierz nazwę konta",
"setAccountNameDesc": "Wybierz nazwę do wyświetlenia dla swojego konta.\nMożesz użyć nazwy z jednego z połączonych kont\n lub utworzyć unikalną niestandardową nazwę.", "setAccountNameDesc": "Wybierz nazwę do wyświetlenia dla swojego konta.\nMożesz użyć nazwy z jednego z połączonych kont\n lub utworzyć unikalną niestandardową nazwę.",
"signInInfoText": "Zapisz się, by zbierać kupony, rywalizować online\ni przenosić postęp gry między urządzeniami", "signInInfoText": "Zaloguj się, by zbierać kupony, rywalizować online\ni przenosić postęp gry między urządzeniami",
"signInText": "Zapisz się", "signInText": "Zaloguj się",
"signInWithDeviceInfoText": "(automatyczne konto dostępne tylko z tego urządzenia)", "signInWithDeviceInfoText": "(automatyczne konto dostępne tylko z tego urządzenia)",
"signInWithDeviceText": "Zapisz się kontem z urządzenia.", "signInWithDeviceText": "Zaloguj się kontem urządzenia",
"signInWithGameCircleText": "Zapisz się z Game Circle", "signInWithGameCircleText": "Zaloguj się z Game Circle",
"signInWithGooglePlayText": "Zapisz się kontem Google Play", "signInWithGooglePlayText": "Zaloguj się kontem Google Play",
"signInWithTestAccountInfoText": "Konto.", "signInWithTestAccountInfoText": "(przestarzały typ konta; w przyszłości używaj konta urządzenia)",
"signInWithTestAccountText": "Zapisz się testowym kontem.", "signInWithTestAccountText": "Zaloguj się kontem testowym",
"signInWithText": "Zaloguj się kontem ${SERVICE}",
"signInWithV2InfoText": "(konto działa na wszystkich platformach)", "signInWithV2InfoText": "(konto działa na wszystkich platformach)",
"signInWithV2Text": "Zaloguj się używając konta BombSquad", "signInWithV2Text": "Zaloguj się kontem BombSquad",
"signOutText": "Wypisz się", "signOutText": "Wypisz się",
"signingInText": "Zapisywanie się...", "signingInText": "Trwa logowanie...",
"signingOutText": "Wypisywanie...", "signingOutText": "Trwa wylogowywanie...",
"testAccountWarningCardboardText": "Ostrzeżenie: Zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem Google w momencie\nwspierania gry przez Google Cardboard.\n\nOd tego momentu musisz zdobywać wszystkie kupony w grze.\n(zaktualizuj grę do wersji BombSquad Pro za darmo)", "testAccountWarningCardboardText": "Ostrzeżenie: Zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem Google w momencie\nwspierania gry przez Google Cardboard.\n\nOd tego momentu musisz zdobywać wszystkie kupony w grze.\n(zaktualizuj grę do wersji BombSquad Pro za darmo)",
"testAccountWarningOculusText": "Ostrzeżenie: zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem oculusowym jeszcze w tym roku,\nktóre będzie oferowało zakup kuponów i inne funkcje.\n\nTeraz musisz zarobić wszystkie kupony grając.\n(jednakże możesz uzyskać aktualizację do wersji Pro za darmo)", "testAccountWarningOculusText": "Ostrzeżenie: zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem oculusowym jeszcze w tym roku,\nktóre będzie oferowało zakup kuponów i inne funkcje.\n\nTeraz musisz zarobić wszystkie kupony grając.\n(jednakże możesz uzyskać aktualizację do wersji Pro za darmo)",
"testAccountWarningText": "Ostrzeżenie: możesz się zapisać używając konta \"test\".\nTo konto jest powiązane z konkretnym urządzeniem i \nmoże okresowo się zresetować. (wobec tego proszę nie\nzbierać/odblokowywać rzeczy lub osiągnięć dla tego konta)", "testAccountWarningText": "Ostrzeżenie: możesz się zapisać używając konta \"test\".\nTo konto jest powiązane z konkretnym urządzeniem i \nmoże okresowo się zresetować. (wobec tego proszę nie\nzbierać/odblokowywać rzeczy lub osiągnięć dla tego konta)",
@ -45,7 +46,7 @@
"unlinkAccountsInstructionsText": "Wybierz konto do rozłączenia", "unlinkAccountsInstructionsText": "Wybierz konto do rozłączenia",
"unlinkAccountsText": "Rozłącz konta", "unlinkAccountsText": "Rozłącz konta",
"unlinkLegacyV1AccountsText": "Rozłącz stare konta (V1)", "unlinkLegacyV1AccountsText": "Rozłącz stare konta (V1)",
"v2LinkInstructionsText": "Użyj tego linku aby stworzyć konto lub zaloguj się.", "v2LinkInstructionsText": "Użyj tego linku, aby stworzyć konto lub zaloguj się.",
"viaAccount": "(przez konto ${NAME})", "viaAccount": "(przez konto ${NAME})",
"youAreLoggedInAsText": "Jesteś zalogowany jako:", "youAreLoggedInAsText": "Jesteś zalogowany jako:",
"youAreSignedInAsText": "Jesteś zalogowany jako:" "youAreSignedInAsText": "Jesteś zalogowany jako:"
@ -54,11 +55,11 @@
"achievementText": "Osiągnięcia", "achievementText": "Osiągnięcia",
"achievements": { "achievements": {
"Boom Goes the Dynamite": { "Boom Goes the Dynamite": {
"description": "Zabij 3 złych gości używając TNT", "description": "Zabij 3 złych gości, używając TNT",
"descriptionComplete": "Zabiłeś 3 złych gości używając TNT", "descriptionComplete": "Zabiłeś 3 złych gości, używając TNT",
"descriptionFull": "Zabij 3 złych gości za pomocą TNT w trybie ${LEVEL}", "descriptionFull": "Zabij 3 złych gości za pomocą TNT w trybie ${LEVEL}",
"descriptionFullComplete": "Zabiłeś 3 złych gości za pomocą TNT w trybie ${LEVEL}", "descriptionFullComplete": "Zabiłeś 3 złych gości za pomocą TNT w trybie ${LEVEL}",
"name": "Uwaga Leci Dynamit" "name": "Uwaga, Leci Dynamit"
}, },
"Boxer": { "Boxer": {
"description": "Wygraj bez używania bomb", "description": "Wygraj bez używania bomb",
@ -339,6 +340,8 @@
"getMoreGamesText": "Więcej rozgrywek...", "getMoreGamesText": "Więcej rozgrywek...",
"titleText": "Dodaj grę" "titleText": "Dodaj grę"
}, },
"addToFavoritesText": "Dodaj do ulubionych",
"addedToFavoritesText": "Dodano '${NAME}' do ulubionych",
"allText": "Wszystko", "allText": "Wszystko",
"allowText": "Zezwól", "allowText": "Zezwól",
"alreadySignedInText": "Twoje konto jest zalogowane z innego urządzenia;\nproszę zmienić konta lub zamknąć grę na innych\nurządzeniach i spróbować ponownie.", "alreadySignedInText": "Twoje konto jest zalogowane z innego urządzenia;\nproszę zmienić konta lub zamknąć grę na innych\nurządzeniach i spróbować ponownie.",
@ -367,7 +370,7 @@
"bombText": "Bomba", "bombText": "Bomba",
"boostText": "Dopalacz", "boostText": "Dopalacz",
"bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} jest konfigurowany w samej aplikacji.", "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} jest konfigurowany w samej aplikacji.",
"buttonText": "Przycisk", "buttonText": "przycisk",
"canWeDebugText": "Chcesz aby BombSquad automatycznie raportował błędy,\nawarie i podstawowe informacje o użytkowaniu deweloperowi?\n\nPrzesyłane dane nie będą zawierać Twoich osobistych danych,\na pomogą jedynie poprawić działanie gry i usunąć jej błędy.", "canWeDebugText": "Chcesz aby BombSquad automatycznie raportował błędy,\nawarie i podstawowe informacje o użytkowaniu deweloperowi?\n\nPrzesyłane dane nie będą zawierać Twoich osobistych danych,\na pomogą jedynie poprawić działanie gry i usunąć jej błędy.",
"cancelText": "Anuluj", "cancelText": "Anuluj",
"cantConfigureDeviceText": "Wybacz ale ${DEVICE} nie jest konfigurowalne.", "cantConfigureDeviceText": "Wybacz ale ${DEVICE} nie jest konfigurowalne.",
@ -376,6 +379,7 @@
"chatMutedText": "Czat Wyciszony", "chatMutedText": "Czat Wyciszony",
"chatUnMuteText": "Podgłośnij Czat", "chatUnMuteText": "Podgłośnij Czat",
"choosingPlayerText": "<wybieram gracza>", "choosingPlayerText": "<wybieram gracza>",
"codesExplainText": "Kody są dostarczane przez dewelopera w celu\ndiagnozowania i poprawiania problemów z kontem.",
"completeThisLevelToProceedText": "Musisz ukończyć ten\netap aby kontynuować!", "completeThisLevelToProceedText": "Musisz ukończyć ten\netap aby kontynuować!",
"completionBonusText": "Bonusowe zakończenie", "completionBonusText": "Bonusowe zakończenie",
"configControllersWindow": { "configControllersWindow": {
@ -392,7 +396,7 @@
}, },
"configGamepadSelectWindow": { "configGamepadSelectWindow": {
"androidNoteText": "Uwaga: wsparcie kontrolera uzależnione jest od urządzenia i wersji Androida.", "androidNoteText": "Uwaga: wsparcie kontrolera uzależnione jest od urządzenia i wersji Androida.",
"pressAnyButtonText": "Naciśnij dowolny na kontrolerze,\nktórego chcesz skonfigurować...", "pressAnyButtonText": "Naciśnij dowolny przycisk na kontrolerze,\nktórego chcesz skonfigurować...",
"titleText": "Skonfiguruj Kontrolery" "titleText": "Skonfiguruj Kontrolery"
}, },
"configGamepadWindow": { "configGamepadWindow": {
@ -400,8 +404,8 @@
"advancedTitleText": "Zaawansowane ustawienia Kontrolera", "advancedTitleText": "Zaawansowane ustawienia Kontrolera",
"analogStickDeadZoneDescriptionText": "(włącz jeśli Twoja postać dryfuje po zwolnieniu drążka)", "analogStickDeadZoneDescriptionText": "(włącz jeśli Twoja postać dryfuje po zwolnieniu drążka)",
"analogStickDeadZoneText": "Martwa strefa analogowego drążka", "analogStickDeadZoneText": "Martwa strefa analogowego drążka",
"appliesToAllText": "(zastosuj dla wszystkich kontrolerów tego typu)", "appliesToAllText": "(dotyczy wszystkich kontrolerów tego typu)",
"autoRecalibrateDescriptionText": "(aktywuj jeśli Twoja postać nie porusza się z pełną szybkością)", "autoRecalibrateDescriptionText": "(aktywuj, jeśli Twoja postać nie porusza się z pełną szybkością)",
"autoRecalibrateText": "Auto kalibracja drążka analogowego", "autoRecalibrateText": "Auto kalibracja drążka analogowego",
"axisText": "oś", "axisText": "oś",
"clearText": "wyczyść", "clearText": "wyczyść",
@ -426,7 +430,7 @@
"runButton2Text": "Uruchom przycisk 2", "runButton2Text": "Uruchom przycisk 2",
"runTrigger1Text": "Uruchom spust 1", "runTrigger1Text": "Uruchom spust 1",
"runTrigger2Text": "Uruchom spust 2", "runTrigger2Text": "Uruchom spust 2",
"runTriggerDescriptionText": "(analogowe triggery pozwalają na uruchomione przy różnych prędkościach)", "runTriggerDescriptionText": "(analogowe triggery pozwalają ci biec przy różnych prędkościach)",
"secondHalfText": "Użyj aby skonfigurować drugiego kontrolera,\nktóry widoczny jest jako pierwszy będąc\npodłączonym do tego samego urządzenia.", "secondHalfText": "Użyj aby skonfigurować drugiego kontrolera,\nktóry widoczny jest jako pierwszy będąc\npodłączonym do tego samego urządzenia.",
"secondaryEnableText": "Aktywuj", "secondaryEnableText": "Aktywuj",
"secondaryText": "Drugi Kontroler", "secondaryText": "Drugi Kontroler",
@ -459,16 +463,17 @@
"titleText": "Skonfiguruj ekran dotykowy", "titleText": "Skonfiguruj ekran dotykowy",
"touchControlsScaleText": "Skala przycisków dotykowych" "touchControlsScaleText": "Skala przycisków dotykowych"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} może zostać skonfigurowany w ustawieniach systemu.",
"configureItNowText": "Skonfigurować teraz?", "configureItNowText": "Skonfigurować teraz?",
"configureText": "Skonfiguruj", "configureText": "Skonfiguruj",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
"amazonText": "Sklep Amazon", "amazonText": "Sklep Amazon",
"appStoreText": "App Store", "appStoreText": "App Store",
"bestResultsText": "Dla lepszych efektów stwórz szybką sieć bezprzewodową.\nMożesz zredukować opóźnienia w grze poprzez: wyłączenie innych\nurządzeń korzystających w czasie gry z sieci wifi, będąc\nodpowiednio blisko routera wifi lub podpięcie się do hosta\nbezpośrednio przewodem sieciowym.", "bestResultsText": "Dla lepszych efektów użyj szybkiej sieci bezprzewodowej. Możesz\nzredukować opóźnienia w grze poprzez wyłączenie innych urządzeń\nkorzystających w czasie gry z sieci wifi, bycie odpowiednio blisko\nroutera wifi lub podpięcie się do hosta bezpośrednio przewodem sieciowym.",
"explanationText": "Aby użyć smartfona lub tableta jako kontrolera w grze,\nzainstaluj na nim aplikację ${REMOTE_APP_NAME}. Do gry ${APP_NAME} można\nprzyłączyć dowolną ilość urządzeń poprzez sieć WiFi i to całkowicie za darmo!", "explanationText": "Aby użyć smartfona lub tableta jako kontrolera w grze,\nzainstaluj na nim aplikację ${REMOTE_APP_NAME}. Do gry ${APP_NAME} można\nprzyłączyć dowolną ilość urządzeń poprzez sieć WiFi i to całkowicie za darmo!",
"forAndroidText": "dla Androida:", "forAndroidText": "dla Androida:",
"forIOSText": "dla iOS:", "forIOSText": "dla iOS:",
"getItForText": "Pobierz ${REMOTE_APP_NAME} dla systemu iOS ze sklepu Apple, a \ndla systemu Android ze sklepu Google Play lub Amazon Appstore.", "getItForText": "Pobierz ${REMOTE_APP_NAME} dla systemu iOS ze sklepu Apple, a \ndla systemu Android ze sklepu Google Play lub Amazon Appstore",
"googlePlayText": "Google Play", "googlePlayText": "Google Play",
"titleText": "Używanie urządzeń mobilnych jako kontrolerów:" "titleText": "Używanie urządzeń mobilnych jako kontrolerów:"
}, },
@ -502,7 +507,7 @@
"powerRankingPointsToRankedText": "(${CURRENT} z ${REMAINING} pkt)", "powerRankingPointsToRankedText": "(${CURRENT} z ${REMAINING} pkt)",
"powerRankingText": "Osiągnięcia", "powerRankingText": "Osiągnięcia",
"prizesText": "Nagrody", "prizesText": "Nagrody",
"proMultInfoText": "Gracze z aktualizacją ${PRO} otrzymują\n${PERCENT}% punktów więcej.", "proMultInfoText": "Gracze z ulepszeniem ${PRO} otrzymują\n${PERCENT}% punktów więcej.",
"seeMoreText": "Więcej...", "seeMoreText": "Więcej...",
"skipWaitText": "Pomiń oczekiwanie", "skipWaitText": "Pomiń oczekiwanie",
"timeRemainingText": "Pozostały czas", "timeRemainingText": "Pozostały czas",
@ -529,7 +534,7 @@
"legalText": "Prawa autorskie:", "legalText": "Prawa autorskie:",
"publicDomainMusicViaText": "Podkład muzyczny - ${NAME}", "publicDomainMusicViaText": "Podkład muzyczny - ${NAME}",
"softwareBasedOnText": "To oprogramowanie jest częściowo oparte na pracy ${NAME}", "softwareBasedOnText": "To oprogramowanie jest częściowo oparte na pracy ${NAME}",
"songCreditText": "${TITLE} wykonywana przez ${PERFORMER}.\nSkomponowana przez ${COMPOSER}. Zorganizowana przez ${ARRANGER}.\nOpublikowana przez ${PUBLISHER}.\nDzięki uprzejmości ${SOURCE}", "songCreditText": "${TITLE} wykonywana przez ${PERFORMER}.\nSkomponowana przez ${COMPOSER}. Zorganizował ją ${ARRANGER}.\nOpublikowana przez ${PUBLISHER}, dzięki uprzejmości ${SOURCE}.",
"soundAndMusicText": "Dźwięk i muzyka:", "soundAndMusicText": "Dźwięk i muzyka:",
"soundsText": "Dźwięki (${SOURCE}):", "soundsText": "Dźwięki (${SOURCE}):",
"specialThanksText": "Specjalne podziękowania dla:", "specialThanksText": "Specjalne podziękowania dla:",
@ -573,12 +578,14 @@
"difficultyEasyText": "Łatwy", "difficultyEasyText": "Łatwy",
"difficultyHardOnlyText": "Tylko w trudnym trybie", "difficultyHardOnlyText": "Tylko w trudnym trybie",
"difficultyHardText": "Trudny", "difficultyHardText": "Trudny",
"difficultyHardUnlockOnlyText": "Ten poziom może zostać odblokowany tylko w trudnym trybie.\nCzy uważasz, że posiadasz to czego wymaga?!", "difficultyHardUnlockOnlyText": "Ten poziom może zostać odblokowany tylko w trudnym trybie.\nCzy uważasz, że posiadasz to, czego wymaga?!?!",
"directBrowserToURLText": "Proszę, otwórz przeglądarkę na podanym adresie:", "directBrowserToURLText": "Proszę, otwórz przeglądarkę na podanym adresie:",
"disableRemoteAppConnectionsText": "Wyłącz łączenia aplikacji BS-Remote", "disableRemoteAppConnectionsText": "Wyłącz łączenia aplikacji BS-Remote",
"disableXInputDescriptionText": "Pozwala na podłączenie 4 kontrolerów, ale może nie działać.", "disableXInputDescriptionText": "Pozwala na podłączenie 4 kontrolerów, ale może nie działać.",
"disableXInputText": "Wyłącz XInput", "disableXInputText": "Wyłącz XInput",
"disabledText": "Wyłączone", "disabledText": "Wyłączone",
"discordFriendsText": "Chcesz poszukać nowych ludzi do gry?\nDołącz do naszego Discorda i znajdź nowych znajomych!",
"discordJoinText": "Dołącz do Discorda",
"doneText": "Gotowe", "doneText": "Gotowe",
"drawText": "Remis", "drawText": "Remis",
"duplicateText": "Duplikuj", "duplicateText": "Duplikuj",
@ -616,7 +623,7 @@
"randomText": "losuj", "randomText": "losuj",
"titleEditText": "Edytuj profil", "titleEditText": "Edytuj profil",
"titleNewText": "Nowy profil", "titleNewText": "Nowy profil",
"unavailableText": "\"${NAME}\" jest zajęta, spróbuj innej.", "unavailableText": "Nazwa \"${NAME}\" jest zajęta; spróbuj innej.",
"upgradeProfileInfoText": "To zarezerwuje nazwę gracza tylko dla\nciebie i pozwoli ci dodać do niego ikonkę.", "upgradeProfileInfoText": "To zarezerwuje nazwę gracza tylko dla\nciebie i pozwoli ci dodać do niego ikonkę.",
"upgradeToGlobalProfileText": "Ulepsz do Profilu Globalnego" "upgradeToGlobalProfileText": "Ulepsz do Profilu Globalnego"
}, },
@ -666,7 +673,7 @@
"exportSuccessText": "'${NAME}' eksportowane.", "exportSuccessText": "'${NAME}' eksportowane.",
"externalStorageText": "Pamięć zewnętrzna", "externalStorageText": "Pamięć zewnętrzna",
"failText": "Niepowodzenie", "failText": "Niepowodzenie",
"fatalErrorText": "O nie, czegoś brakuje lub jest uszkodzone.\nSpróbuj przeinstalować grę lub skontaktuj się \npoprzez ${EMAIL} dla uzyskania pomocy.", "fatalErrorText": "O nie, czegoś brakuje lub coś jest uszkodzone.\nSpróbuj przeinstalować grę lub skontaktuj się \npoprzez ${EMAIL} dla uzyskania pomocy.",
"fileSelectorWindow": { "fileSelectorWindow": {
"titleFileFolderText": "Wybierz plik lub katalog", "titleFileFolderText": "Wybierz plik lub katalog",
"titleFileText": "Wybierz plik", "titleFileText": "Wybierz plik",
@ -711,7 +718,7 @@
"gamesToText": "${WINCOUNT} do ${LOSECOUNT}", "gamesToText": "${WINCOUNT} do ${LOSECOUNT}",
"gatherWindow": { "gatherWindow": {
"aboutDescriptionLocalMultiplayerExtraText": "Pamiętaj: każde urządzenie podczas imprezy może posiadać\nwięcej niż jednego gracza jeśli masz więcej kontrolerów.", "aboutDescriptionLocalMultiplayerExtraText": "Pamiętaj: każde urządzenie podczas imprezy może posiadać\nwięcej niż jednego gracza jeśli masz więcej kontrolerów.",
"aboutDescriptionText": "Używaj tych zakładek aby zorganizować imprezę.\n\nImprezy pozwalają na organizowanie rozgrywek i\nturniejów ze znajomymi wykorzystując różne urządzenia.\n\nUżyj przycisku ${PARTY} w prawym górnym rogu aby\nrozmawiać i współdziałać podczas imprezy.\n(na kontrolerze wciśnij ${BUTTON} gdy jesteś w menu)", "aboutDescriptionText": "Używaj tych zakładek, aby zorganizować imprezę.\n\nImprezy pozwalają na organizowanie rozgrywek i\nturniejów ze znajomymi, wykorzystując różne urządzenia.\n\nUżyj przycisku ${PARTY} w prawym górnym rogu, aby\nrozmawiać i współdziałać podczas imprezy.\n(na kontrolerze wciśnij ${BUTTON}, gdy jesteś w menu)",
"aboutText": "Info", "aboutText": "Info",
"addressFetchErrorText": "<błąd pobierania adresów>", "addressFetchErrorText": "<błąd pobierania adresów>",
"appInviteInfoText": "Zaproś przyjaciół by wypróbowali BombSquada, a dostaną \n${COUNT} darmowych kuponów. Dostaniesz ${YOU_COUNT}\nza każdego ktory wypróbuje.", "appInviteInfoText": "Zaproś przyjaciół by wypróbowali BombSquada, a dostaną \n${COUNT} darmowych kuponów. Dostaniesz ${YOU_COUNT}\nza każdego ktory wypróbuje.",
@ -741,13 +748,13 @@
"friendPromoCodeExpireText": "Ten kod wygaśnie po ${EXPIRE_HOURS} godzinach i działa tylko dla nowych graczy.", "friendPromoCodeExpireText": "Ten kod wygaśnie po ${EXPIRE_HOURS} godzinach i działa tylko dla nowych graczy.",
"friendPromoCodeInfoText": "Może zostać wykupione do ${COUNT} kuponów.\n\nIdź do \"Ustawienia->Zaawansowane->Wpisz Kod Promocyjny\" w grze aby go użyć. Idź do bombsquadgame.com by pobrać\nlinki do wszystkich wspieranych platform. Ten kod\nwygaśnie w ${EXPIRE_HOURS} godzin i jest prawidłowy tylko dla nowych graczy.", "friendPromoCodeInfoText": "Może zostać wykupione do ${COUNT} kuponów.\n\nIdź do \"Ustawienia->Zaawansowane->Wpisz Kod Promocyjny\" w grze aby go użyć. Idź do bombsquadgame.com by pobrać\nlinki do wszystkich wspieranych platform. Ten kod\nwygaśnie w ${EXPIRE_HOURS} godzin i jest prawidłowy tylko dla nowych graczy.",
"friendPromoCodeInstructionsText": "Aby użyć, otwórz ${APP_NAME} i idź do \"Ustawienia->Zaawansowane-> Wpisz kod\".\nWejdź na bombsquadgame.com by zobaczyć linki dla wszystkich dostępnych platform (Android itp.)", "friendPromoCodeInstructionsText": "Aby użyć, otwórz ${APP_NAME} i idź do \"Ustawienia->Zaawansowane-> Wpisz kod\".\nWejdź na bombsquadgame.com by zobaczyć linki dla wszystkich dostępnych platform (Android itp.)",
"friendPromoCodeRedeemLongText": "Może być żądane do ${COUNT} darmowych kuponów dla najwięcej ${MAX_USES} ludzi.", "friendPromoCodeRedeemLongText": "Wykorzystanie go daje ${COUNT} darmowych kuponów dla najwięcej ${MAX_USES} ludzi.",
"friendPromoCodeRedeemShortText": "Może być żądane do ${COUNT} kuponów w grze.", "friendPromoCodeRedeemShortText": "Może być żądane do ${COUNT} kuponów w grze.",
"friendPromoCodeWhereToEnterText": "(W \"Ustawienia->Zaawansowane->Wpisz kod\")", "friendPromoCodeWhereToEnterText": "(W \"Ustawienia->Zaawansowane->Wpisz kod\")",
"getFriendInviteCodeText": "Zdobądź kod promocyjny kumpla", "getFriendInviteCodeText": "Zdobądź kod promocyjny kumpla",
"googlePlayDescriptionText": "Zaproś użytkowników Google Play na imprezę:", "googlePlayDescriptionText": "Zaproś użytkowników Google Play na imprezę:",
"googlePlayInviteText": "Zaproś", "googlePlayInviteText": "Zaproś",
"googlePlayReInviteText": "Obecnie jest ${COUNT} graczy Google Play'a na imprezie,\nktórzy zostaną rozłączeni jeśli uruchomisz nowe zaproszenie.\nUwzględnij ich w nowym zaproszeniu, aby mogli powrócić.", "googlePlayReInviteText": "Obecnie jest ${COUNT} graczy z Google Play'a na imprezie,\nktórzy zostaną rozłączeni jeśli uruchomisz nowe zaproszenie.\nUwzględnij ich w nowym zaproszeniu, aby mogli powrócić.",
"googlePlaySeeInvitesText": "Zobacz zaproszenia", "googlePlaySeeInvitesText": "Zobacz zaproszenia",
"googlePlayText": "Google Play", "googlePlayText": "Google Play",
"googlePlayVersionOnlyText": "(Tylko Android / Google Play)", "googlePlayVersionOnlyText": "(Tylko Android / Google Play)",
@ -775,11 +782,12 @@
"manualYourLocalAddressText": "Twój adres lokalny:", "manualYourLocalAddressText": "Twój adres lokalny:",
"nearbyText": "W pobliżu", "nearbyText": "W pobliżu",
"noConnectionText": "<brak połączenia>", "noConnectionText": "<brak połączenia>",
"noPartiesAddedText": "Nie dodano imprez",
"otherVersionsText": "(Inne wersje)", "otherVersionsText": "(Inne wersje)",
"partyCodeText": "Kod imprezy", "partyCodeText": "Kod imprezy",
"partyInviteAcceptText": "Akceptuj", "partyInviteAcceptText": "Akceptuj",
"partyInviteDeclineText": "Ignoruj", "partyInviteDeclineText": "Ignoruj",
"partyInviteGooglePlayExtraText": "(zobacz zakładkę 'Google Play' w oknie 'Punkt Zborny')", "partyInviteGooglePlayExtraText": "(zobacz zakładkę 'Google Play' w oknie 'Zbiórka')",
"partyInviteIgnoreText": "Ignoruj", "partyInviteIgnoreText": "Ignoruj",
"partyInviteText": "${NAME} zaprosił Cię abyś\ndołączył do ich imprezy.", "partyInviteText": "${NAME} zaprosił Cię abyś\ndołączył do ich imprezy.",
"partyNameText": "Nazwa Imprezy", "partyNameText": "Nazwa Imprezy",
@ -807,7 +815,7 @@
"startHostingText": "Hostuj", "startHostingText": "Hostuj",
"startStopHostingMinutesText": "Możesz rozpocząć i zakończyć hostowanie za darmo przez następne ${MINUTES} minut.", "startStopHostingMinutesText": "Możesz rozpocząć i zakończyć hostowanie za darmo przez następne ${MINUTES} minut.",
"stopHostingText": "Zakończ hostowanie", "stopHostingText": "Zakończ hostowanie",
"titleText": "Punkt Zborny", "titleText": "Zbiórka",
"wifiDirectDescriptionBottomText": "Jeśli wszystkie urządzenia posiadają panel 'Wi-Fi Direct', to powinny użyć go aby\nodnaleźć i połączyć się między sobą. Kiedy wszystkie są już połączone, możesz utworzyć\nimprezę używając zakładki 'Lokalna sieć', tak samo jak w standardowej sieci Wi-Fi.\n\nDla optymalnego działania, host Wi-Fi Direct powinien być hostem imprezy w ${APP_NAME}.", "wifiDirectDescriptionBottomText": "Jeśli wszystkie urządzenia posiadają panel 'Wi-Fi Direct', to powinny użyć go aby\nodnaleźć i połączyć się między sobą. Kiedy wszystkie są już połączone, możesz utworzyć\nimprezę używając zakładki 'Lokalna sieć', tak samo jak w standardowej sieci Wi-Fi.\n\nDla optymalnego działania, host Wi-Fi Direct powinien być hostem imprezy w ${APP_NAME}.",
"wifiDirectDescriptionTopText": "Wi-Fi Direct może być używany do bezpośredniego łączenia urządzeń na\nAndroidzie bez konieczności stosowania sieci Wi-Fi. Najlepiej działa na\nurządzeniach z systemem Android 4.2 lub nowszym.\nAby go użyć, otwórz ustawienia Wi-Fi urządzenia i odszukaj 'Wi-Fi Direct'.", "wifiDirectDescriptionTopText": "Wi-Fi Direct może być używany do bezpośredniego łączenia urządzeń na\nAndroidzie bez konieczności stosowania sieci Wi-Fi. Najlepiej działa na\nurządzeniach z systemem Android 4.2 lub nowszym.\nAby go użyć, otwórz ustawienia Wi-Fi urządzenia i odszukaj 'Wi-Fi Direct'.",
"wifiDirectOpenWiFiSettingsText": "Otwórz ustawienia Wi-Fi", "wifiDirectOpenWiFiSettingsText": "Otwórz ustawienia Wi-Fi",
@ -824,7 +832,7 @@
"titleText": "Zdobądź monety" "titleText": "Zdobądź monety"
}, },
"getTicketsWindow": { "getTicketsWindow": {
"freeText": "DARMOWE!", "freeText": "ZA DARMO!",
"freeTicketsText": "Darmowe kupony", "freeTicketsText": "Darmowe kupony",
"inProgressText": "Transakcja w toku; proszę spróbować za chwilkę.", "inProgressText": "Transakcja w toku; proszę spróbować za chwilkę.",
"purchasesRestoredText": "Zakupy przywrócone.", "purchasesRestoredText": "Zakupy przywrócone.",
@ -834,7 +842,7 @@
"ticketPack1Text": "Mała paczka kuponów", "ticketPack1Text": "Mała paczka kuponów",
"ticketPack2Text": "Średnia paczka kuponów", "ticketPack2Text": "Średnia paczka kuponów",
"ticketPack3Text": "Duża paczka kuponów", "ticketPack3Text": "Duża paczka kuponów",
"ticketPack4Text": "Paczka Kolos kuponów", "ticketPack4Text": "Kolosalna paczka kuponów",
"ticketPack5Text": "Mamucia paczka kuponów", "ticketPack5Text": "Mamucia paczka kuponów",
"ticketPack6Text": "Paczka Ultimate kuponów", "ticketPack6Text": "Paczka Ultimate kuponów",
"ticketsFromASponsorText": "Obejrzyj reklamę\ndla ${COUNT} kuponów", "ticketsFromASponsorText": "Obejrzyj reklamę\ndla ${COUNT} kuponów",
@ -855,10 +863,12 @@
"alwaysText": "Zawsze", "alwaysText": "Zawsze",
"fullScreenCmdText": "Pełny ekran (Cmd-F)", "fullScreenCmdText": "Pełny ekran (Cmd-F)",
"fullScreenCtrlText": "Pełny ekran (Ctrl+F)", "fullScreenCtrlText": "Pełny ekran (Ctrl+F)",
"fullScreenText": "Pełny ekran",
"gammaText": "Gamma", "gammaText": "Gamma",
"highText": "Wysokie", "highText": "Wysokie",
"higherText": "Max", "higherText": "Max",
"lowText": "Niskie", "lowText": "Niskie",
"maxFPSText": "Maks FPS",
"mediumText": "Średnie", "mediumText": "Średnie",
"neverText": "Nigdy", "neverText": "Nigdy",
"resolutionText": "Rozdzielczość", "resolutionText": "Rozdzielczość",
@ -872,7 +882,7 @@
"helpWindow": { "helpWindow": {
"bombInfoText": "- Bomba -\nSilniejsza niż ciosy, lecz\nz powodu obrażeń może Cię\nwpędzić do grobu. Dla\nlepszego efektu wyrzuć ją przed\nwypaleniem się lontu.", "bombInfoText": "- Bomba -\nSilniejsza niż ciosy, lecz\nz powodu obrażeń może Cię\nwpędzić do grobu. Dla\nlepszego efektu wyrzuć ją przed\nwypaleniem się lontu.",
"canHelpText": "${APP_NAME} może Ci w tym pomóc", "canHelpText": "${APP_NAME} może Ci w tym pomóc",
"controllersInfoText": "Możesz zagrać w ${APP_NAME} ze znajomymi poprzez sieć lub na tym\nsamym urządzeniu jeśli masz wystarczająco dużo kontrolerów.\n${APP_NAME} obsługuje wiele z nich; możesz nawet użyć smartfonów\njako kontrolery wykorzystując aplikację '${REMOTE_APP_NAME}'.\nZobacz Ustawienia->Kontrolery, aby uzyskać szczegółowe informacje", "controllersInfoText": "Możesz zagrać w ${APP_NAME} ze znajomymi poprzez sieć lub na tym\nsamym urządzeniu, jeśli masz wystarczająco dużo kontrolerów.\n${APP_NAME} obsługuje wiele z nich; możesz nawet użyć smartfonów\njako kontrolery, wykorzystując aplikację '${REMOTE_APP_NAME}'.\nZobacz Ustawienia->Kontrolery, aby uzyskać szczegółowe informacje.",
"controllersInfoTextFantasia": "Gracz może używać zdalnego kontrolera, jednak zalecane są\ngamepady. Możesz także użyć urządzeń mobilnych jako kontrolerów\ngry za pomocą darmowej aplikacji 'BombSquad Remote'.\nSprawdź informacje dostępne w ustawieniach kontrolerów.", "controllersInfoTextFantasia": "Gracz może używać zdalnego kontrolera, jednak zalecane są\ngamepady. Możesz także użyć urządzeń mobilnych jako kontrolerów\ngry za pomocą darmowej aplikacji 'BombSquad Remote'.\nSprawdź informacje dostępne w ustawieniach kontrolerów.",
"controllersInfoTextMac": "Jeden lub dwóch graczy może używać klawiatury, jednak najlepiej korzystać z\ngamepadów. Gra obsługuje pady USB, kontrolery PS3, Xbox360, Wiimote i urządzenia\nz systemem iOS/Android. Na pewno coś z tego posiadasz aby sterować postaciami?\nWięcej informacji dostępnych jest w ustawieniach kontrolerów.", "controllersInfoTextMac": "Jeden lub dwóch graczy może używać klawiatury, jednak najlepiej korzystać z\ngamepadów. Gra obsługuje pady USB, kontrolery PS3, Xbox360, Wiimote i urządzenia\nz systemem iOS/Android. Na pewno coś z tego posiadasz aby sterować postaciami?\nWięcej informacji dostępnych jest w ustawieniach kontrolerów.",
"controllersInfoTextOuya": "Do gry w BombSquad możesz wykorzystać kontrolery OUYA, PS3, Xbox360\ni wiele innych gamepadów podłączanych za pomocą USB lub Bluetootha.\nMożesz również używać jako kontrolery urządzenia z systemami iOS/Android\nz pomocą darmowej aplikacji 'BombSquad Remote'. Więcej informacji w\nustawieniach kontrolerów.", "controllersInfoTextOuya": "Do gry w BombSquad możesz wykorzystać kontrolery OUYA, PS3, Xbox360\ni wiele innych gamepadów podłączanych za pomocą USB lub Bluetootha.\nMożesz również używać jako kontrolery urządzenia z systemami iOS/Android\nz pomocą darmowej aplikacji 'BombSquad Remote'. Więcej informacji w\nustawieniach kontrolerów.",
@ -880,7 +890,7 @@
"controllersText": "Kontrolery", "controllersText": "Kontrolery",
"controlsSubtitleText": "Twoja postać w ${APP_NAME} posiada kilka podstawowych umiejętności:", "controlsSubtitleText": "Twoja postać w ${APP_NAME} posiada kilka podstawowych umiejętności:",
"controlsText": "Przyciski", "controlsText": "Przyciski",
"devicesInfoText": "Wersja VR ${APP_NAME} może być używana w rozgrywce sieciowej wraz z\nwersją regularną, więc wbijaj do gry ze swoimi telefonami, tabletami\ni komputerami do rozgrywki. Wersja regularna gry może być również\nwykorzystana do przyłączenia się zainteresowanych do wersji VR aby\npokazać jak wygląda rozgrywka.", "devicesInfoText": "Wersja VR ${APP_NAME} może być używana w rozgrywce sieciowej wraz z\nwersją regularną, więc wyciągaj swoje dodatkowe telefony, tablety\noraz komputery i wbijaj do gry. Regularną wersję gry można nawet\nużyć do połączenia się z wersją VR tylko po to, aby umożliwić\nludziom z zewnątrz oglądanie tej akcji.",
"devicesText": "Urządzenia", "devicesText": "Urządzenia",
"friendsGoodText": "Dobrze ich mieć. ${APP_NAME} sprawia największą frajdę\nz kilkoma graczami. Gra może obsłużyć do 8 graczy jednocześnie.", "friendsGoodText": "Dobrze ich mieć. ${APP_NAME} sprawia największą frajdę\nz kilkoma graczami. Gra może obsłużyć do 8 graczy jednocześnie.",
"friendsText": "Znajomych", "friendsText": "Znajomych",
@ -1105,8 +1115,10 @@
"noExternalStorageErrorText": "Brak pamięci zewnętrznej w tym urządzeniu", "noExternalStorageErrorText": "Brak pamięci zewnętrznej w tym urządzeniu",
"noGameCircleText": "Błąd: niezalogowany w GameCircle", "noGameCircleText": "Błąd: niezalogowany w GameCircle",
"noJoinCoopMidwayText": "Rozgrywki trybu Kooperacji nie mogą być łączone w czasie ich trwania.", "noJoinCoopMidwayText": "Rozgrywki trybu Kooperacji nie mogą być łączone w czasie ich trwania.",
"noPluginsInstalledText": "Brak zainstalowanych pluginów",
"noProfilesErrorText": "Nie masz własnego profilu gracza, dlatego nazwano Cię: '${NAME}'.\nPrzejdź do Ustawień->Profile Gracza aby stworzyć własny.", "noProfilesErrorText": "Nie masz własnego profilu gracza, dlatego nazwano Cię: '${NAME}'.\nPrzejdź do Ustawień->Profile Gracza aby stworzyć własny.",
"noScoresYetText": "Brak wyników do tej pory.", "noScoresYetText": "Brak wyników do tej pory.",
"noServersFoundText": "Nie znaleziono serwerów.",
"noThanksText": "Nie, dziękuję", "noThanksText": "Nie, dziękuję",
"noTournamentsInTestBuildText": "OSTRZEŻENIE: Wyniki turniejów z tej wersji testowej będą ignorowane.", "noTournamentsInTestBuildText": "OSTRZEŻENIE: Wyniki turniejów z tej wersji testowej będą ignorowane.",
"noValidMapsErrorText": "Nie znaleziono żadnych map dla tego typu rozgrywki.", "noValidMapsErrorText": "Nie znaleziono żadnych map dla tego typu rozgrywki.",
@ -1119,9 +1131,9 @@
"notUsingAccountText": "Uwaga: ignorowanie konta ${SERVICE}.\nIdź do \"Konto -> Zaloguj się kontem ${SERVICE}\", jeżeli chcesz go używać.", "notUsingAccountText": "Uwaga: ignorowanie konta ${SERVICE}.\nIdź do \"Konto -> Zaloguj się kontem ${SERVICE}\", jeżeli chcesz go używać.",
"nothingIsSelectedErrorText": "Nic nie zaznaczyłeś!", "nothingIsSelectedErrorText": "Nic nie zaznaczyłeś!",
"numberText": "#${NUMBER}", "numberText": "#${NUMBER}",
"offText": "Off", "offText": "Wył.",
"okText": "Ok", "okText": "Ok",
"onText": "On", "onText": "Wł.",
"oneMomentText": "Chwileczkę...", "oneMomentText": "Chwileczkę...",
"onslaughtRespawnText": "${PLAYER} odrodzi się w fali ${WAVE}", "onslaughtRespawnText": "${PLAYER} odrodzi się w fali ${WAVE}",
"orText": "${A} lub ${B}", "orText": "${A} lub ${B}",
@ -1188,17 +1200,17 @@
"pluginsRemovedText": "Usunięto ${NUM} pluginy(ów)", "pluginsRemovedText": "Usunięto ${NUM} pluginy(ów)",
"pluginsText": "Pluginy", "pluginsText": "Pluginy",
"practiceText": "Praktyka", "practiceText": "Praktyka",
"pressAnyButtonPlayAgainText": "Naciśnij dowolny przycisk aby zagrać ponownie...", "pressAnyButtonPlayAgainText": "Naciśnij dowolny przycisk, aby zagrać ponownie...",
"pressAnyButtonText": "Naciśnij dowolny przycisk aby kontynuować...", "pressAnyButtonText": "Naciśnij dowolny przycisk, aby kontynuować...",
"pressAnyButtonToJoinText": "naciśnij dowolny przycisk aby dołączyć...", "pressAnyButtonToJoinText": "naciśnij dowolny przycisk, aby dołączyć...",
"pressAnyKeyButtonPlayAgainText": "Naciśnij dowolny klawisz/przycisk aby zagrać ponownie...", "pressAnyKeyButtonPlayAgainText": "Naciśnij dowolny klawisz/przycisk, aby zagrać ponownie...",
"pressAnyKeyButtonText": "Naciśnij dowolny klawisz/przycisk aby kontynuować...", "pressAnyKeyButtonText": "Naciśnij dowolny klawisz/przycisk, aby kontynuować...",
"pressAnyKeyText": "Naciśnij dowolny klawisz...", "pressAnyKeyText": "Naciśnij dowolny klawisz...",
"pressJumpToFlyText": "** Naciśnij wielokrotnie skok aby polecieć **", "pressJumpToFlyText": "** Naciskaj wielokrotnie skok, aby polecieć **",
"pressPunchToJoinText": "naciśnij CIOS aby dołączyć...", "pressPunchToJoinText": "naciśnij CIOS, aby dołączyć...",
"pressToOverrideCharacterText": "naciśnij ${BUTTONS} aby zastąpić swoją postać", "pressToOverrideCharacterText": "naciśnij ${BUTTONS}, aby zastąpić swoją postać",
"pressToSelectProfileText": "naciśnij ${BUTTONS} aby wybrać gracza.", "pressToSelectProfileText": "naciśnij ${BUTTONS}, aby wybrać gracza",
"pressToSelectTeamText": "naciśnij ${BUTTONS} aby wybrać drużynę.", "pressToSelectTeamText": "naciśnij ${BUTTONS}, aby wybrać drużynę",
"profileInfoText": "Stwórz profile dla siebie i swoich znajomych\ndostosowując ich nazwy i kolory postaci.", "profileInfoText": "Stwórz profile dla siebie i swoich znajomych\ndostosowując ich nazwy i kolory postaci.",
"promoCodeWindow": { "promoCodeWindow": {
"codeText": "Kod", "codeText": "Kod",
@ -1209,7 +1221,7 @@
"ps3ControllersWindow": { "ps3ControllersWindow": {
"macInstructionsText": "Wyłącz zasilanie konsoli PS3, upewnij się, że masz uruchomiony\nBluetooth w swoim Mac'u, następnie podłącz kontroler do portu\nUSB Mac'a aby sparować urządzenia. Od teraz można używać na\nkontrolerze przycisku 'home' aby podłączyć go do Mac'a w obu\ntrybach - przewodowym (USB) i bezprzewodowym (Bluetooth).\n\nNa niektórych Mac'ach trzeba podać kod aby urządzenia sparować.\nJeśli się tak stanie poszukaj poradnika na google.\n\n\n\n\nKontrolery PS3 podłączone bezprzewodowo powinny być widoczne na\nliście urządzeń w Preferencjach Systemu->Bluetooth. Być może\ntrzeba będzie je usunąć z tej listy, kiedy zechcesz korzystać\nz nich ponownie w PS3.\n\nPamiętaj aby rozłączyć je z Bluetootha kiedy nie będą używane\nponieważ wyładują się ich baterie.\n\nBluetooth powinien obsłużyć do 7 podłączonych urządzeń, chociaż\nliczba ta może się wahać.", "macInstructionsText": "Wyłącz zasilanie konsoli PS3, upewnij się, że masz uruchomiony\nBluetooth w swoim Mac'u, następnie podłącz kontroler do portu\nUSB Mac'a aby sparować urządzenia. Od teraz można używać na\nkontrolerze przycisku 'home' aby podłączyć go do Mac'a w obu\ntrybach - przewodowym (USB) i bezprzewodowym (Bluetooth).\n\nNa niektórych Mac'ach trzeba podać kod aby urządzenia sparować.\nJeśli się tak stanie poszukaj poradnika na google.\n\n\n\n\nKontrolery PS3 podłączone bezprzewodowo powinny być widoczne na\nliście urządzeń w Preferencjach Systemu->Bluetooth. Być może\ntrzeba będzie je usunąć z tej listy, kiedy zechcesz korzystać\nz nich ponownie w PS3.\n\nPamiętaj aby rozłączyć je z Bluetootha kiedy nie będą używane\nponieważ wyładują się ich baterie.\n\nBluetooth powinien obsłużyć do 7 podłączonych urządzeń, chociaż\nliczba ta może się wahać.",
"macInstructionsTextScale": 0.74, "macInstructionsTextScale": 0.74,
"ouyaInstructionsText": "Aby używać kontrolerów PS3 z konsolą OUYA, po prostu podłącz je kablem USB\naby sparować urządzenia. Może to spowodować rozłączenie innych kontrolerów,\nwięc powinieneś później uruchomić ponownie konsolę OUYA i odłączyć kabel USB.\n\nOd teraz powinien być aktywny przycisk HOME aby połączyć się bezprzewodowo. Kiedy zakończysz grę, przytrzymaj HOME przez 10 sekund aby wyłączyć kontroler;\nw przeciwnym razie może on wyczerpać jego baterie.", "ouyaInstructionsText": "Aby używać kontrolera PS3 z konsolą OUYA, po prostu podłącz go kablem USB,\naby go sparować. Może to spowodować rozłączenie innych kontrolerów,\nwięc powinieneś później uruchomić ponownie konsolę OUYA i odłączyć kabel USB.\n\nOd teraz powinien być aktywny przycisk HOME, aby połączyć się bezprzewodowo.\nKiedy zakończysz grę, przytrzymaj HOME przez 10 sekund, aby wyłączyć kontroler;\nw przeciwnym razie może on wyczerpać jego baterie.",
"ouyaInstructionsTextScale": 0.74, "ouyaInstructionsTextScale": 0.74,
"pairingTutorialText": "poradnik video parowania kontrolerów", "pairingTutorialText": "poradnik video parowania kontrolerów",
"titleText": "Korzystanie z kontrolerów PS3 w ${APP_NAME}:" "titleText": "Korzystanie z kontrolerów PS3 w ${APP_NAME}:"
@ -1218,7 +1230,7 @@
"punchBoldText": "CIOS", "punchBoldText": "CIOS",
"punchText": "Cios", "punchText": "Cios",
"purchaseForText": "Kup za ${PRICE}", "purchaseForText": "Kup za ${PRICE}",
"purchaseGameText": "Zakup Grę", "purchaseGameText": "Kup Grę",
"purchasingText": "Kupowanie...", "purchasingText": "Kupowanie...",
"quitGameText": "Wyjść z ${APP_NAME}?", "quitGameText": "Wyjść z ${APP_NAME}?",
"quittingIn5SecondsText": "Wyjście za 5 sekund...", "quittingIn5SecondsText": "Wyjście za 5 sekund...",
@ -1260,7 +1272,7 @@
"start": "Start", "start": "Start",
"version_mismatch": "Wersje nie pasują.\nSprawdź czy BombSquad i BombSquad Remote\nmają najnowszą wersję i spróbuj ponownie." "version_mismatch": "Wersje nie pasują.\nSprawdź czy BombSquad i BombSquad Remote\nmają najnowszą wersję i spróbuj ponownie."
}, },
"removeInGameAdsText": "Odblokowywując wersję \"${PRO}\" pozbędziesz się reklam w grze.", "removeInGameAdsText": "Odblokowując wersję \"${PRO}\", pozbędziesz się reklam w grze.",
"renameText": "Zmień nazwę", "renameText": "Zmień nazwę",
"replayEndText": "Zakończ powtórkę", "replayEndText": "Zakończ powtórkę",
"replayNameDefaultText": "Ostatnia powtórka", "replayNameDefaultText": "Ostatnia powtórka",
@ -1282,7 +1294,9 @@
"runBoldText": "URUCHOM", "runBoldText": "URUCHOM",
"runText": "Uruchom", "runText": "Uruchom",
"saveText": "Zapisz", "saveText": "Zapisz",
"scanScriptsErrorText": "Błąd w skanowaniu skryptów; Sprawdź konsolę dla szczegółów", "scanScriptsErrorText": "Błąd w skanowaniu skryptów. Sprawdź konsolę dla szczegółów.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} oraz ${NUM} innych modułów potrzebują aktualizacji do api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} potrzebuje aktualizacji do api ${API}.",
"scoreChallengesText": "Wyzwania Punktowe", "scoreChallengesText": "Wyzwania Punktowe",
"scoreListUnavailableText": "Lista wyników niedostępna.", "scoreListUnavailableText": "Lista wyników niedostępna.",
"scoreText": "Wynik", "scoreText": "Wynik",
@ -1312,14 +1326,14 @@
"alwaysUseInternalKeyboardText": "Zawsze używaj wewn. klawiatury", "alwaysUseInternalKeyboardText": "Zawsze używaj wewn. klawiatury",
"benchmarksText": "Benchmarki & Testy Wydajności", "benchmarksText": "Benchmarki & Testy Wydajności",
"disableCameraGyroscopeMotionText": "Wyłącz Kontrolę Kamery Żyroskopem", "disableCameraGyroscopeMotionText": "Wyłącz Kontrolę Kamery Żyroskopem",
"disableCameraShakeText": "Wyłącz Trzęsącą Kamerę", "disableCameraShakeText": "Wyłącz trzęsienie kamery",
"disableThisNotice": "(możesz wyłączyć to powiadomienie w ustawieniach zaawansowanych)", "disableThisNotice": "(możesz wyłączyć to powiadomienie w ustawieniach zaawansowanych)",
"enablePackageModsDescriptionText": "(aktywuje dodatkowe możliwości modowania ale wyłącza grę sieciową)", "enablePackageModsDescriptionText": "(aktywuje dodatkowe możliwości modowania ale wyłącza grę sieciową)",
"enablePackageModsText": "Włącz lokalne pakiety modów", "enablePackageModsText": "Włącz lokalne pakiety modów",
"enterPromoCodeText": "Wpisz kod", "enterPromoCodeText": "Wpisz kod",
"forTestingText": "Uwaga: wartości stosowane do testów będą utracone po wyjściu z gry.", "forTestingText": "Uwaga: wartości stosowane do testów będą utracone po wyjściu z gry.",
"helpTranslateText": "Tłumaczenia ${APP_NAME} na inne języki są wysiłkiem społeczności\nfanów tej gry. Jeśli chcesz przyczynić się lub poprawić istniejące\nbłędy w tłumaczeniu, kliknij w poniższy link. Z góry dziękuję!", "helpTranslateText": "Tłumaczenia ${APP_NAME} na inne języki są wysiłkiem społeczności\nfanów tej gry. Jeśli chcesz przyczynić się lub poprawić istniejące\nbłędy w tłumaczeniu, kliknij w poniższy link. Z góry dziękuję!",
"kickIdlePlayersText": "Wyrzuć nieaktywnych graczy", "kickIdlePlayersText": "Wyrzucaj nieaktywnych graczy",
"kidFriendlyModeText": "Tryb dla dzieciaków (zredukowana przemoc itd.)", "kidFriendlyModeText": "Tryb dla dzieciaków (zredukowana przemoc itd.)",
"languageText": "Język", "languageText": "Język",
"moddingGuideText": "Przewodnik modowania gry", "moddingGuideText": "Przewodnik modowania gry",
@ -1327,6 +1341,7 @@
"netTestingText": "Testowanie sieci", "netTestingText": "Testowanie sieci",
"resetText": "Reset", "resetText": "Reset",
"showBombTrajectoriesText": "Pokaż trajektorię bomb", "showBombTrajectoriesText": "Pokaż trajektorię bomb",
"showDevConsoleButtonText": "Pokaż przycisk konsoli deweloperskiej",
"showInGamePingText": "Pokaż ping w grze", "showInGamePingText": "Pokaż ping w grze",
"showPlayerNamesText": "Pokazuj nazwy graczy", "showPlayerNamesText": "Pokazuj nazwy graczy",
"showUserModsText": "Pokaż katalog modów", "showUserModsText": "Pokaż katalog modów",
@ -1334,7 +1349,7 @@
"translationEditorButtonText": "Edytor tłumaczeń ${APP_NAME}", "translationEditorButtonText": "Edytor tłumaczeń ${APP_NAME}",
"translationFetchErrorText": "status tłumaczenia niedostępny", "translationFetchErrorText": "status tłumaczenia niedostępny",
"translationFetchingStatusText": "sprawdzanie statusu tłumaczenia...", "translationFetchingStatusText": "sprawdzanie statusu tłumaczenia...",
"translationInformMe": "Powiadom mnie gdy mój język będzie potrzebował uaktualnienia", "translationInformMe": "Powiadom mnie, gdy mój język będzie potrzebował uaktualnienia",
"translationNoUpdateNeededText": "Obecnie używany język jest aktualny; ekstra!", "translationNoUpdateNeededText": "Obecnie używany język jest aktualny; ekstra!",
"translationUpdateNeededText": "** obecnie używany język wymaga jego zaktualizowania! **", "translationUpdateNeededText": "** obecnie używany język wymaga jego zaktualizowania! **",
"vrTestingText": "Testowanie VR" "vrTestingText": "Testowanie VR"
@ -1422,6 +1437,8 @@
"storeText": "Sklep", "storeText": "Sklep",
"submitText": "Prześlij", "submitText": "Prześlij",
"submittingPromoCodeText": "Przesyłanie Kodu...", "submittingPromoCodeText": "Przesyłanie Kodu...",
"successText": "Sukces!",
"supportEmailText": "Jeśli doświadczasz jakichś problemów z\naplikacją, wyślij e-maila na ${EMAIL}.",
"teamNamesColorText": "Nazwy Drużyn/Kolory...", "teamNamesColorText": "Nazwy Drużyn/Kolory...",
"teamsText": "Gra Zespołowa", "teamsText": "Gra Zespołowa",
"telnetAccessGrantedText": "Dostęp telnet włączony.", "telnetAccessGrantedText": "Dostęp telnet włączony.",
@ -1433,7 +1450,7 @@
"thankYouText": "Dziękuję za Twoje wsparcie! Miłej gry!", "thankYouText": "Dziękuję za Twoje wsparcie! Miłej gry!",
"threeKillText": "POTRÓJNE ZABÓJSTWO!!", "threeKillText": "POTRÓJNE ZABÓJSTWO!!",
"timeBonusText": "Bonus czasowy", "timeBonusText": "Bonus czasowy",
"timeElapsedText": "Czas upłynął", "timeElapsedText": "Czas, jaki upłynął",
"timeExpiredText": "Czas minął", "timeExpiredText": "Czas minął",
"timeSuffixDaysText": "${COUNT}d", "timeSuffixDaysText": "${COUNT}d",
"timeSuffixHoursText": "${COUNT}h", "timeSuffixHoursText": "${COUNT}h",
@ -1461,7 +1478,7 @@
"Butch": "Butch", "Butch": "Butch",
"Easter Bunny": "Zajączek Wielkanocny", "Easter Bunny": "Zajączek Wielkanocny",
"Flopsy": "Flopsy", "Flopsy": "Flopsy",
"Frosty": "Frosty", "Frosty": "Mrozek",
"Gretel": "Małgosia", "Gretel": "Małgosia",
"Grumbledorf": "Grumbledorf", "Grumbledorf": "Grumbledorf",
"Jack Morgan": "Jack Morgan", "Jack Morgan": "Jack Morgan",
@ -1504,11 +1521,11 @@
"Infinite Onslaught": "Nieskończony Atak", "Infinite Onslaught": "Nieskończony Atak",
"Infinite Runaround": "Nieskończone Otaczanie", "Infinite Runaround": "Nieskończone Otaczanie",
"Onslaught": "Nieskończony Atak", "Onslaught": "Nieskończony Atak",
"Onslaught Training": "Atakujący Trening", "Onslaught Training": "Treningowy Atak",
"Pro ${GAME}": "Zawodowy tryb ${GAME}", "Pro ${GAME}": "Cięższy tryb ${GAME}",
"Pro Football": "Zawodowy Futbol", "Pro Football": "Cięższy Futbol",
"Pro Onslaught": "Atak Zawodowca", "Pro Onslaught": "Cięższy Atak",
"Pro Runaround": "Zawodowe Otaczanie", "Pro Runaround": "Cięższe Otaczanie",
"Rookie ${GAME}": "Rekrucki tryb ${GAME}", "Rookie ${GAME}": "Rekrucki tryb ${GAME}",
"Rookie Football": "Futbol Rekruta", "Rookie Football": "Futbol Rekruta",
"Rookie Onslaught": "Atak Rekruta", "Rookie Onslaught": "Atak Rekruta",
@ -1520,7 +1537,7 @@
"Uber Runaround": "Super Otaczanie" "Uber Runaround": "Super Otaczanie"
}, },
"gameDescriptions": { "gameDescriptions": {
"Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Bądź wybrańcem przez określony czas aby wygrać.\nZabij wybrańca aby się nim stać.", "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Bądź wybrańcem przez określony czas, aby wygrać.\nZabij wybrańca, aby się nim stać.",
"Bomb as many targets as you can.": "Zbombarduj tyle celów, ile tylko możesz.", "Bomb as many targets as you can.": "Zbombarduj tyle celów, ile tylko możesz.",
"Carry the flag for ${ARG1} seconds.": "Utrzymaj flagę przez ${ARG1} sekund.", "Carry the flag for ${ARG1} seconds.": "Utrzymaj flagę przez ${ARG1} sekund.",
"Carry the flag for a set length of time.": "Utrzymaj flagę przez określony czas.", "Carry the flag for a set length of time.": "Utrzymaj flagę przez określony czas.",
@ -1689,7 +1706,7 @@
"An error has occurred; please contact support. (${ERROR})": "Wystąpił błąd; skontaktuj się z pomocą techniczną. (${ERROR})", "An error has occurred; please contact support. (${ERROR})": "Wystąpił błąd; skontaktuj się z pomocą techniczną. (${ERROR})",
"An error has occurred; please contact support@froemling.net.": "Wystąpił błąd; skontaktuj się z support@froemling.net.", "An error has occurred; please contact support@froemling.net.": "Wystąpił błąd; skontaktuj się z support@froemling.net.",
"An error has occurred; please try again later.": "Wystąpił błąd; spróbuj ponownie później.", "An error has occurred; please try again later.": "Wystąpił błąd; spróbuj ponownie później.",
"Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Na pewno chcesz połączyć te konta?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nUwaga: To nie może być cofnięte!", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Na pewno chcesz połączyć te konta?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nNie da się tego cofnąć!",
"BombSquad Pro unlocked!": "BombSquad Pro odblokowane!", "BombSquad Pro unlocked!": "BombSquad Pro odblokowane!",
"Can't link 2 accounts of this type.": "Nie można połączyć dwóch kont tego typu.", "Can't link 2 accounts of this type.": "Nie można połączyć dwóch kont tego typu.",
"Can't link 2 diamond league accounts.": "Nie można połączyć dwóch kont w diamentowej lidze.", "Can't link 2 diamond league accounts.": "Nie można połączyć dwóch kont w diamentowej lidze.",
@ -1706,7 +1723,7 @@
"Item unlocked!": "Przedmiot odblokowany!", "Item unlocked!": "Przedmiot odblokowany!",
"LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ŁĄCZENIE ODRZUCONE. ${ACCOUNT} zawiera\nznaczący postęp który zostałby USUNIĘTY.\nMożesz połączyć konta na odwrót jeśli chcesz\n(i stracić postęp Z TEGO konta).", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ŁĄCZENIE ODRZUCONE. ${ACCOUNT} zawiera\nznaczący postęp który zostałby USUNIĘTY.\nMożesz połączyć konta na odwrót jeśli chcesz\n(i stracić postęp Z TEGO konta).",
"Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Połączyć konto ${ACCOUNT} z tym kontem?\nCały postęp z konta ${ACCOUNT} będzie stracony.\nNie można tego odwrócić. Pewna decyzja?", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Połączyć konto ${ACCOUNT} z tym kontem?\nCały postęp z konta ${ACCOUNT} będzie stracony.\nNie można tego odwrócić. Pewna decyzja?",
"Max number of playlists reached.": "Osiągnięto maksymalną ilość playlist.", "Max number of playlists reached.": "Osiągnięto maksymalną liczbę playlist.",
"Max number of profiles reached.": "Osiągnięto maksymalną liczbę profili.", "Max number of profiles reached.": "Osiągnięto maksymalną liczbę profili.",
"Maximum friend code rewards reached.": "Osiągnięto limit kodów promocyjnych.", "Maximum friend code rewards reached.": "Osiągnięto limit kodów promocyjnych.",
"Message is too long.": "Wiadomość jest za długa.", "Message is too long.": "Wiadomość jest za długa.",
@ -1731,7 +1748,7 @@
"Tournaments require ${VERSION} or newer": "Turnieje potrzebują ${VERSION} albo nowszej", "Tournaments require ${VERSION} or newer": "Turnieje potrzebują ${VERSION} albo nowszej",
"Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Rozłączyć konto ${ACCOUNT} z tego konta?\nCały postęp z konta ${ACCOUNT} zostanie zresetowany.\n(oprócz osiągnięć w niektórych przypadkach)", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Rozłączyć konto ${ACCOUNT} z tego konta?\nCały postęp z konta ${ACCOUNT} zostanie zresetowany.\n(oprócz osiągnięć w niektórych przypadkach)",
"WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "OSTRZEŻENIE: przeciwko Tobie zostały złożone skargi o oszukiwanie.\nKonta ludzi oszukujących zostaną zablokowane. Proszę grać uczciwie.", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "OSTRZEŻENIE: przeciwko Tobie zostały złożone skargi o oszukiwanie.\nKonta ludzi oszukujących zostaną zablokowane. Proszę grać uczciwie.",
"Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Chcesz połączyć swoje konto z urządzenia z tym?\n\nTwoje konto urządzenia to ${ACCOUNT1}\nTo konto to ${ACCOUNT2}\n\nTo pozwoli Ci zapisać istniejący postęp.\nUwaga: To nie może zostać cofnięte!!!", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Chcesz połączyć swoje konto z urządzenia z tym?\n\nTwoje konto urządzenia to ${ACCOUNT1}\nTo konto to ${ACCOUNT2}\n\nTo pozwoli Ci zapisać istniejący postęp.\nUwaga: Nie da się tego cofnąć!",
"You already own this!": "Już to posiadasz!", "You already own this!": "Już to posiadasz!",
"You can join in ${COUNT} seconds.": "Możesz dołączyć w ciągu ${COUNT} sekund.", "You can join in ${COUNT} seconds.": "Możesz dołączyć w ciągu ${COUNT} sekund.",
"You don't have enough tickets for this!": "Nie masz wystarczająco dużo kuponów!", "You don't have enough tickets for this!": "Nie masz wystarczająco dużo kuponów!",
@ -1743,7 +1760,7 @@
"You must update to the newest version of the game to do this.": "Musisz zaktualizować grę do nowej wersji aby to zrobić.", "You must update to the newest version of the game to do this.": "Musisz zaktualizować grę do nowej wersji aby to zrobić.",
"You must wait a few seconds before entering a new code.": "Musisz odczekać kilka sekund zanim wpiszesz nowy kod.", "You must wait a few seconds before entering a new code.": "Musisz odczekać kilka sekund zanim wpiszesz nowy kod.",
"You ranked #${RANK} in the last tournament. Thanks for playing!": "Zostałeś sklasyfikowany na ${RANK} pozycji w ostatnim turnieju. Dzięki za udział!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Zostałeś sklasyfikowany na ${RANK} pozycji w ostatnim turnieju. Dzięki za udział!",
"Your account was rejected. Are you signed in?": "Twoje Konto Zostało Odrzucone. Jesteś Zalogowany?", "Your account was rejected. Are you signed in?": "Twoje konto zostało odrzucone. Czy jesteś zalogowany?",
"Your copy of the game has been modified.\nPlease revert any changes and try again.": "Twoja kopia gry została zmodyfikowana.\nCofnij zmiany i spróbuj ponownie.", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Twoja kopia gry została zmodyfikowana.\nCofnij zmiany i spróbuj ponownie.",
"Your friend code was used by ${ACCOUNT}": "Kod kumpla został użyty przez ${ACCOUNT}" "Your friend code was used by ${ACCOUNT}": "Kod kumpla został użyty przez ${ACCOUNT}"
}, },
@ -1801,37 +1818,37 @@
}, },
"tips": { "tips": {
"A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfekcyjne w czasie wykonanie biegu, skoku, obrotu i uderzenia\nmoże zabić jednym ruchem wzbudzając respekt wśród znajomych.", "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfekcyjne w czasie wykonanie biegu, skoku, obrotu i uderzenia\nmoże zabić jednym ruchem wzbudzając respekt wśród znajomych.",
"Always remember to floss.": "Pamiętaj żeby nitkować zęby.", "Always remember to floss.": "Pamiętaj, żeby nitkować zęby.",
"Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Stwórz takie profile gracza (nazwa i wygląd) dla siebie i znajomych, które\nbędą Wam najbardziej odpowiadać zamiast tych losowo dobieranych.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Stwórz takie profile gracza (nazwa i wygląd) dla siebie i znajomych, które\nbędą Wam najbardziej odpowiadać zamiast tych losowo dobieranych.",
"Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Pudła z Klątwą zamienią Cię w tykającą bombę.\nJedynym ratunkiem jest wtedy szybkie zdobycie apteczki.", "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Pudła z Klątwą zamienią Cię w tykającą bombę.\nJedynym ratunkiem jest wtedy szybkie zdobycie apteczki.",
"Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Pomimo różnego wyglądu, postacie posiadają te same umiejętności, więc ma\non tylko znaczenie wizualne. Wobec tego dobierz taki, który Ci odpowiada.", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Pomimo różnego wyglądu, postacie posiadają te same umiejętności, więc ma\non tylko znaczenie wizualne. Wobec tego dobierz taki, który Ci odpowiada.",
"Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Nie bądź zbyt pewny siebie mając tarczę energetyczną; wciąż ktoś może Cię zrzucić z klifu.", "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Nie bądź zbyt pewny siebie mając tarczę energetyczną; wciąż ktoś może Cię zrzucić z klifu.",
"Don't run all the time. Really. You will fall off cliffs.": "Nie biegaj cały czas, bo spadniesz z klifu.", "Don't run all the time. Really. You will fall off cliffs.": "Nie biegaj cały czas, bo spadniesz z klifu.",
"Don't spin for too long; you'll become dizzy and fall.": "Nie obracaj się za długo; zakręci ci się w głowie i się wywrócisz.", "Don't spin for too long; you'll become dizzy and fall.": "Nie obracaj się za długo; zakręci ci się w głowie i się wywrócisz.",
"Hold any button to run. (Trigger buttons work well if you have them)": "Przytrzymaj dowolny przycisk aby biec. (Triggery działają równie\ndobrze (jeśli je masz)).", "Hold any button to run. (Trigger buttons work well if you have them)": "Przytrzymaj dowolny przycisk, aby biec. (Triggery działają równie dobrze, jeśli je masz).",
"Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Przytrzymaj dowolny przycisk aby biec. Wówczas osiągniesz szybciej\nswój cel lecz biegnąc ciężko się skręca, więc uważaj aby nie spaść.", "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Przytrzymaj dowolny przycisk aby biec. Wówczas osiągniesz szybciej\nswój cel lecz biegnąc ciężko się skręca, więc uważaj aby nie spaść.",
"Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Lodowe bomby nie są potężne, ale potrafią zamrozić każdego kto\nbędzie w ich polu rażenia, wówczas będzie on podatny na skruszenie.", "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Lodowe bomby nie są potężne, ale potrafią zamrozić każdego kto\nbędzie w ich polu rażenia, wówczas będzie on podatny na skruszenie.",
"If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jeśli ktoś Cię podniesie, uderz go wówczas Cię puści.\nSkutkuje to również w prawdziwym życiu ;)", "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jeśli ktoś Cię podniesie, uderz go wówczas Cię puści.\nDziała to również w prawdziwym życiu ;)",
"If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów, zainstaluj aplikację '${REMOTE_APP_NAME}'\nna swoich urządzeniach, aby użyć ich jako kontrolerów.", "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów, zainstaluj aplikację '${REMOTE_APP_NAME}'\nna swoich urządzeniach, aby użyć ich jako kontrolerów.",
"If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów do gry, zainstaluj 'BombSquad Remote'\ndostępny w odpowiednich sklepach dla urządzeń iOS/Android.\nUżyj telefonów i tabletów jako kontrolerów do gry.", "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów do gry, zainstaluj 'BombSquad Remote'\ndostępny w odpowiednich sklepach dla urządzeń iOS/Android.\nUżyj telefonów i tabletów jako kontrolerów do gry.",
"If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Jeśli przyklei się do Ciebie bomba przylepna, skacz i kręć się szalenie, to może ją\nzrzucisz. Jeżeli Ci się nie uda, wówczas twoje ostatnie chwile będą przezabawne ;).", "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Jeśli przyklei się do Ciebie bomba przylepna, skacz i kręć się szalenie, to może ją\nzrzucisz. Jeżeli Ci się nie uda, wówczas twoje ostatnie chwile będą przezabawne ;).",
"If you kill an enemy in one hit you get double points for it.": "Jeśli zabijesz wroga jednym uderzeniem, otrzymasz podwójne punkty.", "If you kill an enemy in one hit you get double points for it.": "Jeśli zabijesz wroga jednym uderzeniem, otrzymasz podwójne punkty.",
"If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jeśli zbierzesz 'Klątwę', to jedyną nadzieją aby\nprzetrwać jest szybkie zebranie apteczki.", "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jeśli zbierzesz 'Klątwę', to jedyną nadzieją, aby\nprzetrwać, jest szybkie zebranie apteczki.",
"If you stay in one place, you're toast. Run and dodge to survive..": "Jeśli będziesz się czaił w jednym miejscu to jesteś usmażony.\nBiegaj i unikaj ataków aby przetrwać.", "If you stay in one place, you're toast. Run and dodge to survive..": "Jeśli będziesz stał w jednym miejscu, to staniesz się tostem. Biegaj i unikaj ataków, aby przetrwać..",
"If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jeśli doświadczasz dużej rotacji wśród graczy, najlepiej włącz 'auto wyrzucanie\nbezczynnych graczy' w ustawieniach. Wyrzuci to tych, którzy nie grają a jedynie\nwiszą w grze blokując nowych chcących zagrać.", "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jeśli doświadczasz dużej rotacji wśród graczy, włącz 'Wyrzucaj nieaktywnych graczy'\nw ustawieniach, a wszyscy, co zapomnieli wyjść z gry, magicznie znikną.",
"If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jeśli Twoje urządzenie mocno się przegrzewa lub po prostu chcesz oszczędzić baterię,\nwyłącz 'Wizualizacje' lub zmniejsz 'Rozdzielczość' w Ustawienia->Grafika", "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jeśli Twoje urządzenie mocno się przegrzewa lub po prostu chcesz oszczędzić baterię,\nwyłącz 'Wizualizacje' lub zmniejsz 'Rozdzielczość' w Ustawienia->Grafika",
"If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Jeśli ilość klatek na sekundę jest zbyt niska, spróbuj\nzmniejszyć rozdzielczość lub jakość ustawień graficznych.", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Jeśli ilość klatek na sekundę jest zbyt niska, spróbuj\nzmniejszyć rozdzielczość lub jakość ustawień graficznych.",
"In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "W trybie 'Przechwycenia Flagi', Twoja flaga musi znajdować się w bazie aby zapunktować.\nJeśli drugi zespół zamierza zdobyć punkt, przechwycenie ich flagi będzie dobrym\nrozwiązaniem aby ich powstrzymać.", "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "W 'Przechwyceniu Flagi' wasza flaga musi znajdować się w waszej bazie, aby zapunktować. Jeśli drugi\nzespół zamierza zdobyć punkt, przechwycenie ich flagi może być dobrym rozwiązaniem, aby ich powstrzymać.",
"In hockey, you'll maintain more speed if you turn gradually.": "Grając w hokeja, większą prędkość utrzymywać będziesz przy\nstopniowym i delikatnym skręcaniu postacią.", "In hockey, you'll maintain more speed if you turn gradually.": "Grając w hokeja, większą prędkość utrzymywać będziesz przy\nstopniowym i delikatnym skręcaniu postacią.",
"It's easier to win with a friend or two helping.": "Łatwiej zwyciężyć grając w zespole z jednym lub kilkoma\ntowarzyszami broni.", "It's easier to win with a friend or two helping.": "Łatwiej zwyciężyć, grając w zespole z jednym lub kilkoma towarzyszami broni.",
"Jump just as you're throwing to get bombs up to the highest levels.": "Dzięki podskokowi przy wyrzucaniu bomby można je wrzucić\nna wyższe, ciężko dostępne poziomy mapy.", "Jump just as you're throwing to get bombs up to the highest levels.": "Dzięki podskokowi przy wyrzucaniu bomby można je wrzucić\nna wyższe, ciężko dostępne poziomy mapy.",
"Land-mines are a good way to stop speedy enemies.": "Miny lądowe są dobrym rozwiązaniem aby powstrzymywać\nszybkich i wściekłych wrogów.", "Land-mines are a good way to stop speedy enemies.": "Miny lądowe idealnie zatrzymują szybkich i wściekłych wrogów.",
"Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Można podnosić i rzucać wieloma rzeczami, włącznie z graczami. Zrzucanie\nwrogów z klifów może być skuteczne, a taka strategia satysfakcjonująca.", "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Można podnosić i rzucać wieloma rzeczami, włącznie z graczami. Zrzucanie\nwrogów z klifów może być skuteczne, a taka strategia satysfakcjonująca.",
"No, you can't get up on the ledge. You have to throw bombs.": "Nie, nie dostaniesz się na wyższe półki. Może rzuć na nie bomby? :)", "No, you can't get up on the ledge. You have to throw bombs.": "Nie, nie dostaniesz się na wyższe półki. Może rzuć na nie bomby? :)",
"Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Gracze mogą dołączyć/opuścić grę w trakcie jej trwania,\na Ty możesz dołączać/odłączać kontrolery w locie.", "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Gracze mogą dołączyć/opuścić grę w trakcie jej trwania,\na Ty możesz dołączać/odłączać kontrolery w locie.",
"Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Gracze mogą się dołączać/opuszczać grę w trakcie większości\nrozgrywek, tak samo można w locie podłączać/rozłączać gamepady.", "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Gracze mogą się dołączać/opuszczać grę w trakcie większości\nrozgrywek, tak samo można w locie podłączać/rozłączać gamepady.",
"Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Bonusy mają czasowe limity jedynie w rozgrywkach trybu Kooperacji.\nW rozgrywkach drużynowych i Free-for-All są Twoje aż do śmierci.", "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Bonusy mają czasowe limity jedynie w rozgrywkach trybu Kooperacji.\nW rozgrywkach drużynowych i Free-for-All są Twoje aż do śmierci.",
"Practice using your momentum to throw bombs more accurately.": "Poćwicz wyczucie tempa aby rzucać bombami dokładniej.", "Practice using your momentum to throw bombs more accurately.": "Poćwicz wyczucie tempa, aby rzucać bombami dokładniej.",
"Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ciosy powodują większe obrażenia jeśli się energicznie porusza\npięściami, więc staraj się biegać, skakać i kręcić jak szalony.", "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ciosy powodują większe obrażenia jeśli się energicznie porusza\npięściami, więc staraj się biegać, skakać i kręcić jak szalony.",
"Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Podbiegnij do tyłu i przed rzuceniem bomby znów\ndo przodu. Pozwoli to na jej dalsze wyrzucenie.", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Podbiegnij do tyłu i przed rzuceniem bomby znów\ndo przodu. Pozwoli to na jej dalsze wyrzucenie.",
"Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Pozbądź się grupy wrogów poprzez\nrzucenie bomby blisko skrzyni TNT.", "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Pozbądź się grupy wrogów poprzez\nrzucenie bomby blisko skrzyni TNT.",
@ -1840,14 +1857,14 @@
"Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Siła rzutu zależy od kierunku, który trzymasz. Aby delikatnie tylko\ncoś podrzucić przed sobą, nie trzymaj żadnego klawisza kierunku.", "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Siła rzutu zależy od kierunku, który trzymasz. Aby delikatnie tylko\ncoś podrzucić przed sobą, nie trzymaj żadnego klawisza kierunku.",
"Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Zmęczony domyślną ścieżką dźwiękową? Zamień ją na swoją!\nZobacz Ustawienia->Audio->Ścieżka dźwiękowa", "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Zmęczony domyślną ścieżką dźwiękową? Zamień ją na swoją!\nZobacz Ustawienia->Audio->Ścieżka dźwiękowa",
"Try 'Cooking off' bombs for a second or two before throwing them.": "Przytrzymaj 'odpaloną bombę' przez 1 lub 2 sekundy zanim ją rzucisz.", "Try 'Cooking off' bombs for a second or two before throwing them.": "Przytrzymaj 'odpaloną bombę' przez 1 lub 2 sekundy zanim ją rzucisz.",
"Try tricking enemies into killing eachother or running off cliffs.": "Spróbuj oszukać wrogów aby się wzajemnie pozabijali lub zrzucili z klifów.", "Try tricking enemies into killing eachother or running off cliffs.": "Spróbuj oszukać wrogów, aby się wzajemnie pozabijali lub zrzucili z klifów.",
"Use the pick-up button to grab the flag < ${PICKUP} >": "Użyj przycisku 'Podnieś' aby chwycić flagę < ${PICKUP} >", "Use the pick-up button to grab the flag < ${PICKUP} >": "Użyj przycisku 'Podnieś' aby chwycić flagę < ${PICKUP} >",
"Whip back and forth to get more distance on your throws..": "Cofnij się... i do przodu, aby uzyskać dalsze rzuty...", "Whip back and forth to get more distance on your throws..": "Cofnij się... i do przodu, aby uzyskać dalsze rzuty...",
"You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Możesz wycelować swoje uderzenia obracając się w lewo lub prawo.\nJest to przydatne do spychania wrogów poza krawędzie lub w hokeju.", "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Możesz wycelować swoje uderzenia obracając się w lewo lub prawo.\nJest to przydatne do spychania wrogów poza krawędzie lub w hokeju.",
"You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Możesz sam kontrolować i określić czas kiedy bomba eksploduje\npo kolorze iskier na jej loncie: żółty.. pomarańczowy.. czerwony.. BUM!", "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Możesz sam kontrolować i określić czas kiedy bomba eksploduje\npo kolorze iskier na jej loncie: żółty.. pomarańczowy.. czerwony.. BUM!",
"You can throw bombs higher if you jump just before throwing.": "Możesz rzucać bombami wyżej jeśli podskoczysz przed wyrzuceniem.", "You can throw bombs higher if you jump just before throwing.": "Możesz rzucać bombami wyżej jeśli podskoczysz przed wyrzuceniem.",
"You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Nie musisz edytować swojego profilu aby zmienić postacie. Naciśnij górny\nprzycisk (podnoszenie) kiedy dołączasz do gry aby zamienić domyślną postać.", "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Nie musisz edytować swojego profilu aby zmienić postacie. Naciśnij górny\nprzycisk (podnoszenie) kiedy dołączasz do gry aby zamienić domyślną postać.",
"You take damage when you whack your head on things,\nso try to not whack your head on things.": "Przyjmujesz obrażenia jeśli uderzasz głową w różne\nrzeczy, więc staraj się tego nie robić.", "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Przyjmujesz obrażenia, jeśli uderzasz głową w różne\nrzeczy, więc staraj się tego nie robić.",
"Your punches do much more damage if you are running or spinning.": "Twoje ciosy zadadzą więcej obrażeń, jeśli będziesz biegać lub się kręcić." "Your punches do much more damage if you are running or spinning.": "Twoje ciosy zadadzą więcej obrażeń, jeśli będziesz biegać lub się kręcić."
} }
}, },
@ -1856,7 +1873,7 @@
"trophiesText": "Zdobycze", "trophiesText": "Zdobycze",
"trophiesThisSeasonText": "Zdobycze w tym Sezonie", "trophiesThisSeasonText": "Zdobycze w tym Sezonie",
"tutorial": { "tutorial": {
"cpuBenchmarkText": "Wykonywanie testu szybkości (głównie testuje szybkość procesora)", "cpuBenchmarkText": "Odtwarzanie samouczka na niedorzecznej prędkości (głównie testuje szybkość procesora)",
"phrase01Text": "Hejka!", "phrase01Text": "Hejka!",
"phrase02Text": "Witaj w ${APP_NAME}!", "phrase02Text": "Witaj w ${APP_NAME}!",
"phrase03Text": "Oto kilka porad jak kontrolować swoją postać:", "phrase03Text": "Oto kilka porad jak kontrolować swoją postać:",
@ -1867,9 +1884,9 @@
"phrase08Text": "Teraz skoczymy i wykonamy obrót aby zwiększyć szybkość.", "phrase08Text": "Teraz skoczymy i wykonamy obrót aby zwiększyć szybkość.",
"phrase09Text": "Ooo, tak lepiej.", "phrase09Text": "Ooo, tak lepiej.",
"phrase10Text": "Bieganie również pomaga.", "phrase10Text": "Bieganie również pomaga.",
"phrase11Text": "Przytrzymaj dowolny przycisk aby biec.", "phrase11Text": "Przytrzymaj dowolny przycisk, aby biec.",
"phrase12Text": "Dla uzyskania mocnych uderzeń, staraj się biegać i obracać.", "phrase12Text": "Dla uzyskania mocnych uderzeń, staraj się biegać i obracać.",
"phrase13Text": "Ojjj... sorki ${NAME}.", "phrase13Text": "Ojjj... sorki, ${NAME}.",
"phrase14Text": "Możesz podnosić i rzucać np. flagami, bombami, a nawet przeciwnikiem - ${NAME}.", "phrase14Text": "Możesz podnosić i rzucać np. flagami, bombami, a nawet przeciwnikiem - ${NAME}.",
"phrase15Text": "Ale BombSquad to głównie BOMBY.", "phrase15Text": "Ale BombSquad to głównie BOMBY.",
"phrase16Text": "Skuteczne rzucanie bombami wymaga odrobinę praktyki.", "phrase16Text": "Skuteczne rzucanie bombami wymaga odrobinę praktyki.",
@ -1882,7 +1899,7 @@
"phrase23Text": "Spróbuj \"przysmażyć\" lont przez sekundę lub dwie.", "phrase23Text": "Spróbuj \"przysmażyć\" lont przez sekundę lub dwie.",
"phrase24Text": "I proszę! Nieźle upieczony.", "phrase24Text": "I proszę! Nieźle upieczony.",
"phrase25Text": "Cóż, to by było na tyle.", "phrase25Text": "Cóż, to by było na tyle.",
"phrase26Text": "A teraz bierz ich tygrysie!", "phrase26Text": "A teraz bierz ich, tygrysie!",
"phrase27Text": "Zapamiętaj to szkolenie rekrucie, a RACZEJ wrócisz żywy!", "phrase27Text": "Zapamiętaj to szkolenie rekrucie, a RACZEJ wrócisz żywy!",
"phrase28Text": "...może...", "phrase28Text": "...może...",
"phrase29Text": "Powodzenia!", "phrase29Text": "Powodzenia!",
@ -1891,10 +1908,10 @@
"randomName3Text": "Benio", "randomName3Text": "Benio",
"randomName4Text": "Czesio", "randomName4Text": "Czesio",
"randomName5Text": "Ignaś", "randomName5Text": "Ignaś",
"skipConfirmText": "Naprawdę chcesz pominąć samouczek? Stuknij lub naciśnij aby zatwierdzić.", "skipConfirmText": "Naprawdę chcesz pominąć samouczek? Stuknij lub naciśnij, aby zatwierdzić.",
"skipVoteCountText": "${COUNT}/${TOTAL} pominiętych głosów", "skipVoteCountText": "${COUNT}/${TOTAL} pominiętych głosów",
"skippingText": "pomijam samouczek...", "skippingText": "pomijam samouczek...",
"toSkipPressAnythingText": "(stuknij lub naciśnij cokolwiek aby pominąć samouczek)" "toSkipPressAnythingText": "(stuknij lub naciśnij cokolwiek, aby pominąć samouczek)"
}, },
"twoKillText": "PODWÓJNE ZABÓJSTWO!", "twoKillText": "PODWÓJNE ZABÓJSTWO!",
"unavailableText": "niedostępne", "unavailableText": "niedostępne",
@ -1902,12 +1919,13 @@
"unlockThisInTheStoreText": "To musi zostać odblokowane w sklepie.", "unlockThisInTheStoreText": "To musi zostać odblokowane w sklepie.",
"unlockThisProfilesText": "By stworzyć więcej niż ${NUM} kont, potrzebujesz:", "unlockThisProfilesText": "By stworzyć więcej niż ${NUM} kont, potrzebujesz:",
"unlockThisText": "Żeby to odblokować, potrzebujesz:", "unlockThisText": "Żeby to odblokować, potrzebujesz:",
"unsupportedHardwareText": "Przepraszam ale ten sprzęt nie jest obsługiwany przez tą wersję gry.", "unsupportedControllerText": "Wybacz, ale kontroler \"${NAME}\" nie jest wspierany.",
"unsupportedHardwareText": "Przepraszam, ale ten sprzęt nie jest obsługiwany przez tę wersję gry.",
"upFirstText": "Pierwsza gra:", "upFirstText": "Pierwsza gra:",
"upNextText": "Kolejna, ${COUNT} gra w rozgrywce:", "upNextText": "Kolejna, ${COUNT} gra w rozgrywce:",
"updatingAccountText": "Aktualizowanie twojego konta...", "updatingAccountText": "Aktualizowanie twojego konta...",
"upgradeText": "Ulepsz", "upgradeText": "Ulepsz",
"upgradeToPlayText": "Aby zagrać odblokuj grę w wersji \"${PRO}\".", "upgradeToPlayText": "Aby zagrać, odblokuj grę w wersji \"${PRO}\".",
"useDefaultText": "Użyj domyślnych", "useDefaultText": "Użyj domyślnych",
"usesExternalControllerText": "Ta gra wykorzystuje zewnętrzny kontroler jako wejście.", "usesExternalControllerText": "Ta gra wykorzystuje zewnętrzny kontroler jako wejście.",
"usingItunesText": "Korzystanie z aplikacji muzycznej jako ścieżki dźwiękowej...", "usingItunesText": "Korzystanie z aplikacji muzycznej jako ścieżki dźwiękowej...",
@ -1915,6 +1933,7 @@
"v2AccountLinkingInfoText": "Aby połączyć konta V2, użyj przycisku \"Zarządzaj Kontem\".", "v2AccountLinkingInfoText": "Aby połączyć konta V2, użyj przycisku \"Zarządzaj Kontem\".",
"validatingBetaText": "Legalizowanie wersji Beta...", "validatingBetaText": "Legalizowanie wersji Beta...",
"validatingTestBuildText": "Sprawdzanie wersji testowej...", "validatingTestBuildText": "Sprawdzanie wersji testowej...",
"viaText": "poprzez",
"victoryText": "Zwycięstwo!", "victoryText": "Zwycięstwo!",
"voteDelayText": "Nie możesz zagłosować przez następne ${NUMBER} sekund", "voteDelayText": "Nie możesz zagłosować przez następne ${NUMBER} sekund",
"voteInProgressText": "Głosowanie jest już w toku.", "voteInProgressText": "Głosowanie jest już w toku.",
@ -1959,7 +1978,7 @@
"wiimoteSetupWindow": { "wiimoteSetupWindow": {
"copyrightText": "Prawa autorskie DarwiinRemote", "copyrightText": "Prawa autorskie DarwiinRemote",
"listenText": "Nasłuchiwanie", "listenText": "Nasłuchiwanie",
"macInstructionsText": "Upewnij się, że twój kontroler Wii jest wyłączony a\nBluetooth uruchomiony na twoim Mac'u, następnie\nnaciśnij 'Słuchaj'. Wsparcie dla Wiimote może być\ntroszkę ciężko kojarzone, więc musisz spróbować\nkilkakrotnie aby uzyskać połączenie.\n\nBluetooth poradzi sobie z połączeniem do 7 urządzeń,\nchociaż ta liczba może się wahać.\n\nBombSquad wspiera oryginalne Wiimotes, Nunchuks,\ni klasyczne kontrolery. Nowy Wii Remote Plus również\npowinien współpracować lecz bez dodatków.", "macInstructionsText": "Upewnij się, że twój kontroler Wii jest wyłączony a\nBluetooth włączony na twoim Mac'u, a następnie\nnaciśnij 'Słuchaj'. Wsparcie dla Wiimote może być\ntroszkę kulawe, więc być może będziesz musiał\npopróbować kilka razy, zanim uzyskasz połączenie.\n\nBluetooth poradzi sobie z połączeniem do 7 urządzeń,\nchociaż ta liczba może się wahać.\n\nBombSquad wspiera oryginalne Wiimoty, Nunchuki\ni klasyczne kontrolery. Nowy Wii Remote Plus również\npowinien współpracować, ale nie z dodatkami.",
"thanksText": "Podziękowania dla zespołu DarwiinRemote\nza wykonanie tej możliwości.", "thanksText": "Podziękowania dla zespołu DarwiinRemote\nza wykonanie tej możliwości.",
"titleText": "Ustawienia Wiimote" "titleText": "Ustawienia Wiimote"
}, },
@ -1974,9 +1993,9 @@
"xbox360ControllersWindow": { "xbox360ControllersWindow": {
"getDriverText": "Pobierz sterownik", "getDriverText": "Pobierz sterownik",
"macInstructions2Text": "Aby używać kontrolery bezprzewodowo, musisz posiadać odbiornik\ndostępny w zestawie 'Bezprzewodowy kontroler Xbox360 dla Windows'.\nJeden odbiornik pozwala na podłączenie do 4 kontrolerów.\n\nWażne: inne odbiorniki mogą nie współpracować ze sterownikiem;\nupewnij się, czy odbiornik posiada napis 'Microsoft', nie 'XBOX360'.\nMicrosoft nie sprzedaje odbiorników osobno, więc musisz nabyć go\nw zestawie z kontrolerem lub zakupić na aukcjach.\n\nJeśli powyższe informacje okazały się przydatne, rozważ przekazanie\ndotacji dla producenta sterownika na jego stronie.", "macInstructions2Text": "Aby używać kontrolery bezprzewodowo, musisz posiadać odbiornik\ndostępny w zestawie 'Bezprzewodowy kontroler Xbox360 dla Windows'.\nJeden odbiornik pozwala na podłączenie do 4 kontrolerów.\n\nWażne: inne odbiorniki mogą nie współpracować ze sterownikiem;\nupewnij się, czy odbiornik posiada napis 'Microsoft', nie 'XBOX360'.\nMicrosoft nie sprzedaje odbiorników osobno, więc musisz nabyć go\nw zestawie z kontrolerem lub zakupić na aukcjach.\n\nJeśli powyższe informacje okazały się przydatne, rozważ przekazanie\ndotacji dla producenta sterownika na jego stronie.",
"macInstructionsText": "Aby użyć kontrolerów z konsoli Xbox360, musisz\nzainstalować sterownik Mac'a dostępny w poniższym linku.\nSterownik współpracuje zarówno z przewodowymi jak i\nbezprzewodowymi kontrolerami.", "macInstructionsText": "Aby użyć kontrolerów z Xboxa 360, musisz zainstalować\nsterownik do Maca dostępny w poniższym linku. Działa on zarówno\nz przewodowymi jak i bezprzewodowymi kontrolerami.",
"ouyaInstructionsText": "Aby skorzystać z bezprzewodowych kontrolerów konsoli Xbox360,\npodłącz je do portów USB urządzeń. Możesz skorzystać z hubu USB\naby podłączyć klika kontrolerów.\n\nAby użyć bezprzewodowe kontrolery musisz posiadać bezprzewodowy\nodbiornik, dostępny w zestawie \"Bezprzewodowy kontroler Xbox360\ndla Windows\" lub sprzedawany oddzielnie. Każdy odbiornik podłączony\ndo portu USB urządzenia pozwoli na podłączenie do 4 bezprzewodowych\nkontrolerów.", "ouyaInstructionsText": "Aby skorzystać z bezprzewodowych kontrolerów konsoli Xbox 360,\npodłącz je do portów USB w twoim urządzeniu. Możesz skorzystać\nz huba USB, aby podłączyć wiele kontrolerów.\n\nAby używać bezprzewodowych kontrolerów, musisz posiadać bezprzewodowy\nodbiornik, dostępny w zestawie \"Bezprzewodowy kontroler Xbox 360 dla \nWindows\" lub sprzedawany oddzielnie. Każdy odbiornik podłączony do portu\nUSB urządzenia pozwoli na podłączenie do 4 bezprzewodowych kontrolerów.",
"titleText": "Wykorzystywanie kontrolerów Xbox360 w ${APP_NAME}" "titleText": "Wykorzystywanie kontrolerów Xbox 360 w ${APP_NAME}:"
}, },
"yesAllowText": "Dajesz!", "yesAllowText": "Dajesz!",
"yourBestScoresText": "Twoje najlepsze wyniki", "yourBestScoresText": "Twoje najlepsze wyniki",

View file

@ -32,6 +32,7 @@
"signInWithGooglePlayText": "Iniciar sessão com Google Play", "signInWithGooglePlayText": "Iniciar sessão com Google Play",
"signInWithTestAccountInfoText": "(tipo de conta legado; use as contas do dispositivo daqui em diante)", "signInWithTestAccountInfoText": "(tipo de conta legado; use as contas do dispositivo daqui em diante)",
"signInWithTestAccountText": "Iniciar sessão com conta teste", "signInWithTestAccountText": "Iniciar sessão com conta teste",
"signInWithText": "Entrar com ${SERVICE}",
"signInWithV2InfoText": "(uma conta que funciona em todas as plataformas)", "signInWithV2InfoText": "(uma conta que funciona em todas as plataformas)",
"signInWithV2Text": "Iniciar sessão com conta do BombSquad", "signInWithV2Text": "Iniciar sessão com conta do BombSquad",
"signOutText": "Finalizar sessão", "signOutText": "Finalizar sessão",
@ -375,6 +376,7 @@
"chatMutedText": "Chat silenciado", "chatMutedText": "Chat silenciado",
"chatUnMuteText": "Reativar som do chat", "chatUnMuteText": "Reativar som do chat",
"choosingPlayerText": "<escolhendo jogador>", "choosingPlayerText": "<escolhendo jogador>",
"codesExplainText": "Os códigos são fornecidos pelo desenvolvedor para \ndiagnosticar e corrigir problemas de conta.",
"completeThisLevelToProceedText": "Você deve completar \neste nível para continuar!", "completeThisLevelToProceedText": "Você deve completar \neste nível para continuar!",
"completionBonusText": "Bônus de conclusão", "completionBonusText": "Bônus de conclusão",
"configControllersWindow": { "configControllersWindow": {
@ -464,6 +466,7 @@
"titleText": "Configurar touchscreen", "titleText": "Configurar touchscreen",
"touchControlsScaleText": "Escala de Toque do Controle" "touchControlsScaleText": "Escala de Toque do Controle"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} pode ser configurado no aplicativo \"Configurações do sistema\".",
"configureItNowText": "Configurar agora?", "configureItNowText": "Configurar agora?",
"configureText": "Configurar", "configureText": "Configurar",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -588,6 +591,8 @@
"disableXInputDescriptionText": "Permite mais de 4 controles mas pode não funcionar bem.", "disableXInputDescriptionText": "Permite mais de 4 controles mas pode não funcionar bem.",
"disableXInputText": "Desativar XInput", "disableXInputText": "Desativar XInput",
"disabledText": "Desabilitado", "disabledText": "Desabilitado",
"discordFriendsText": "Quer procurar por pessoas para jogar com elas?\nEntre no nosso Discord e encontre novos amigos!",
"discordJoinText": "Junte-se ao Discord",
"doneText": "Concluído", "doneText": "Concluído",
"drawText": "Empate", "drawText": "Empate",
"duplicateText": "Duplicar", "duplicateText": "Duplicar",
@ -863,10 +868,12 @@
"autoText": "Auto", "autoText": "Auto",
"fullScreenCmdText": "Tela cheia (Cmd-F)", "fullScreenCmdText": "Tela cheia (Cmd-F)",
"fullScreenCtrlText": "Tela cheia (Ctrl-F)", "fullScreenCtrlText": "Tela cheia (Ctrl-F)",
"fullScreenText": "Tela cheia",
"gammaText": "Gama", "gammaText": "Gama",
"highText": "Alto", "highText": "Alto",
"higherText": "Mais alto", "higherText": "Mais alto",
"lowText": "Baixo", "lowText": "Baixo",
"maxFPSText": "FPS máximo",
"mediumText": "Médio", "mediumText": "Médio",
"neverText": "Nunca", "neverText": "Nunca",
"resolutionText": "Resolução", "resolutionText": "Resolução",
@ -1129,6 +1136,7 @@
"noJoinCoopMidwayText": "Jogos cooperativos não podem ser afiliados no meio do caminho.", "noJoinCoopMidwayText": "Jogos cooperativos não podem ser afiliados no meio do caminho.",
"noProfilesErrorText": "Você não tem perfis de jogadores, então você está preso com '${NAME}'.\nVá para Configurações->Perfis de Jogador para criar um perfil.", "noProfilesErrorText": "Você não tem perfis de jogadores, então você está preso com '${NAME}'.\nVá para Configurações->Perfis de Jogador para criar um perfil.",
"noScoresYetText": "Ainda sem pontuação.", "noScoresYetText": "Ainda sem pontuação.",
"noServersFoundText": "Servidores não encontrados.",
"noThanksText": "Não, obrigado", "noThanksText": "Não, obrigado",
"noTournamentsInTestBuildText": "Atenção: As pontuações dos torneios desta compilação de teste serão ignoradas.", "noTournamentsInTestBuildText": "Atenção: As pontuações dos torneios desta compilação de teste serão ignoradas.",
"noValidMapsErrorText": "Nenhum mapa válido encontrado para este tipo de jogo.", "noValidMapsErrorText": "Nenhum mapa válido encontrado para este tipo de jogo.",
@ -1355,6 +1363,7 @@
"netTestingText": "Teste de conexão", "netTestingText": "Teste de conexão",
"resetText": "Redefinir", "resetText": "Redefinir",
"showBombTrajectoriesText": "Mostrar trajetórias da bomba", "showBombTrajectoriesText": "Mostrar trajetórias da bomba",
"showDevConsoleButtonText": "Mostrar console de desenvolvedor",
"showInGamePingText": "Mostrar latência no jogo", "showInGamePingText": "Mostrar latência no jogo",
"showPlayerNamesText": "Mostrar nomes dos jogadores", "showPlayerNamesText": "Mostrar nomes dos jogadores",
"showUserModsText": "Mostrar Pasta de Modificações", "showUserModsText": "Mostrar Pasta de Modificações",
@ -1450,6 +1459,8 @@
"storeText": "Loja", "storeText": "Loja",
"submitText": "Valor", "submitText": "Valor",
"submittingPromoCodeText": "Enviando código promocional...", "submittingPromoCodeText": "Enviando código promocional...",
"successText": "Sucesso!",
"supportEmailText": "Se estiver passando por problemas com o aplicativo, \nenvie um e-mail para ${EMAIL}.",
"teamNamesColorText": "Nome/cores das equipes...", "teamNamesColorText": "Nome/cores das equipes...",
"teamsText": "Times", "teamsText": "Times",
"telnetAccessGrantedText": "Acesso ao Telnet ativado.", "telnetAccessGrantedText": "Acesso ao Telnet ativado.",
@ -1505,7 +1516,7 @@
"Santa Claus": "Papai Noel", "Santa Claus": "Papai Noel",
"Snake Shadow": "Serpente Sombria", "Snake Shadow": "Serpente Sombria",
"Spaz": "Spaz", "Spaz": "Spaz",
"Taobao Mascot": "Mascote da Taobao", "Taobao Mascot": "Mascote Taobao",
"Todd": "Teddy", "Todd": "Teddy",
"Todd McBurton": "Todd McBurton", "Todd McBurton": "Todd McBurton",
"Xara": "Zara", "Xara": "Zara",
@ -1931,6 +1942,7 @@
"unlockThisInTheStoreText": "Isto deve ser desbloqueado na loja.", "unlockThisInTheStoreText": "Isto deve ser desbloqueado na loja.",
"unlockThisProfilesText": "Para criar mais que ${NUM} perfis, você precisa:", "unlockThisProfilesText": "Para criar mais que ${NUM} perfis, você precisa:",
"unlockThisText": "Para desbloquear isso:", "unlockThisText": "Para desbloquear isso:",
"unsupportedControllerText": "Desculpe, o controlador \"${NAME}\" não é compatível.",
"unsupportedHardwareText": "Desculpe, este hardware não é suportado por esta versão do jogo.", "unsupportedHardwareText": "Desculpe, este hardware não é suportado por esta versão do jogo.",
"upFirstText": "Em primeiro lugar:", "upFirstText": "Em primeiro lugar:",
"upNextText": "O próximo jogo em ${COUNT}:", "upNextText": "O próximo jogo em ${COUNT}:",
@ -1944,6 +1956,7 @@
"v2AccountLinkingInfoText": "Para vincular contas V2, use o botão 'Gerenciar conta'.", "v2AccountLinkingInfoText": "Para vincular contas V2, use o botão 'Gerenciar conta'.",
"validatingBetaText": "Validando Beta...", "validatingBetaText": "Validando Beta...",
"validatingTestBuildText": "Validando versão de teste...", "validatingTestBuildText": "Validando versão de teste...",
"viaText": "via",
"victoryText": "Vitória!", "victoryText": "Vitória!",
"voteDelayText": "Você não pode começar outra votação por ${NUMBER} segundo(s)", "voteDelayText": "Você não pode começar outra votação por ${NUMBER} segundo(s)",
"voteInProgressText": "Uma votação já está em progresso.", "voteInProgressText": "Uma votação já está em progresso.",

View file

@ -33,6 +33,7 @@
"signInWithGooglePlayText": "Войти через Google Play", "signInWithGooglePlayText": "Войти через Google Play",
"signInWithTestAccountInfoText": "(устаревший тип аккаунта; в дальнейшем используйте аккаунт устройства)", "signInWithTestAccountInfoText": "(устаревший тип аккаунта; в дальнейшем используйте аккаунт устройства)",
"signInWithTestAccountText": "Войти через тестовый аккаунт", "signInWithTestAccountText": "Войти через тестовый аккаунт",
"signInWithText": "Войти при помощи ${SERVICE}",
"signInWithV2InfoText": "(аккаунт, который работает на всех платформах)", "signInWithV2InfoText": "(аккаунт, который работает на всех платформах)",
"signInWithV2Text": "Войти через аккаунт BombSquad", "signInWithV2Text": "Войти через аккаунт BombSquad",
"signOutText": "Выйти", "signOutText": "Выйти",
@ -75,7 +76,7 @@
}, },
"Flawless Victory": { "Flawless Victory": {
"description": "Победите не получив урона", "description": "Победите не получив урона",
"descriptionComplete": "Победа без получения урона", "descriptionComplete": "Победил без получения урона",
"descriptionFull": "Пройдите уровень ${LEVEL} не получив урона", "descriptionFull": "Пройдите уровень ${LEVEL} не получив урона",
"descriptionFullComplete": "Уровень ${LEVEL} пройден без урона", "descriptionFullComplete": "Уровень ${LEVEL} пройден без урона",
"name": "Чистая победа" "name": "Чистая победа"
@ -376,6 +377,7 @@
"chatMutedText": "Чат заглушен", "chatMutedText": "Чат заглушен",
"chatUnMuteText": "Включить чат", "chatUnMuteText": "Включить чат",
"choosingPlayerText": "<выбор игрока>", "choosingPlayerText": "<выбор игрока>",
"codesExplainText": "Коды предоставлены разработчиком, чтобы\nвыявлять и исправлять ошибки с аккаунтом.",
"completeThisLevelToProceedText": "Чтобы продолжить, нужно\nпройти этот уровень!", "completeThisLevelToProceedText": "Чтобы продолжить, нужно\nпройти этот уровень!",
"completionBonusText": "Бонус за прохождение", "completionBonusText": "Бонус за прохождение",
"configControllersWindow": { "configControllersWindow": {
@ -460,6 +462,7 @@
"titleText": "Настройка сенсорного экрана", "titleText": "Настройка сенсорного экрана",
"touchControlsScaleText": "Шкала сенсоров" "touchControlsScaleText": "Шкала сенсоров"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} может быть настроен в приложении системных настроек.",
"configureItNowText": "Настроить сейчас?", "configureItNowText": "Настроить сейчас?",
"configureText": "Настроить", "configureText": "Настроить",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -576,12 +579,14 @@
"difficultyEasyText": "Легкий", "difficultyEasyText": "Легкий",
"difficultyHardOnlyText": "Только в трудном режиме", "difficultyHardOnlyText": "Только в трудном режиме",
"difficultyHardText": "Трудный", "difficultyHardText": "Трудный",
"difficultyHardUnlockOnlyText": "Этот уровень может быть открыт только в сложном режиме.\nДумаете, сможете!?!?!", "difficultyHardUnlockOnlyText": "Этот уровень может быть открыт только в сложном режиме.\nДумаете, сможете это сделать!?!?!",
"directBrowserToURLText": "Пожалуйста, направьте веб-браузер по следующему адресу:", "directBrowserToURLText": "Пожалуйста, направьте веб-браузер по следующему адресу:",
"disableRemoteAppConnectionsText": "Отключить соединения RemoteApp", "disableRemoteAppConnectionsText": "Отключить соединения RemoteApp",
"disableXInputDescriptionText": "Позволяет подключение более 4 контроллеров, но может не очень хорошо работать.", "disableXInputDescriptionText": "Позволяет подключение более 4 контроллеров, но может не очень хорошо работать.",
"disableXInputText": "Отключить XInput", "disableXInputText": "Отключить XInput",
"disabledText": "Отключено", "disabledText": "Отключено",
"discordFriendsText": "Желаете поискать новых людей с которыми можно поиграть?\nПрисоединяйтесь к нашему Discord и находите новых друзей!",
"discordJoinText": "Присоединиться к Discord",
"doneText": "Готово", "doneText": "Готово",
"drawText": "Ничья", "drawText": "Ничья",
"duplicateText": "Дублировать", "duplicateText": "Дублировать",
@ -859,10 +864,12 @@
"alwaysText": "Всегда", "alwaysText": "Всегда",
"fullScreenCmdText": "Полноэкранный (Cmd-F)", "fullScreenCmdText": "Полноэкранный (Cmd-F)",
"fullScreenCtrlText": "Полноэкранный (Ctrl-F)", "fullScreenCtrlText": "Полноэкранный (Ctrl-F)",
"fullScreenText": "Полный экран",
"gammaText": "Гамма", "gammaText": "Гамма",
"highText": "Высокий", "highText": "Высокий",
"higherText": "Ультра", "higherText": "Ультра",
"lowText": "Низкий", "lowText": "Низкий",
"maxFPSText": "Максимальный FPS",
"mediumText": "Средний", "mediumText": "Средний",
"neverText": "Никогда", "neverText": "Никогда",
"resolutionText": "Разрешение", "resolutionText": "Разрешение",
@ -1112,6 +1119,7 @@
"noJoinCoopMidwayText": "К кооперативным играм нельзя присоединиться посреди игры.", "noJoinCoopMidwayText": "К кооперативным играм нельзя присоединиться посреди игры.",
"noProfilesErrorText": "У вас нет профиля игрока, так что вас будут звать '${NAME}'.\nСоздать профиль можно перейдя в 'Настройки' > 'Профили игроков'.", "noProfilesErrorText": "У вас нет профиля игрока, так что вас будут звать '${NAME}'.\nСоздать профиль можно перейдя в 'Настройки' > 'Профили игроков'.",
"noScoresYetText": "Счета пока нет.", "noScoresYetText": "Счета пока нет.",
"noServersFoundText": "Серверы не найдены.",
"noThanksText": "Нет, спасибо", "noThanksText": "Нет, спасибо",
"noTournamentsInTestBuildText": "ВНИМАНИЕ: Турнирные очки из этой тестовой сборки будут не засчитаны.", "noTournamentsInTestBuildText": "ВНИМАНИЕ: Турнирные очки из этой тестовой сборки будут не засчитаны.",
"noValidMapsErrorText": "Для данного типа игры не найдено корректных карт.", "noValidMapsErrorText": "Для данного типа игры не найдено корректных карт.",
@ -1331,6 +1339,7 @@
"netTestingText": "Тестирование сети", "netTestingText": "Тестирование сети",
"resetText": "Сбросить", "resetText": "Сбросить",
"showBombTrajectoriesText": "Показывать траекторию бомбы", "showBombTrajectoriesText": "Показывать траекторию бомбы",
"showDevConsoleButtonText": "Показать кнопку консоли",
"showInGamePingText": "Показать Ping", "showInGamePingText": "Показать Ping",
"showPlayerNamesText": "Показывать имена игроков", "showPlayerNamesText": "Показывать имена игроков",
"showUserModsText": "Показать папку модов", "showUserModsText": "Показать папку модов",
@ -1426,6 +1435,8 @@
"storeText": "Магазин", "storeText": "Магазин",
"submitText": "Отправить", "submitText": "Отправить",
"submittingPromoCodeText": "Активация кода....", "submittingPromoCodeText": "Активация кода....",
"successText": "Успех!",
"supportEmailText": "Если вы испытываете какие-то проблемы с приложением,\nпожалуйста, напишите на почту ${EMAIL}.",
"teamNamesColorText": "имена/цвета команд", "teamNamesColorText": "имена/цвета команд",
"teamsText": "Команды", "teamsText": "Команды",
"telnetAccessGrantedText": "Доступ Telnet включен.", "telnetAccessGrantedText": "Доступ Telnet включен.",
@ -1907,6 +1918,7 @@
"unlockThisInTheStoreText": "Это должно быть разблокировано в магазине.", "unlockThisInTheStoreText": "Это должно быть разблокировано в магазине.",
"unlockThisProfilesText": "Чтобы создать более ${NUM} профиль, Вам необходимо:", "unlockThisProfilesText": "Чтобы создать более ${NUM} профиль, Вам необходимо:",
"unlockThisText": "Чтобы разблокировать это, вам нужно:", "unlockThisText": "Чтобы разблокировать это, вам нужно:",
"unsupportedControllerText": "К сожалению, контроллер \"${NAME}\" не поддерживается.",
"unsupportedHardwareText": "К сожалению, это оборудование не поддерживается в этой сборке игры.", "unsupportedHardwareText": "К сожалению, это оборудование не поддерживается в этой сборке игры.",
"upFirstText": "Для начала:", "upFirstText": "Для начала:",
"upNextText": "Далее в игре ${COUNT}:", "upNextText": "Далее в игре ${COUNT}:",
@ -1920,6 +1932,7 @@
"v2AccountLinkingInfoText": "Чтобы обьединить старый и новый аккаунты, используйте кнопку 'Обьединить аккаунты'", "v2AccountLinkingInfoText": "Чтобы обьединить старый и новый аккаунты, используйте кнопку 'Обьединить аккаунты'",
"validatingBetaText": "Валидация бета-версии...", "validatingBetaText": "Валидация бета-версии...",
"validatingTestBuildText": "Проверка тестовой сборки...", "validatingTestBuildText": "Проверка тестовой сборки...",
"viaText": "используя",
"victoryText": "Победа!", "victoryText": "Победа!",
"voteDelayText": "Невозможно начать новое голосование еще ${NUMBER} секунд", "voteDelayText": "Невозможно начать новое голосование еще ${NUMBER} секунд",
"voteInProgressText": "Голосование уже в процессе.", "voteInProgressText": "Голосование уже в процессе.",

View file

@ -18,7 +18,7 @@
"linkAccountsText": "Vincular Cuentas", "linkAccountsText": "Vincular Cuentas",
"linkedAccountsText": "Cuentas Vinculadas:", "linkedAccountsText": "Cuentas Vinculadas:",
"manageAccountText": "Administrar Cuenta", "manageAccountText": "Administrar Cuenta",
"nameChangeConfirm": "¿Seguro cambiar tu nombre a ${NAME}?", "nameChangeConfirm": "¿Cambiar tu nombre de cuenta a ${NAME}?",
"notLoggedInText": "<no estás conectado>", "notLoggedInText": "<no estás conectado>",
"resetProgressConfirmNoAchievementsText": "Esto reiniciará tu progreso cooperativo y \ntus puntajes locales (a excepción de tus boletos).\nEsto no puede deshacerse. ¿Estás seguro?", "resetProgressConfirmNoAchievementsText": "Esto reiniciará tu progreso cooperativo y \ntus puntajes locales (a excepción de tus boletos).\nEsto no puede deshacerse. ¿Estás seguro?",
"resetProgressConfirmText": "Esto reiniciará tus logros, récords\ny progreso en el modo cooperativo.\nLos cambios no se pueden deshacer.\n¿Estás seguro?", "resetProgressConfirmText": "Esto reiniciará tus logros, récords\ny progreso en el modo cooperativo.\nLos cambios no se pueden deshacer.\n¿Estás seguro?",
@ -33,6 +33,7 @@
"signInWithGooglePlayText": "Iniciar sesión con Google Play", "signInWithGooglePlayText": "Iniciar sesión con Google Play",
"signInWithTestAccountInfoText": "(tipo de cuenta heredada; usa las cuentas de dispositivos más adelante)", "signInWithTestAccountInfoText": "(tipo de cuenta heredada; usa las cuentas de dispositivos más adelante)",
"signInWithTestAccountText": "Iniciar sesión con cuenta de prueba", "signInWithTestAccountText": "Iniciar sesión con cuenta de prueba",
"signInWithText": "Iniciar sesion con ${SERVICE}",
"signInWithV2InfoText": "(una cuenta que funciona en todas las plataformas)", "signInWithV2InfoText": "(una cuenta que funciona en todas las plataformas)",
"signInWithV2Text": "Iniciar sesión con una cuenta de BombSquad", "signInWithV2Text": "Iniciar sesión con una cuenta de BombSquad",
"signOutText": "Cerrar Sesión", "signOutText": "Cerrar Sesión",
@ -43,10 +44,10 @@
"testAccountWarningText": "Advertencia: te estás registrando con una cuenta de\nprueba. Esta cuenta está vinculada a este dispositivo y\npuede que se reinicie periódicamente. (Así que no\ngastes mucho tiempo coleccionando/desbloqueando objetos)\n\nJuega una versión pública del juego y usa una \"cuenta real\"\n(Game-Center, Google Plus, etc.) Esto también te dejará\nguardar tu progreso en la nube y poder compartirlo con\ndiferentes dispositivos.", "testAccountWarningText": "Advertencia: te estás registrando con una cuenta de\nprueba. Esta cuenta está vinculada a este dispositivo y\npuede que se reinicie periódicamente. (Así que no\ngastes mucho tiempo coleccionando/desbloqueando objetos)\n\nJuega una versión pública del juego y usa una \"cuenta real\"\n(Game-Center, Google Plus, etc.) Esto también te dejará\nguardar tu progreso en la nube y poder compartirlo con\ndiferentes dispositivos.",
"ticketsText": "Boletos: ${COUNT}", "ticketsText": "Boletos: ${COUNT}",
"titleText": "Cuenta", "titleText": "Cuenta",
"unlinkAccountsInstructionsText": "Selecciona una cuenta para desenlazar", "unlinkAccountsInstructionsText": "Selecciona una cuenta para desvincular",
"unlinkAccountsText": "Desenlazar Cuentas", "unlinkAccountsText": "Desvincular Cuentas",
"unlinkLegacyV1AccountsText": "Desenlazar Cuentas Heredadas (V1)", "unlinkLegacyV1AccountsText": "Desvincular Cuentas (V1) Heredadas",
"v2LinkInstructionsText": "Usa este enlace para crearte una cuenta o para iniciar sesión", "v2LinkInstructionsText": "Usa este enlace para crearte una cuenta o para iniciar sesión.",
"viaAccount": "(cuenta vía ${NAME})", "viaAccount": "(cuenta vía ${NAME})",
"youAreLoggedInAsText": "Estás conectado como:", "youAreLoggedInAsText": "Estás conectado como:",
"youAreSignedInAsText": "Has iniciado sesión como:" "youAreSignedInAsText": "Has iniciado sesión como:"
@ -81,8 +82,8 @@
"name": "Victoria Impecable" "name": "Victoria Impecable"
}, },
"Free Loader": { "Free Loader": {
"descriptionFull": "Empieza un juego de Libre-para-Todos con 2 o más jugadores", "descriptionFull": "Empieza un juego de Todos-Contra-Todos con 2 o más jugadores",
"descriptionFullComplete": "Empezó un juego de Libre-Para-Todos con 2 o más jugadores", "descriptionFullComplete": "Empezó un juego de Todos-Contra-Todos con 2 o más jugadores",
"name": "Cargador Libre" "name": "Cargador Libre"
}, },
"Gold Miner": { "Gold Miner": {
@ -168,10 +169,10 @@
"name": "Mago De La ${LEVEL}" "name": "Mago De La ${LEVEL}"
}, },
"Precision Bombing": { "Precision Bombing": {
"description": "Gana sin ningún potenciador", "description": "Gana sin potenciadores",
"descriptionComplete": "Has ganado sin usar ningún potenciador", "descriptionComplete": "Ganó sin potenciadores",
"descriptionFull": "Gana ${LEVEL} sin usar potenciadores", "descriptionFull": "Gana ${LEVEL} sin potenciadores",
"descriptionFullComplete": "Ganó ${LEVEL} sin ningún potenciador", "descriptionFullComplete": "Ganó ${LEVEL} sin potenciadores",
"name": "Bombardeo De Precisión" "name": "Bombardeo De Precisión"
}, },
"Pro Boxer": { "Pro Boxer": {
@ -203,7 +204,7 @@
"name": "Victoria en ${LEVEL}" "name": "Victoria en ${LEVEL}"
}, },
"Pro Runaround Victory": { "Pro Runaround Victory": {
"description": "Completa todas las hordas", "description": "Completa todas las oleadas",
"descriptionComplete": "Completó todas las oleadas", "descriptionComplete": "Completó todas las oleadas",
"descriptionFull": "Completa todas las oleadas en ${LEVEL}", "descriptionFull": "Completa todas las oleadas en ${LEVEL}",
"descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}", "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}",
@ -224,10 +225,10 @@
"name": "Victoria en ${LEVEL}" "name": "Victoria en ${LEVEL}"
}, },
"Rookie Onslaught Victory": { "Rookie Onslaught Victory": {
"description": "Vence todas las hordas", "description": "Vence todas las oleadas",
"descriptionComplete": "Venció todas las hordas", "descriptionComplete": "Venció todas las oleadas",
"descriptionFull": "Vence todas las hordas en ${LEVEL}", "descriptionFull": "Vence todas las oleadas en ${LEVEL}",
"descriptionFullComplete": "Venció todas las hordas en ${LEVEL}", "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}",
"name": "Victoria en ${LEVEL}" "name": "Victoria en ${LEVEL}"
}, },
"Runaround God": { "Runaround God": {
@ -265,7 +266,7 @@
}, },
"Super Mega Punch": { "Super Mega Punch": {
"description": "Inflige 100% de daño con un solo golpe", "description": "Inflige 100% de daño con un solo golpe",
"descriptionComplete": "Infligiste 100% de daño con un solo golpe", "descriptionComplete": "Infligió 100% de daño con un solo golpe",
"descriptionFull": "Inflige 100% de daño con un golpe en ${LEVEL}", "descriptionFull": "Inflige 100% de daño con un golpe en ${LEVEL}",
"descriptionFullComplete": "Infligió 100% de daño con un golpe en ${LEVEL}", "descriptionFullComplete": "Infligió 100% de daño con un golpe en ${LEVEL}",
"name": "Súper Mega Golpe" "name": "Súper Mega Golpe"
@ -280,7 +281,7 @@
"TNT Terror": { "TNT Terror": {
"description": "Mata a 6 chicos malos con TNT", "description": "Mata a 6 chicos malos con TNT",
"descriptionComplete": "Mató a 6 chicos malos con TNT", "descriptionComplete": "Mató a 6 chicos malos con TNT",
"descriptionFull": "Mató a 6 chicos malos con TNT en ${LEVEL}", "descriptionFull": "Mata a 6 chicos malos con TNT en ${LEVEL}",
"descriptionFullComplete": "Mató a 6 chicos malos con TNT en ${LEVEL}", "descriptionFullComplete": "Mató a 6 chicos malos con TNT en ${LEVEL}",
"name": "Pirómano" "name": "Pirómano"
}, },
@ -318,28 +319,30 @@
"name": "Victoria En ${LEVEL}" "name": "Victoria En ${LEVEL}"
}, },
"Uber Onslaught Victory": { "Uber Onslaught Victory": {
"description": "Vence todas las hordas", "description": "Vence todas las oleadas",
"descriptionComplete": "Venció todas las hordas", "descriptionComplete": "Venció todas las oleadas",
"descriptionFull": "Vence todas las hordas en ${LEVEL}", "descriptionFull": "Vence todas las oleadas en ${LEVEL}",
"descriptionFullComplete": "Venció todas las hordas en ${LEVEL}", "descriptionFullComplete": "Venció todas las oleadas en ${LEVEL}",
"name": "Victoria En ${LEVEL}" "name": "Victoria En ${LEVEL}"
}, },
"Uber Runaround Victory": { "Uber Runaround Victory": {
"description": "Completa todas las hordas", "description": "Completa todas las oleadas",
"descriptionComplete": "Completó todas las hordas", "descriptionComplete": "Completó todas las oleadas",
"descriptionFull": "Completa todas las hordas en ${LEVEL}", "descriptionFull": "Completa todas las oleadas en ${LEVEL}",
"descriptionFullComplete": "Completó todas las hordas en ${LEVEL}", "descriptionFullComplete": "Completó todas las oleadas en ${LEVEL}",
"name": "Victoria En ${LEVEL}" "name": "Victoria En ${LEVEL}"
} }
}, },
"achievementsRemainingText": "Logros Pendientes:", "achievementsRemainingText": "Logros Pendientes:",
"achievementsText": "Logros", "achievementsText": "Logros",
"achievementsUnavailableForOldSeasonsText": "Lo sentimos, los logros específicos no están disponibles para temporadas anteriores.", "achievementsUnavailableForOldSeasonsText": "Disculpe, los logros específicos no están disponibles para temporadas anteriores.",
"activatedText": "${THING} activado.", "activatedText": "${THING} activado.",
"addGameWindow": { "addGameWindow": {
"getMoreGamesText": "Obtén Más Juegos...", "getMoreGamesText": "Conseguir Más Juegos...",
"titleText": "Agregar Juego" "titleText": "Agregar Juego"
}, },
"addToFavoritesText": "Añadir a Favoritos",
"addedToFavoritesText": "'${NAME}' añadido a Favoritos.",
"allText": "Todo", "allText": "Todo",
"allowText": "Permitir", "allowText": "Permitir",
"alreadySignedInText": "Tu cuenta está registrada en otro dispositivo;\npor favor cambia de cuentas o cierra el juego en tu \notro dispositivo e inténtalo de nuevo.", "alreadySignedInText": "Tu cuenta está registrada en otro dispositivo;\npor favor cambia de cuentas o cierra el juego en tu \notro dispositivo e inténtalo de nuevo.",
@ -373,10 +376,11 @@
"cancelText": "Cancelar", "cancelText": "Cancelar",
"cantConfigureDeviceText": "Lo sentimos, ${DEVICE} no es configurable.", "cantConfigureDeviceText": "Lo sentimos, ${DEVICE} no es configurable.",
"challengeEndedText": "Este desafío ha terminado.", "challengeEndedText": "Este desafío ha terminado.",
"chatMuteText": "Silenciar chat", "chatMuteText": "Silenciar Chat",
"chatMutedText": "Chat silenciado", "chatMutedText": "Chat Silenciado",
"chatUnMuteText": "Desilenciar chat", "chatUnMuteText": "Desilenciar Chat",
"choosingPlayerText": "<eligiendo jugador>", "choosingPlayerText": "<eligiendo jugador>",
"codesExplainText": "Los códigos son proporcionados por el desarrollador para\ndiagnosticar y corregir problemas de la cuenta.",
"completeThisLevelToProceedText": "¡Debes completar\neste nivel para avanzar!", "completeThisLevelToProceedText": "¡Debes completar\neste nivel para avanzar!",
"completionBonusText": "Bono Por Completar", "completionBonusText": "Bono Por Completar",
"configControllersWindow": { "configControllersWindow": {
@ -462,6 +466,7 @@
"titleText": "Configura la Pantalla Táctil", "titleText": "Configura la Pantalla Táctil",
"touchControlsScaleText": "Ampliador de controles táctiles" "touchControlsScaleText": "Ampliador de controles táctiles"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} se puede configurar en la aplicación Configuración del Sistema.",
"configureItNowText": "Configurar ahora?", "configureItNowText": "Configurar ahora?",
"configureText": "Configurar", "configureText": "Configurar",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -481,15 +486,15 @@
"continueText": "Continuar", "continueText": "Continuar",
"controlsText": "Controles", "controlsText": "Controles",
"coopSelectWindow": { "coopSelectWindow": {
"activenessAllTimeInfoText": "Esto no aplica en los rankings de 'Todo el tiempo'.", "activenessAllTimeInfoText": "Esto no aplica a las clasificaciones de todo-el-tiempo.",
"activenessInfoText": "Este multiplicador aumenta en los días que juegas\ny disminuye cuando no juegas.", "activenessInfoText": "Este multiplicador aumenta en los días que juegas\ny disminuye cuando no juegas.",
"activityText": "Actividad", "activityText": "Actividad",
"campaignText": "Campaña", "campaignText": "Campaña",
"challengesInfoText": "Gana premios por completar los mini-juegos.\n\nLos premios y la dificultad de los niveles incrementa\ncada vez que se completa y\ndecrece cuando uno expira o no se cumple.", "challengesInfoText": "Gana premios por completar los mini-juegos.\n\nLos premios y la dificultad de los niveles incrementa\ncada vez que se completa y\ndecrece cuando uno expira o no se cumple.",
"challengesText": "Desafíos", "challengesText": "Desafíos",
"currentBestText": "Mejor del Momento", "currentBestText": "Mejor Actual",
"customText": "Personalizado", "customText": "Personalizado",
"entryFeeText": "Precio", "entryFeeText": "Entrada",
"forfeitConfirmText": "¿Renunciar a este desafío?", "forfeitConfirmText": "¿Renunciar a este desafío?",
"forfeitNotAllowedYetText": "Todavía no puedes abandonar este desafío.", "forfeitNotAllowedYetText": "Todavía no puedes abandonar este desafío.",
"forfeitText": "Abandonar", "forfeitText": "Abandonar",
@ -505,11 +510,11 @@
"powerRankingPointsMultText": "(x ${NUMBER} pts)", "powerRankingPointsMultText": "(x ${NUMBER} pts)",
"powerRankingPointsText": "${NUMBER} pts", "powerRankingPointsText": "${NUMBER} pts",
"powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)",
"powerRankingText": "Clasificación de Poder", "powerRankingText": "Clasificación De Poder",
"prizesText": "Premios", "prizesText": "Premios",
"proMultInfoText": "Los jugadores con la mejora ${PRO}\nreciben una bonificación del ${PERCENT}% de puntos.", "proMultInfoText": "Los jugadores con la mejora ${PRO}\nreciben una bonificación del ${PERCENT}% de puntos.",
"seeMoreText": "Más...", "seeMoreText": "Más...",
"skipWaitText": "Saltar la Espera", "skipWaitText": "Omitir La Espera",
"timeRemainingText": "Tiempo Restante", "timeRemainingText": "Tiempo Restante",
"titleText": "Modo cooperativo", "titleText": "Modo cooperativo",
"toRankedText": "Para Clasificar", "toRankedText": "Para Clasificar",
@ -573,17 +578,19 @@
"demoText": "Demo", "demoText": "Demo",
"denyText": "Denegar", "denyText": "Denegar",
"deprecatedText": "Obsoleto", "deprecatedText": "Obsoleto",
"desktopResText": "Resolución de Escritorio", "desktopResText": "Resolución De Escritorio",
"deviceAccountUpgradeText": "Advertencia:\nIniciaste sesión con una cuenta de dispositivo (${NAME}).\nLas cuentas de dispositivo serán removidas en una futura actualización.\nActualiza a una cuenta V2 si quieres conservar tu progreso.", "deviceAccountUpgradeText": "Advertencia:\nIniciaste sesión con una cuenta de dispositivo (${NAME}).\nLas cuentas de dispositivo serán removidas en una futura actualización.\nActualiza a una cuenta V2 si quieres conservar tu progreso.",
"difficultyEasyText": "Fácil", "difficultyEasyText": "Fácil",
"difficultyHardOnlyText": "Solo Modo Difícil", "difficultyHardOnlyText": "Solo Modo Difícil",
"difficultyHardText": "Difícil", "difficultyHardText": "Difícil",
"difficultyHardUnlockOnlyText": "Este nivel solo puede ser desbloqueado en modo difícil.\n¡¿¡¿¡Piensas tener lo que se necesita!?!?!", "difficultyHardUnlockOnlyText": "Este nivel solo puede ser desbloqueado en modo difícil.\n¡¿¡¿¡Piensas tener lo que se necesita!?!?!",
"directBrowserToURLText": "Por favor abre la siguiente URL en tu navegador:", "directBrowserToURLText": "Por favor abre la siguiente URL en tu navegador:",
"disableRemoteAppConnectionsText": "Deshabilitar Conexiones Remotas de la Aplicación", "disableRemoteAppConnectionsText": "Deshabilitar Conexiones Remotas De La Aplicación",
"disableXInputDescriptionText": "Permite más de 4 controladores pero puede que no funcione bien.", "disableXInputDescriptionText": "Permite más de 4 controladores pero puede que no funcione bien.",
"disableXInputText": "Deshabilitar XInput", "disableXInputText": "Deshabilitar XInput",
"disabledText": "Deshabilitado", "disabledText": "Deshabilitado",
"discordFriendsText": "¿Quieres buscar gente nueva con quien jugar?\n¡Únete a nuestro Discord y encuentra nuevos amigos!",
"discordJoinText": "Únete a el Discord",
"doneText": "Hecho", "doneText": "Hecho",
"drawText": "Empate", "drawText": "Empate",
"duplicateText": "Duplicar", "duplicateText": "Duplicar",
@ -594,11 +601,11 @@
"cantSaveEmptyListText": "¡No puedes guardar una lista de juegos vacía!", "cantSaveEmptyListText": "¡No puedes guardar una lista de juegos vacía!",
"editGameText": "Editar\nJuego", "editGameText": "Editar\nJuego",
"gameListText": "Lista de juegos", "gameListText": "Lista de juegos",
"listNameText": "Nombre de la Lista de juegos", "listNameText": "Nombre De La Lista De Juegos",
"nameText": "Nombre", "nameText": "Nombre",
"removeGameText": "Remover\nJuego", "removeGameText": "Remover\nJuego",
"saveText": "Guardar Lista", "saveText": "Guardar Lista",
"titleText": "Editor de Lista de juegos" "titleText": "Editor De Lista De Juegos"
}, },
"editProfileWindow": { "editProfileWindow": {
"accountProfileInfoText": "Este perfil de jugador especial tiene un nombre\ny un icono basado en tu cuenta.\n\n${ICONS}\n\nCrea perfiles personalizados si quieres usar\ndiferentes nombres o iconos personalizados.", "accountProfileInfoText": "Este perfil de jugador especial tiene un nombre\ny un icono basado en tu cuenta.\n\n${ICONS}\n\nCrea perfiles personalizados si quieres usar\ndiferentes nombres o iconos personalizados.",
@ -608,15 +615,15 @@
"characterText": "personaje", "characterText": "personaje",
"checkingAvailabilityText": "Revisando la disponibilidad para \"${NAME}\"...", "checkingAvailabilityText": "Revisando la disponibilidad para \"${NAME}\"...",
"colorText": "color", "colorText": "color",
"getMoreCharactersText": "Obtener Más Personajes...", "getMoreCharactersText": "Conseguir Más Personajes...",
"getMoreIconsText": "Obtener Más Iconos...", "getMoreIconsText": "Conseguir Más Iconos...",
"globalProfileInfoText": "Los perfiles globales tienen un nombre único\na nivel mundial. También tienen iconos personalizados.", "globalProfileInfoText": "Los perfiles globales tienen un nombre único\na nivel mundial. También tienen iconos personalizados.",
"globalProfileText": "(perfil global)", "globalProfileText": "(perfil global)",
"highlightText": "resalte", "highlightText": "resalte",
"iconText": "icono", "iconText": "icono",
"localProfileInfoText": "Los perfiles locales no tienen iconos y no hay garantía\nque los nombres sean únicos. Obtén un perfil global\npara reservar un nombre único y tengas un icono personalizado.", "localProfileInfoText": "Los perfiles locales no tienen iconos y no hay garantía\nque los nombres sean únicos. Crea un perfil global\npara reservar un nombre único y tengas un icono personalizado.",
"localProfileText": "(perfil local)", "localProfileText": "(perfil local)",
"nameDescriptionText": "Nombre del Jugador", "nameDescriptionText": "Nombre Del Jugador",
"nameText": "Nombre", "nameText": "Nombre",
"randomText": "aleatorio", "randomText": "aleatorio",
"titleEditText": "Editar Perfil", "titleEditText": "Editar Perfil",
@ -639,24 +646,24 @@
"duplicateText": "Duplicar\nBanda Sonora", "duplicateText": "Duplicar\nBanda Sonora",
"editSoundtrackText": "Editor de Banda Sonora", "editSoundtrackText": "Editor de Banda Sonora",
"editText": "Editar\nBanda Sonora", "editText": "Editar\nBanda Sonora",
"fetchingITunesText": "buscando playlists en la App de Música...", "fetchingITunesText": "buscando playlists en la App De Música...",
"musicVolumeZeroWarning": "Advertencia: el volumen de la música está en 0", "musicVolumeZeroWarning": "Advertencia: el volumen de la música está en 0",
"nameText": "Nombre", "nameText": "Nombre",
"newSoundtrackNameText": "Mi Banda Sonora ${COUNT}", "newSoundtrackNameText": "Mi Banda Sonora ${COUNT}",
"newSoundtrackText": "Nueva Banda Sonora:", "newSoundtrackText": "Nueva Banda Sonora:",
"newText": "Nueva\nBanda Sonora", "newText": "Nueva\nBanda Sonora",
"selectAPlaylistText": "Selecciona Una Playlist", "selectAPlaylistText": "Selecciona Una Playlist",
"selectASourceText": "Fuente de la Música", "selectASourceText": "Fuente De La Música",
"soundtrackText": "pista de audio", "soundtrackText": "pista de audio",
"testText": "prueba", "testText": "prueba",
"titleText": "Bandas Sonoras", "titleText": "Bandas Sonoras",
"useDefaultGameMusicText": "Música del Juego Predeterminada", "useDefaultGameMusicText": "Música Del Juego Por Defecto",
"useITunesPlaylistText": "Playlist de la App de Música", "useITunesPlaylistText": "Playlist De La App De Música",
"useMusicFileText": "Archivo de Audio (MP3, etc)", "useMusicFileText": "Archivo De Música (mp3, etc)",
"useMusicFolderText": "Carpeta de Archivos de Audio" "useMusicFolderText": "Carpeta de Archivos de Audio"
}, },
"editText": "Editar", "editText": "Editar",
"enabledText": "Activado", "enabledText": "Habilitado",
"endText": "Fin", "endText": "Fin",
"enjoyText": "¡Diviértete!", "enjoyText": "¡Diviértete!",
"epicDescriptionFilterText": "${DESCRIPTION} En cámara lenta épica.", "epicDescriptionFilterText": "${DESCRIPTION} En cámara lenta épica.",
@ -684,11 +691,11 @@
"finalTimeText": "Tiempo Final", "finalTimeText": "Tiempo Final",
"finishingInstallText": "Instalación casi lista; espera un momento...", "finishingInstallText": "Instalación casi lista; espera un momento...",
"fireTVRemoteWarningText": "* Para una mejor experiencia, \nutiliza controles o instala la\napp '${REMOTE_APP_NAME}' en tus\ndispositivos móviles.", "fireTVRemoteWarningText": "* Para una mejor experiencia, \nutiliza controles o instala la\napp '${REMOTE_APP_NAME}' en tus\ndispositivos móviles.",
"firstToFinalText": "Primero de ${COUNT} Final", "firstToFinalText": "Primero de ${COUNT} Finales",
"firstToSeriesText": "Primero de ${COUNT} Serie", "firstToSeriesText": "Primero de ${COUNT} Series",
"fiveKillText": "¡¡¡ASESINATO QUÍNTUPLE!!!", "fiveKillText": "¡¡¡COMBO QUÍNTUPLE!!!",
"flawlessWaveText": Horda perfecta!", "flawlessWaveText": Oleada Perfecta!",
"fourKillText": "¡¡¡ASESINATO CUÁDRUPLE!!!", "fourKillText": "¡¡¡COMBO CUÁDRUPLE!!!",
"freeForAllText": "Pelea libre", "freeForAllText": "Pelea libre",
"friendScoresUnavailableText": "Puntaje no disponible.", "friendScoresUnavailableText": "Puntaje no disponible.",
"gameCenterText": "GameCenter", "gameCenterText": "GameCenter",
@ -709,22 +716,22 @@
"titleText": "Personalizar Playlists de ${TYPE}" "titleText": "Personalizar Playlists de ${TYPE}"
}, },
"gameSettingsWindow": { "gameSettingsWindow": {
"addGameText": "Agrega juego" "addGameText": "Agregar Juego"
}, },
"gamepadDetectedText": "1 control detectado.", "gamepadDetectedText": "1 control detectado.",
"gamepadsDetectedText": "${COUNT} controles detectados.", "gamepadsDetectedText": "${COUNT} controles detectados.",
"gamesToText": "${WINCOUNT} juegos a ${LOSECOUNT}", "gamesToText": "${WINCOUNT} juegos a ${LOSECOUNT}",
"gatherWindow": { "gatherWindow": {
"aboutDescriptionLocalMultiplayerExtraText": "Recuerda: cualquier dispositivo en la fiesta puede\ntener más de un jugador si tienen controles suficientes.", "aboutDescriptionLocalMultiplayerExtraText": "Recuerda: cualquier dispositivo en la fiesta puede\ntener más de un jugador si tienen controles suficientes.",
"aboutDescriptionText": "Usa estas pestañas para crear una fiesta.\n\nLas fiestas te permiten jugar y competir con\ntus amigos con sus propios dispositivos.\n\nUsa el botón ${PARTY} en la parte superior\nderecha para chatear e interactuar con tu fiesta.\n(En el control, presiona ${BUTTON} mientras estés en el menú)", "aboutDescriptionText": "Usa estas pestañas para armar una partida.\n\nLas partidas te permiten jugar y competir con\ntus amigos a través de diferentes dispositivos.\n\nUsa el botón ${PARTY} en la parte superior\nderecha para chatear e interactuar con tu partida.\n(En el control, presiona ${BUTTON} mientras estés en el menú)",
"aboutText": "Acerca de", "aboutText": "Acerca De",
"addressFetchErrorText": "<error consiguiendo dirección>", "addressFetchErrorText": "<error consiguiendo dirección>",
"appInviteInfoText": "Invita amigos a probar BombSquad y recibirán\n${COUNT} ticketes gratis. Tu obtendrás\n${YOU_COUNT} por cada amigo que acepte.", "appInviteInfoText": "Invita amigos a probar BombSquad y recibirán\n${COUNT} ticketes gratis. Tu obtendrás\n${YOU_COUNT} por cada amigo que acepte.",
"appInviteMessageText": "${NAME} te envió ${COUNT} boletos en ${APP_NAME}", "appInviteMessageText": "${NAME} te envió ${COUNT} boletos en ${APP_NAME}",
"appInviteSendACodeText": "Envíales Un Código", "appInviteSendACodeText": "Envíales Un Código",
"appInviteTitleText": "Invitación De La Aplicación ${APP_NAME}", "appInviteTitleText": "Invitación De La Aplicación ${APP_NAME}",
"bluetoothAndroidSupportText": "(funciona con cualquier dispositivo Android con Bluetooth)", "bluetoothAndroidSupportText": "(funciona con cualquier dispositivo Android con Bluetooth)",
"bluetoothDescriptionText": "Alojar/unirse a una fiesta vía Bluetooth:", "bluetoothDescriptionText": "Alojar/unirse a una partida vía Bluetooth:",
"bluetoothHostText": "Alojar vía Bluetooth", "bluetoothHostText": "Alojar vía Bluetooth",
"bluetoothJoinText": "Unirse vía Bluetooth", "bluetoothJoinText": "Unirse vía Bluetooth",
"bluetoothText": "Bluetooth", "bluetoothText": "Bluetooth",
@ -738,7 +745,7 @@
"emailItText": "Envíar Correo", "emailItText": "Envíar Correo",
"favoritesSaveText": "Guardar Como Favorito", "favoritesSaveText": "Guardar Como Favorito",
"favoritesText": "Favoritos", "favoritesText": "Favoritos",
"freeCloudServerAvailableMinutesText": "El siguiente server estara disponible en ${MINUTES} minutos", "freeCloudServerAvailableMinutesText": "El siguiente servidor estará disponible en ${MINUTES} minutos.",
"freeCloudServerAvailableNowText": "¡Servidor en la nube gratuito disponible!", "freeCloudServerAvailableNowText": "¡Servidor en la nube gratuito disponible!",
"freeCloudServerNotAvailableText": "No hay servidores en la nube gratuitos disponibles.", "freeCloudServerNotAvailableText": "No hay servidores en la nube gratuitos disponibles.",
"friendHasSentPromoCodeText": "Recibiste ${COUNT} boletos de ${APP_NAME} de ${NAME}", "friendHasSentPromoCodeText": "Recibiste ${COUNT} boletos de ${APP_NAME} de ${NAME}",
@ -770,7 +777,7 @@
"manualConnectText": "Conectar", "manualConnectText": "Conectar",
"manualDescriptionText": "Unirse a una partida por dirección:", "manualDescriptionText": "Unirse a una partida por dirección:",
"manualJoinSectionText": "Unirse Por Dirección", "manualJoinSectionText": "Unirse Por Dirección",
"manualJoinableFromInternetText": "¿Se pueden unir desde internet?", "manualJoinableFromInternetText": "¿Se pueden unir desde internet?:",
"manualJoinableNoWithAsteriskText": "NO*", "manualJoinableNoWithAsteriskText": "NO*",
"manualJoinableYesText": "SÍ", "manualJoinableYesText": "SÍ",
"manualRouterForwardingText": "*para arreglarlo, configura tu router para que redireccione el puerto UDP ${PORT} a tu dirección local", "manualRouterForwardingText": "*para arreglarlo, configura tu router para que redireccione el puerto UDP ${PORT} a tu dirección local",
@ -779,6 +786,7 @@
"manualYourLocalAddressText": "Tu dirección local:", "manualYourLocalAddressText": "Tu dirección local:",
"nearbyText": "Cerca", "nearbyText": "Cerca",
"noConnectionText": "<sin conexión>", "noConnectionText": "<sin conexión>",
"noPartiesAddedText": "Sin Fiestas Añadidas",
"otherVersionsText": "(otras versiones)", "otherVersionsText": "(otras versiones)",
"partyCodeText": "Código De La Partida", "partyCodeText": "Código De La Partida",
"partyInviteAcceptText": "Aceptar", "partyInviteAcceptText": "Aceptar",
@ -787,7 +795,7 @@
"partyInviteIgnoreText": "Ignorar", "partyInviteIgnoreText": "Ignorar",
"partyInviteText": "${NAME} te ha invitado\na unirse a su partida!", "partyInviteText": "${NAME} te ha invitado\na unirse a su partida!",
"partyNameText": "Nombre De La Partida", "partyNameText": "Nombre De La Partida",
"partyServerRunningText": "Tu servidor de fiesta se esta ejecutando.", "partyServerRunningText": "Tu servidor de partida se esta ejecutando.",
"partySizeText": "tamaño de partida", "partySizeText": "tamaño de partida",
"partyStatusCheckingText": "comprobando estado...", "partyStatusCheckingText": "comprobando estado...",
"partyStatusJoinableText": "ahora se pueden unir a tu partida desde internet", "partyStatusJoinableText": "ahora se pueden unir a tu partida desde internet",
@ -843,9 +851,9 @@
"ticketsFromASponsorText": "Ver un anuncio\na cambio de ${COUNT} boletos", "ticketsFromASponsorText": "Ver un anuncio\na cambio de ${COUNT} boletos",
"ticketsText": "${COUNT} Boletos", "ticketsText": "${COUNT} Boletos",
"titleText": "Conseguir Boletos", "titleText": "Conseguir Boletos",
"unavailableLinkAccountText": "Lo sentimos, las compras no están disponibles en esta plataforma.\nComo una solución, puedes enlazar esta cuenta a otra\nplataforma y hacer tus compras desde ahí.", "unavailableLinkAccountText": "Disculpe, las compras no están disponibles en esta plataforma.\nComo una solución, puedes enlazar esta cuenta a otra\nplataforma y hacer tus compras desde ahí.",
"unavailableTemporarilyText": "No disponible por el momento; por favor inténtalo más tarde.", "unavailableTemporarilyText": "No disponible por el momento; por favor inténtalo más tarde.",
"unavailableText": "Lo sentimos, no se encuentra disponible.", "unavailableText": "Disculpe, esto no esta disponible.",
"versionTooOldText": "Lo sentimos, esta versión del juego es muy antigua; por favor actualízala a una nueva versión.", "versionTooOldText": "Lo sentimos, esta versión del juego es muy antigua; por favor actualízala a una nueva versión.",
"youHaveShortText": "tienes ${COUNT}", "youHaveShortText": "tienes ${COUNT}",
"youHaveText": "tienes ${COUNT} boletos" "youHaveText": "tienes ${COUNT} boletos"
@ -858,10 +866,12 @@
"alwaysText": "Siempre", "alwaysText": "Siempre",
"fullScreenCmdText": "Pantalla completa (Cmd-F)", "fullScreenCmdText": "Pantalla completa (Cmd-F)",
"fullScreenCtrlText": "Pantalla completa (Ctrl-F)", "fullScreenCtrlText": "Pantalla completa (Ctrl-F)",
"fullScreenText": "Pantalla completa",
"gammaText": "Gama", "gammaText": "Gama",
"highText": "Alta", "highText": "Alta",
"higherText": "Muy Alta", "higherText": "Muy Alta",
"lowText": "Baja", "lowText": "Baja",
"maxFPSText": "FPS Máximos",
"mediumText": "Mediana", "mediumText": "Mediana",
"neverText": "Nunca", "neverText": "Nunca",
"resolutionText": "Resolución", "resolutionText": "Resolución",
@ -940,25 +950,25 @@
"importText": "Importar", "importText": "Importar",
"importingText": "Importando...", "importingText": "Importando...",
"inGameClippedNameText": "en el juego será\n\"${NAME}\"", "inGameClippedNameText": "en el juego será\n\"${NAME}\"",
"installDiskSpaceErrorText": "ERROR: Incapaz de completar la instalación\nPuede que te hayas quedado sin espacio.\nLibera un poco de tu espacio e intenta de nuevo.", "installDiskSpaceErrorText": "ERROR: Incapaz de completar la instalación.\nPuede que te hayas quedado sin espacio.\nLibera un poco de tu espacio e intenta de nuevo.",
"internal": { "internal": {
"arrowsToExitListText": "pulsa ${LEFT} o ${RIGHT} para salir de la lista", "arrowsToExitListText": "pulsa ${LEFT} o ${RIGHT} para salir de la lista",
"buttonText": "botón", "buttonText": "botón",
"cantKickHostError": "No puedes expulsar al host", "cantKickHostError": "No puedes expulsar al anfitrión.",
"chatBlockedText": "A ${NAME} le hemos bloqueado el chat por ${TIME} segundos.", "chatBlockedText": "${NAME} esta bloqueado del chat por ${TIME} segundos.",
"connectedToGameText": "'${NAME}' se unió", "connectedToGameText": "Unido a '${NAME}'",
"connectedToPartyText": "¡Unido a la fiesta de ${NAME}!", "connectedToPartyText": "¡Unido a la partida de ${NAME}!",
"connectingToPartyText": "Conectando...", "connectingToPartyText": "Conectando...",
"connectionFailedHostAlreadyInPartyText": "Conexión fallida; Host esta en otra fiesta.", "connectionFailedHostAlreadyInPartyText": "Conexión fallida; el anfitrión está en otra partida.",
"connectionFailedPartyFullText": "Conexión fallida; la fiesta está llena.", "connectionFailedPartyFullText": "Conexión fallida; la partida está llena.",
"connectionFailedText": "Conexión fallida.", "connectionFailedText": "Conexión fallida.",
"connectionFailedVersionMismatchText": "Conexión fallida; Host corre una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", "connectionFailedVersionMismatchText": "Conexión fallida; el anfitrión corre una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.",
"connectionRejectedText": "Conexión rechazada.", "connectionRejectedText": "Conexión rechazada.",
"controllerConnectedText": "${CONTROLLER} conectado.", "controllerConnectedText": "${CONTROLLER} conectado.",
"controllerDetectedText": "1 control detectado.", "controllerDetectedText": "1 control detectado.",
"controllerDisconnectedText": "${CONTROLLER} desconectado.", "controllerDisconnectedText": "${CONTROLLER} desconectado.",
"controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Intenta conectarlo de nuevo.", "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Intenta conectarlo de nuevo.",
"controllerForMenusOnlyText": "Este control no puede ser usado para jugar; solo para navegar por menus.", "controllerForMenusOnlyText": "Este control no puede ser usado para jugar; solo para navegar por menús.",
"controllerReconnectedText": "${CONTROLLER} reconectado.", "controllerReconnectedText": "${CONTROLLER} reconectado.",
"controllersConnectedText": "${COUNT} controles conectados.", "controllersConnectedText": "${COUNT} controles conectados.",
"controllersDetectedText": "${COUNT} controles detectados.", "controllersDetectedText": "${COUNT} controles detectados.",
@ -967,8 +977,8 @@
"errorPlayingMusicText": "Error reproduciendo música: ${MUSIC}", "errorPlayingMusicText": "Error reproduciendo música: ${MUSIC}",
"errorResettingAchievementsText": "Incapaz de reiniciar los logros; por favor inténtalo de nuevo más tarde.", "errorResettingAchievementsText": "Incapaz de reiniciar los logros; por favor inténtalo de nuevo más tarde.",
"hasMenuControlText": "${NAME} tiene el control del menú.", "hasMenuControlText": "${NAME} tiene el control del menú.",
"incompatibleNewerVersionHostText": "El host está corriendo una versión nueva del juego.\nActualiza a la última versión y vuelve a intentarlo.", "incompatibleNewerVersionHostText": "El anfitrión está ejecutando una versión nueva del juego.\nActualiza a la última versión y vuelve a intentarlo.",
"incompatibleVersionHostText": "Host corre una versión diferente del juego; imposible conectar.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", "incompatibleVersionHostText": "El anfitrión está ejecutando una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.",
"incompatibleVersionPlayerText": "${NAME} está ejecutando una versión diferente del juego.\nAsegúrate de que ambos estén actualizados y vuelve a intentarlo.", "incompatibleVersionPlayerText": "${NAME} está ejecutando una versión diferente del juego.\nAsegúrate de que ambos estén actualizados y vuelve a intentarlo.",
"invalidAddressErrorText": "Error: dirección inválida.", "invalidAddressErrorText": "Error: dirección inválida.",
"invalidNameErrorText": "Error: nombre inválido.", "invalidNameErrorText": "Error: nombre inválido.",
@ -977,7 +987,7 @@
"invitationsSentText": "${COUNT} invitaciones enviadas.", "invitationsSentText": "${COUNT} invitaciones enviadas.",
"joinedPartyInstructionsText": "Alguien se ha unido a tu fiesta.\nVe a 'Jugar' para iniciar un juego.", "joinedPartyInstructionsText": "Alguien se ha unido a tu fiesta.\nVe a 'Jugar' para iniciar un juego.",
"keyboardText": "Teclado", "keyboardText": "Teclado",
"kickIdlePlayersKickedText": "Expulsando a ${NAME} por ser inactivo.", "kickIdlePlayersKickedText": "Expulsando a ${NAME} por estar inactivo.",
"kickIdlePlayersWarning1Text": "${NAME} será expulsado en ${COUNT} segundos si sigue inactivo.", "kickIdlePlayersWarning1Text": "${NAME} será expulsado en ${COUNT} segundos si sigue inactivo.",
"kickIdlePlayersWarning2Text": "(puedes apagar esto en Ajustes -> Avanzado)", "kickIdlePlayersWarning2Text": "(puedes apagar esto en Ajustes -> Avanzado)",
"leftGameText": "Abandonó '${NAME}'.", "leftGameText": "Abandonó '${NAME}'.",
@ -996,7 +1006,7 @@
"touchScreenJoinWarningText": "Te uniste con la pantalla táctil.\nSi este fue un error, presiona 'Menú->Dejar juego' con ella.", "touchScreenJoinWarningText": "Te uniste con la pantalla táctil.\nSi este fue un error, presiona 'Menú->Dejar juego' con ella.",
"touchScreenText": "Pantalla Táctil", "touchScreenText": "Pantalla Táctil",
"trialText": "prueba", "trialText": "prueba",
"unableToResolveHostText": "Error: no se ha podido resolver el host", "unableToResolveHostText": "Error: incapaz de encontrar el anfitrión.",
"unavailableNoConnectionText": "No disponible por el momento (¿No tienes conexión a internet?)", "unavailableNoConnectionText": "No disponible por el momento (¿No tienes conexión a internet?)",
"vrOrientationResetCardboardText": "Usa esto para reiniciar la orientación VR.\nPara jugar el juego necesitarás un control externo.", "vrOrientationResetCardboardText": "Usa esto para reiniciar la orientación VR.\nPara jugar el juego necesitarás un control externo.",
"vrOrientationResetText": "Orientación VR reiniciada.", "vrOrientationResetText": "Orientación VR reiniciada.",
@ -1012,10 +1022,10 @@
"kickOccurredText": "${NAME} ha sido expulsado.", "kickOccurredText": "${NAME} ha sido expulsado.",
"kickQuestionText": "¿Expulsar a ${NAME}?", "kickQuestionText": "¿Expulsar a ${NAME}?",
"kickText": "Expulsar", "kickText": "Expulsar",
"kickVoteCantKickAdminsText": "Los admins no pueden ser expulsados.", "kickVoteCantKickAdminsText": "Los administradores no pueden ser expulsados.",
"kickVoteCantKickSelfText": "Claro que no, no puedes expulsarte a ti mismo.", "kickVoteCantKickSelfText": "No puedes expulsarte a ti mismo.",
"kickVoteFailedNotEnoughVotersText": "No hay suficientes jugadores para votar.", "kickVoteFailedNotEnoughVotersText": "No hay suficientes jugadores para votar.",
"kickVoteFailedText": "Votación de expulsión fallida", "kickVoteFailedText": "Votación de expulsión fallida.",
"kickVoteStartedText": "Se ha iniciado una votación de expulsión para '${NAME}'.", "kickVoteStartedText": "Se ha iniciado una votación de expulsión para '${NAME}'.",
"kickVoteText": "Votar para Expulsar", "kickVoteText": "Votar para Expulsar",
"kickVotingDisabledText": "El voto para expulsar no está disponible.", "kickVotingDisabledText": "El voto para expulsar no está disponible.",
@ -1070,9 +1080,9 @@
"mainMenu": { "mainMenu": {
"creditsText": "Créditos", "creditsText": "Créditos",
"demoMenuText": "Menú Demo", "demoMenuText": "Menú Demo",
"endGameText": "Terminar juego", "endGameText": "Terminar Juego",
"endTestText": "Terminar prueba", "endTestText": "Terminar Prueba",
"exitGameText": "Salir del juego", "exitGameText": "Salir Del Juego",
"exitToMenuText": "¿Salir al menú?", "exitToMenuText": "¿Salir al menú?",
"howToPlayText": "Cómo Jugar", "howToPlayText": "Cómo Jugar",
"justPlayerText": "(Solo ${NAME})", "justPlayerText": "(Solo ${NAME})",
@ -1100,14 +1110,14 @@
"mostViolatedPlayerText": "Jugador Más Violado", "mostViolatedPlayerText": "Jugador Más Violado",
"mostViolentPlayerText": "Jugador Más Violento", "mostViolentPlayerText": "Jugador Más Violento",
"moveText": "Mover", "moveText": "Mover",
"multiKillText": "¡¡¡ASESINATO-${COUNT}!!!", "multiKillText": "¡¡¡COMBO DE ${COUNT}!!!",
"multiPlayerCountText": "${COUNT} jugadores", "multiPlayerCountText": "${COUNT} jugadores",
"mustInviteFriendsText": "Nota: debes invitar a tus amigos en\nel panel \"${GATHER}\" o conectar\ncontroles para jugar multijugador.", "mustInviteFriendsText": "Nota: debes invitar a tus amigos en\nel panel \"${GATHER}\" o conectar\ncontroles para jugar multijugador.",
"nameBetrayedText": "${NAME} traicionó a ${VICTIM}.", "nameBetrayedText": "${NAME} traicionó a ${VICTIM}.",
"nameDiedText": "${NAME} ha muerto.", "nameDiedText": "${NAME} ha muerto.",
"nameKilledText": "${NAME} mató a ${VICTIM}.", "nameKilledText": "${NAME} mató a ${VICTIM}.",
"nameNotEmptyText": "¡El nombre no puede quedar vacío!", "nameNotEmptyText": "¡El nombre no puede quedar vacío!",
"nameScoresText": "¡${NAME} anotó!", "nameScoresText": "¡${NAME} Anotó!",
"nameSuicideKidFriendlyText": "${NAME} murió por accidente.", "nameSuicideKidFriendlyText": "${NAME} murió por accidente.",
"nameSuicideText": "${NAME} cometió suicidio.", "nameSuicideText": "${NAME} cometió suicidio.",
"nameText": "Nombre", "nameText": "Nombre",
@ -1123,8 +1133,10 @@
"noExternalStorageErrorText": "No se encontraron almacenamientos externos en este dispositivo", "noExternalStorageErrorText": "No se encontraron almacenamientos externos en este dispositivo",
"noGameCircleText": "Error: no registrado en GameCircle", "noGameCircleText": "Error: no registrado en GameCircle",
"noJoinCoopMidwayText": "Jugadores no pueden unirse en mitad de un juego.", "noJoinCoopMidwayText": "Jugadores no pueden unirse en mitad de un juego.",
"noPluginsInstalledText": "Sin Complementos Instalados",
"noProfilesErrorText": "No haz creado ningún perfil, por lo que tendrás que llamarte '${NAME}'.\nVe a Ajustes>Perfiles para que te hagas un perfil.", "noProfilesErrorText": "No haz creado ningún perfil, por lo que tendrás que llamarte '${NAME}'.\nVe a Ajustes>Perfiles para que te hagas un perfil.",
"noScoresYetText": "Sin puntuaciones aún.", "noScoresYetText": "Sin puntajes aún.",
"noServersFoundText": "No se encontraron servidores.",
"noThanksText": "No Gracias", "noThanksText": "No Gracias",
"noTournamentsInTestBuildText": "ADVERTENCIA: los puntajes de los torneos en esta versión de prueba serán ignorados.", "noTournamentsInTestBuildText": "ADVERTENCIA: los puntajes de los torneos en esta versión de prueba serán ignorados.",
"noValidMapsErrorText": "Mapas válidos no encontrados para este tipo de juego.", "noValidMapsErrorText": "Mapas válidos no encontrados para este tipo de juego.",
@ -1134,14 +1146,14 @@
"notSignedInErrorText": "Debes iniciar sesión para hacer esto.", "notSignedInErrorText": "Debes iniciar sesión para hacer esto.",
"notSignedInGooglePlayErrorText": "Debes iniciar sesión con Google Play para hacer esto.", "notSignedInGooglePlayErrorText": "Debes iniciar sesión con Google Play para hacer esto.",
"notSignedInText": "No registrado", "notSignedInText": "No registrado",
"notUsingAccountText": "Nota: ignorando su cuenta de ${SERVICE}.\nVaya a 'Cuenta -> Ingresar con ${SERVICE}' si quieres usarla", "notUsingAccountText": "Nota: ignorando su cuenta de ${SERVICE}.\nVaya a 'Cuenta -> Ingresar con ${SERVICE}' si quieres usarla.",
"nothingIsSelectedErrorText": "¡No hay nada seleccionado!", "nothingIsSelectedErrorText": "¡No hay nada seleccionado!",
"numberText": "#${NUMBER}", "numberText": "#${NUMBER}",
"offText": "Apagar", "offText": "Apagar",
"okText": "Aceptar", "okText": "Aceptar",
"onText": "Encender", "onText": "Encender",
"oneMomentText": "Un Momento...", "oneMomentText": "Un Momento...",
"onslaughtRespawnText": "${PLAYER} reaparecerá en la horda ${WAVE}", "onslaughtRespawnText": "${PLAYER} reaparecerá en la oleada ${WAVE}",
"orText": "${A} o ${B}", "orText": "${A} o ${B}",
"otherText": "Otros...", "otherText": "Otros...",
"outOfText": "(#${RANK} de ${ALL})", "outOfText": "(#${RANK} de ${ALL})",
@ -1150,17 +1162,17 @@
"partyWindow": { "partyWindow": {
"chatMessageText": "Mensaje Del Chat", "chatMessageText": "Mensaje Del Chat",
"emptyText": "Tu partida está vacía", "emptyText": "Tu partida está vacía",
"hostText": "(anfitrión)", "hostText": "(host)",
"sendText": "Enviar", "sendText": "Enviar",
"titleText": "Tu Partida" "titleText": "Tu Partida"
}, },
"pausedByHostText": "(pausado por el anfitrión)", "pausedByHostText": "(pausado por el host)",
"perfectWaveText": "¡Oleada Perfecta!", "perfectWaveText": "¡Oleada Perfecta!",
"pickUpBoldText": "LEVANTAR", "pickUpBoldText": "LEVANTAR",
"pickUpText": "Recoger", "pickUpText": "Recoger",
"playModes": { "playModes": {
"coopText": "Cooperativo", "coopText": "Cooperativo",
"freeForAllText": "Libre-para-Todos", "freeForAllText": "Todos-contra-Todos",
"multiTeamText": "Múlti-Equipo", "multiTeamText": "Múlti-Equipo",
"singlePlayerCoopText": "Solo Un Jugador / Cooperativo", "singlePlayerCoopText": "Solo Un Jugador / Cooperativo",
"teamsText": "Equipos" "teamsText": "Equipos"
@ -1183,7 +1195,7 @@
"playerProfilesWindow": { "playerProfilesWindow": {
"cantDeleteAccountProfileText": "No puedes borrar el perfil de tu cuenta.", "cantDeleteAccountProfileText": "No puedes borrar el perfil de tu cuenta.",
"deleteButtonText": "Borrar\nPerfil", "deleteButtonText": "Borrar\nPerfil",
"deleteConfirmText": "Borrar '${PROFILE}'?", "deleteConfirmText": "¿Borrar '${PROFILE}'?",
"editButtonText": "Editar\nPerfil", "editButtonText": "Editar\nPerfil",
"explanationText": "(nombres de jugadores personalizados y apariencias para esta cuenta)", "explanationText": "(nombres de jugadores personalizados y apariencias para esta cuenta)",
"newButtonText": "Nuevo\nPerfil", "newButtonText": "Nuevo\nPerfil",
@ -1196,8 +1208,8 @@
"playlistsText": "Listas de juegos", "playlistsText": "Listas de juegos",
"pleaseRateText": "Si te gusta ${APP_NAME}, por favor tomate un momento\npara calificar o escribir una reseña. Esto proporcionará\ninformación útil y ayuda al soporte del futuro desarrollo del juego.\n\n¡gracias!\n-eric", "pleaseRateText": "Si te gusta ${APP_NAME}, por favor tomate un momento\npara calificar o escribir una reseña. Esto proporcionará\ninformación útil y ayuda al soporte del futuro desarrollo del juego.\n\n¡gracias!\n-eric",
"pleaseWaitText": "Por favor, espera...", "pleaseWaitText": "Por favor, espera...",
"pluginClassLoadErrorText": "Error al cargar la clase del plugin '${PLUGIN}': ${ERROR}", "pluginClassLoadErrorText": "Error cargando la clase del complemento '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Error al iniciar el plugin '${PLUGIN}': ${ERROR}", "pluginInitErrorText": "Error iniciando complemento '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "Ajustes De Complementos", "pluginSettingsText": "Ajustes De Complementos",
"pluginsAutoEnableNewText": "Auto Habilitar Nuevos Complementos", "pluginsAutoEnableNewText": "Auto Habilitar Nuevos Complementos",
"pluginsDetectedText": "Nuevo(s) complemento(s) detectado(s). Reinicie para activarlo(s), o configuralo(s) en ajustes.", "pluginsDetectedText": "Nuevo(s) complemento(s) detectado(s). Reinicie para activarlo(s), o configuralo(s) en ajustes.",
@ -1239,7 +1251,7 @@
"purchaseGameText": "Comprar Juego", "purchaseGameText": "Comprar Juego",
"purchasingText": "Comprando...", "purchasingText": "Comprando...",
"quitGameText": "¿Salir de ${APP_NAME}?", "quitGameText": "¿Salir de ${APP_NAME}?",
"quittingIn5SecondsText": "Abandonando en 5 segundos...", "quittingIn5SecondsText": "Saliendo en 5 segundos...",
"randomPlayerNamesText": "DEFAULT_NAMES, Pablo, Fulanito, Menganita, Martín, Franco, Pancho, Tomás, Bruno, Federico, Juan, Joaquín, Huevo Duro, Chico Rico", "randomPlayerNamesText": "DEFAULT_NAMES, Pablo, Fulanito, Menganita, Martín, Franco, Pancho, Tomás, Bruno, Federico, Juan, Joaquín, Huevo Duro, Chico Rico",
"randomText": "Generar", "randomText": "Generar",
"rankText": "Rango", "rankText": "Rango",
@ -1254,7 +1266,7 @@
"app_name_short": "BSRemoto", "app_name_short": "BSRemoto",
"button_position": "Posición De Los Botones", "button_position": "Posición De Los Botones",
"button_size": "Tamaño De Los Botones", "button_size": "Tamaño De Los Botones",
"cant_resolve_host": "No se encuentra el alojador.", "cant_resolve_host": "No se encuentra el anfitrión.",
"capturing": "Captando...", "capturing": "Captando...",
"connected": "Conectado.", "connected": "Conectado.",
"description": "Usa tu teléfono o tableta como control para BombSquad.\nHasta 8 dispositivos pueden conectarse a la vez para un épico caos multijugador local en un solo TV o tableta", "description": "Usa tu teléfono o tableta como control para BombSquad.\nHasta 8 dispositivos pueden conectarse a la vez para un épico caos multijugador local en un solo TV o tableta",
@ -1263,11 +1275,11 @@
"dpad_floating": "flotante", "dpad_floating": "flotante",
"dpad_position": "Posición Del D-Pad", "dpad_position": "Posición Del D-Pad",
"dpad_size": "Tamaño Del D-Pad", "dpad_size": "Tamaño Del D-Pad",
"dpad_type": "Tipo de D-Pad", "dpad_type": "Tipo De D-Pad",
"enter_an_address": "Ingresa una dirección", "enter_an_address": "Ingresa una dirección",
"game_full": "El juego está lleno o no acepta conexiones.", "game_full": "El juego está lleno o no acepta conexiones.",
"game_shut_down": "El juego se ha cerrado.", "game_shut_down": "El juego se ha cerrado.",
"hardware_buttons": "Botones de Hardware", "hardware_buttons": "Botones Del Hardware",
"join_by_address": "Unirse por dirección...", "join_by_address": "Unirse por dirección...",
"lag": "Lag: ${SECONDS} segundos", "lag": "Lag: ${SECONDS} segundos",
"reset": "Reestablecer a predeterminado", "reset": "Reestablecer a predeterminado",
@ -1286,7 +1298,7 @@
"replayRenameWarningText": "Renombra \"${REPLAY}\" despues de un juego si quieres quedarte con el; o sino será reemplazado.", "replayRenameWarningText": "Renombra \"${REPLAY}\" despues de un juego si quieres quedarte con el; o sino será reemplazado.",
"replayVersionErrorText": "Lo sentimos, esta repetición fue hecha en una\nversión diferente del juego y no se puede usar.", "replayVersionErrorText": "Lo sentimos, esta repetición fue hecha en una\nversión diferente del juego y no se puede usar.",
"replayWatchText": "Ver Repetición", "replayWatchText": "Ver Repetición",
"replayWriteErrorText": "Error creando archivo de repetición", "replayWriteErrorText": "Error creando archivo de repetición.",
"replaysText": "Repeticiones", "replaysText": "Repeticiones",
"reportPlayerExplanationText": "Usa este email para reportar trampas, lenguaje inapropiado, u otro mal comportamiento.\nPor favor, describelo aquí abajo:", "reportPlayerExplanationText": "Usa este email para reportar trampas, lenguaje inapropiado, u otro mal comportamiento.\nPor favor, describelo aquí abajo:",
"reportThisPlayerCheatingText": "Trampas", "reportThisPlayerCheatingText": "Trampas",
@ -1303,8 +1315,8 @@
"scanScriptsMultipleModulesNeedUpdatesText": "Los ${PATH} y ${NUM} y otros módulo(s) se deberán actualizar para el api ${API}", "scanScriptsMultipleModulesNeedUpdatesText": "Los ${PATH} y ${NUM} y otros módulo(s) se deberán actualizar para el api ${API}",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} se deberá actualizar para el api ${API}", "scanScriptsSingleModuleNeedsUpdatesText": "${PATH} se deberá actualizar para el api ${API}",
"scoreChallengesText": "Desafíos De Puntuación", "scoreChallengesText": "Desafíos De Puntuación",
"scoreListUnavailableText": "La lista de puntuaciones no está disponible.", "scoreListUnavailableText": "La lista de puntajes no está disponible.",
"scoreText": "Puntuación", "scoreText": "Puntaje",
"scoreUnits": { "scoreUnits": {
"millisecondsText": "Milisegundos", "millisecondsText": "Milisegundos",
"pointsText": "Puntos", "pointsText": "Puntos",
@ -1332,7 +1344,7 @@
"benchmarksText": "Puntos De Referencia & Pruebas De Estrés", "benchmarksText": "Puntos De Referencia & Pruebas De Estrés",
"disableCameraGyroscopeMotionText": "Deshabilitar El Movimiento Del Giroscopio De La Cámara", "disableCameraGyroscopeMotionText": "Deshabilitar El Movimiento Del Giroscopio De La Cámara",
"disableCameraShakeText": "Deshabilitar El Temblor De La Cámara", "disableCameraShakeText": "Deshabilitar El Temblor De La Cámara",
"disableThisNotice": "(puedes desactivar este aviso en ajustes avanzados)", "disableThisNotice": "(puedes deshabilitar este aviso en ajustes avanzados)",
"enablePackageModsDescriptionText": "(enciende modificaciones pero apaga juegos vía red)", "enablePackageModsDescriptionText": "(enciende modificaciones pero apaga juegos vía red)",
"enablePackageModsText": "Encender Modificaciones Locales", "enablePackageModsText": "Encender Modificaciones Locales",
"enterPromoCodeText": "Ingresar Código", "enterPromoCodeText": "Ingresar Código",
@ -1347,7 +1359,8 @@
"mustRestartText": "Tienes que reiniciar el juego para que tome efecto.", "mustRestartText": "Tienes que reiniciar el juego para que tome efecto.",
"netTestingText": "Prueba De Red", "netTestingText": "Prueba De Red",
"resetText": "Reiniciar", "resetText": "Reiniciar",
"showBombTrajectoriesText": "Mostrar Trajectorias De Las Bombas", "showBombTrajectoriesText": "Mostrar Trayectorias De Las Bombas",
"showDevConsoleButtonText": "Mostrar Botón de Consola de Desarrollador",
"showInGamePingText": "Mostrar Ping En El Juego", "showInGamePingText": "Mostrar Ping En El Juego",
"showPlayerNamesText": "Mostrar Nombres De Los Jugadores", "showPlayerNamesText": "Mostrar Nombres De Los Jugadores",
"showUserModsText": "Mostrar Carpeta De Mods", "showUserModsText": "Mostrar Carpeta De Mods",
@ -1403,7 +1416,7 @@
"charactersText": "Personajes", "charactersText": "Personajes",
"comingSoonText": "Próximamente...", "comingSoonText": "Próximamente...",
"extrasText": "Extras", "extrasText": "Extras",
"freeBombSquadProText": "BombSquad ahora es gratis, pero ya que compraste el juego recibirás\nla mejora de BombSquad Pro y ${COUNT} boletos como agradecimiento.\n¡Disfruta de las nuevas funciones, y gracias por tu apoyo!\n-Eric", "freeBombSquadProText": "BombSquad es gratis, pero ya que compraste el juego recibirás\nla mejora de BombSquad Pro y ${COUNT} boletos como agradecimiento.\n¡Disfruta de las nuevas funciones, y gracias por tu apoyo!\n-Eric",
"gameUpgradesText": "Mejoras", "gameUpgradesText": "Mejoras",
"getCoinsText": "Obtén monedas", "getCoinsText": "Obtén monedas",
"holidaySpecialText": "¡Especial De Temporada!", "holidaySpecialText": "¡Especial De Temporada!",
@ -1425,7 +1438,7 @@
"salePercentText": "(${PERCENT}% menos)", "salePercentText": "(${PERCENT}% menos)",
"saleText": "OFERTA", "saleText": "OFERTA",
"searchText": "Buscar", "searchText": "Buscar",
"teamsFreeForAllGamesText": "Juegos de Equipos / Libre-para-Todos", "teamsFreeForAllGamesText": "Juegos de Equipos / Todos-para-Todos",
"totalWorthText": "*** ¡${TOTAL_WORTH} de valor! ***", "totalWorthText": "*** ¡${TOTAL_WORTH} de valor! ***",
"upgradeQuestionText": "¿Mejorar?", "upgradeQuestionText": "¿Mejorar?",
"winterSpecialText": "Especial De Invierno", "winterSpecialText": "Especial De Invierno",
@ -1438,21 +1451,23 @@
"customize2Text": "Personaliza personajes, mini-juegos, e incluso la banda sonora.", "customize2Text": "Personaliza personajes, mini-juegos, e incluso la banda sonora.",
"customizeText": "Modifica personajes y crea tus propias listas de mini-juegos.", "customizeText": "Modifica personajes y crea tus propias listas de mini-juegos.",
"sportsMoreFunText": "Los deportes son más divertidos con explosivos.", "sportsMoreFunText": "Los deportes son más divertidos con explosivos.",
"teamUpAgainstComputerText": "Forma equipo contra la computadora." "teamUpAgainstComputerText": "Forma un equipo contra la computadora."
}, },
"storeText": "Tienda", "storeText": "Tienda",
"submitText": "Enviar", "submitText": "Enviar",
"submittingPromoCodeText": "Enviando Código...", "submittingPromoCodeText": "Enviando Código...",
"successText": "¡Éxito!",
"supportEmailText": "Si estas teniendo algun problema con la\napp, porfavor manda un email a ${EMAIL}.",
"teamNamesColorText": "Nombres De Equipos/Colores...", "teamNamesColorText": "Nombres De Equipos/Colores...",
"teamsText": "Equipos", "teamsText": "Equipos",
"telnetAccessGrantedText": "Acceso a Telnet activado.", "telnetAccessGrantedText": "Acceso a Telnet activado.",
"telnetAccessText": "Acceso a Telnet detectado; ¿permitir?", "telnetAccessText": "Acceso a Telnet detectado; ¿permitir?",
"testBuildErrorText": "Esta versión de prueba ya no es activa; busca una versión más nueva.", "testBuildErrorText": "Esta versión de prueba ya no es activa; busca una versión más nueva.",
"testBuildText": "Versión De Prueba", "testBuildText": "Compilación De Prueba",
"testBuildValidateErrorText": "Imposible validar esta versión de prueba (¿no tienes conexión a internet?)", "testBuildValidateErrorText": "Incapaz de validar esta compilación de prueba (¿no tienes conexión a internet?)",
"testBuildValidatedText": "Versión de Prueba Validada; ¡Disfruta!", "testBuildValidatedText": "Compilación De Prueba Validada; ¡Disfruta!",
"thankYouText": "¡Gracias por tu ayuda! ¡¡Disfruta el juego!!", "thankYouText": "¡Gracias por tu ayuda! ¡¡Disfruta el juego!!",
"threeKillText": "¡¡ASESINATO TRIPLE!!", "threeKillText": "¡¡COMBO TRIPLE!!",
"timeBonusText": "Bono De Tiempo", "timeBonusText": "Bono De Tiempo",
"timeElapsedText": "Tiempo Transcurrido", "timeElapsedText": "Tiempo Transcurrido",
"timeExpiredText": "Tiempo Expirado", "timeExpiredText": "Tiempo Expirado",
@ -1482,7 +1497,7 @@
"Butch": "Butch", "Butch": "Butch",
"Easter Bunny": "Conejo De Pascua", "Easter Bunny": "Conejo De Pascua",
"Flopsy": "Pelusa", "Flopsy": "Pelusa",
"Frosty": "Escarchy", "Frosty": "Frosty",
"Gretel": "Gretel", "Gretel": "Gretel",
"Grumbledorf": "Grumbledorf", "Grumbledorf": "Grumbledorf",
"Jack Morgan": "Jack Morgan", "Jack Morgan": "Jack Morgan",
@ -1527,7 +1542,7 @@
"Onslaught": "Matanza Infinita", "Onslaught": "Matanza Infinita",
"Onslaught Training": "Entrenamiento De Matanza", "Onslaught Training": "Entrenamiento De Matanza",
"Pro ${GAME}": "${GAME} Pro", "Pro ${GAME}": "${GAME} Pro",
"Pro Football": "Fútbol Pro", "Pro Football": "Rugby Pro",
"Pro Onslaught": "Matanza Pro", "Pro Onslaught": "Matanza Pro",
"Pro Runaround": "Evasiva Pro", "Pro Runaround": "Evasiva Pro",
"Rookie ${GAME}": "Novato ${GAME}", "Rookie ${GAME}": "Novato ${GAME}",
@ -1553,7 +1568,7 @@
"Get the flag to the enemy end zone.": "Lleva la bandera enemiga a tu zona.", "Get the flag to the enemy end zone.": "Lleva la bandera enemiga a tu zona.",
"How fast can you defeat the ninjas?": "¿Cuán rápido puedes derrotar a los ninjas?", "How fast can you defeat the ninjas?": "¿Cuán rápido puedes derrotar a los ninjas?",
"Kill a set number of enemies to win.": "Mata a un número determinado de enemigos para ganar.", "Kill a set number of enemies to win.": "Mata a un número determinado de enemigos para ganar.",
"Last one standing wins.": "El último de pie gana.", "Last one standing wins.": "El último en pie gana.",
"Last remaining alive wins.": "El último en quedar vivo gana.", "Last remaining alive wins.": "El último en quedar vivo gana.",
"Last team standing wins.": "El último equipo en pie gana.", "Last team standing wins.": "El último equipo en pie gana.",
"Prevent enemies from reaching the exit.": "Evita que los enemigos lleguen a la salida.", "Prevent enemies from reaching the exit.": "Evita que los enemigos lleguen a la salida.",
@ -1581,7 +1596,7 @@
"carry the flag for ${ARG1} seconds": "carga la bandera por ${ARG1} segundos.", "carry the flag for ${ARG1} seconds": "carga la bandera por ${ARG1} segundos.",
"kill ${ARG1} enemies": "mata a ${ARG1} enemigos", "kill ${ARG1} enemies": "mata a ${ARG1} enemigos",
"last one standing wins": "el último en pie gana", "last one standing wins": "el último en pie gana",
"last team standing wins": "el último equipo en caer gana", "last team standing wins": "el último equipo en pie gana",
"return ${ARG1} flags": "devuelve ${ARG1} banderas", "return ${ARG1} flags": "devuelve ${ARG1} banderas",
"return 1 flag": "devuelve 1 bandera", "return 1 flag": "devuelve 1 bandera",
"run ${ARG1} laps": "da ${ARG1} vueltas", "run ${ARG1} laps": "da ${ARG1} vueltas",
@ -1669,7 +1684,7 @@
"Big G": "Gran G", "Big G": "Gran G",
"Bridgit": "Puentecito", "Bridgit": "Puentecito",
"Courtyard": "Patio Real", "Courtyard": "Patio Real",
"Crag Castle": "Castillo De Piedra", "Crag Castle": "Castillo Del Risco",
"Doom Shroom": "Hongo De La Muerte", "Doom Shroom": "Hongo De La Muerte",
"Football Stadium": "Estadio De Fútbol", "Football Stadium": "Estadio De Fútbol",
"Happy Thoughts": "Pensamientos Felices", "Happy Thoughts": "Pensamientos Felices",
@ -1694,78 +1709,78 @@
"scoreNames": { "scoreNames": {
"Flags": "Banderas", "Flags": "Banderas",
"Goals": "Goles", "Goals": "Goles",
"Score": "Puntuación", "Score": "Puntaje",
"Survived": "Sobrevivió", "Survived": "Sobrevivió",
"Time": "Tiempo", "Time": "Tiempo",
"Time Held": "Tiempo Mantenido" "Time Held": "Tiempo Mantenido"
}, },
"serverResponses": { "serverResponses": {
"A code has already been used on this account.": "Este código ya ha sido usado en esta cuenta", "A code has already been used on this account.": "Este código ya ha sido usado en esta cuenta.",
"A reward has already been given for that address.": "Ya se le ha dado una recompensa a esa dirección.", "A reward has already been given for that address.": "Ya se le ha dado una recompensa a esa dirección.",
"Account linking successful!": Enlace de cuenta exitoso!", "Account linking successful!": Vinculación de cuenta exitosa!",
"Account unlinking successful!": "¡Desenlace de cuenta exitoso!", "Account unlinking successful!": "¡Desvinculación de cuenta exitosa!",
"Accounts are already linked.": "Las cuentas ya se encuentran enlazadas.", "Accounts are already linked.": "Las cuentas ya están vinculadas.",
"Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "No se pudo verificar la vista del anuncio. \nPor favor asegúrese de estar ejecutando una versión oficial y actualizada del juego.", "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "No se pudo verificar la vista del anuncio. \nPor favor asegúrese de estar ejecutando una versión oficial y actualizada del juego.",
"An error has occurred; (${ERROR})": "Se ha producido un error; (${ERROR})", "An error has occurred; (${ERROR})": "Un error ha ocurrido; (${ERROR})",
"An error has occurred; please contact support. (${ERROR})": "Se ha producido un error; por favor contácte con soporte. (${ERROR})", "An error has occurred; please contact support. (${ERROR})": "Un error ha ocurrido; por favor contacta al soporte. (${ERROR})",
"An error has occurred; please contact support@froemling.net.": "Ha ocurrido un error; contacta a support@froemling.net.", "An error has occurred; please contact support@froemling.net.": "Un error ha ocurrido; por favor contacta a support@froemling.net.",
"An error has occurred; please try again later.": "Un error ha ocurrido; por favor intenta más tarde.", "An error has occurred; please try again later.": "Un error ha ocurrido; por favor intentalo más tarde.",
"Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "¿Quieres enlazar estas cuentas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n¡Esto no se puede deshacer!", "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "¿Quieres vincular estas cuentas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n¡Esto no se puede deshacer!",
"BombSquad Pro unlocked!": "¡BombSquad Pro desbloqueado!", "BombSquad Pro unlocked!": "¡BombSquad Pro desbloqueado!",
"Can't link 2 accounts of this type.": "No puedes enlazar dos cuentas de este tipo.", "Can't link 2 accounts of this type.": "No se pueden vincular 2 cuentas de este tipo.",
"Can't link 2 diamond league accounts.": "No pueden enlazar dos cuentas de liga diamante.", "Can't link 2 diamond league accounts.": "No se pueden vincular 2 cuentas de liga diamante.",
"Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se pudo enlazar; sobrepasaría el máximo de ${COUNT} cuentas enlazadas.", "Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se pudo vincular; sobrepasaría el máximo de cuentas vinculadas de ${COUNT}.",
"Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trampa detectada; puntajes y premios suspendidos por ${COUNT} días.", "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trampa detectada; puntajes y premios suspendidos por ${COUNT} días.",
"Could not establish a secure connection.": "No se pudo establecer una conexión segura.", "Could not establish a secure connection.": "No se pudo establecer una conexión segura.",
"Daily maximum reached.": "Máximo diario conseguido.", "Daily maximum reached.": "Máximo diario conseguido.",
"Entering tournament...": "Entrando a torneo...", "Entering tournament...": "Entrando al torneo...",
"Invalid code.": "Código inválido.", "Invalid code.": "Código inválido.",
"Invalid payment; purchase canceled.": "Pago inválido; compra cancelada.", "Invalid payment; purchase canceled.": "Pago inválido; compra cancelada.",
"Invalid promo code.": "Código promocional inválido.", "Invalid promo code.": "Código promocional inválido.",
"Invalid purchase.": "Compra inválida.", "Invalid purchase.": "Compra inválida.",
"Invalid tournament entry; score will be ignored.": "Entrada de torneo inválida; el puntaje será ignorado.", "Invalid tournament entry; score will be ignored.": "Entrada de torneo inválida; el puntaje será ignorado.",
"Item unlocked!": Objeto desbloqueado!", "Item unlocked!": Artículo desbloqueado!",
"LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULACÍON DENEGADO. ${ACCOUNT} contiene\ndatos significativos que TODOS SERÍAN PERDIDOS.\nPuede vincular en el orden opuesto si lo desea\n(y pierda los datos de ESTA cuenta en su lugar)", "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULACIÓN DENEGADA. ${ACCOUNT} contiene\ndatos significativos que podrían PERDERSE EN SU TOTALIDAD.\nPuedes vincular en el orden opuesto si lo desea\n(y pierda los datos de ESTA cuenta en su lugar)",
"Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "¿Enlazar ${ACCOUNT} a esta cuenta?\nTodos los datos en ${ACCOUNT} desaparecerán.\nEsto no se puede deshacer. ¿Estás seguro?", "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "¿Vincular ${ACCOUNT} a esta cuenta?\nTodos los datos en ${ACCOUNT} desaparecerán.\nEsto no se puede deshacer. ¿Estás seguro?",
"Max number of playlists reached.": "Número máximo de listas de reproducción alcanzado.", "Max number of playlists reached.": "Número máximo de playlits alcanzado.",
"Max number of profiles reached.": "Número máximo de perfiles alcanzado.", "Max number of profiles reached.": "Número máximo de perfiles alcanzado.",
"Maximum friend code rewards reached.": "Máximo de premios por códigos de amigos alcanzado.", "Maximum friend code rewards reached.": "Máximo de premios por códigos de amigos alcanzado.",
"Message is too long.": "El Mensaje es muy largo.", "Message is too long.": "El Mensaje es muy largo.",
"No servers are available. Please try again soon.": "Sin servidores disponibles. Por favor intenta después.", "No servers are available. Please try again soon.": "Sin servidores disponibles. Por favor inténtalo después.",
"Profile \"${NAME}\" upgraded successfully.": "El perfil \"${NAME}\" se ha mejorado satisfactoriamente.", "Profile \"${NAME}\" upgraded successfully.": "El perfil \"${NAME}\" se ha mejorado satisfactoriamente.",
"Profile could not be upgraded.": "El perfil no pudo ser mejorado.", "Profile could not be upgraded.": "El perfil no pudo ser mejorado.",
"Purchase successful!": "¡Compra exitosa!", "Purchase successful!": "¡Compra exitosa!",
"Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Has recibido ${COUNT} boletos por iniciar sesión.\nRegresa mañana para recibir ${TOMORROW_COUNT} boletos.", "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Has recibido ${COUNT} boletos por iniciar sesión.\nRegresa mañana para recibir ${TOMORROW_COUNT} boletos.",
"Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funcionalidad del servidor ya no es compatible en esta versión del juego;\nActualiza a una versión más reciente.", "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funcionalidad del servidor ya no es compatible en esta versión del juego;\nActualiza a una versión más reciente.",
"Sorry, there are no uses remaining on this code.": "Perdón, pero no quedan usos disponibles de este código.", "Sorry, there are no uses remaining on this code.": "Disculpe, pero no quedan usos disponibles de este código.",
"Sorry, this code has already been used.": "Perdón, este código ya ha sido usado.", "Sorry, this code has already been used.": "Disculpe, este código ya ha sido usado.",
"Sorry, this code has expired.": "Perdón, este código ha expirado.", "Sorry, this code has expired.": "Disculpe, este código ha expirado.",
"Sorry, this code only works for new accounts.": "Perdón, este código solo sirve para cuentas nuevas.", "Sorry, this code only works for new accounts.": "Disculpe, este código solo funciona para cuentas nuevas.",
"Still searching for nearby servers; please try again soon.": "Todavía buscando por servidores cercanos; intente de nuevo más tarde.", "Still searching for nearby servers; please try again soon.": "Todavía buscando por servidores cercanos; intente de nuevo más tarde.",
"Temporarily unavailable; please try again later.": "Temporalmente desactivado; por favor, inténtalo luego.", "Temporarily unavailable; please try again later.": "Temporalmente indisponible; por favor inténtalo más tarde.",
"The tournament ended before you finished.": "El torneo terminó antes de que terminaras.", "The tournament ended before you finished.": "El torneo terminó antes de que terminaras.",
"This account cannot be unlinked for ${NUM} days.": "Esta cuenta no puede ser desenlazada por ${NUM} días.", "This account cannot be unlinked for ${NUM} days.": "Esta cuenta no puede ser desvinculada por ${NUM} días.",
"This code cannot be used on the account that created it.": "Este código no puede ser usado en la misma cuenta que ha sido creado.", "This code cannot be used on the account that created it.": "Este código no puede ser usado en la misma cuenta que ha sido creado.",
"This is currently unavailable; please try again later.": "Esto Está No Disponible actualmente; por favor inténtelo más tarde", "This is currently unavailable; please try again later.": "Esto esta indisponible actualmente; por favor inténtelo más tarde",
"This requires version ${VERSION} or newer.": "Esto requiere la versión ${VERSION} o una más nueva.", "This requires version ${VERSION} or newer.": "Esto requiere la versión ${VERSION} o una más reciente.",
"Tournaments disabled due to rooted device.": "Los torneos han sido desactivados debido a que tu dispositivo es root", "Tournaments disabled due to rooted device.": "Los torneos han sido deshabilitados debido a que tú dispositivo esta rooteado.",
"Tournaments require ${VERSION} or newer": "El torneo requiere la versión ${VERSION} o versiones recientes", "Tournaments require ${VERSION} or newer": "Los torneos requieren la versión ${VERSION} o una más nueva",
"Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "¿Desenlazar ${ACCOUNT} de esta cuenta?\nTodos los datos en ${ACCOUNT} se reiniciarán\n(excepto los logros en algunos casos).", "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "¿Desvincular ${ACCOUNT} de esta cuenta?\nTodos los datos en ${ACCOUNT} se reiniciarán.\n(excepto los logros en algunos casos)",
"WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTENCIA: se han emitido reclamaciones de piratería contra tu cuenta.\nLas cuentas que se encuentren pirateadas serán prohibidas. Por favor, juega limpio.", "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTENCIA: se han emitido reclamaciones de hacks contra tu cuenta.\nLas cuentas que se encuentren pirateadas serán prohibidas. Por favor juega limpio.",
"Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "¿Quieres enlazar tu cuenta de dispositivo a esta otra?\n\nTu cuenta de dispositivo es ${ACCOUNT1}\nEsta cuenta es ${ACCOUNT2}\n\nEsto permitirá guardar tu progreso actual.\nAdvertencia: ¡Esto no se puede deshacer!", "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "¿Quieres vincular tu cuenta de dispositivo a esta otra?\n\nTu cuenta de dispositivo es ${ACCOUNT1}\nEsta cuenta es ${ACCOUNT2}\n\nEsto permitirá guardar tu progreso actual.\nAdvertencia: ¡Esto no se puede deshacer!",
"You already own this!": "¡Ya posees esto!", "You already own this!": "¡Ya posees esto!",
"You can join in ${COUNT} seconds.": "Puedes unirte en ${COUNT} segundos.", "You can join in ${COUNT} seconds.": "Puedes unirte en ${COUNT} segundos.",
"You don't have enough tickets for this!": "¡No tienes suficientes boletos para esto!", "You don't have enough tickets for this!": "¡No tienes suficientes boletos para esto!",
"You don't own that.": "No tienes eso.", "You don't own that.": "No tienes eso.",
"You got ${COUNT} tickets!": "¡Obtuviste ${COUNT} boletos!", "You got ${COUNT} tickets!": "¡Obtuviste ${COUNT} boletos!",
"You got a ${ITEM}!": Recibiste un ${ITEM}!", "You got a ${ITEM}!": Conseguiste un ${ITEM}!",
"You have been promoted to a new league; congratulations!": "¡Has sido ascendido a una nueva liga! ¡Felicidades!", "You have been promoted to a new league; congratulations!": "Has sido ascendido a una nueva liga; ¡felicitaciones!",
"You must update to a newer version of the app to do this.": "Debes actualizar la aplicación a una versión más reciente para hacer esto.", "You must update to a newer version of the app to do this.": "Debes actualizar la aplicación a una versión más reciente para hacer esto.",
"You must update to the newest version of the game to do this.": "Necesitas actualizar a la versión más reciente del juego para hacer esto.", "You must update to the newest version of the game to do this.": "Necesitas actualizar a la versión más reciente del juego para hacer esto.",
"You must wait a few seconds before entering a new code.": "Debes esperar unos segundos antes de ingresar un código nuevo.", "You must wait a few seconds before entering a new code.": "Debes esperar unos segundos antes de ingresar un código nuevo.",
"You ranked #${RANK} in the last tournament. Thanks for playing!": "Quedaste en la posición #${RANK} en el campeonato. ¡Gracias por jugar!", "You ranked #${RANK} in the last tournament. Thanks for playing!": "Quedaste en la posición #${RANK} en el campeonato. ¡Gracias por jugar!",
"Your account was rejected. Are you signed in?": "Tu cuenta fue rechazada. ¿Estas registrado?", "Your account was rejected. Are you signed in?": "Tu cuenta fue rechazada. ¿Estas registrado?",
"Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tu copia del juego fue modificada.\nPor favor revierte estos cambios e intenta de nuevo", "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tu copia del juego fue modificada.\nPor favor revierte estos cambios e intenta de nuevo.",
"Your friend code was used by ${ACCOUNT}": "Tu código de amigo fue usado por ${ACCOUNT}" "Your friend code was used by ${ACCOUNT}": "Tu código de amigo fue usado por ${ACCOUNT}"
}, },
"settingNames": { "settingNames": {
@ -1780,7 +1795,7 @@
"8 Seconds": "8 Segundos", "8 Seconds": "8 Segundos",
"Allow Negative Scores": "Permitir Puntajes Negativos", "Allow Negative Scores": "Permitir Puntajes Negativos",
"Balance Total Lives": "Repartir Vidas Totales", "Balance Total Lives": "Repartir Vidas Totales",
"Bomb Spawning": "Aparición De Bombas", "Bomb Spawning": "Aparecer Bombas",
"Chosen One Gets Gloves": "El Elegido Consigue Guantes De Boxeo", "Chosen One Gets Gloves": "El Elegido Consigue Guantes De Boxeo",
"Chosen One Gets Shield": "El Elegido Consigue Electro-Escudo", "Chosen One Gets Shield": "El Elegido Consigue Electro-Escudo",
"Chosen One Time": "Tiempo Del Elegido", "Chosen One Time": "Tiempo Del Elegido",
@ -1789,14 +1804,14 @@
"Entire Team Must Finish": "Todo el Equipo Debe Terminar", "Entire Team Must Finish": "Todo el Equipo Debe Terminar",
"Epic Mode": "Modo Épico", "Epic Mode": "Modo Épico",
"Flag Idle Return Time": "Tiempo De Retorno de Bandera Inactiva", "Flag Idle Return Time": "Tiempo De Retorno de Bandera Inactiva",
"Flag Touch Return Time": "Toque De Bandera Tiempo De Retorno", "Flag Touch Return Time": "Retorno de Bandera con Toque",
"Hold Time": "Retención", "Hold Time": "Retención",
"Kills to Win Per Player": "Asesinatos para Ganar Por Jugador", "Kills to Win Per Player": "Asesinatos para Ganar Por Jugador",
"Laps": "Vueltas", "Laps": "Vueltas",
"Lives Per Player": "Vidas Por Jugador", "Lives Per Player": "Vidas Por Jugador",
"Long": "Largo", "Long": "Largo",
"Longer": "Más Largo", "Longer": "Más Largo",
"Mine Spawning": "Minas Apareciendo", "Mine Spawning": "Aparecer Minas",
"No Mines": "Sin Minas", "No Mines": "Sin Minas",
"None": "Ninguno", "None": "Ninguno",
"Normal": "Normal", "Normal": "Normal",
@ -1810,9 +1825,9 @@
"Time Limit": "Límite De Tiempo" "Time Limit": "Límite De Tiempo"
}, },
"statements": { "statements": {
"${TEAM} is disqualified because ${PLAYER} left": "El equipo ${TEAM} ha sido descalificado porque ${PLAYER} se ha ido.", "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} ha sido descalificado porque ${PLAYER} se ha ido",
"Killing ${NAME} for skipping part of the track!": "¡Matando a ${NAME} por saltarse un pedazo de la pista!", "Killing ${NAME} for skipping part of the track!": "¡Matando a ${NAME} por saltarse un pedazo de la pista!",
"Warning to ${NAME}: turbo / button-spamming knocks you out.": "Advertencia para ${NAME}: turbo / El spameo de botones te noqueará." "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Advertencia para ${NAME}: turbo / spam de botones te noqueará."
}, },
"teamNames": { "teamNames": {
"Bad Guys": "Chicos Malos", "Bad Guys": "Chicos Malos",
@ -1821,17 +1836,17 @@
"Red": "Rojo" "Red": "Rojo"
}, },
"tips": { "tips": {
"A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un 'corre-salta-gira-golpea' perfecto puede destrozar de un solo impacto\ny ganarte el respeto de tus amigos para toda la vida.", "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un corre-salta-gira-golpea perfecto puede destrozar de un solo impacto\ny ganarte el respeto de tus amigos para toda la vida.",
"Always remember to floss.": "Siempre acuérdate de cepillar tus dientes.", "Always remember to floss.": "Siempre acuérdate de cepillar tus dientes.",
"Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crea perfiles para ti y tus amigos con nombres\ny colores personalizados en vez de usar aleatorios.", "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crea perfiles para ti y tus amigos con nombres\ny colores personalizados en vez de usar aleatorios.",
"Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Las cajas de maldición te convierten en una bomba de tiempo.\nLa única cura es agarrar rápidamente un botiquín.", "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Las cajas de maldición te convierten en una bomba de tiempo.\nLa única cura es agarrar rápidamente un botiquín.",
"Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "A pesar de su apariencia, las habilidades de todos los personajes\nson idénticas, así que escoge el que más se parezca a ti.", "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "A pesar de sus apariencias, las habilidades de todos los personajes\nson idénticas, así que escoge el que más se parezca a ti.",
"Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "No eres invencible con ese electro-escudo; todavía puedes caerte de un acantilado.", "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "No eres invencible con ese electro-escudo; todavía puedes caerte de un acantilado.",
"Don't run all the time. Really. You will fall off cliffs.": "No corras todo el tiempo. En serio. Te vas a caer.", "Don't run all the time. Really. You will fall off cliffs.": "No corras todo el tiempo. En serio. Te vas a caer.",
"Don't spin for too long; you'll become dizzy and fall.": "No gires por un largo tiempo; puedes marearte y caer.", "Don't spin for too long; you'll become dizzy and fall.": "No gires por un largo tiempo; puedes marearte y caer.",
"Hold any button to run. (Trigger buttons work well if you have them)": "Mantén cualquier botón para correr. (Los botones de gatillo son para eso)", "Hold any button to run. (Trigger buttons work well if you have them)": "Mantén cualquier botón para correr. (Los botones de gatillo son para eso)",
"Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantén pulsado cualquier botón para correr. Llegarás a lugares más rápido\npero no girarás muy bien, así que ten cuidado con los acantilados.", "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantén pulsado cualquier botón para correr. Llegarás a lugares más rápido\npero no girarás muy bien, así que ten cuidado con los acantilados.",
"Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Las Bombas de hielo no son muy potentes, pero congelan lo\nque toquen, dejando a tus enemigos vulnerables a romperse.", "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Las Bombas de Hielo no son muy potentes, pero congelan lo\nque toquen, dejando a tus enemigos vulnerables a romperse.",
"If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si alguien te recoge, dale un golpe y te soltará.\nTambién funciona en la vida real.", "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si alguien te recoge, dale un golpe y te soltará.\nTambién funciona en la vida real.",
"If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Si no tienes suficientes controles, instala la aplicación '${REMOTE_APP_NAME}'\nen tus dispositivos móviles para utilizarlos como controles.", "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Si no tienes suficientes controles, instala la aplicación '${REMOTE_APP_NAME}'\nen tus dispositivos móviles para utilizarlos como controles.",
"If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Te faltan controles? Instala la aplicación 'BombSquad Remote'\nen tu dispositivo iOS o Android para usarlo como control.", "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Te faltan controles? Instala la aplicación 'BombSquad Remote'\nen tu dispositivo iOS o Android para usarlo como control.",
@ -1840,7 +1855,7 @@
"If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Si tomaste una maldición, tu única esperanza es\nencontrar un botiquín en tus últimos segundos.", "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Si tomaste una maldición, tu única esperanza es\nencontrar un botiquín en tus últimos segundos.",
"If you stay in one place, you're toast. Run and dodge to survive..": "Si te quedas quieto, estás frito. Corre y esquiva para sobrevivir...", "If you stay in one place, you're toast. Run and dodge to survive..": "Si te quedas quieto, estás frito. Corre y esquiva para sobrevivir...",
"If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Si tienes muchos jugadores yendo y viniendo, activa 'expulsar jugadores inactivos'\nen ajustes en caso de que alguien se olvide de abandonar el juego.", "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Si tienes muchos jugadores yendo y viniendo, activa 'expulsar jugadores inactivos'\nen ajustes en caso de que alguien se olvide de abandonar el juego.",
"If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si tu dispositivo se pone caliente o te gustaría conservar batería,\nbaja los \"Visuales\" o \"Resolución\" en configuración->Gráficos", "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si tu dispositivo se pone caliente o te gustaría conservar batería,\nbaja los \"Visuales\" o \"Resolución\" en Configuración->Gráficos",
"If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Si la imagen va lenta, intenta reducir la resolución\no los visuales en los ajustes gráficos del juego.", "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Si la imagen va lenta, intenta reducir la resolución\no los visuales en los ajustes gráficos del juego.",
"In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "En Captura la Bandera, la tuya debe estar en tu base para que anotes.\nSi el otro equipo está a punto de anotar, el arrebatar su bandera evitará que lo hagan.", "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "En Captura la Bandera, la tuya debe estar en tu base para que anotes.\nSi el otro equipo está a punto de anotar, el arrebatar su bandera evitará que lo hagan.",
"In hockey, you'll maintain more speed if you turn gradually.": "En hockey, mantendrás tu impulso si giras gradualmente.", "In hockey, you'll maintain more speed if you turn gradually.": "En hockey, mantendrás tu impulso si giras gradualmente.",
@ -1849,12 +1864,12 @@
"Land-mines are a good way to stop speedy enemies.": "Las minas-terrestres son una buena manera para detener enemigos veloces.", "Land-mines are a good way to stop speedy enemies.": "Las minas-terrestres son una buena manera para detener enemigos veloces.",
"Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muchas cosas se pueden recoger y lanzar, incluyendo a otros jugadores.\nArroja a tus enemigos por los precipicios. Te sentirás mejor.", "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muchas cosas se pueden recoger y lanzar, incluyendo a otros jugadores.\nArroja a tus enemigos por los precipicios. Te sentirás mejor.",
"No, you can't get up on the ledge. You have to throw bombs.": "No, no puedes subir a la cornisa. Tienes que lanzar bombas.", "No, you can't get up on the ledge. You have to throw bombs.": "No, no puedes subir a la cornisa. Tienes que lanzar bombas.",
"Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Jugadores pueden unirse e irse en medio de casi todos los juegos,\ntambién puedes poner o quitar controles en cualquier momento.", "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Los jugadores pueden unirse e irse en medio de casi todos los juegos,\ntambién puedes poner o quitar controles en cualquier momento.",
"Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Los jugadores pueden unirse y abandonar en el transcurso del juego,\ny también puedes conectar y desconectar controles cuando quieras.", "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Los jugadores pueden unirse y abandonar en el transcurso del juego,\ny también puedes conectar y desconectar controles cuando quieras.",
"Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Los poderes sólo tienen tiempo límite en juego cooperativo.\nEn los equipos y Pelea libre son tuyos hasta que seas eliminado.", "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Los poderes sólo tienen tiempo límite en juego cooperativo.\nEn los equipos y Pelea libre son tuyos hasta que seas eliminado.",
"Practice using your momentum to throw bombs more accurately.": "Práctica usando tu impulso para tirar bombas con más precisión.", "Practice using your momentum to throw bombs more accurately.": "Practica usando tu impulso para tirar bombas con más precisión.",
"Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Los golpes hacen más daño cuanto más rápido se mueven tus puños,\nasí que intenta correr, saltar, y girar como un loco.", "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Los golpes hacen más daño cuanto más rápido se mueven tus puños,\nasí que intenta correr, saltar, y girar como un loco.",
"Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corre de un lado a otro antes de lanzar una\nbomba de 'latigazo' para lanzarla lejos.", "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corre de un lado a otro antes de lanzar una\nbomba para 'latiguearla' y lanzarla lejos.",
"Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimina un gran cantidad de enemigos\nal detonar una bomba cerca de una caja TNT.", "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimina un gran cantidad de enemigos\nal detonar una bomba cerca de una caja TNT.",
"The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La cabeza es la zona más vulnerable, una bomba pegajosa\na la cabeza usualmente significa game-over.", "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La cabeza es la zona más vulnerable, una bomba pegajosa\na la cabeza usualmente significa game-over.",
"This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nivel no tiene fin, pero un alto puntaje aquí\nte hará ganar el respeto eterno por todo el mundo.", "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nivel no tiene fin, pero un alto puntaje aquí\nte hará ganar el respeto eterno por todo el mundo.",
@ -1894,7 +1909,7 @@
"phrase14Text": "Puedes recoger y lanzar cosas como banderas.. o ${NAME}.", "phrase14Text": "Puedes recoger y lanzar cosas como banderas.. o ${NAME}.",
"phrase15Text": "Por último, hay bombas.", "phrase15Text": "Por último, hay bombas.",
"phrase16Text": "Lanzar bombas bien requiere práctica.", "phrase16Text": "Lanzar bombas bien requiere práctica.",
"phrase17Text": "¡Auch! No fue un muy buen tiro.", "phrase17Text": "¡Auch! No fue un buen tiro.",
"phrase18Text": "Moverte ayuda a lanzarlas más lejos.", "phrase18Text": "Moverte ayuda a lanzarlas más lejos.",
"phrase19Text": "Saltar ayuda a lanzarlas más alto.", "phrase19Text": "Saltar ayuda a lanzarlas más alto.",
"phrase20Text": "\"Latiguea\" tus bombas para hacer lanzamientos aún más lejanos.", "phrase20Text": "\"Latiguea\" tus bombas para hacer lanzamientos aún más lejanos.",
@ -1906,7 +1921,7 @@
"phrase26Text": "¡Ahora ve por ellos, campeón!", "phrase26Text": "¡Ahora ve por ellos, campeón!",
"phrase27Text": "Recuerda tu entrenamiento, ¡y VOLVERÁS con vida!", "phrase27Text": "Recuerda tu entrenamiento, ¡y VOLVERÁS con vida!",
"phrase28Text": "...o a lo mejor...", "phrase28Text": "...o a lo mejor...",
"phrase29Text": "¡Buena suerte!", "phrase29Text": "¡Buena Suerte!",
"randomName1Text": "Federico", "randomName1Text": "Federico",
"randomName2Text": "Enrique", "randomName2Text": "Enrique",
"randomName3Text": "Guillermo", "randomName3Text": "Guillermo",
@ -1917,13 +1932,14 @@
"skippingText": "omitiendo el tutorial...", "skippingText": "omitiendo el tutorial...",
"toSkipPressAnythingText": "(pulsa cualquier botón para omitir el tutorial)" "toSkipPressAnythingText": "(pulsa cualquier botón para omitir el tutorial)"
}, },
"twoKillText": ASESINATO DOBLE!", "twoKillText": COMBO DOBLE!",
"unavailableText": "no disponible", "unavailableText": "no disponible",
"unconfiguredControllerDetectedText": "Control desconfigurado detectado:", "unconfiguredControllerDetectedText": "Control desconfigurado detectado:",
"unlockThisInTheStoreText": "Esto debe ser desbloqueado en la tienda.", "unlockThisInTheStoreText": "Esto debe ser desbloqueado en la tienda.",
"unlockThisProfilesText": "Para crear más de ${NUM} cuentas, necesitas:", "unlockThisProfilesText": "Para crear más de ${NUM} cuentas, necesitas:",
"unlockThisText": "Para desbloquear esto, necesitas:", "unlockThisText": "Para desbloquear esto, necesitas:",
"unsupportedHardwareText": "Lo sentimos, este dispositivo no soporta esta versión del juego.", "unsupportedControllerText": "Lo sentimos, el controlador \"${NAME}\" no es compatible.",
"unsupportedHardwareText": "Disculpe, este dispositivo no soporta esta compilación del juego.",
"upFirstText": "A continuación:", "upFirstText": "A continuación:",
"upNextText": "A continuación en el juego ${COUNT}:", "upNextText": "A continuación en el juego ${COUNT}:",
"updatingAccountText": "Actualizando tu cuenta...", "updatingAccountText": "Actualizando tu cuenta...",
@ -1933,9 +1949,10 @@
"usesExternalControllerText": "Este juego usa un control externo como entrada.", "usesExternalControllerText": "Este juego usa un control externo como entrada.",
"usingItunesText": "Usando Aplicación De Música para la banda sonora...", "usingItunesText": "Usando Aplicación De Música para la banda sonora...",
"usingItunesTurnRepeatAndShuffleOnText": "Asegúrate de que mezclar esté ENCENDIDO y repetir TODOS esté activado en iTunes.", "usingItunesTurnRepeatAndShuffleOnText": "Asegúrate de que mezclar esté ENCENDIDO y repetir TODOS esté activado en iTunes.",
"v2AccountLinkingInfoText": "Para enlazar cuentas V2, usa el botón \"Administrar Cuenta\".", "v2AccountLinkingInfoText": "Para vincular cuentas V2, usa el botón \"Administrar Cuenta\".",
"validatingBetaText": "Validando Beta…", "validatingBetaText": "Validando Beta…",
"validatingTestBuildText": "Validando Versión de Prueba...", "validatingTestBuildText": "Validando Compilación De Prueba...",
"viaText": "a través de",
"victoryText": "¡Victoria!", "victoryText": "¡Victoria!",
"voteDelayText": "No puedes iniciar otra votación por ${NUMBER} segundos.", "voteDelayText": "No puedes iniciar otra votación por ${NUMBER} segundos.",
"voteInProgressText": "Ya hay una votación en progreso.", "voteInProgressText": "Ya hay una votación en progreso.",
@ -1944,7 +1961,7 @@
"vsText": "vs.", "vsText": "vs.",
"waitingForHostText": "(esperando a que ${HOST} continúe)", "waitingForHostText": "(esperando a que ${HOST} continúe)",
"waitingForLocalPlayersText": "Esperando jugadores locales...", "waitingForLocalPlayersText": "Esperando jugadores locales...",
"waitingForPlayersText": "esperando por jugadores para unirse...", "waitingForPlayersText": "esperando jugadores para unirse...",
"waitingInLineText": "Esperando en línea (la partida está llena)...", "waitingInLineText": "Esperando en línea (la partida está llena)...",
"watchAVideoText": "Ver un Vídeo", "watchAVideoText": "Ver un Vídeo",
"watchAnAdText": "Ver un Anuncio", "watchAnAdText": "Ver un Anuncio",
@ -1953,14 +1970,14 @@
"deleteReplayButtonText": "Borrar\nRepetición", "deleteReplayButtonText": "Borrar\nRepetición",
"myReplaysText": "Mis Repeticiones", "myReplaysText": "Mis Repeticiones",
"noReplaySelectedErrorText": "Ninguna Repetición Seleccionada", "noReplaySelectedErrorText": "Ninguna Repetición Seleccionada",
"playbackSpeedText": "Velocidad de Reproducción: ${SPEED}", "playbackSpeedText": "Velocidad De Reproducción: ${SPEED}",
"renameReplayButtonText": "Renombrar\nRepetición", "renameReplayButtonText": "Renombrar\nRepetición",
"renameReplayText": "Renombrar \"${REPLAY}\" a:", "renameReplayText": "Renombrar \"${REPLAY}\" a:",
"renameText": "Renombrar", "renameText": "Renombrar",
"replayDeleteErrorText": "Error borrando la repetición.", "replayDeleteErrorText": "Error borrando la repetición.",
"replayNameText": "Nombre De Repetición", "replayNameText": "Nombre De Repetición",
"replayRenameErrorAlreadyExistsText": "Una repetición con ese nombre ya existe.", "replayRenameErrorAlreadyExistsText": "Una repetición con ese nombre ya existe.",
"replayRenameErrorInvalidName": "No se puede renombrar la repetición: Nombre inválido.", "replayRenameErrorInvalidName": "No se puede renombrar la repetición; nombre inválido.",
"replayRenameErrorText": "Error renombrando repetición.", "replayRenameErrorText": "Error renombrando repetición.",
"sharedReplaysText": "Repeticiones Compartidas", "sharedReplaysText": "Repeticiones Compartidas",
"titleText": "Ver", "titleText": "Ver",
@ -1975,7 +1992,7 @@
"wiimoteListenWindow": { "wiimoteListenWindow": {
"listeningText": "Esperando controles Wii...", "listeningText": "Esperando controles Wii...",
"pressText": "Presiona los botones 1 y 2 simultáneamente.", "pressText": "Presiona los botones 1 y 2 simultáneamente.",
"pressText2": "En controles Wii más nuevos con Motion Plus integrado, pulsa mejor el botón 'sinc' rojo en la parte trasera.", "pressText2": "En controles Wii más nuevos con Motion Plus integrado, pulsa mejor el botón 'sync' rojo en la parte trasera.",
"pressText2Scale": 0.55, "pressText2Scale": 0.55,
"pressTextScale": 1.0 "pressTextScale": 1.0
}, },
@ -1990,7 +2007,7 @@
"titleText": "Configuración Wii" "titleText": "Configuración Wii"
}, },
"winsPlayerText": "¡${NAME} Gana!", "winsPlayerText": "¡${NAME} Gana!",
"winsTeamText": "¡${NAME} Gana!!", "winsTeamText": "¡${NAME} Gana!",
"winsText": "¡${NAME} Gana!", "winsText": "¡${NAME} Gana!",
"workspaceSyncErrorText": "Error al sincronizar ${WORKSPACE}. Mira el registro para más detalles.", "workspaceSyncErrorText": "Error al sincronizar ${WORKSPACE}. Mira el registro para más detalles.",
"workspaceSyncReuseText": "No se puede sincronizar ${WORKSPACE}. Reusando la versión sincronizada anterior.", "workspaceSyncReuseText": "No se puede sincronizar ${WORKSPACE}. Reusando la versión sincronizada anterior.",
@ -1998,7 +2015,7 @@
"worldsBestScoresText": "Mejores Puntuaciones Mundiales", "worldsBestScoresText": "Mejores Puntuaciones Mundiales",
"worldsBestTimesText": "Mejores Tiempos Mundiales", "worldsBestTimesText": "Mejores Tiempos Mundiales",
"xbox360ControllersWindow": { "xbox360ControllersWindow": {
"getDriverText": "Obtener Driver", "getDriverText": "Obtener Controlador",
"macInstructions2Text": "Para usar controles inalámbricos, necesitarás el receptor que\nviene con el 'Control de Xbox 360 para Windows'.\nUn receptor te permite conectar hasta cuatro controles.\n\nImportante: Receptores de tercera mano no funcionarán con este controlador;\nasegúrate de que tu receptor tenga el logo de 'Microsoft', no 'XBOX 360'.\nMicrosoft ya no vende receptores por separado, por lo que necesitarás\nel que venía con el control, o si no tendrás que buscar uno por internet.\n\nSi encuentras que esto fue útil, por favor considera donar\nal desarrollador del controlador en su sitio de internet.", "macInstructions2Text": "Para usar controles inalámbricos, necesitarás el receptor que\nviene con el 'Control de Xbox 360 para Windows'.\nUn receptor te permite conectar hasta cuatro controles.\n\nImportante: Receptores de tercera mano no funcionarán con este controlador;\nasegúrate de que tu receptor tenga el logo de 'Microsoft', no 'XBOX 360'.\nMicrosoft ya no vende receptores por separado, por lo que necesitarás\nel que venía con el control, o si no tendrás que buscar uno por internet.\n\nSi encuentras que esto fue útil, por favor considera donar\nal desarrollador del controlador en su sitio de internet.",
"macInstructions2TextScale": 0.76, "macInstructions2TextScale": 0.76,
"macInstructionsText": "Para usar controles de Xbox 360, necesitarás instalar\nel controlador para Mac disponible en el siguiente enlace.\nFunciona con controles con cable e inalámbricos.", "macInstructionsText": "Para usar controles de Xbox 360, necesitarás instalar\nel controlador para Mac disponible en el siguiente enlace.\nFunciona con controles con cable e inalámbricos.",
@ -2007,7 +2024,7 @@
"ouyaInstructionsTextScale": 0.8, "ouyaInstructionsTextScale": 0.8,
"titleText": "Usando Controles de Xbox 360 con ${APP_NAME}:" "titleText": "Usando Controles de Xbox 360 con ${APP_NAME}:"
}, },
"yesAllowText": "¡Sí, Permítir!", "yesAllowText": "¡Sí, Permitir!",
"yourBestScoresText": "Tus Mejores Puntuaciones", "yourBestScoresText": "Tus Mejores Puntajes",
"yourBestTimesText": "Tus Mejores Tiempos" "yourBestTimesText": "Tus Mejores Tiempos"
} }

View file

@ -30,7 +30,7 @@
"signInWithDeviceText": "Logga in med ett enhetskonto", "signInWithDeviceText": "Logga in med ett enhetskonto",
"signInWithGameCircleText": "Logga in med Spel Cirkel", "signInWithGameCircleText": "Logga in med Spel Cirkel",
"signInWithGooglePlayText": "Logga in med Google Play", "signInWithGooglePlayText": "Logga in med Google Play",
"signInWithTestAccountInfoText": "(allmän konto typ; använd enhets konton för att fortsätta)", "signInWithTestAccountInfoText": "(allmän konto typ; använd enhets konton för att fortsätta) ",
"signInWithTestAccountText": "Logga in med ett testkonto", "signInWithTestAccountText": "Logga in med ett testkonto",
"signInWithV2InfoText": "(ett konto som fungerar på alla plattformar)", "signInWithV2InfoText": "(ett konto som fungerar på alla plattformar)",
"signInWithV2Text": "Logga in med ett BombSquad-konto", "signInWithV2Text": "Logga in med ett BombSquad-konto",
@ -1205,7 +1205,7 @@
}, },
"showText": "Visa", "showText": "Visa",
"signInForPromoCodeText": "Du måste logga in på ett konto för att promotion koder ska aktiveras.", "signInForPromoCodeText": "Du måste logga in på ett konto för att promotion koder ska aktiveras.",
"signInWithGameCenterText": "För att använda ett Game Center konto, \nlogga in via Game Center appen.", "signInWithGameCenterText": "För att använda ett Game Center konto, \nlogga in via Game Center appen. ",
"singleGamePlaylistNameText": "Endast ${GAME}", "singleGamePlaylistNameText": "Endast ${GAME}",
"singlePlayerCountText": "1 spelare", "singlePlayerCountText": "1 spelare",
"soloNameFilterText": "Solo ${NAME}", "soloNameFilterText": "Solo ${NAME}",

View file

@ -446,6 +446,7 @@
"swipeText": "ஸ்வைப்", "swipeText": "ஸ்வைப்",
"titleText": "தொடுதிரையை உள்ளமைக்கவும்" "titleText": "தொடுதிரையை உள்ளமைக்கவும்"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} ஐ சிஸ்டம் அமைப்புகள் பயன்பாட்டில் உள்ளமைக்க முடியும்.",
"configureItNowText": "இப்போது அதை உள்ளமைக்கவா?", "configureItNowText": "இப்போது அதை உள்ளமைக்கவா?",
"configureText": "உள்ளமை", "configureText": "உள்ளமை",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -816,10 +817,12 @@
"alwaysText": "எப்போதும்", "alwaysText": "எப்போதும்",
"fullScreenCmdText": "முழுத்திரை (Cmd-F)", "fullScreenCmdText": "முழுத்திரை (Cmd-F)",
"fullScreenCtrlText": "முழுத்திரை (Ctrl-F)", "fullScreenCtrlText": "முழுத்திரை (Ctrl-F)",
"fullScreenText": "முழு திரை",
"gammaText": "காமா", "gammaText": "காமா",
"highText": "உயர்", "highText": "உயர்",
"higherText": "அதிக", "higherText": "அதிக",
"lowText": "குறைந்த", "lowText": "குறைந்த",
"maxFPSText": "அதிக FPS",
"mediumText": "நடுத்தர", "mediumText": "நடுத்தர",
"neverText": "ஒருபோதும்", "neverText": "ஒருபோதும்",
"resolutionText": "பகுத்தல்", "resolutionText": "பகுத்தல்",
@ -1059,6 +1062,7 @@
"noExternalStorageErrorText": "இந்தச் சாதனத்தில் வெளிப்புறச் சேமிப்பு இல்லை", "noExternalStorageErrorText": "இந்தச் சாதனத்தில் வெளிப்புறச் சேமிப்பு இல்லை",
"noGameCircleText": "பிழை: GameCircle இல் உள்நுழையவில்லை", "noGameCircleText": "பிழை: GameCircle இல் உள்நுழையவில்லை",
"noScoresYetText": "இன்னும் மதிப்பெண்கள் இல்லை.", "noScoresYetText": "இன்னும் மதிப்பெண்கள் இல்லை.",
"noServersFoundText": "சேவையகங்கள் எதுவும் இல்லை.",
"noThanksText": "இல்லை, நன்றி!", "noThanksText": "இல்லை, நன்றி!",
"noTournamentsInTestBuildText": "எச்சரிக்கை: இந்த சோதனை உருவாக்கத்தில் இருந்து போட்டியின் மதிப்பெண்கள் புறக்கணிக்கப்படும்.", "noTournamentsInTestBuildText": "எச்சரிக்கை: இந்த சோதனை உருவாக்கத்தில் இருந்து போட்டியின் மதிப்பெண்கள் புறக்கணிக்கப்படும்.",
"noValidMapsErrorText": "இந்த விளையாட்டு வகைக்கு சரியான வரைபடங்கள் இல்லை.", "noValidMapsErrorText": "இந்த விளையாட்டு வகைக்கு சரியான வரைபடங்கள் இல்லை.",
@ -1270,6 +1274,7 @@
"netTestingText": "நெட்வொர்க் சோதனை", "netTestingText": "நெட்வொர்க் சோதனை",
"resetText": "மீட்டு", "resetText": "மீட்டு",
"showBombTrajectoriesText": "வெடிகுண்டு பாதைகளைக் காட்டு", "showBombTrajectoriesText": "வெடிகுண்டு பாதைகளைக் காட்டு",
"showDevConsoleButtonText": "உருவாக்குபவர் பணியகத்தை காட்டு",
"showInGamePingText": "இன்-கேம் பிங்கைக் காட்டு", "showInGamePingText": "இன்-கேம் பிங்கைக் காட்டு",
"showPlayerNamesText": "பிளேயர் பெயர்களைக் காட்டு", "showPlayerNamesText": "பிளேயர் பெயர்களைக் காட்டு",
"showUserModsText": "மோட்ஸ் கோப்புறையைக் காட்டு", "showUserModsText": "மோட்ஸ் கோப்புறையைக் காட்டு",
@ -1361,6 +1366,7 @@
"storeText": "ஸ்டோர்", "storeText": "ஸ்டோர்",
"submitText": "சமர்ப்பிக்கவும்", "submitText": "சமர்ப்பிக்கவும்",
"submittingPromoCodeText": "குறியீட்டைச் சமர்ப்பிக்கிறது...", "submittingPromoCodeText": "குறியீட்டைச் சமர்ப்பிக்கிறது...",
"successText": "வெற்றி!",
"teamNamesColorText": "அணியின் பெயர்கள்/நிறங்கள்...", "teamNamesColorText": "அணியின் பெயர்கள்/நிறங்கள்...",
"telnetAccessGrantedText": "டெல்நெட் அணுகல் இயக்கப்பட்டது.", "telnetAccessGrantedText": "டெல்நெட் அணுகல் இயக்கப்பட்டது.",
"telnetAccessText": "டெல்நெட் அணுகல் கண்டறியப்பட்டது; அனுமதிக்கவா?", "telnetAccessText": "டெல்நெட் அணுகல் கண்டறியப்பட்டது; அனுமதிக்கவா?",
@ -1814,6 +1820,7 @@
"unlockThisInTheStoreText": "இதை ஸ்டோரில் திறக்க வேண்டும்.", "unlockThisInTheStoreText": "இதை ஸ்டோரில் திறக்க வேண்டும்.",
"unlockThisProfilesText": "${NUM} க்கும் அதிகமான சுயவிவரங்களை உருவாக்க, உங்களுக்கு இது தேவை:", "unlockThisProfilesText": "${NUM} க்கும் அதிகமான சுயவிவரங்களை உருவாக்க, உங்களுக்கு இது தேவை:",
"unlockThisText": "இதைத் திறக்க, உங்களுக்குத் தேவை:", "unlockThisText": "இதைத் திறக்க, உங்களுக்குத் தேவை:",
"unsupportedControllerText": "மன்னிக்கவும், கட்டுப்படுத்தி \"${NAME}\" ஆதரிக்கப்படவில்லை.",
"unsupportedHardwareText": "மன்னிக்கவும், இந்த வன்பொருள் விளையாட்டின் உருவாக்கத்தால் ஆதரிக்கப்படவில்லை.", "unsupportedHardwareText": "மன்னிக்கவும், இந்த வன்பொருள் விளையாட்டின் உருவாக்கத்தால் ஆதரிக்கப்படவில்லை.",
"upFirstText": "முதலில் மேலே:", "upFirstText": "முதலில் மேலே:",
"upNextText": "${COUNT} விளையாட்டில் அடுத்தது:", "upNextText": "${COUNT} விளையாட்டில் அடுத்தது:",

View file

@ -30,6 +30,7 @@
"signInWithGooglePlayText": "ลงชื่อเข้าใช้ด้วยบัญชี Google Play", "signInWithGooglePlayText": "ลงชื่อเข้าใช้ด้วยบัญชี Google Play",
"signInWithTestAccountInfoText": "(บัญชีทดลอง;เลือกตัวเลือกนี้เพื่อไปต่อ)", "signInWithTestAccountInfoText": "(บัญชีทดลอง;เลือกตัวเลือกนี้เพื่อไปต่อ)",
"signInWithTestAccountText": "ลงชื่อเข้าใช้เพื่อทดลอง", "signInWithTestAccountText": "ลงชื่อเข้าใช้เพื่อทดลอง",
"signInWithText": "เข้าสู่ระบบด้วย ${SERVICE}",
"signInWithV2InfoText": "(บัญชีที่ใช้งานได้กับทุกแพลตฟอร์ม)", "signInWithV2InfoText": "(บัญชีที่ใช้งานได้กับทุกแพลตฟอร์ม)",
"signInWithV2Text": "ลงชื่อเข้าใช้ด้วยบัญชี BombSquad", "signInWithV2Text": "ลงชื่อเข้าใช้ด้วยบัญชี BombSquad",
"signOutText": "ออกจากระบบ", "signOutText": "ออกจากระบบ",
@ -333,6 +334,7 @@
"getMoreGamesText": "รับเกมเพิ่มเติม", "getMoreGamesText": "รับเกมเพิ่มเติม",
"titleText": "เพิ่มเกม" "titleText": "เพิ่มเกม"
}, },
"allText": "ทั้งหมด",
"allowText": "ยอมรับ", "allowText": "ยอมรับ",
"alreadySignedInText": "บัญชีของคุณลงชื่อเข้าใช้จากอุปกรณ์อื่น\nโปรดเปลี่ยนบัญชีหรือปิดเกมของคุณ\nอุปกรณ์อื่นและลองอีกครั้ง", "alreadySignedInText": "บัญชีของคุณลงชื่อเข้าใช้จากอุปกรณ์อื่น\nโปรดเปลี่ยนบัญชีหรือปิดเกมของคุณ\nอุปกรณ์อื่นและลองอีกครั้ง",
"apiVersionErrorText": "ไม่สามารถโหลดโมดูล ${NAME} ได้; มันอยู่ในเวอร์ชั่น api ${VERSION_USED}; แต่เราต้องการเวอร์ชั่น ${VERSION_REQUIRED}", "apiVersionErrorText": "ไม่สามารถโหลดโมดูล ${NAME} ได้; มันอยู่ในเวอร์ชั่น api ${VERSION_USED}; แต่เราต้องการเวอร์ชั่น ${VERSION_REQUIRED}",
@ -445,6 +447,7 @@
"swipeText": "การปัด", "swipeText": "การปัด",
"titleText": "การตั้งค่าหน้าจอสัมผัส" "titleText": "การตั้งค่าหน้าจอสัมผัส"
}, },
"configureDeviceInSystemSettingsText": "",
"configureItNowText": "จะตั้งค่ามันตอนนี้หรือไม่?", "configureItNowText": "จะตั้งค่ามันตอนนี้หรือไม่?",
"configureText": "ตั้งค่า", "configureText": "ตั้งค่า",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -1042,7 +1045,7 @@
"nameSuicideKidFriendlyText": "${NAME} ตายจากอุบัติเหตุ", "nameSuicideKidFriendlyText": "${NAME} ตายจากอุบัติเหตุ",
"nameSuicideText": "${NAME} ฆ่าตัวตาย", "nameSuicideText": "${NAME} ฆ่าตัวตาย",
"nameText": "ชื่อ", "nameText": "ชื่อ",
"nativeText": "พื้นเมือง", "nativeText": "ดั้งเดิม",
"newPersonalBestText": "ใหม่ส่วนตัวดีที่สุด!", "newPersonalBestText": "ใหม่ส่วนตัวดีที่สุด!",
"newTestBuildAvailableText": "มีการสร้างการทดสอบที่ใหม่กว่า! (${VERSION} บิลด์ ${BUILD})\nรับได้ที่ ${ADDRESS}", "newTestBuildAvailableText": "มีการสร้างการทดสอบที่ใหม่กว่า! (${VERSION} บิลด์ ${BUILD})\nรับได้ที่ ${ADDRESS}",
"newText": "ใหม่", "newText": "ใหม่",
@ -1054,6 +1057,7 @@
"noExternalStorageErrorText": "ไม่พบที่จัดเก็บข้อมูลภายนอกในอุปกรณ์นี้", "noExternalStorageErrorText": "ไม่พบที่จัดเก็บข้อมูลภายนอกในอุปกรณ์นี้",
"noGameCircleText": "ข้อผิดพลาด: ไม่ได้ลงชื่อเข้าใช้ GameCircle", "noGameCircleText": "ข้อผิดพลาด: ไม่ได้ลงชื่อเข้าใช้ GameCircle",
"noScoresYetText": "ไม่มีคะแนน", "noScoresYetText": "ไม่มีคะแนน",
"noServersFoundText": "ไม่พบเซิร์ฟเวอร์",
"noThanksText": "ไม่เป็นไรขอบคุณ", "noThanksText": "ไม่เป็นไรขอบคุณ",
"noTournamentsInTestBuildText": "คำเตือน: คะแนนการแข่งขันจากรุ่นทดสอบนี้จะถูกละเว้น", "noTournamentsInTestBuildText": "คำเตือน: คะแนนการแข่งขันจากรุ่นทดสอบนี้จะถูกละเว้น",
"noValidMapsErrorText": "ไม่พบแผนที่ที่ถูกต้องสำหรับเกมนี้", "noValidMapsErrorText": "ไม่พบแผนที่ที่ถูกต้องสำหรับเกมนี้",

View file

@ -31,6 +31,7 @@
"signInWithGooglePlayText": "Google Play ile Giriş yap", "signInWithGooglePlayText": "Google Play ile Giriş yap",
"signInWithTestAccountInfoText": "(miras hesabı;bu cihaz hesaplarını ileride de kullan)", "signInWithTestAccountInfoText": "(miras hesabı;bu cihaz hesaplarını ileride de kullan)",
"signInWithTestAccountText": "Test hesabı ile Giriş yap", "signInWithTestAccountText": "Test hesabı ile Giriş yap",
"signInWithText": "${SERVICE} ile giriş yap.",
"signInWithV2InfoText": "(bütün platformlarda çalışan bir hesap)", "signInWithV2InfoText": "(bütün platformlarda çalışan bir hesap)",
"signInWithV2Text": "BombSquad hesabıyla giriş yap", "signInWithV2Text": "BombSquad hesabıyla giriş yap",
"signOutText": ıkış Yap", "signOutText": ıkış Yap",
@ -368,6 +369,7 @@
"chatMutedText": "Sohbet Susturuldu", "chatMutedText": "Sohbet Susturuldu",
"chatUnMuteText": "Konuşmayı aç", "chatUnMuteText": "Konuşmayı aç",
"choosingPlayerText": "<oyuncu seçme>", "choosingPlayerText": "<oyuncu seçme>",
"codesExplainText": "Kodlar geliştirici tarafından sağlanır\nhesap sorunlarını teşhis edin ve düzeltin.",
"completeThisLevelToProceedText": "İlerlemek için bu \nseviyeyi tamamlamalısınız!", "completeThisLevelToProceedText": "İlerlemek için bu \nseviyeyi tamamlamalısınız!",
"completionBonusText": "Tamamlama Bonusu", "completionBonusText": "Tamamlama Bonusu",
"configControllersWindow": { "configControllersWindow": {
@ -448,6 +450,7 @@
"swipeText": "sürme", "swipeText": "sürme",
"titleText": "Dokunmatikleri Yapılandır" "titleText": "Dokunmatikleri Yapılandır"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} Sistem ayarları uygulamasında yapılandırılabilir.",
"configureItNowText": "Şimdi yapılandır?", "configureItNowText": "Şimdi yapılandır?",
"configureText": "Yapılandır", "configureText": "Yapılandır",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -561,6 +564,8 @@
"disableXInputDescriptionText": "4 kontrolcüden fazla kullanılabilir fakat iyi çalışmayabilir.", "disableXInputDescriptionText": "4 kontrolcüden fazla kullanılabilir fakat iyi çalışmayabilir.",
"disableXInputText": "XInput etkisizleştir", "disableXInputText": "XInput etkisizleştir",
"disabledText": "Kullanılmıyor", "disabledText": "Kullanılmıyor",
"discordFriendsText": "Yeni oyuncularmı arıyorsun?\nDiscord sunucumuza katılarak yeni arkadaşlar edinebilirsin!",
"discordJoinText": "Discord sunucumuza katıl",
"doneText": "Tamam", "doneText": "Tamam",
"drawText": "Beraberlik", "drawText": "Beraberlik",
"duplicateText": "Kopyala", "duplicateText": "Kopyala",
@ -817,10 +822,12 @@
"alwaysText": "Her Zaman", "alwaysText": "Her Zaman",
"fullScreenCmdText": "Tam Ekran (Cmd-F)", "fullScreenCmdText": "Tam Ekran (Cmd-F)",
"fullScreenCtrlText": "Tam Ekran (Ctrl-F)", "fullScreenCtrlText": "Tam Ekran (Ctrl-F)",
"fullScreenText": "Tam Ekran",
"gammaText": "Gama", "gammaText": "Gama",
"highText": "Yüksek", "highText": "Yüksek",
"higherText": "Çok Yüksek", "higherText": "Çok Yüksek",
"lowText": "Düşük", "lowText": "Düşük",
"maxFPSText": "Maksimum FPS",
"mediumText": "Orta", "mediumText": "Orta",
"neverText": "Asla", "neverText": "Asla",
"resolutionText": "Çözünürlük", "resolutionText": "Çözünürlük",
@ -1059,6 +1066,7 @@
"noExternalStorageErrorText": "Bu cihazda harici depolama bulunamadı", "noExternalStorageErrorText": "Bu cihazda harici depolama bulunamadı",
"noGameCircleText": "Hata: GameCircle girişi yapılamadı", "noGameCircleText": "Hata: GameCircle girişi yapılamadı",
"noScoresYetText": "Henüz skor yok.", "noScoresYetText": "Henüz skor yok.",
"noServersFoundText": "Sunucu Bulunamadı.",
"noThanksText": "Hayır Teşekkürler", "noThanksText": "Hayır Teşekkürler",
"noTournamentsInTestBuildText": "DİKKAT: Bu test sürümündeki turnuva skorları dikkate alınmayacaktır.", "noTournamentsInTestBuildText": "DİKKAT: Bu test sürümündeki turnuva skorları dikkate alınmayacaktır.",
"noValidMapsErrorText": "Bu oyun tipi için geçerli harita bulunamadı.", "noValidMapsErrorText": "Bu oyun tipi için geçerli harita bulunamadı.",
@ -1268,6 +1276,7 @@
"netTestingText": "Ağ Testi", "netTestingText": "Ağ Testi",
"resetText": "Sıfırla", "resetText": "Sıfırla",
"showBombTrajectoriesText": "Bomba Gidişatını Göster", "showBombTrajectoriesText": "Bomba Gidişatını Göster",
"showDevConsoleButtonText": "Geliştirici panelini aç",
"showInGamePingText": "Oyun İçinde Gecikmeyi Göster", "showInGamePingText": "Oyun İçinde Gecikmeyi Göster",
"showPlayerNamesText": "Oyuncu Adlarını Göster", "showPlayerNamesText": "Oyuncu Adlarını Göster",
"showUserModsText": "Mod Klasörünü Göster", "showUserModsText": "Mod Klasörünü Göster",
@ -1360,6 +1369,8 @@
"storeText": "Mağaza", "storeText": "Mağaza",
"submitText": "Gönder", "submitText": "Gönder",
"submittingPromoCodeText": "Kod Gönderiliyor...", "submittingPromoCodeText": "Kod Gönderiliyor...",
"successText": "Başarı!",
"supportEmailText": "Uygulama ile ilgili herhangi bir sorun yaşıyorsanız,\nlütfen ${EMAIL} adresine e-posta gönderin.",
"teamNamesColorText": "Takım isimleri/Renkler...", "teamNamesColorText": "Takım isimleri/Renkler...",
"telnetAccessGrantedText": "Telnet Erişimi aktif.", "telnetAccessGrantedText": "Telnet Erişimi aktif.",
"telnetAccessText": "Telnet erişimi algılandı; izin ver?", "telnetAccessText": "Telnet erişimi algılandı; izin ver?",
@ -1813,6 +1824,7 @@
"unlockThisInTheStoreText": "Bunun mağazada kilidi açık olmalı.", "unlockThisInTheStoreText": "Bunun mağazada kilidi açık olmalı.",
"unlockThisProfilesText": "${NUM} taneden daha fazla profil yaratmak için ihtiyacın olan:", "unlockThisProfilesText": "${NUM} taneden daha fazla profil yaratmak için ihtiyacın olan:",
"unlockThisText": "Bu kilidi açmak için ihtiyacın olan:", "unlockThisText": "Bu kilidi açmak için ihtiyacın olan:",
"unsupportedControllerText": "Üzgünüm, kontrolcü \"${NAME}\" desteklenmiyor.",
"unsupportedHardwareText": "Üzgünüz, bu donanım oyunun bu sürümü tarafından desteklenmiyor.", "unsupportedHardwareText": "Üzgünüz, bu donanım oyunun bu sürümü tarafından desteklenmiyor.",
"upFirstText": "İlki:", "upFirstText": "İlki:",
"upNextText": "Sıradaki oyun ${COUNT}:", "upNextText": "Sıradaki oyun ${COUNT}:",
@ -1825,6 +1837,7 @@
"usingItunesTurnRepeatAndShuffleOnText": "Lütfen iTunes da karıştırmanın KAPALI oldugundan ve Yinelemenin TÜM oldugundan emin olun. ", "usingItunesTurnRepeatAndShuffleOnText": "Lütfen iTunes da karıştırmanın KAPALI oldugundan ve Yinelemenin TÜM oldugundan emin olun. ",
"v2AccountLinkingInfoText": "V2 hesapları bağlamak için, 'Hesabı yönet' butonuna tıklayın.", "v2AccountLinkingInfoText": "V2 hesapları bağlamak için, 'Hesabı yönet' butonuna tıklayın.",
"validatingTestBuildText": "Test Yapısı Onaylanıyor...", "validatingTestBuildText": "Test Yapısı Onaylanıyor...",
"viaText": "Böylede bilinir",
"victoryText": "Galibiyet!", "victoryText": "Galibiyet!",
"voteDelayText": "${NUMBER} saniye boyunca başka oylama başlatamazsın.", "voteDelayText": "${NUMBER} saniye boyunca başka oylama başlatamazsın.",
"voteInProgressText": "Oylama zaten işlemde.", "voteInProgressText": "Oylama zaten işlemde.",

View file

@ -31,6 +31,7 @@
"signInWithGooglePlayText": "Увійти через Google Play", "signInWithGooglePlayText": "Увійти через Google Play",
"signInWithTestAccountInfoText": "(тест-аккаунт; надалі використовуйте акаунт пристрою)", "signInWithTestAccountInfoText": "(тест-аккаунт; надалі використовуйте акаунт пристрою)",
"signInWithTestAccountText": "Увійти через тестовий акаунт", "signInWithTestAccountText": "Увійти через тестовий акаунт",
"signInWithText": "Увійти за допомогою ${SERVICE}",
"signInWithV2InfoText": "(обліковий запис, який працює на всіх платформах)", "signInWithV2InfoText": "(обліковий запис, який працює на всіх платформах)",
"signInWithV2Text": "Увійдіть за допомогою облікового запису BombSquad", "signInWithV2Text": "Увійдіть за допомогою облікового запису BombSquad",
"signOutText": "Вийти", "signOutText": "Вийти",
@ -449,6 +450,7 @@
"swipeText": "змахнути", "swipeText": "змахнути",
"titleText": "Налаштування сенсорного екрану" "titleText": "Налаштування сенсорного екрану"
}, },
"configureDeviceInSystemSettingsText": "${DEVICE} можна налаштувати в налаштуваннях системи",
"configureItNowText": "Налаштувати зараз?", "configureItNowText": "Налаштувати зараз?",
"configureText": "Налаштувати", "configureText": "Налаштувати",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -818,10 +820,12 @@
"alwaysText": "Завжди", "alwaysText": "Завжди",
"fullScreenCmdText": "Повноекранний (Cmd-F)", "fullScreenCmdText": "Повноекранний (Cmd-F)",
"fullScreenCtrlText": "Повноекранний (Ctrl-F)", "fullScreenCtrlText": "Повноекранний (Ctrl-F)",
"fullScreenText": "Повний екран",
"gammaText": "Гамма", "gammaText": "Гамма",
"highText": "Високий", "highText": "Високий",
"higherText": "Вище", "higherText": "Вище",
"lowText": "Низький", "lowText": "Низький",
"maxFPSText": "Максимальна частота кадрів",
"mediumText": "Середній", "mediumText": "Середній",
"neverText": "Ніколи", "neverText": "Ніколи",
"resolutionText": "Розширення", "resolutionText": "Розширення",
@ -1060,6 +1064,7 @@
"noExternalStorageErrorText": "На цьому пристрої не знайдено зовнішньої пам'яті", "noExternalStorageErrorText": "На цьому пристрої не знайдено зовнішньої пам'яті",
"noGameCircleText": "Помилка: не ввійшли в GameCircle", "noGameCircleText": "Помилка: не ввійшли в GameCircle",
"noScoresYetText": "Рахунка поки немає.", "noScoresYetText": "Рахунка поки немає.",
"noServersFoundText": "Серверів не знайдено",
"noThanksText": "Ні дякую", "noThanksText": "Ні дякую",
"noTournamentsInTestBuildText": "ВАЖЛИВО: Турнірні Очки на цій тестовій версії будуть ігноровані.", "noTournamentsInTestBuildText": "ВАЖЛИВО: Турнірні Очки на цій тестовій версії будуть ігноровані.",
"noValidMapsErrorText": "Для даного типу гри не знайдено коректних карт.", "noValidMapsErrorText": "Для даного типу гри не знайдено коректних карт.",
@ -1269,6 +1274,7 @@
"netTestingText": "Тестування мережі", "netTestingText": "Тестування мережі",
"resetText": "Скинути", "resetText": "Скинути",
"showBombTrajectoriesText": "Показувати траєкторію бомби", "showBombTrajectoriesText": "Показувати траєкторію бомби",
"showDevConsoleButtonText": "Показати кнопку консолі адміністратора",
"showInGamePingText": "Показувати пінг у грі", "showInGamePingText": "Показувати пінг у грі",
"showPlayerNamesText": "Показувати імена гравців", "showPlayerNamesText": "Показувати імена гравців",
"showUserModsText": "Показати теку модів", "showUserModsText": "Показати теку модів",
@ -1360,6 +1366,7 @@
"storeText": "Магазин", "storeText": "Магазин",
"submitText": "Відправити", "submitText": "Відправити",
"submittingPromoCodeText": "Активація коду...", "submittingPromoCodeText": "Активація коду...",
"successText": "Успішно!",
"teamNamesColorText": "імена/кольори команд", "teamNamesColorText": "імена/кольори команд",
"telnetAccessGrantedText": "Доступ Telnet включений.", "telnetAccessGrantedText": "Доступ Telnet включений.",
"telnetAccessText": "Виявлено доступ Telnet. Дозволити?", "telnetAccessText": "Виявлено доступ Telnet. Дозволити?",
@ -1813,6 +1820,7 @@
"unlockThisInTheStoreText": "Це повинно бути розблоковано в магазині.", "unlockThisInTheStoreText": "Це повинно бути розблоковано в магазині.",
"unlockThisProfilesText": "Щоб створити більш ${NUM} профіль, Вам необхідно:", "unlockThisProfilesText": "Щоб створити більш ${NUM} профіль, Вам необхідно:",
"unlockThisText": "Щоб розблокувати це, вам потрібно:", "unlockThisText": "Щоб розблокувати це, вам потрібно:",
"unsupportedControllerText": "Вибачте, контролер \"${NAME}\" не підтримується.",
"unsupportedHardwareText": "На жаль, це устаткування не підтримується в цій збірці гри.", "unsupportedHardwareText": "На жаль, це устаткування не підтримується в цій збірці гри.",
"upFirstText": "Для початку:", "upFirstText": "Для початку:",
"upNextText": "Далі в грі ${COUNT}:", "upNextText": "Далі в грі ${COUNT}:",

View file

@ -29,6 +29,7 @@
"signInWithGooglePlayText": "Conétate co Google Play", "signInWithGooglePlayText": "Conétate co Google Play",
"signInWithTestAccountInfoText": "(account de proa vecio: in fuduro dòpara un account łogałe)", "signInWithTestAccountInfoText": "(account de proa vecio: in fuduro dòpara un account łogałe)",
"signInWithTestAccountText": "Conétate co un account de proa", "signInWithTestAccountText": "Conétate co un account de proa",
"signInWithText": "Acedi co ${SERVICE}",
"signInWithV2InfoText": "(un account che fusiona so tute łe piataforme)", "signInWithV2InfoText": "(un account che fusiona so tute łe piataforme)",
"signInWithV2Text": "Acedi co un account BombSquad", "signInWithV2Text": "Acedi co un account BombSquad",
"signOutText": "Sortisi da l'account", "signOutText": "Sortisi da l'account",
@ -365,6 +366,7 @@
"chatMutedText": "Ciacołada siłensiada", "chatMutedText": "Ciacołada siłensiada",
"chatUnMuteText": "Reativa son", "chatUnMuteText": "Reativa son",
"choosingPlayerText": "<sernisi zugador>", "choosingPlayerText": "<sernisi zugador>",
"codesExplainText": "I còdazi i vien fornìi da'l dezviłupador par\ndiagnostegar e corèjar problemi so l'account.",
"completeThisLevelToProceedText": "Par ndar vanti te ghè\nda conpletar 'sto łeveło!", "completeThisLevelToProceedText": "Par ndar vanti te ghè\nda conpletar 'sto łeveło!",
"completionBonusText": "Premio de concruzion", "completionBonusText": "Premio de concruzion",
"configControllersWindow": { "configControllersWindow": {
@ -445,6 +447,7 @@
"swipeText": "zlizo", "swipeText": "zlizo",
"titleText": "Configura schermo tàtiłe" "titleText": "Configura schermo tàtiłe"
}, },
"configureDeviceInSystemSettingsText": "Se połe configurar ${DEVICE} so łe Inpostasion de Sistema.",
"configureItNowText": "Vutu configurarlo deso?", "configureItNowText": "Vutu configurarlo deso?",
"configureText": "Configura", "configureText": "Configura",
"connectMobileDevicesWindow": { "connectMobileDevicesWindow": {
@ -558,6 +561,8 @@
"disableXInputDescriptionText": "Dòpara pì de 4 controładori (ma co'l riscio che no i funsione ben).", "disableXInputDescriptionText": "Dòpara pì de 4 controładori (ma co'l riscio che no i funsione ben).",
"disableXInputText": "Dezativa XInput", "disableXInputText": "Dezativa XInput",
"disabledText": "Dezativà", "disabledText": "Dezativà",
"discordFriendsText": "Ghetu caro catar parsone nove par zugarghe insenbre?\nZóntate so'l nostro canałe Discord e cata fora amighi novi!",
"discordJoinText": "Zóntate so Discord",
"doneText": "Fato", "doneText": "Fato",
"drawText": "Pata", "drawText": "Pata",
"duplicateText": "Zdopia", "duplicateText": "Zdopia",
@ -814,10 +819,12 @@
"alwaysText": "Senpre", "alwaysText": "Senpre",
"fullScreenCmdText": "Schermo pien (Cmd-F)", "fullScreenCmdText": "Schermo pien (Cmd-F)",
"fullScreenCtrlText": "Schermo pien (Ctrl-F)", "fullScreenCtrlText": "Schermo pien (Ctrl-F)",
"fullScreenText": "Schermo pien",
"gammaText": "Gama", "gammaText": "Gama",
"highText": "Alta", "highText": "Alta",
"higherText": "Màsema", "higherText": "Màsema",
"lowText": "Basa", "lowText": "Basa",
"maxFPSText": "FPS màsemi",
"mediumText": "Mezana", "mediumText": "Mezana",
"neverText": "Mai", "neverText": "Mai",
"resolutionText": "Resołusion", "resolutionText": "Resołusion",
@ -1056,6 +1063,7 @@
"noExternalStorageErrorText": "So sto dispozidivo no ze stà catada gnauna memoria esterna", "noExternalStorageErrorText": "So sto dispozidivo no ze stà catada gnauna memoria esterna",
"noGameCircleText": "Eror: no te si miga conetesto co GameCircle", "noGameCircleText": "Eror: no te si miga conetesto co GameCircle",
"noScoresYetText": "Gnancora gnaun puntejo.", "noScoresYetText": "Gnancora gnaun puntejo.",
"noServersFoundText": "Gnaun server catà.",
"noThanksText": "Nò, grasie", "noThanksText": "Nò, grasie",
"noTournamentsInTestBuildText": "AVERTENSA: i punteji de'l tornèo de 'sta varsion de proa i vegnarà ignorài.", "noTournamentsInTestBuildText": "AVERTENSA: i punteji de'l tornèo de 'sta varsion de proa i vegnarà ignorài.",
"noValidMapsErrorText": "A no ze stà catà gnaun łeveło vàłido par 'sto tipo de zugo.", "noValidMapsErrorText": "A no ze stà catà gnaun łeveło vàłido par 'sto tipo de zugo.",
@ -1265,6 +1273,7 @@
"netTestingText": "Proa de rede", "netTestingText": "Proa de rede",
"resetText": "Reinposta", "resetText": "Reinposta",
"showBombTrajectoriesText": "Mostra trajetore bonbe", "showBombTrajectoriesText": "Mostra trajetore bonbe",
"showDevConsoleButtonText": "Mostra boton cuadro comandi dezviłupador",
"showInGamePingText": "Mostra łatensa de'l zugo", "showInGamePingText": "Mostra łatensa de'l zugo",
"showPlayerNamesText": "Mostra nomi zugadori", "showPlayerNamesText": "Mostra nomi zugadori",
"showUserModsText": "Mostra carteła modifegasion", "showUserModsText": "Mostra carteła modifegasion",
@ -1356,6 +1365,8 @@
"storeText": "Botega", "storeText": "Botega",
"submitText": "Manda", "submitText": "Manda",
"submittingPromoCodeText": "Trazmision còdaze...", "submittingPromoCodeText": "Trazmision còdaze...",
"successText": "A posto!",
"supportEmailText": "Se te vedi calche problema so l'apl,\nmanda na mail a ${EMAIL}.",
"teamNamesColorText": "Nome/Cołor scuadra...", "teamNamesColorText": "Nome/Cołor scuadra...",
"telnetAccessGrantedText": "Aceso a telnet ativà.", "telnetAccessGrantedText": "Aceso a telnet ativà.",
"telnetAccessText": "Rełevà aceso a telnet: vutu autorizarlo?", "telnetAccessText": "Rełevà aceso a telnet: vutu autorizarlo?",
@ -1809,6 +1820,7 @@
"unlockThisInTheStoreText": "Da dezblocar inte ła botega.", "unlockThisInTheStoreText": "Da dezblocar inte ła botega.",
"unlockThisProfilesText": "Par crear pì de ${NUM} profiłi, A te serve:", "unlockThisProfilesText": "Par crear pì de ${NUM} profiłi, A te serve:",
"unlockThisText": "Par dezblocar 'sta funsion A te serve:", "unlockThisText": "Par dezblocar 'sta funsion A te serve:",
"unsupportedControllerText": "El controłador \"${NAME}\" no'l ze miga suportà.",
"unsupportedHardwareText": "Ne despiaze, 'sto hardware no'l ze mìa conpatìbiłe co 'sta varsion de'l zugo.", "unsupportedHardwareText": "Ne despiaze, 'sto hardware no'l ze mìa conpatìbiłe co 'sta varsion de'l zugo.",
"upFirstText": "Par tacar:", "upFirstText": "Par tacar:",
"upNextText": "Inte'l łeveło n°${COUNT}:", "upNextText": "Inte'l łeveło n°${COUNT}:",
@ -1820,6 +1832,7 @@
"usingItunesText": "Doparar l'apl de mùzega par el son de fondo...", "usingItunesText": "Doparar l'apl de mùzega par el son de fondo...",
"v2AccountLinkingInfoText": "Par łigar un account V2 dòpara el boton 'Jestisi account'.", "v2AccountLinkingInfoText": "Par łigar un account V2 dòpara el boton 'Jestisi account'.",
"validatingTestBuildText": "Confermasion varsion de proa...", "validatingTestBuildText": "Confermasion varsion de proa...",
"viaText": "co",
"victoryText": "Vitoria!", "victoryText": "Vitoria!",
"voteDelayText": "A no te połi tacar n'antra votasion par ${NUMBER} segondi", "voteDelayText": "A no te połi tacar n'antra votasion par ${NUMBER} segondi",
"voteInProgressText": "A ze dezà in corso na votasion.", "voteInProgressText": "A ze dezà in corso na votasion.",

View file

@ -1,4 +1,4 @@
from .core import contents, where from .core import contents, where
__all__ = ["contents", "where"] __all__ = ["contents", "where"]
__version__ = "2023.05.07" __version__ = "2023.11.17"

View file

@ -791,34 +791,6 @@ uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post
# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post
# Label: "Hongkong Post Root CA 1"
# Serial: 1000
# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca
# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58
# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2
-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
AmvZWg==
-----END CERTIFICATE-----
# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
# Label: "SecureSign RootCA11" # Label: "SecureSign RootCA11"
@ -909,49 +881,6 @@ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
WD9f WD9f
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
# Serial: 6047274297262753887
# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3
# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa
# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef
-----BEGIN CERTIFICATE-----
MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
-----END CERTIFICATE-----
# Issuer: CN=Izenpe.com O=IZENPE S.A. # Issuer: CN=Izenpe.com O=IZENPE S.A.
# Subject: CN=Izenpe.com O=IZENPE S.A. # Subject: CN=Izenpe.com O=IZENPE S.A.
# Label: "Izenpe.com" # Label: "Izenpe.com"
@ -1676,50 +1605,6 @@ HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi
# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi
# Label: "E-Tugra Certification Authority"
# Serial: 7667447206703254355
# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49
# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39
# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c
-----BEGIN CERTIFICATE-----
MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
-----END CERTIFICATE-----
# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
# Label: "T-TeleSec GlobalRoot Class 2" # Label: "T-TeleSec GlobalRoot Class 2"
@ -4397,73 +4282,6 @@ ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
# Label: "E-Tugra Global Root CA RSA v3"
# Serial: 75951268308633135324246244059508261641472512052
# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4
# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9
# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2
-----BEGIN CERTIFICATE-----
MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQEL
BQAwgYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUt
VHVncmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYw
JAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIFJTQSB2MzAeFw0yMDAzMTgw
OTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMG
QW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1
Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBD
QSBSU0EgdjMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J7
7gnJY9LTQ91ew6aEOErxjYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscx
uj7X/iWpKo429NEvx7epXTPcMHD4QGxLsqYxYdE0PD0xesevxKenhOGXpOhL9hd8
7jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF/YP9f4RtNGx/ardLAQO/
rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8qQedmCeFL
l+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bG
wzrwbMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4
znKS4iicvObpCdg604nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBO
M/J+JjKsBY04pOZ2PJ8QaQ5tndLBeSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK
5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiMbIedBi3x7+PmBvrFZhNb/FAH
nnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbgh3cXTJ2w2Amo
DVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD
AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSy
tK7mLfcm1ap1LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEL
BQADggIBAImocn+M684uGMQQgC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ
6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN438o2Fi+CiJ+8EUdPdk3ILY7r3y18
Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/qln0F7psTpURs+APQ
3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3sSdPk
vmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn9
9t2HVhjYsCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQ
mhty3QUBjYZgv6Rn7rWlDdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YA
VSgU7NbHEqIbZULpkejLPoeJVF3Zr52XnGnnCv8PWniLYypMfUeUP95L6VPQMPHF
9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFHIK+WEj5jlB0E5y67hscM
moi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiXYY60MGo8
bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ
-----END CERTIFICATE-----
# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center
# Label: "E-Tugra Global Root CA ECC v3"
# Serial: 218504919822255052842371958738296604628416471745
# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64
# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84
# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13
-----BEGIN CERTIFICATE-----
MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw
gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn
cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD
VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2
NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r
YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh
IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF
Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ
KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK
fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB
Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C
MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp
ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6
7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx
vmjkI6TZraE3
-----END CERTIFICATE-----
# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. # Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD.
# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. # Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD.
# Label: "Security Communication RootCA3" # Label: "Security Communication RootCA3"
@ -4587,3 +4405,374 @@ AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA
94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B 94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B
43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== 43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w==
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited
# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited
# Label: "Sectigo Public Server Authentication Root E46"
# Serial: 88989738453351742415770396670917916916
# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01
# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a
# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83
-----BEGIN CERTIFICATE-----
MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
-----END CERTIFICATE-----
# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited
# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited
# Label: "Sectigo Public Server Authentication Root R46"
# Serial: 156256931880233212765902055439220583700
# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5
# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38
# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06
-----BEGIN CERTIFICATE-----
MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY
MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp
YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa
ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz
SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf
iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X
ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3
IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS
VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE
SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu
+Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt
8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L
HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt
zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c
mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ
YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52
gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA
Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB
JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX
DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui
TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5
dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
-----END CERTIFICATE-----
# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation
# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation
# Label: "SSL.com TLS RSA Root CA 2022"
# Serial: 148535279242832292258835760425842727825
# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da
# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca
# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed
-----BEGIN CERTIFICATE-----
MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO
MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD
DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX
DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw
b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP
L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY
t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins
S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3
PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO
L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3
R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w
dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS
+YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS
d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG
AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f
gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z
NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt
hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM
QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf
R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ
DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW
P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy
lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq
bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w
AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q
r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji
Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU
98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA=
-----END CERTIFICATE-----
# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation
# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation
# Label: "SSL.com TLS ECC Root CA 2022"
# Serial: 26605119622390491762507526719404364228
# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5
# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39
# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43
-----BEGIN CERTIFICATE-----
MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw
CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT
U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2
MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh
dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG
ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm
acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN
SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME
GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW
uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp
15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN
b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==
-----END CERTIFICATE-----
# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos
# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos
# Label: "Atos TrustedRoot Root CA ECC TLS 2021"
# Serial: 81873346711060652204712539181482831616
# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8
# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd
# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8
-----BEGIN CERTIFICATE-----
MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF
Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI
zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X
tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4
AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2
KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
9H1/IISpQuQo
-----END CERTIFICATE-----
# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos
# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos
# Label: "Atos TrustedRoot Root CA RSA TLS 2021"
# Serial: 111436099570196163832749341232207667876
# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2
# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48
# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f
-----BEGIN CERTIFICATE-----
MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM
MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx
MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00
MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD
QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z
4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv
Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ
kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs
GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln
nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh
3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD
0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy
geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8
ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB
c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI
pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS
4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs
o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ
qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw
xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM
rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4
AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR
0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY
o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5
dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE
oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==
-----END CERTIFICATE-----
# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc.
# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc.
# Label: "TrustAsia Global Root CA G3"
# Serial: 576386314500428537169965010905813481816650257167
# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04
# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7
# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08
-----BEGIN CERTIFICATE-----
MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM
BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp
ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe
Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw
IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU
cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS
T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK
AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1
nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep
qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA
yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs
hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX
zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv
kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT
f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA
uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB
o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih
MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E
BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4
wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2
XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1
JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j
ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV
VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx
xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on
AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d
7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj
gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV
+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo
FGWsJwt0ivKH
-----END CERTIFICATE-----
# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc.
# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc.
# Label: "TrustAsia Global Root CA G4"
# Serial: 451799571007117016466790293371524403291602933463
# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb
# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a
# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c
-----BEGIN CERTIFICATE-----
MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw
WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y
MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD
VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz
dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx
s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw
LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij
YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD
pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE
AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR
UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj
/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA==
-----END CERTIFICATE-----
# Issuer: CN=CommScope Public Trust ECC Root-01 O=CommScope
# Subject: CN=CommScope Public Trust ECC Root-01 O=CommScope
# Label: "CommScope Public Trust ECC Root-01"
# Serial: 385011430473757362783587124273108818652468453534
# MD5 Fingerprint: 3a:40:a7:fc:03:8c:9c:38:79:2f:3a:a2:6c:b6:0a:16
# SHA1 Fingerprint: 07:86:c0:d8:dd:8e:c0:80:98:06:98:d0:58:7a:ef:de:a6:cc:a2:5d
# SHA256 Fingerprint: 11:43:7c:da:7b:b4:5e:41:36:5f:45:b3:9a:38:98:6b:0d:e0:0d:ef:34:8e:0c:7b:b0:87:36:33:80:0b:c3:8b
-----BEGIN CERTIFICATE-----
MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMw
TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t
bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNa
Fw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv
cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDEw
djAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLxeP0C
flfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJE
hRGnSjot6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggq
hkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg
2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liWpDVfG2XqYZpwI7UNo5uS
Um9poIyNStDuiw7LR47QjRE=
-----END CERTIFICATE-----
# Issuer: CN=CommScope Public Trust ECC Root-02 O=CommScope
# Subject: CN=CommScope Public Trust ECC Root-02 O=CommScope
# Label: "CommScope Public Trust ECC Root-02"
# Serial: 234015080301808452132356021271193974922492992893
# MD5 Fingerprint: 59:b0:44:d5:65:4d:b8:5c:55:19:92:02:b6:d1:94:b2
# SHA1 Fingerprint: 3c:3f:ef:57:0f:fe:65:93:86:9e:a0:fe:b0:f6:ed:8e:d1:13:c7:e5
# SHA256 Fingerprint: 2f:fb:7f:81:3b:bb:b3:c8:9a:b4:e8:16:2d:0f:16:d7:15:09:a8:30:cc:9d:73:c2:62:e5:14:08:75:d1:ad:4a
-----BEGIN CERTIFICATE-----
MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMw
TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t
bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRa
Fw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv
cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDIw
djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/MMDAL
j2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmU
v4RDsNuESgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggq
hkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/n
ich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs73u1Z/GtMMH9ZzkXpc2AV
mkzw5l4lIhVtwodZ0LKOag==
-----END CERTIFICATE-----
# Issuer: CN=CommScope Public Trust RSA Root-01 O=CommScope
# Subject: CN=CommScope Public Trust RSA Root-01 O=CommScope
# Label: "CommScope Public Trust RSA Root-01"
# Serial: 354030733275608256394402989253558293562031411421
# MD5 Fingerprint: 0e:b4:15:bc:87:63:5d:5d:02:73:d4:26:38:68:73:d8
# SHA1 Fingerprint: 6d:0a:5f:f7:b4:23:06:b4:85:b3:b7:97:64:fc:ac:75:f5:33:f2:93
# SHA256 Fingerprint: 02:bd:f9:6e:2a:45:dd:9b:f1:8f:c7:e1:db:df:21:a0:37:9b:a3:c9:c2:61:03:44:cf:d8:d6:06:fe:c1:ed:81
-----BEGIN CERTIFICATE-----
MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQEL
BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi
Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1
NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t
U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt
MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45FtnYSk
YZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslh
suitQDy6uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0al
DrJLpA6lfO741GIDuZNqihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3Oj
WiE260f6GBfZumbCk6SP/F2krfxQapWsvCQz0b2If4b19bJzKo98rwjyGpg/qYFl
P8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/cZip8UlF1y5mO6D1cv547
KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTifBSeolz7p
UcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/
kQO9lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JO
Hg9O5j9ZpSPcPYeoKFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkB
Ea801M/XrmLTBQe0MXXgDW1XT2mH+VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6U
CBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm45P3luG0wDQYJ
KoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6
NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQ
nmhUQo8mUuJM3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+
QgvfKNmwrZggvkN80V4aCRckjXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2v
trV0KnahP/t1MJ+UXjulYPPLXAziDslg+MkfFoom3ecnf+slpoq9uC02EJqxWE2a
aE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/WNyVntHKLr4W96ioD
j8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+o/E4
Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0w
lREQKC6/oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHn
YfkUyq+Dj7+vsQpZXdxc1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVoc
icCMb3SgazNNtQEo/a2tiRc7ppqEvOuM6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw
-----END CERTIFICATE-----
# Issuer: CN=CommScope Public Trust RSA Root-02 O=CommScope
# Subject: CN=CommScope Public Trust RSA Root-02 O=CommScope
# Label: "CommScope Public Trust RSA Root-02"
# Serial: 480062499834624527752716769107743131258796508494
# MD5 Fingerprint: e1:29:f9:62:7b:76:e2:96:6d:f3:d4:d7:0f:ae:1f:aa
# SHA1 Fingerprint: ea:b0:e2:52:1b:89:93:4c:11:68:f2:d8:9a:ac:22:4c:a3:8a:57:ae
# SHA256 Fingerprint: ff:e9:43:d7:93:42:4b:4f:7c:44:0c:1c:3d:64:8d:53:63:f3:4b:82:dc:87:aa:7a:9f:11:8f:c5:de:e1:01:f1
-----BEGIN CERTIFICATE-----
MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQEL
BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi
Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2
NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t
U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt
MDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3VrCLE
NQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0
kyI9p+Kx7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1C
rWDaSWqVcN3SAOLMV2MCe5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxz
hkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2WWy09X6GDRl224yW4fKcZgBzqZUPckXk2
LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rpM9kzXzehxfCrPfp4sOcs
n/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIfhs1w/tku
FT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5
kQMreyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3
wNemKfrb3vOTlycEVS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6v
wQcQeKwRoi9C8DfF8rhW3Q5iLc4tVn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs
5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7GxcJXvYXowDQYJ
KoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB
KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3
+VGXu6TwYofF1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbyme
APnCKfWxkxlSaRosTKCL4BWaMS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3Nyq
pgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xdgSGn2rtO/+YHqP65DSdsu3BaVXoT
6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2OHG1QAk8mGEPej1WF
sQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+NmYWvt
PjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2d
lklyALKrdVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670
v64fG9PiO/yzcnMcmyiQiRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17O
rg3bhzjlP1v9mxnhMUF6cKojawHhRUzNlM47ni3niAIi9G7oyOzWPPO5std3eqx7
-----END CERTIFICATE-----

View file

@ -60,6 +60,7 @@ __all__ = [
'clear_overloads', 'clear_overloads',
'dataclass_transform', 'dataclass_transform',
'deprecated', 'deprecated',
'Doc',
'get_overloads', 'get_overloads',
'final', 'final',
'get_args', 'get_args',
@ -248,32 +249,7 @@ class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
return 'typing_extensions.' + self._name return 'typing_extensions.' + self._name
# On older versions of typing there is an internal class named "Final". Final = typing.Final
# 3.8+
if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7):
Final = typing.Final
# 3.7
else:
class _FinalForm(_ExtensionsSpecialForm, _root=True):
def __getitem__(self, parameters):
item = typing._type_check(parameters,
f'{self._name} accepts only a single type.')
return typing._GenericAlias(self, (item,))
Final = _FinalForm('Final',
doc="""A special typing construct to indicate that a name
cannot be re-assigned or overridden in a subclass.
For example:
MAX_SIZE: Final = 9000
MAX_SIZE += 1 # Error reported by type checker
class Connection:
TIMEOUT: Final[int] = 10
class FastConnector(Connection):
TIMEOUT = 1 # Error reported by type checker
There is no runtime checking of these properties.""")
if sys.version_info >= (3, 11): if sys.version_info >= (3, 11):
final = typing.final final = typing.final
@ -465,8 +441,6 @@ Type = typing.Type
# Various ABCs mimicking those in collections.abc. # Various ABCs mimicking those in collections.abc.
# A few are simply re-exported for completeness. # A few are simply re-exported for completeness.
Awaitable = typing.Awaitable Awaitable = typing.Awaitable
Coroutine = typing.Coroutine Coroutine = typing.Coroutine
AsyncIterable = typing.AsyncIterable AsyncIterable = typing.AsyncIterable
@ -475,14 +449,7 @@ Deque = typing.Deque
ContextManager = typing.ContextManager ContextManager = typing.ContextManager
AsyncContextManager = typing.AsyncContextManager AsyncContextManager = typing.AsyncContextManager
DefaultDict = typing.DefaultDict DefaultDict = typing.DefaultDict
OrderedDict = typing.OrderedDict
# 3.7.2+
if hasattr(typing, 'OrderedDict'):
OrderedDict = typing.OrderedDict
# 3.7.0-3.7.2
else:
OrderedDict = typing._alias(collections.OrderedDict, (KT, VT))
Counter = typing.Counter Counter = typing.Counter
ChainMap = typing.ChainMap ChainMap = typing.ChainMap
AsyncGenerator = typing.AsyncGenerator AsyncGenerator = typing.AsyncGenerator
@ -508,12 +475,6 @@ _EXCLUDED_ATTRS = {
"__protocol_attrs__", "__callable_proto_members_only__", "__protocol_attrs__", "__callable_proto_members_only__",
} }
if sys.version_info < (3, 8):
_EXCLUDED_ATTRS |= {
"_gorg", "__next_in_mro__", "__extra__", "__tree_hash__", "__args__",
"__origin__"
}
if sys.version_info >= (3, 9): if sys.version_info >= (3, 9):
_EXCLUDED_ATTRS.add("__class_getitem__") _EXCLUDED_ATTRS.add("__class_getitem__")
@ -535,46 +496,6 @@ def _get_protocol_attrs(cls):
return attrs return attrs
def _maybe_adjust_parameters(cls):
"""Helper function used in Protocol.__init_subclass__ and _TypedDictMeta.__new__.
The contents of this function are very similar
to logic found in typing.Generic.__init_subclass__
on the CPython main branch.
"""
tvars = []
if '__orig_bases__' in cls.__dict__:
tvars = _collect_type_vars(cls.__orig_bases__)
# Look for Generic[T1, ..., Tn] or Protocol[T1, ..., Tn].
# If found, tvars must be a subset of it.
# If not found, tvars is it.
# Also check for and reject plain Generic,
# and reject multiple Generic[...] and/or Protocol[...].
gvars = None
for base in cls.__orig_bases__:
if (isinstance(base, typing._GenericAlias) and
base.__origin__ in (typing.Generic, Protocol)):
# for error messages
the_base = base.__origin__.__name__
if gvars is not None:
raise TypeError(
"Cannot inherit from Generic[...]"
" and/or Protocol[...] multiple types.")
gvars = base.__parameters__
if gvars is None:
gvars = tvars
else:
tvarset = set(tvars)
gvarset = set(gvars)
if not tvarset <= gvarset:
s_vars = ', '.join(str(t) for t in tvars if t not in gvarset)
s_args = ', '.join(str(g) for g in gvars)
raise TypeError(f"Some type variables ({s_vars}) are"
f" not listed in {the_base}[{s_args}]")
tvars = gvars
cls.__parameters__ = tuple(tvars)
def _caller(depth=2): def _caller(depth=2):
try: try:
return sys._getframe(depth).f_globals.get('__name__', '__main__') return sys._getframe(depth).f_globals.get('__name__', '__main__')
@ -598,17 +519,10 @@ else:
if type(self)._is_protocol: if type(self)._is_protocol:
raise TypeError('Protocols cannot be instantiated') raise TypeError('Protocols cannot be instantiated')
if sys.version_info >= (3, 8):
# Inheriting from typing._ProtocolMeta isn't actually desirable, # Inheriting from typing._ProtocolMeta isn't actually desirable,
# but is necessary to allow typing.Protocol and typing_extensions.Protocol # but is necessary to allow typing.Protocol and typing_extensions.Protocol
# to mix without getting TypeErrors about "metaclass conflict" # to mix without getting TypeErrors about "metaclass conflict"
_typing_Protocol = typing.Protocol class _ProtocolMeta(type(typing.Protocol)):
_ProtocolMetaBase = type(_typing_Protocol)
else:
_typing_Protocol = _marker
_ProtocolMetaBase = abc.ABCMeta
class _ProtocolMeta(_ProtocolMetaBase):
# This metaclass is somewhat unfortunate, # This metaclass is somewhat unfortunate,
# but is necessary for several reasons... # but is necessary for several reasons...
# #
@ -618,10 +532,10 @@ else:
def __new__(mcls, name, bases, namespace, **kwargs): def __new__(mcls, name, bases, namespace, **kwargs):
if name == "Protocol" and len(bases) < 2: if name == "Protocol" and len(bases) < 2:
pass pass
elif {Protocol, _typing_Protocol} & set(bases): elif {Protocol, typing.Protocol} & set(bases):
for base in bases: for base in bases:
if not ( if not (
base in {object, typing.Generic, Protocol, _typing_Protocol} base in {object, typing.Generic, Protocol, typing.Protocol}
or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, []) or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, [])
or is_protocol(base) or is_protocol(base)
): ):
@ -699,12 +613,10 @@ else:
def __eq__(cls, other): def __eq__(cls, other):
# Hack so that typing.Generic.__class_getitem__ # Hack so that typing.Generic.__class_getitem__
# treats typing_extensions.Protocol # treats typing_extensions.Protocol
# as equivalent to typing.Protocol on Python 3.8+ # as equivalent to typing.Protocol
if abc.ABCMeta.__eq__(cls, other) is True: if abc.ABCMeta.__eq__(cls, other) is True:
return True return True
return ( return cls is Protocol and other is typing.Protocol
cls is Protocol and other is getattr(typing, "Protocol", object())
)
# This has to be defined, or the abc-module cache # This has to be defined, or the abc-module cache
# complains about classes with this metaclass being unhashable, # complains about classes with this metaclass being unhashable,
@ -737,7 +649,6 @@ else:
return NotImplemented return NotImplemented
return True return True
if sys.version_info >= (3, 8):
class Protocol(typing.Generic, metaclass=_ProtocolMeta): class Protocol(typing.Generic, metaclass=_ProtocolMeta):
__doc__ = typing.Protocol.__doc__ __doc__ = typing.Protocol.__doc__
__slots__ = () __slots__ = ()
@ -759,124 +670,12 @@ else:
if cls._is_protocol and cls.__init__ is Protocol.__init__: if cls._is_protocol and cls.__init__ is Protocol.__init__:
cls.__init__ = _no_init cls.__init__ = _no_init
else:
class Protocol(metaclass=_ProtocolMeta):
# There is quite a lot of overlapping code with typing.Generic.
# Unfortunately it is hard to avoid this on Python <3.8,
# as the typing module on Python 3.7 doesn't let us subclass typing.Generic!
"""Base class for protocol classes. Protocol classes are defined as::
class Proto(Protocol): # The "runtime" alias exists for backwards compatibility.
def meth(self) -> int: runtime = runtime_checkable = typing.runtime_checkable
...
Such classes are primarily used with static type checkers that recognize
structural subtyping (static duck-typing), for example::
class C:
def meth(self) -> int:
return 0
def func(x: Proto) -> int:
return x.meth()
func(C()) # Passes static type check
See PEP 544 for details. Protocol classes decorated with
@typing_extensions.runtime_checkable act
as simple-minded runtime-checkable protocols that check
only the presence of given attributes, ignoring their type signatures.
Protocol classes can be generic, they are defined as::
class GenProto(Protocol[T]):
def meth(self) -> T:
...
"""
__slots__ = ()
_is_protocol = True
_is_runtime_protocol = False
def __new__(cls, *args, **kwds):
if cls is Protocol:
raise TypeError("Type Protocol cannot be instantiated; "
"it can only be used as a base class")
return super().__new__(cls)
@typing._tp_cache
def __class_getitem__(cls, params):
if not isinstance(params, tuple):
params = (params,)
if not params and cls is not typing.Tuple:
raise TypeError(
f"Parameter list to {cls.__qualname__}[...] cannot be empty")
msg = "Parameters to generic types must be types."
params = tuple(typing._type_check(p, msg) for p in params)
if cls is Protocol:
# Generic can only be subscripted with unique type variables.
if not all(isinstance(p, typing.TypeVar) for p in params):
i = 0
while isinstance(params[i], typing.TypeVar):
i += 1
raise TypeError(
"Parameters to Protocol[...] must all be type variables."
f" Parameter {i + 1} is {params[i]}")
if len(set(params)) != len(params):
raise TypeError(
"Parameters to Protocol[...] must all be unique")
else:
# Subscripting a regular Generic subclass.
_check_generic(cls, params, len(cls.__parameters__))
return typing._GenericAlias(cls, params)
def __init_subclass__(cls, *args, **kwargs):
if '__orig_bases__' in cls.__dict__:
error = typing.Generic in cls.__orig_bases__
else:
error = typing.Generic in cls.__bases__
if error:
raise TypeError("Cannot inherit from plain Generic")
_maybe_adjust_parameters(cls)
# Determine if this is a protocol or a concrete subclass.
if not cls.__dict__.get('_is_protocol', None):
cls._is_protocol = any(b is Protocol for b in cls.__bases__)
# Set (or override) the protocol subclass hook.
if '__subclasshook__' not in cls.__dict__:
cls.__subclasshook__ = _proto_hook
# Prohibit instantiation for protocol classes
if cls._is_protocol and cls.__init__ is Protocol.__init__:
cls.__init__ = _no_init
if sys.version_info >= (3, 8): # Our version of runtime-checkable protocols is faster on Python 3.8-3.11
runtime_checkable = typing.runtime_checkable
else:
def runtime_checkable(cls):
"""Mark a protocol class as a runtime protocol, so that it
can be used with isinstance() and issubclass(). Raise TypeError
if applied to a non-protocol class.
This allows a simple-minded structural check very similar to the
one-offs in collections.abc such as Hashable.
"""
if not (
(isinstance(cls, _ProtocolMeta) or issubclass(cls, typing.Generic))
and getattr(cls, "_is_protocol", False)
):
raise TypeError('@runtime_checkable can be only applied to protocol classes,'
f' got {cls!r}')
cls._is_runtime_protocol = True
return cls
# Exists for backwards compatibility.
runtime = runtime_checkable
# Our version of runtime-checkable protocols is faster on Python 3.7-3.11
if sys.version_info >= (3, 12): if sys.version_info >= (3, 12):
SupportsInt = typing.SupportsInt SupportsInt = typing.SupportsInt
SupportsFloat = typing.SupportsFloat SupportsFloat = typing.SupportsFloat
@ -986,11 +785,6 @@ else:
# 3.10.0 and later # 3.10.0 and later
_TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters _TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters
if sys.version_info >= (3, 8):
_fake_name = "Protocol"
else:
_fake_name = "_Protocol"
class _TypedDictMeta(type): class _TypedDictMeta(type):
def __new__(cls, name, bases, ns, total=True): def __new__(cls, name, bases, ns, total=True):
"""Create new typed dict class object. """Create new typed dict class object.
@ -1011,10 +805,10 @@ else:
generic_base = () generic_base = ()
# typing.py generally doesn't let you inherit from plain Generic, unless # typing.py generally doesn't let you inherit from plain Generic, unless
# the name of the class happens to be "Protocol" (or "_Protocol" on 3.7). # the name of the class happens to be "Protocol"
tp_dict = type.__new__(_TypedDictMeta, _fake_name, (*generic_base, dict), ns) tp_dict = type.__new__(_TypedDictMeta, "Protocol", (*generic_base, dict), ns)
tp_dict.__name__ = name tp_dict.__name__ = name
if tp_dict.__qualname__ == _fake_name: if tp_dict.__qualname__ == "Protocol":
tp_dict.__qualname__ = name tp_dict.__qualname__ = name
if not hasattr(tp_dict, '__orig_bases__'): if not hasattr(tp_dict, '__orig_bases__'):
@ -1077,7 +871,7 @@ else:
_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
@_ensure_subclassable(lambda bases: (_TypedDict,)) @_ensure_subclassable(lambda bases: (_TypedDict,))
def TypedDict(__typename, __fields=_marker, *, total=True, **kwargs): def TypedDict(typename, fields=_marker, /, *, total=True, **kwargs):
"""A simple typed namespace. At runtime it is equivalent to a plain dict. """A simple typed namespace. At runtime it is equivalent to a plain dict.
TypedDict creates a dictionary type such that a type checker will expect all TypedDict creates a dictionary type such that a type checker will expect all
@ -1124,20 +918,20 @@ else:
See PEP 655 for more details on Required and NotRequired. See PEP 655 for more details on Required and NotRequired.
""" """
if __fields is _marker or __fields is None: if fields is _marker or fields is None:
if __fields is _marker: if fields is _marker:
deprecated_thing = "Failing to pass a value for the 'fields' parameter" deprecated_thing = "Failing to pass a value for the 'fields' parameter"
else: else:
deprecated_thing = "Passing `None` as the 'fields' parameter" deprecated_thing = "Passing `None` as the 'fields' parameter"
example = f"`{__typename} = TypedDict({__typename!r}, {{}})`" example = f"`{typename} = TypedDict({typename!r}, {{}})`"
deprecation_msg = ( deprecation_msg = (
f"{deprecated_thing} is deprecated and will be disallowed in " f"{deprecated_thing} is deprecated and will be disallowed in "
"Python 3.15. To create a TypedDict class with 0 fields " "Python 3.15. To create a TypedDict class with 0 fields "
"using the functional syntax, pass an empty dictionary, e.g. " "using the functional syntax, pass an empty dictionary, e.g. "
) + example + "." ) + example + "."
warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2) warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2)
__fields = kwargs fields = kwargs
elif kwargs: elif kwargs:
raise TypeError("TypedDict takes either a dict or keyword arguments," raise TypeError("TypedDict takes either a dict or keyword arguments,"
" but not both") " but not both")
@ -1150,13 +944,13 @@ else:
stacklevel=2, stacklevel=2,
) )
ns = {'__annotations__': dict(__fields)} ns = {'__annotations__': dict(fields)}
module = _caller() module = _caller()
if module is not None: if module is not None:
# Setting correct module is necessary to make typed dict classes pickleable. # Setting correct module is necessary to make typed dict classes pickleable.
ns['__module__'] = module ns['__module__'] = module
td = _TypedDictMeta(__typename, (), ns, total=total) td = _TypedDictMeta(typename, (), ns, total=total)
td.__orig_bases__ = (TypedDict,) td.__orig_bases__ = (TypedDict,)
return td return td
@ -1186,7 +980,7 @@ if hasattr(typing, "assert_type"):
assert_type = typing.assert_type assert_type = typing.assert_type
else: else:
def assert_type(__val, __typ): def assert_type(val, typ, /):
"""Assert (to the type checker) that the value is of the given type. """Assert (to the type checker) that the value is of the given type.
When the type checker encounters a call to assert_type(), it When the type checker encounters a call to assert_type(), it
@ -1199,12 +993,12 @@ else:
At runtime this returns the first argument unchanged and otherwise At runtime this returns the first argument unchanged and otherwise
does nothing. does nothing.
""" """
return __val return val
if hasattr(typing, "Required"): if hasattr(typing, "Required"): # 3.11+
get_type_hints = typing.get_type_hints get_type_hints = typing.get_type_hints
else: else: # <=3.10
# replaces _strip_annotations() # replaces _strip_annotations()
def _strip_extras(t): def _strip_extras(t):
"""Strips Annotated, Required and NotRequired from a given type.""" """Strips Annotated, Required and NotRequired from a given type."""
@ -1262,11 +1056,11 @@ else:
- If two dict arguments are passed, they specify globals and - If two dict arguments are passed, they specify globals and
locals, respectively. locals, respectively.
""" """
if hasattr(typing, "Annotated"): if hasattr(typing, "Annotated"): # 3.9+
hint = typing.get_type_hints( hint = typing.get_type_hints(
obj, globalns=globalns, localns=localns, include_extras=True obj, globalns=globalns, localns=localns, include_extras=True
) )
else: else: # 3.8
hint = typing.get_type_hints(obj, globalns=globalns, localns=localns) hint = typing.get_type_hints(obj, globalns=globalns, localns=localns)
if include_extras: if include_extras:
return hint return hint
@ -1279,7 +1073,7 @@ if hasattr(typing, 'Annotated'):
# Not exported and not a public API, but needed for get_origin() and get_args() # Not exported and not a public API, but needed for get_origin() and get_args()
# to work. # to work.
_AnnotatedAlias = typing._AnnotatedAlias _AnnotatedAlias = typing._AnnotatedAlias
# 3.7-3.8 # 3.8
else: else:
class _AnnotatedAlias(typing._GenericAlias, _root=True): class _AnnotatedAlias(typing._GenericAlias, _root=True):
"""Runtime representation of an annotated type. """Runtime representation of an annotated type.
@ -1384,7 +1178,7 @@ else:
if sys.version_info[:2] >= (3, 10): if sys.version_info[:2] >= (3, 10):
get_origin = typing.get_origin get_origin = typing.get_origin
get_args = typing.get_args get_args = typing.get_args
# 3.7-3.9 # 3.8-3.9
else: else:
try: try:
# 3.9+ # 3.9+
@ -1462,7 +1256,7 @@ elif sys.version_info[:2] >= (3, 9):
It's invalid when used anywhere except as in the example above. It's invalid when used anywhere except as in the example above.
""" """
raise TypeError(f"{self} is not subscriptable") raise TypeError(f"{self} is not subscriptable")
# 3.7-3.8 # 3.8
else: else:
TypeAlias = _ExtensionsSpecialForm( TypeAlias = _ExtensionsSpecialForm(
'TypeAlias', 'TypeAlias',
@ -1484,6 +1278,9 @@ def _set_default(type_param, default):
type_param.__default__ = tuple((typing._type_check(d, "Default must be a type") type_param.__default__ = tuple((typing._type_check(d, "Default must be a type")
for d in default)) for d in default))
elif default != _marker: elif default != _marker:
if isinstance(type_param, ParamSpec) and default is ...: # ... not valid <3.11
type_param.__default__ = default
else:
type_param.__default__ = typing._type_check(default, "Default must be a type") type_param.__default__ = typing._type_check(default, "Default must be a type")
else: else:
type_param.__default__ = None type_param.__default__ = None
@ -1519,7 +1316,7 @@ class TypeVar(metaclass=_TypeVarLikeMeta):
covariant=False, contravariant=False, covariant=False, contravariant=False,
default=_marker, infer_variance=False): default=_marker, infer_variance=False):
if hasattr(typing, "TypeAliasType"): if hasattr(typing, "TypeAliasType"):
# PEP 695 implemented, can pass infer_variance to typing.TypeVar # PEP 695 implemented (3.12+), can pass infer_variance to typing.TypeVar
typevar = typing.TypeVar(name, *constraints, bound=bound, typevar = typing.TypeVar(name, *constraints, bound=bound,
covariant=covariant, contravariant=contravariant, covariant=covariant, contravariant=contravariant,
infer_variance=infer_variance) infer_variance=infer_variance)
@ -1541,7 +1338,7 @@ class TypeVar(metaclass=_TypeVarLikeMeta):
if hasattr(typing, 'ParamSpecArgs'): if hasattr(typing, 'ParamSpecArgs'):
ParamSpecArgs = typing.ParamSpecArgs ParamSpecArgs = typing.ParamSpecArgs
ParamSpecKwargs = typing.ParamSpecKwargs ParamSpecKwargs = typing.ParamSpecKwargs
# 3.7-3.9 # 3.8-3.9
else: else:
class _Immutable: class _Immutable:
"""Mixin to indicate that object should not be copied.""" """Mixin to indicate that object should not be copied."""
@ -1630,7 +1427,7 @@ if hasattr(typing, 'ParamSpec'):
def __init_subclass__(cls) -> None: def __init_subclass__(cls) -> None:
raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type") raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type")
# 3.7-3.9 # 3.8-3.9
else: else:
# Inherits from list as a workaround for Callable checks in Python < 3.9.2. # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
@ -1735,7 +1532,7 @@ else:
pass pass
# 3.7-3.9 # 3.8-3.9
if not hasattr(typing, 'Concatenate'): if not hasattr(typing, 'Concatenate'):
# Inherits from list as a workaround for Callable checks in Python < 3.9.2. # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
class _ConcatenateGenericAlias(list): class _ConcatenateGenericAlias(list):
@ -1770,7 +1567,7 @@ if not hasattr(typing, 'Concatenate'):
) )
# 3.7-3.9 # 3.8-3.9
@typing._tp_cache @typing._tp_cache
def _concatenate_getitem(self, parameters): def _concatenate_getitem(self, parameters):
if parameters == (): if parameters == ():
@ -1804,7 +1601,7 @@ elif sys.version_info[:2] >= (3, 9):
See PEP 612 for detailed information. See PEP 612 for detailed information.
""" """
return _concatenate_getitem(self, parameters) return _concatenate_getitem(self, parameters)
# 3.7-8 # 3.8
else: else:
class _ConcatenateForm(_ExtensionsSpecialForm, _root=True): class _ConcatenateForm(_ExtensionsSpecialForm, _root=True):
def __getitem__(self, parameters): def __getitem__(self, parameters):
@ -1874,7 +1671,7 @@ elif sys.version_info[:2] >= (3, 9):
""" """
item = typing._type_check(parameters, f'{self} accepts only a single type.') item = typing._type_check(parameters, f'{self} accepts only a single type.')
return typing._GenericAlias(self, (item,)) return typing._GenericAlias(self, (item,))
# 3.7-3.8 # 3.8
else: else:
class _TypeGuardForm(_ExtensionsSpecialForm, _root=True): class _TypeGuardForm(_ExtensionsSpecialForm, _root=True):
def __getitem__(self, parameters): def __getitem__(self, parameters):
@ -1972,7 +1769,7 @@ class _SpecialForm(typing._Final, _root=True):
return self._getitem(self, parameters) return self._getitem(self, parameters)
if hasattr(typing, "LiteralString"): if hasattr(typing, "LiteralString"): # 3.11+
LiteralString = typing.LiteralString LiteralString = typing.LiteralString
else: else:
@_SpecialForm @_SpecialForm
@ -1995,7 +1792,7 @@ else:
raise TypeError(f"{self} is not subscriptable") raise TypeError(f"{self} is not subscriptable")
if hasattr(typing, "Self"): if hasattr(typing, "Self"): # 3.11+
Self = typing.Self Self = typing.Self
else: else:
@_SpecialForm @_SpecialForm
@ -2016,7 +1813,7 @@ else:
raise TypeError(f"{self} is not subscriptable") raise TypeError(f"{self} is not subscriptable")
if hasattr(typing, "Never"): if hasattr(typing, "Never"): # 3.11+
Never = typing.Never Never = typing.Never
else: else:
@_SpecialForm @_SpecialForm
@ -2046,10 +1843,10 @@ else:
raise TypeError(f"{self} is not subscriptable") raise TypeError(f"{self} is not subscriptable")
if hasattr(typing, 'Required'): if hasattr(typing, 'Required'): # 3.11+
Required = typing.Required Required = typing.Required
NotRequired = typing.NotRequired NotRequired = typing.NotRequired
elif sys.version_info[:2] >= (3, 9): elif sys.version_info[:2] >= (3, 9): # 3.9-3.10
@_ExtensionsSpecialForm @_ExtensionsSpecialForm
def Required(self, parameters): def Required(self, parameters):
"""A special typing construct to mark a key of a total=False TypedDict """A special typing construct to mark a key of a total=False TypedDict
@ -2087,7 +1884,7 @@ elif sys.version_info[:2] >= (3, 9):
item = typing._type_check(parameters, f'{self._name} accepts only a single type.') item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
return typing._GenericAlias(self, (item,)) return typing._GenericAlias(self, (item,))
else: else: # 3.8
class _RequiredForm(_ExtensionsSpecialForm, _root=True): class _RequiredForm(_ExtensionsSpecialForm, _root=True):
def __getitem__(self, parameters): def __getitem__(self, parameters):
item = typing._type_check(parameters, item = typing._type_check(parameters,
@ -2175,7 +1972,7 @@ if sys.version_info >= (3, 12): # PEP 692 changed the repr of Unpack[]
def _is_unpack(obj): def _is_unpack(obj):
return get_origin(obj) is Unpack return get_origin(obj) is Unpack
elif sys.version_info[:2] >= (3, 9): elif sys.version_info[:2] >= (3, 9): # 3.9+
class _UnpackSpecialForm(_ExtensionsSpecialForm, _root=True): class _UnpackSpecialForm(_ExtensionsSpecialForm, _root=True):
def __init__(self, getitem): def __init__(self, getitem):
super().__init__(getitem) super().__init__(getitem)
@ -2192,7 +1989,7 @@ elif sys.version_info[:2] >= (3, 9):
def _is_unpack(obj): def _is_unpack(obj):
return isinstance(obj, _UnpackAlias) return isinstance(obj, _UnpackAlias)
else: else: # 3.8
class _UnpackAlias(typing._GenericAlias, _root=True): class _UnpackAlias(typing._GenericAlias, _root=True):
__class__ = typing.TypeVar __class__ = typing.TypeVar
@ -2225,7 +2022,7 @@ if hasattr(typing, "TypeVarTuple"): # 3.11+
def __init_subclass__(self, *args, **kwds): def __init_subclass__(self, *args, **kwds):
raise TypeError("Cannot subclass special typing classes") raise TypeError("Cannot subclass special typing classes")
else: else: # <=3.10
class TypeVarTuple(_DefaultMixin): class TypeVarTuple(_DefaultMixin):
"""Type variable tuple. """Type variable tuple.
@ -2304,10 +2101,10 @@ else:
raise TypeError("Cannot subclass special typing classes") raise TypeError("Cannot subclass special typing classes")
if hasattr(typing, "reveal_type"): if hasattr(typing, "reveal_type"): # 3.11+
reveal_type = typing.reveal_type reveal_type = typing.reveal_type
else: else: # <=3.10
def reveal_type(__obj: T) -> T: def reveal_type(obj: T, /) -> T:
"""Reveal the inferred type of a variable. """Reveal the inferred type of a variable.
When a static type checker encounters a call to ``reveal_type()``, When a static type checker encounters a call to ``reveal_type()``,
@ -2323,14 +2120,14 @@ else:
argument and returns it unchanged. argument and returns it unchanged.
""" """
print(f"Runtime type is {type(__obj).__name__!r}", file=sys.stderr) print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
return __obj return obj
if hasattr(typing, "assert_never"): if hasattr(typing, "assert_never"): # 3.11+
assert_never = typing.assert_never assert_never = typing.assert_never
else: else: # <=3.10
def assert_never(__arg: Never) -> Never: def assert_never(arg: Never, /) -> Never:
"""Assert to the type checker that a line of code is unreachable. """Assert to the type checker that a line of code is unreachable.
Example:: Example::
@ -2353,10 +2150,10 @@ else:
raise AssertionError("Expected code to be unreachable") raise AssertionError("Expected code to be unreachable")
if sys.version_info >= (3, 12): if sys.version_info >= (3, 12): # 3.12+
# dataclass_transform exists in 3.11 but lacks the frozen_default parameter # dataclass_transform exists in 3.11 but lacks the frozen_default parameter
dataclass_transform = typing.dataclass_transform dataclass_transform = typing.dataclass_transform
else: else: # <=3.11
def dataclass_transform( def dataclass_transform(
*, *,
eq_default: bool = True, eq_default: bool = True,
@ -2443,12 +2240,12 @@ else:
return decorator return decorator
if hasattr(typing, "override"): if hasattr(typing, "override"): # 3.12+
override = typing.override override = typing.override
else: else: # <=3.11
_F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any]) _F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any])
def override(__arg: _F) -> _F: def override(arg: _F, /) -> _F:
"""Indicate that a method is intended to override a method in a base class. """Indicate that a method is intended to override a method in a base class.
Usage: Usage:
@ -2475,13 +2272,13 @@ else:
""" """
try: try:
__arg.__override__ = True arg.__override__ = True
except (AttributeError, TypeError): except (AttributeError, TypeError):
# Skip the attribute silently if it is not writable. # Skip the attribute silently if it is not writable.
# AttributeError happens if the object has __slots__ or a # AttributeError happens if the object has __slots__ or a
# read-only property, TypeError if it's a builtin class. # read-only property, TypeError if it's a builtin class.
pass pass
return __arg return arg
if hasattr(typing, "deprecated"): if hasattr(typing, "deprecated"):
@ -2490,7 +2287,8 @@ else:
_T = typing.TypeVar("_T") _T = typing.TypeVar("_T")
def deprecated( def deprecated(
__msg: str, msg: str,
/,
*, *,
category: typing.Optional[typing.Type[Warning]] = DeprecationWarning, category: typing.Optional[typing.Type[Warning]] = DeprecationWarning,
stacklevel: int = 1, stacklevel: int = 1,
@ -2533,17 +2331,17 @@ else:
See PEP 702 for details. See PEP 702 for details.
""" """
def decorator(__arg: _T) -> _T: def decorator(arg: _T, /) -> _T:
if category is None: if category is None:
__arg.__deprecated__ = __msg arg.__deprecated__ = msg
return __arg return arg
elif isinstance(__arg, type): elif isinstance(arg, type):
original_new = __arg.__new__ original_new = arg.__new__
has_init = __arg.__init__ is not object.__init__ has_init = arg.__init__ is not object.__init__
@functools.wraps(original_new) @functools.wraps(original_new)
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
warnings.warn(__msg, category=category, stacklevel=stacklevel + 1) warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
if original_new is not object.__new__: if original_new is not object.__new__:
return original_new(cls, *args, **kwargs) return original_new(cls, *args, **kwargs)
# Mirrors a similar check in object.__new__. # Mirrors a similar check in object.__new__.
@ -2552,21 +2350,21 @@ else:
else: else:
return original_new(cls) return original_new(cls)
__arg.__new__ = staticmethod(__new__) arg.__new__ = staticmethod(__new__)
__arg.__deprecated__ = __new__.__deprecated__ = __msg arg.__deprecated__ = __new__.__deprecated__ = msg
return __arg return arg
elif callable(__arg): elif callable(arg):
@functools.wraps(__arg) @functools.wraps(arg)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
warnings.warn(__msg, category=category, stacklevel=stacklevel + 1) warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
return __arg(*args, **kwargs) return arg(*args, **kwargs)
__arg.__deprecated__ = wrapper.__deprecated__ = __msg arg.__deprecated__ = wrapper.__deprecated__ = msg
return wrapper return wrapper
else: else:
raise TypeError( raise TypeError(
"@deprecated decorator with non-None category must be applied to " "@deprecated decorator with non-None category must be applied to "
f"a class or callable, not {__arg!r}" f"a class or callable, not {arg!r}"
) )
return decorator return decorator
@ -2584,7 +2382,7 @@ if not hasattr(typing, "TypeVarTuple"):
typing._check_generic = _check_generic typing._check_generic = _check_generic
# Backport typing.NamedTuple as it exists in Python 3.12. # Backport typing.NamedTuple as it exists in Python 3.13.
# In 3.11, the ability to define generic `NamedTuple`s was supported. # In 3.11, the ability to define generic `NamedTuple`s was supported.
# This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8. # This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8.
# On 3.12, we added __orig_bases__ to call-based NamedTuples # On 3.12, we added __orig_bases__ to call-based NamedTuples
@ -2655,7 +2453,7 @@ else:
return (_NamedTuple,) return (_NamedTuple,)
@_ensure_subclassable(_namedtuple_mro_entries) @_ensure_subclassable(_namedtuple_mro_entries)
def NamedTuple(__typename, __fields=_marker, **kwargs): def NamedTuple(typename, fields=_marker, /, **kwargs):
"""Typed version of namedtuple. """Typed version of namedtuple.
Usage:: Usage::
@ -2675,7 +2473,7 @@ else:
Employee = NamedTuple('Employee', [('name', str), ('id', int)]) Employee = NamedTuple('Employee', [('name', str), ('id', int)])
""" """
if __fields is _marker: if fields is _marker:
if kwargs: if kwargs:
deprecated_thing = "Creating NamedTuple classes using keyword arguments" deprecated_thing = "Creating NamedTuple classes using keyword arguments"
deprecation_msg = ( deprecation_msg = (
@ -2684,14 +2482,14 @@ else:
) )
else: else:
deprecated_thing = "Failing to pass a value for the 'fields' parameter" deprecated_thing = "Failing to pass a value for the 'fields' parameter"
example = f"`{__typename} = NamedTuple({__typename!r}, [])`" example = f"`{typename} = NamedTuple({typename!r}, [])`"
deprecation_msg = ( deprecation_msg = (
"{name} is deprecated and will be disallowed in Python {remove}. " "{name} is deprecated and will be disallowed in Python {remove}. "
"To create a NamedTuple class with 0 fields " "To create a NamedTuple class with 0 fields "
"using the functional syntax, " "using the functional syntax, "
"pass an empty list, e.g. " "pass an empty list, e.g. "
) + example + "." ) + example + "."
elif __fields is None: elif fields is None:
if kwargs: if kwargs:
raise TypeError( raise TypeError(
"Cannot pass `None` as the 'fields' parameter " "Cannot pass `None` as the 'fields' parameter "
@ -2699,7 +2497,7 @@ else:
) )
else: else:
deprecated_thing = "Passing `None` as the 'fields' parameter" deprecated_thing = "Passing `None` as the 'fields' parameter"
example = f"`{__typename} = NamedTuple({__typename!r}, [])`" example = f"`{typename} = NamedTuple({typename!r}, [])`"
deprecation_msg = ( deprecation_msg = (
"{name} is deprecated and will be disallowed in Python {remove}. " "{name} is deprecated and will be disallowed in Python {remove}. "
"To create a NamedTuple class with 0 fields " "To create a NamedTuple class with 0 fields "
@ -2709,27 +2507,17 @@ else:
elif kwargs: elif kwargs:
raise TypeError("Either list of fields or keywords" raise TypeError("Either list of fields or keywords"
" can be provided to NamedTuple, not both") " can be provided to NamedTuple, not both")
if __fields is _marker or __fields is None: if fields is _marker or fields is None:
warnings.warn( warnings.warn(
deprecation_msg.format(name=deprecated_thing, remove="3.15"), deprecation_msg.format(name=deprecated_thing, remove="3.15"),
DeprecationWarning, DeprecationWarning,
stacklevel=2, stacklevel=2,
) )
__fields = kwargs.items() fields = kwargs.items()
nt = _make_nmtuple(__typename, __fields, module=_caller()) nt = _make_nmtuple(typename, fields, module=_caller())
nt.__orig_bases__ = (NamedTuple,) nt.__orig_bases__ = (NamedTuple,)
return nt return nt
# On 3.8+, alter the signature so that it matches typing.NamedTuple.
# The signature of typing.NamedTuple on >=3.8 is invalid syntax in Python 3.7,
# so just leave the signature as it is on 3.7.
if sys.version_info >= (3, 8):
_new_signature = '(typename, fields=None, /, **kwargs)'
if isinstance(NamedTuple, _types.FunctionType):
NamedTuple.__text_signature__ = _new_signature
else:
NamedTuple.__call__.__text_signature__ = _new_signature
if hasattr(collections.abc, "Buffer"): if hasattr(collections.abc, "Buffer"):
Buffer = collections.abc.Buffer Buffer = collections.abc.Buffer
@ -2764,7 +2552,7 @@ else:
if hasattr(_types, "get_original_bases"): if hasattr(_types, "get_original_bases"):
get_original_bases = _types.get_original_bases get_original_bases = _types.get_original_bases
else: else:
def get_original_bases(__cls): def get_original_bases(cls, /):
"""Return the class's "original" bases prior to modification by `__mro_entries__`. """Return the class's "original" bases prior to modification by `__mro_entries__`.
Examples:: Examples::
@ -2786,13 +2574,10 @@ else:
assert get_original_bases(int) == (object,) assert get_original_bases(int) == (object,)
""" """
try: try:
return __cls.__orig_bases__ return cls.__dict__.get("__orig_bases__", cls.__bases__)
except AttributeError:
try:
return __cls.__bases__
except AttributeError: except AttributeError:
raise TypeError( raise TypeError(
f'Expected an instance of type, not {type(__cls).__name__!r}' f'Expected an instance of type, not {type(cls).__name__!r}'
) from None ) from None
@ -2920,13 +2705,13 @@ else:
# Setting this attribute closes the TypeAliasType from further modification # Setting this attribute closes the TypeAliasType from further modification
self.__name__ = name self.__name__ = name
def __setattr__(self, __name: str, __value: object) -> None: def __setattr__(self, name: str, value: object, /) -> None:
if hasattr(self, "__name__"): if hasattr(self, "__name__"):
self._raise_attribute_error(__name) self._raise_attribute_error(name)
super().__setattr__(__name, __value) super().__setattr__(name, value)
def __delattr__(self, __name: str) -> Never: def __delattr__(self, name: str, /) -> Never:
self._raise_attribute_error(__name) self._raise_attribute_error(name)
def _raise_attribute_error(self, name: str) -> Never: def _raise_attribute_error(self, name: str) -> Never:
# Match the Python 3.12 error messages exactly # Match the Python 3.12 error messages exactly
@ -2987,7 +2772,7 @@ if hasattr(typing, "is_protocol"):
is_protocol = typing.is_protocol is_protocol = typing.is_protocol
get_protocol_members = typing.get_protocol_members get_protocol_members = typing.get_protocol_members
else: else:
def is_protocol(__tp: type) -> bool: def is_protocol(tp: type, /) -> bool:
"""Return True if the given type is a Protocol. """Return True if the given type is a Protocol.
Example:: Example::
@ -3002,13 +2787,13 @@ else:
False False
""" """
return ( return (
isinstance(__tp, type) isinstance(tp, type)
and getattr(__tp, '_is_protocol', False) and getattr(tp, '_is_protocol', False)
and __tp is not Protocol and tp is not Protocol
and __tp is not getattr(typing, "Protocol", object()) and tp is not typing.Protocol
) )
def get_protocol_members(__tp: type) -> typing.FrozenSet[str]: def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]:
"""Return the set of members defined in a Protocol. """Return the set of members defined in a Protocol.
Example:: Example::
@ -3022,11 +2807,46 @@ else:
Raise a TypeError for arguments that are not Protocols. Raise a TypeError for arguments that are not Protocols.
""" """
if not is_protocol(__tp): if not is_protocol(tp):
raise TypeError(f'{__tp!r} is not a Protocol') raise TypeError(f'{tp!r} is not a Protocol')
if hasattr(__tp, '__protocol_attrs__'): if hasattr(tp, '__protocol_attrs__'):
return frozenset(__tp.__protocol_attrs__) return frozenset(tp.__protocol_attrs__)
return frozenset(_get_protocol_attrs(__tp)) return frozenset(_get_protocol_attrs(tp))
if hasattr(typing, "Doc"):
Doc = typing.Doc
else:
class Doc:
"""Define the documentation of a type annotation using ``Annotated``, to be
used in class attributes, function and method parameters, return values,
and variables.
The value should be a positional-only string literal to allow static tools
like editors and documentation generators to use it.
This complements docstrings.
The string value passed is available in the attribute ``documentation``.
Example::
>>> from typing_extensions import Annotated, Doc
>>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ...
"""
def __init__(self, documentation: str, /) -> None:
self.documentation = documentation
def __repr__(self) -> str:
return f"Doc({self.documentation!r})"
def __hash__(self) -> int:
return hash(self.documentation)
def __eq__(self, other: object) -> bool:
if not isinstance(other, Doc):
return NotImplemented
return self.documentation == other.documentation
# Aliases for items that have always been in typing. # Aliases for items that have always been in typing.

View file

@ -27,7 +27,10 @@ from _babase import (
apptime, apptime,
apptimer, apptimer,
AppTimer, AppTimer,
can_toggle_fullscreen, fullscreen_control_available,
fullscreen_control_get,
fullscreen_control_key_shortcut,
fullscreen_control_set,
charstr, charstr,
clipboard_get_text, clipboard_get_text,
clipboard_has_text, clipboard_has_text,
@ -58,10 +61,8 @@ from _babase import (
in_logic_thread, in_logic_thread,
increment_analytics_count, increment_analytics_count,
is_os_playing_music, is_os_playing_music,
is_running_on_fire_tv,
is_xcode_build, is_xcode_build,
lock_all_input, lock_all_input,
mac_music_app_get_library_source,
mac_music_app_get_playlists, mac_music_app_get_playlists,
mac_music_app_get_volume, mac_music_app_get_volume,
mac_music_app_init, mac_music_app_init,
@ -72,7 +73,10 @@ from _babase import (
music_player_set_volume, music_player_set_volume,
music_player_shutdown, music_player_shutdown,
music_player_stop, music_player_stop,
native_review_request,
native_review_request_supported,
native_stack_trace, native_stack_trace,
open_file_externally,
print_load_info, print_load_info,
pushcall, pushcall,
quit, quit,
@ -82,7 +86,6 @@ from _babase import (
screenmessage, screenmessage,
set_analytics_screen, set_analytics_screen,
set_low_level_config_value, set_low_level_config_value,
set_stress_testing,
set_thread_name, set_thread_name,
set_ui_input_device, set_ui_input_device,
show_progress_bar, show_progress_bar,
@ -114,6 +117,11 @@ from babase._apputils import (
AppHealthMonitor, AppHealthMonitor,
) )
from babase._cloud import CloudSubsystem from babase._cloud import CloudSubsystem
from babase._devconsole import (
DevConsoleTab,
DevConsoleTabEntry,
DevConsoleSubsystem,
)
from babase._emptyappmode import EmptyAppMode from babase._emptyappmode import EmptyAppMode
from babase._error import ( from babase._error import (
print_exception, print_exception,
@ -146,9 +154,8 @@ from babase._general import (
getclass, getclass,
get_type_name, get_type_name,
) )
from babase._keyboard import Keyboard
from babase._language import Lstr, LanguageSubsystem from babase._language import Lstr, LanguageSubsystem
from babase._login import LoginAdapter from babase._login import LoginAdapter, LoginInfo
# noinspection PyProtectedMember # noinspection PyProtectedMember
# (PyCharm inspection bug?) # (PyCharm inspection bug?)
@ -157,6 +164,7 @@ from babase._mgen.enums import (
SpecialChar, SpecialChar,
InputType, InputType,
UIScale, UIScale,
QuitType,
) )
from babase._math import normalized_color, is_point_in_box, vec3validate from babase._math import normalized_color, is_point_in_box, vec3validate
from babase._meta import MetadataSubsystem from babase._meta import MetadataSubsystem
@ -194,7 +202,10 @@ __all__ = [
'apptimer', 'apptimer',
'AppTimer', 'AppTimer',
'Call', 'Call',
'can_toggle_fullscreen', 'fullscreen_control_available',
'fullscreen_control_get',
'fullscreen_control_key_shortcut',
'fullscreen_control_set',
'charstr', 'charstr',
'clipboard_get_text', 'clipboard_get_text',
'clipboard_has_text', 'clipboard_has_text',
@ -206,6 +217,9 @@ __all__ = [
'ContextError', 'ContextError',
'ContextRef', 'ContextRef',
'DelegateNotFoundError', 'DelegateNotFoundError',
'DevConsoleTab',
'DevConsoleTabEntry',
'DevConsoleSubsystem',
'DisplayTime', 'DisplayTime',
'displaytime', 'displaytime',
'displaytimer', 'displaytimer',
@ -244,14 +258,12 @@ __all__ = [
'is_browser_likely_available', 'is_browser_likely_available',
'is_os_playing_music', 'is_os_playing_music',
'is_point_in_box', 'is_point_in_box',
'is_running_on_fire_tv',
'is_xcode_build', 'is_xcode_build',
'Keyboard',
'LanguageSubsystem', 'LanguageSubsystem',
'lock_all_input', 'lock_all_input',
'LoginAdapter', 'LoginAdapter',
'LoginInfo',
'Lstr', 'Lstr',
'mac_music_app_get_library_source',
'mac_music_app_get_playlists', 'mac_music_app_get_playlists',
'mac_music_app_get_volume', 'mac_music_app_get_volume',
'mac_music_app_init', 'mac_music_app_init',
@ -264,10 +276,13 @@ __all__ = [
'music_player_set_volume', 'music_player_set_volume',
'music_player_shutdown', 'music_player_shutdown',
'music_player_stop', 'music_player_stop',
'native_review_request',
'native_review_request_supported',
'native_stack_trace', 'native_stack_trace',
'NodeNotFoundError', 'NodeNotFoundError',
'normalized_color', 'normalized_color',
'NotFoundError', 'NotFoundError',
'open_file_externally',
'Permission', 'Permission',
'PlayerNotFoundError', 'PlayerNotFoundError',
'Plugin', 'Plugin',
@ -278,6 +293,7 @@ __all__ = [
'print_load_info', 'print_load_info',
'pushcall', 'pushcall',
'quit', 'quit',
'QuitType',
'reload_media', 'reload_media',
'request_permission', 'request_permission',
'safecolor', 'safecolor',
@ -287,7 +303,6 @@ __all__ = [
'SessionTeamNotFoundError', 'SessionTeamNotFoundError',
'set_analytics_screen', 'set_analytics_screen',
'set_low_level_config_value', 'set_low_level_config_value',
'set_stress_testing',
'set_thread_name', 'set_thread_name',
'set_ui_input_device', 'set_ui_input_device',
'show_progress_bar', 'show_progress_bar',

View file

@ -6,7 +6,7 @@ from __future__ import annotations
import hashlib import hashlib
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, assert_never
from efro.call import tpartial from efro.call import tpartial
from efro.error import CommunicationError from efro.error import CommunicationError
@ -16,7 +16,7 @@ import _babase
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any
from babase._login import LoginAdapter from babase._login import LoginAdapter, LoginInfo
DEBUG_LOG = False DEBUG_LOG = False
@ -27,10 +27,12 @@ class AccountV2Subsystem:
Category: **App Classes** Category: **App Classes**
Access the single shared instance of this class at 'ba.app.accounts'. Access the single shared instance of this class at 'ba.app.plus.accounts'.
""" """
def __init__(self) -> None: def __init__(self) -> None:
from babase._login import LoginAdapterGPGS, LoginAdapterGameCenter
# Whether or not everything related to an initial login # Whether or not everything related to an initial login
# (or lack thereof) has completed. This includes things like # (or lack thereof) has completed. This includes things like
# workspace syncing. Completion of this is what flips the app # workspace syncing. Completion of this is what flips the app
@ -45,16 +47,13 @@ class AccountV2Subsystem:
self._implicit_state_changed = False self._implicit_state_changed = False
self._can_do_auto_sign_in = True self._can_do_auto_sign_in = True
if _babase.app.classic is None: adapter: LoginAdapter
raise RuntimeError('Needs updating for no-classic case.') if _babase.using_google_play_game_services():
adapter = LoginAdapterGPGS()
if ( self.login_adapters[adapter.login_type] = adapter
_babase.app.classic.platform == 'android' if _babase.using_game_center():
and _babase.app.classic.subplatform == 'google' adapter = LoginAdapterGameCenter()
): self.login_adapters[adapter.login_type] = adapter
from babase._login import LoginAdapterGPGS
self.login_adapters[LoginType.GPGS] = LoginAdapterGPGS()
def on_app_loading(self) -> None: def on_app_loading(self) -> None:
"""Should be called at standard on_app_loading time.""" """Should be called at standard on_app_loading time."""
@ -62,10 +61,6 @@ class AccountV2Subsystem:
for adapter in self.login_adapters.values(): for adapter in self.login_adapters.values():
adapter.on_app_loading() adapter.on_app_loading()
def set_primary_credentials(self, credentials: str | None) -> None:
"""Set credentials for the primary app account."""
raise NotImplementedError('This should be overridden.')
def have_primary_credentials(self) -> bool: def have_primary_credentials(self) -> bool:
"""Are credentials currently set for the primary app account? """Are credentials currently set for the primary app account?
@ -80,10 +75,6 @@ class AccountV2Subsystem:
"""The primary account for the app, or None if not logged in.""" """The primary account for the app, or None if not logged in."""
return self.do_get_primary() return self.do_get_primary()
def do_get_primary(self) -> AccountV2Handle | None:
"""Internal - should be overridden by subclass."""
return None
def on_primary_account_changed( def on_primary_account_changed(
self, account: AccountV2Handle | None self, account: AccountV2Handle | None
) -> None: ) -> None:
@ -142,6 +133,8 @@ class AccountV2Subsystem:
"""An implicit sign-in happened (called by native layer).""" """An implicit sign-in happened (called by native layer)."""
from babase._login import LoginAdapter from babase._login import LoginAdapter
assert _babase.in_logic_thread()
with _babase.ContextRef.empty(): with _babase.ContextRef.empty():
self.login_adapters[login_type].set_implicit_login_state( self.login_adapters[login_type].set_implicit_login_state(
LoginAdapter.ImplicitLoginState( LoginAdapter.ImplicitLoginState(
@ -151,6 +144,7 @@ class AccountV2Subsystem:
def on_implicit_sign_out(self, login_type: LoginType) -> None: def on_implicit_sign_out(self, login_type: LoginType) -> None:
"""An implicit sign-out happened (called by native layer).""" """An implicit sign-out happened (called by native layer)."""
assert _babase.in_logic_thread()
with _babase.ContextRef.empty(): with _babase.ContextRef.empty():
self.login_adapters[login_type].set_implicit_login_state(None) self.login_adapters[login_type].set_implicit_login_state(None)
@ -192,9 +186,10 @@ class AccountV2Subsystem:
cfgkey = 'ImplicitLoginStates' cfgkey = 'ImplicitLoginStates'
cfgdict = _babase.app.config.setdefault(cfgkey, {}) cfgdict = _babase.app.config.setdefault(cfgkey, {})
# Store which (if any) adapter is currently implicitly signed in. # Store which (if any) adapter is currently implicitly signed
# Making the assumption there will only ever be one implicit # in. Making the assumption there will only ever be one implicit
# adapter at a time; may need to update this if that changes. # adapter at a time; may need to revisit this logic if that
# changes.
prev_state = cfgdict.get(login_type.value) prev_state = cfgdict.get(login_type.value)
if state is None: if state is None:
self._implicit_signed_in_adapter = None self._implicit_signed_in_adapter = None
@ -205,18 +200,26 @@ class AccountV2Subsystem:
state.login_id state.login_id
) )
# Special case: if the user is already signed in but not with # Special case: if the user is already signed in but not
# this implicit login, we may want to let them know that the # with this implicit login, let them know that the 'Welcome
# 'Welcome back FOO' they likely just saw is not actually # back FOO' they likely just saw is not actually accurate.
# accurate.
if ( if (
self.primary is not None self.primary is not None
and not self.login_adapters[login_type].is_back_end_active() and not self.login_adapters[login_type].is_back_end_active()
): ):
service_str: Lstr | None
if login_type is LoginType.GPGS: if login_type is LoginType.GPGS:
service_str = Lstr(resource='googlePlayText') service_str = Lstr(resource='googlePlayText')
else: elif login_type is LoginType.GAME_CENTER:
# Note: Apparently Game Center is just called 'Game
# Center' in all languages. Can revisit if not true.
# https://developer.apple.com/forums/thread/725779
service_str = Lstr(value='Game Center')
elif login_type is LoginType.EMAIL:
# Not possible; just here for exhaustive coverage.
service_str = None service_str = None
else:
assert_never(login_type)
if service_str is not None: if service_str is not None:
_babase.apptimer( _babase.apptimer(
2.0, 2.0,
@ -259,6 +262,14 @@ class AccountV2Subsystem:
# We may want to auto-sign-in based on this new state. # We may want to auto-sign-in based on this new state.
self._update_auto_sign_in() self._update_auto_sign_in()
def do_get_primary(self) -> AccountV2Handle | None:
"""Internal - should be overridden by subclass."""
raise NotImplementedError('This should be overridden.')
def set_primary_credentials(self, credentials: str | None) -> None:
"""Set credentials for the primary app account."""
raise NotImplementedError('This should be overridden.')
def _update_auto_sign_in(self) -> None: def _update_auto_sign_in(self) -> None:
plus = _babase.app.plus plus = _babase.app.plus
assert plus is not None assert plus is not None
@ -266,7 +277,7 @@ class AccountV2Subsystem:
# If implicit state has changed, try to respond. # If implicit state has changed, try to respond.
if self._implicit_state_changed: if self._implicit_state_changed:
if self._implicit_signed_in_adapter is None: if self._implicit_signed_in_adapter is None:
# If implicit back-end is signed out, follow suit # If implicit back-end has signed out, we follow suit
# immediately; no need to wait for network connectivity. # immediately; no need to wait for network connectivity.
if DEBUG_LOG: if DEBUG_LOG:
logging.debug( logging.debug(
@ -286,9 +297,8 @@ class AccountV2Subsystem:
# Consider this an 'explicit' sign in because the # Consider this an 'explicit' sign in because the
# implicit-login state change presumably was triggered # implicit-login state change presumably was triggered
# by some user action (signing in, signing out, or # by some user action (signing in, signing out, or
# switching accounts via the back-end). # switching accounts via the back-end). NOTE: should
# NOTE: should test case where we don't have # test case where we don't have connectivity here.
# connectivity here.
if plus.cloud.is_connected(): if plus.cloud.is_connected():
if DEBUG_LOG: if DEBUG_LOG:
logging.debug( logging.debug(
@ -419,14 +429,11 @@ class AccountV2Handle:
used with some operations such as cloud messaging. used with some operations such as cloud messaging.
""" """
def __init__(self) -> None: accountid: str
self.tag = '?' tag: str
workspacename: str | None
self.workspacename: str | None = None workspaceid: str | None
self.workspaceid: str | None = None logins: dict[LoginType, LoginInfo]
# Login types and their display-names associated with this account.
self.logins: dict[LoginType, str] = {}
def __enter__(self) -> None: def __enter__(self) -> None:
"""Support for "with" statement. """Support for "with" statement.

View file

@ -1,12 +1,10 @@
# Released under the MIT License. See LICENSE for details. # Released under the MIT License. See LICENSE for details.
# #
"""Functionality related to the high level state of the app.""" """Functionality related to the high level state of the app."""
# pylint: disable=too-many-lines
from __future__ import annotations from __future__ import annotations
import os import os
import logging import logging
import warnings
from enum import Enum from enum import Enum
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
@ -24,6 +22,7 @@ from babase._appcomponent import AppComponentSubsystem
from babase._appmodeselector import AppModeSelector from babase._appmodeselector import AppModeSelector
from babase._appintent import AppIntentDefault, AppIntentExec from babase._appintent import AppIntentDefault, AppIntentExec
from babase._stringedit import StringEditSubsystem from babase._stringedit import StringEditSubsystem
from babase._devconsole import DevConsoleSubsystem
if TYPE_CHECKING: if TYPE_CHECKING:
import asyncio import asyncio
@ -57,6 +56,8 @@ class App:
# pylint: disable=too-many-public-methods # pylint: disable=too-many-public-methods
# A few things defined as non-optional values but not actually
# available until the app starts.
plugins: PluginSubsystem plugins: PluginSubsystem
lang: LanguageSubsystem lang: LanguageSubsystem
health_monitor: AppHealthMonitor health_monitor: AppHealthMonitor
@ -71,7 +72,7 @@ class App:
# The app has not yet begun starting and should not be used in # The app has not yet begun starting and should not be used in
# any way. # any way.
NOT_RUNNING = 0 NOT_STARTED = 0
# The native layer is spinning up its machinery (screens, # The native layer is spinning up its machinery (screens,
# renderers, etc.). Nothing should happen in the Python layer # renderers, etc.). Nothing should happen in the Python layer
@ -91,13 +92,23 @@ class App:
# All pieces are in place and the app is now doing its thing. # All pieces are in place and the app is now doing its thing.
RUNNING = 4 RUNNING = 4
# The app is backgrounded or otherwise suspended. # Used on platforms such as mobile where the app basically needs
PAUSED = 5 # to shut down while backgrounded. In this state, all event
# loops are suspended and all graphics and audio must cease
# completely. Be aware that the suspended state can be entered
# from any other state including NATIVE_BOOTSTRAPPING and
# SHUTTING_DOWN.
SUSPENDED = 5
# The app is shutting down. # The app is shutting down. This process may involve sending
# network messages or other things that can take up to a few
# seconds, so ideally graphics and audio should remain
# functional (with fades or spinners or whatever to show
# something is happening).
SHUTTING_DOWN = 6 SHUTTING_DOWN = 6
# The app has completed shutdown. # The app has completed shutdown. Any code running here should
# be basically immediate.
SHUTDOWN_COMPLETE = 7 SHUTDOWN_COMPLETE = 7
class DefaultAppModeSelector(AppModeSelector): class DefaultAppModeSelector(AppModeSelector):
@ -140,9 +151,9 @@ class App:
def __init__(self) -> None: def __init__(self) -> None:
"""(internal) """(internal)
Do not instantiate this class; access the single shared instance Do not instantiate this class. You can access the single shared
of it as 'app' which is available in various Ballistica instance of it through various high level packages: 'babase.app',
feature-set modules such as babase. 'bascenev1.app', 'bauiv1.app', etc.
""" """
# Hack for docs-generation: we can be imported with dummy modules # Hack for docs-generation: we can be imported with dummy modules
@ -151,32 +162,35 @@ class App:
return return
self.env: babase.Env = _babase.Env() self.env: babase.Env = _babase.Env()
self.state = self.State.NOT_RUNNING self.state = self.State.NOT_STARTED
# Default executor which can be used for misc background # Default executor which can be used for misc background
# processing. It should also be passed to any additional asyncio # processing. It should also be passed to any additional asyncio
# loops we create so that everything shares the same single set # loops we create so that everything shares the same single set
# of worker threads. # of worker threads.
self.threadpool = ThreadPoolExecutor(thread_name_prefix='baworker') self.threadpool = ThreadPoolExecutor(
thread_name_prefix='baworker',
initializer=self._thread_pool_thread_init,
)
self.meta = MetadataSubsystem() self.meta = MetadataSubsystem()
self.net = NetworkSubsystem() self.net = NetworkSubsystem()
self.workspaces = WorkspaceSubsystem() self.workspaces = WorkspaceSubsystem()
self.components = AppComponentSubsystem() self.components = AppComponentSubsystem()
self.stringedit = StringEditSubsystem() self.stringedit = StringEditSubsystem()
self.devconsole = DevConsoleSubsystem()
# This is incremented any time the app is backgrounded or # This is incremented any time the app is backgrounded or
# foregrounded; can be a simple way to determine if network data # foregrounded; can be a simple way to determine if network data
# should be refreshed/etc. # should be refreshed/etc.
self.fg_state = 0 self.fg_state = 0
self.config_file_healthy: bool = False
self._subsystems: list[AppSubsystem] = [] self._subsystems: list[AppSubsystem] = []
self._native_bootstrapping_completed = False self._native_bootstrapping_completed = False
self._init_completed = False self._init_completed = False
self._meta_scan_completed = False self._meta_scan_completed = False
self._native_start_called = False self._native_start_called = False
self._native_paused = False self._native_suspended = False
self._native_shutdown_called = False self._native_shutdown_called = False
self._native_shutdown_complete_called = False self._native_shutdown_complete_called = False
self._initial_sign_in_completed = False self._initial_sign_in_completed = False
@ -194,8 +208,11 @@ class App:
self._mode_selector: babase.AppModeSelector | None = None self._mode_selector: babase.AppModeSelector | None = None
self._shutdown_task: asyncio.Task[None] | None = None self._shutdown_task: asyncio.Task[None] | None = None
self._shutdown_tasks: list[Coroutine[None, None, None]] = [ self._shutdown_tasks: list[Coroutine[None, None, None]] = [
self._wait_for_shutdown_suppressions() self._wait_for_shutdown_suppressions(),
self._fade_and_shutdown_graphics(),
self._fade_and_shutdown_audio(),
] ]
self._pool_thread_count = 0
def postinit(self) -> None: def postinit(self) -> None:
"""Called after we've been inited and assigned to babase.app. """Called after we've been inited and assigned to babase.app.
@ -212,6 +229,15 @@ class App:
self.lang = LanguageSubsystem() self.lang = LanguageSubsystem()
self.plugins = PluginSubsystem() self.plugins = PluginSubsystem()
@property
def active(self) -> bool:
"""Whether the app is currently front and center.
This will be False when the app is hidden, other activities
are covering it, etc. (depending on the platform).
"""
return _babase.app_is_active()
@property @property
def aioloop(self) -> asyncio.AbstractEventLoop: def aioloop(self) -> asyncio.AbstractEventLoop:
"""The logic thread's asyncio event loop. """The logic thread's asyncio event loop.
@ -311,7 +337,7 @@ class App:
def add_shutdown_task(self, coro: Coroutine[None, None, None]) -> None: def add_shutdown_task(self, coro: Coroutine[None, None, None]) -> None:
"""Add a task to be run on app shutdown. """Add a task to be run on app shutdown.
Note that tasks will be killed after Note that shutdown tasks will be canceled after
App.SHUTDOWN_TASK_TIMEOUT_SECONDS if they are still running. App.SHUTDOWN_TASK_TIMEOUT_SECONDS if they are still running.
""" """
if ( if (
@ -385,18 +411,18 @@ class App:
self._native_bootstrapping_completed = True self._native_bootstrapping_completed = True
self._update_state() self._update_state()
def on_native_pause(self) -> None: def on_native_suspend(self) -> None:
"""Called by the native layer when the app pauses.""" """Called by the native layer when the app is suspended."""
assert _babase.in_logic_thread() assert _babase.in_logic_thread()
assert not self._native_paused # Should avoid redundant calls. assert not self._native_suspended # Should avoid redundant calls.
self._native_paused = True self._native_suspended = True
self._update_state() self._update_state()
def on_native_resume(self) -> None: def on_native_unsuspend(self) -> None:
"""Called by the native layer when the app resumes.""" """Called by the native layer when the app suspension ends."""
assert _babase.in_logic_thread() assert _babase.in_logic_thread()
assert self._native_paused # Should avoid redundant calls. assert self._native_suspended # Should avoid redundant calls.
self._native_paused = False self._native_suspended = False
self._update_state() self._update_state()
def on_native_shutdown(self) -> None: def on_native_shutdown(self) -> None:
@ -415,7 +441,7 @@ class App:
"""(internal)""" """(internal)"""
from babase._appconfig import read_app_config from babase._appconfig import read_app_config
self._config, self.config_file_healthy = read_app_config() self._config = read_app_config()
def handle_deep_link(self, url: str) -> None: def handle_deep_link(self, url: str) -> None:
"""Handle a deep link URL.""" """Handle a deep link URL."""
@ -493,7 +519,7 @@ class App:
except Exception: except Exception:
logging.exception('Error setting app intent to %s.', intent) logging.exception('Error setting app intent to %s.', intent)
_babase.pushcall( _babase.pushcall(
tpartial(self._apply_intent_error, intent), tpartial(self._display_set_intent_error, intent),
from_other_thread=True, from_other_thread=True,
) )
@ -538,10 +564,11 @@ class App:
'Error handling intent %s in app-mode %s.', intent, mode 'Error handling intent %s in app-mode %s.', intent, mode
) )
def _apply_intent_error(self, intent: AppIntent) -> None: def _display_set_intent_error(self, intent: AppIntent) -> None:
"""Show the *user* something went wrong setting an intent."""
from babase._language import Lstr from babase._language import Lstr
del intent # Unused. del intent
_babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0)) _babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
_babase.getsimplesound('error').play() _babase.getsimplesound('error').play()
@ -564,19 +591,6 @@ class App:
self._aioloop = _asyncio.setup_asyncio() self._aioloop = _asyncio.setup_asyncio()
self.health_monitor = AppHealthMonitor() self.health_monitor = AppHealthMonitor()
# Only proceed if our config file is healthy so we don't
# overwrite a broken one or whatnot and wipe out data.
if not self.config_file_healthy:
if self.classic is not None:
handled = self.classic.show_config_error_window()
if handled:
return
# For now on other systems we just overwrite the bum config.
# At this point settings are already set; lets just commit
# them to disk.
_appconfig.commit_app_config(force=True)
# __FEATURESET_APP_SUBSYSTEM_CREATE_BEGIN__ # __FEATURESET_APP_SUBSYSTEM_CREATE_BEGIN__
# This section generated by batools.appmodule; do not edit. # This section generated by batools.appmodule; do not edit.
@ -726,15 +740,15 @@ class App:
_babase.lifecyclelog('app state shutting down') _babase.lifecyclelog('app state shutting down')
self._on_shutting_down() self._on_shutting_down()
elif self._native_paused: elif self._native_suspended:
# Entering paused state: # Entering suspended state:
if self.state is not self.State.PAUSED: if self.state is not self.State.SUSPENDED:
self.state = self.State.PAUSED self.state = self.State.SUSPENDED
self._on_pause() self._on_suspend()
else: else:
# Leaving paused state: # Leaving suspended state:
if self.state is self.State.PAUSED: if self.state is self.State.SUSPENDED:
self._on_resume() self._on_unsuspend()
# Entering or returning to running state # Entering or returning to running state
if self._initial_sign_in_completed and self._meta_scan_completed: if self._initial_sign_in_completed and self._meta_scan_completed:
@ -768,7 +782,7 @@ class App:
self.state = self.State.NATIVE_BOOTSTRAPPING self.state = self.State.NATIVE_BOOTSTRAPPING
_babase.lifecyclelog('app state native bootstrapping') _babase.lifecyclelog('app state native bootstrapping')
else: else:
# Only logical possibility left is NOT_RUNNING, in which # Only logical possibility left is NOT_STARTED, in which
# case we should not be getting called. # case we should not be getting called.
logging.warning( logging.warning(
'App._update_state called while in %s state;' 'App._update_state called while in %s state;'
@ -780,6 +794,7 @@ class App:
async def _shutdown(self) -> None: async def _shutdown(self) -> None:
import asyncio import asyncio
_babase.lock_all_input()
try: try:
async with asyncio.TaskGroup() as task_group: async with asyncio.TaskGroup() as task_group:
for task_coro in self._shutdown_tasks: for task_coro in self._shutdown_tasks:
@ -809,33 +824,33 @@ class App:
try: try:
await asyncio.wait_for(task, self.SHUTDOWN_TASK_TIMEOUT_SECONDS) await asyncio.wait_for(task, self.SHUTDOWN_TASK_TIMEOUT_SECONDS)
except Exception: except Exception:
logging.exception('Error in shutdown task.') logging.exception('Error in shutdown task (%s).', coro)
def _on_pause(self) -> None: def _on_suspend(self) -> None:
"""Called when the app goes to a paused state.""" """Called when the app goes to a suspended state."""
assert _babase.in_logic_thread() assert _babase.in_logic_thread()
# Pause all app subsystems in the opposite order they were inited. # Suspend all app subsystems in the opposite order they were inited.
for subsystem in reversed(self._subsystems): for subsystem in reversed(self._subsystems):
try: try:
subsystem.on_app_pause() subsystem.on_app_suspend()
except Exception: except Exception:
logging.exception( logging.exception(
'Error in on_app_pause for subsystem %s.', subsystem 'Error in on_app_suspend for subsystem %s.', subsystem
) )
def _on_resume(self) -> None: def _on_unsuspend(self) -> None:
"""Called when resuming.""" """Called when unsuspending."""
assert _babase.in_logic_thread() assert _babase.in_logic_thread()
self.fg_state += 1 self.fg_state += 1
# Resume all app subsystems in the same order they were inited. # Unsuspend all app subsystems in the same order they were inited.
for subsystem in self._subsystems: for subsystem in self._subsystems:
try: try:
subsystem.on_app_resume() subsystem.on_app_unsuspend()
except Exception: except Exception:
logging.exception( logging.exception(
'Error in on_app_resume for subsystem %s.', subsystem 'Error in on_app_unsuspend for subsystem %s.', subsystem
) )
def _on_shutting_down(self) -> None: def _on_shutting_down(self) -> None:
@ -875,10 +890,45 @@ class App:
import asyncio import asyncio
# Spin and wait for anything blocking shutdown to complete. # Spin and wait for anything blocking shutdown to complete.
starttime = _babase.apptime()
_babase.lifecyclelog('shutdown-suppress wait begin') _babase.lifecyclelog('shutdown-suppress wait begin')
while _babase.shutdown_suppress_count() > 0: while _babase.shutdown_suppress_count() > 0:
await asyncio.sleep(0.001) await asyncio.sleep(0.001)
_babase.lifecyclelog('shutdown-suppress wait end') _babase.lifecyclelog('shutdown-suppress wait end')
duration = _babase.apptime() - starttime
if duration > 1.0:
logging.warning(
'Shutdown-suppressions lasted longer than ideal '
'(%.2f seconds).',
duration,
)
async def _fade_and_shutdown_graphics(self) -> None:
import asyncio
# Kick off a short fade and give it time to complete.
_babase.lifecyclelog('fade-and-shutdown-graphics begin')
_babase.fade_screen(False, time=0.15)
await asyncio.sleep(0.15)
# Now tell the graphics system to go down and wait until
# it has done so.
_babase.graphics_shutdown_begin()
while not _babase.graphics_shutdown_is_complete():
await asyncio.sleep(0.01)
_babase.lifecyclelog('fade-and-shutdown-graphics end')
async def _fade_and_shutdown_audio(self) -> None:
import asyncio
# Tell the audio system to go down and give it a bit of
# time to do so gracefully.
_babase.lifecyclelog('fade-and-shutdown-audio begin')
_babase.audio_shutdown_begin()
await asyncio.sleep(0.15)
while not _babase.audio_shutdown_is_complete():
await asyncio.sleep(0.01)
_babase.lifecyclelog('fade-and-shutdown-audio end')
def _threadpool_no_wait_done(self, fut: Future) -> None: def _threadpool_no_wait_done(self, fut: Future) -> None:
try: try:
@ -888,243 +938,7 @@ class App:
'Error in work submitted via threadpool_submit_no_wait()' 'Error in work submitted via threadpool_submit_no_wait()'
) )
# -------------------------------------------------------------------- def _thread_pool_thread_init(self) -> None:
# THE FOLLOWING ARE DEPRECATED AND WILL BE REMOVED IN A FUTURE UPDATE. # Help keep things clear in profiling tools/etc.
# -------------------------------------------------------------------- self._pool_thread_count += 1
_babase.set_thread_name(f'ballistica worker-{self._pool_thread_count}')
@property
def build_number(self) -> int:
"""Integer build number.
This value increases by at least 1 with each release of the engine.
It is independent of the human readable babase.App.version string.
"""
warnings.warn(
'app.build_number is deprecated; use app.env.build_number',
DeprecationWarning,
stacklevel=2,
)
return self.env.build_number
@property
def device_name(self) -> str:
"""Name of the device running the app."""
warnings.warn(
'app.device_name is deprecated; use app.env.device_name',
DeprecationWarning,
stacklevel=2,
)
return self.env.device_name
@property
def config_file_path(self) -> str:
"""Where the app's config file is stored on disk."""
warnings.warn(
'app.config_file_path is deprecated;'
' use app.env.config_file_path',
DeprecationWarning,
stacklevel=2,
)
return self.env.config_file_path
@property
def version(self) -> str:
"""Human-readable engine version string; something like '1.3.24'.
This should not be interpreted as a number; it may contain
string elements such as 'alpha', 'beta', 'test', etc.
If a numeric version is needed, use `build_number`.
"""
warnings.warn(
'app.version is deprecated; use app.env.version',
DeprecationWarning,
stacklevel=2,
)
return self.env.version
@property
def debug_build(self) -> bool:
"""Whether the app was compiled in debug mode.
Debug builds generally run substantially slower than non-debug
builds due to compiler optimizations being disabled and extra
checks being run.
"""
warnings.warn(
'app.debug_build is deprecated; use app.env.debug',
DeprecationWarning,
stacklevel=2,
)
return self.env.debug
@property
def test_build(self) -> bool:
"""Whether the app was compiled in test mode.
Test mode enables extra checks and features that are useful for
release testing but which do not slow the game down significantly.
"""
warnings.warn(
'app.test_build is deprecated; use app.env.test',
DeprecationWarning,
stacklevel=2,
)
return self.env.test
@property
def data_directory(self) -> str:
"""Path where static app data lives."""
warnings.warn(
'app.data_directory is deprecated; use app.env.data_directory',
DeprecationWarning,
stacklevel=2,
)
return self.env.data_directory
@property
def python_directory_user(self) -> str | None:
"""Path where the app expects its user scripts (mods) to live.
Be aware that this value may be None if ballistica is running in
a non-standard environment, and that python-path modifications may
cause modules to be loaded from other locations.
"""
warnings.warn(
'app.python_directory_user is deprecated;'
' use app.env.python_directory_user',
DeprecationWarning,
stacklevel=2,
)
return self.env.python_directory_user
@property
def python_directory_app(self) -> str | None:
"""Path where the app expects its bundled modules to live.
Be aware that this value may be None if Ballistica is running in
a non-standard environment, and that python-path modifications may
cause modules to be loaded from other locations.
"""
warnings.warn(
'app.python_directory_app is deprecated;'
' use app.env.python_directory_app',
DeprecationWarning,
stacklevel=2,
)
return self.env.python_directory_app
@property
def python_directory_app_site(self) -> str | None:
"""Path where the app expects its bundled pip modules to live.
Be aware that this value may be None if Ballistica is running in
a non-standard environment, and that python-path modifications may
cause modules to be loaded from other locations.
"""
warnings.warn(
'app.python_directory_app_site is deprecated;'
' use app.env.python_directory_app_site',
DeprecationWarning,
stacklevel=2,
)
return self.env.python_directory_app_site
@property
def api_version(self) -> int:
"""The app's api version.
Only Python modules and packages associated with the current API
version number will be detected by the game (see the ba_meta tag).
This value will change whenever substantial backward-incompatible
changes are introduced to ballistica APIs. When that happens,
modules/packages should be updated accordingly and set to target
the newer API version number.
"""
warnings.warn(
'app.api_version is deprecated; use app.env.api_version',
DeprecationWarning,
stacklevel=2,
)
return self.env.api_version
@property
def on_tv(self) -> bool:
"""Whether the app is currently running on a TV."""
warnings.warn(
'app.on_tv is deprecated; use app.env.tv',
DeprecationWarning,
stacklevel=2,
)
return self.env.tv
@property
def vr_mode(self) -> bool:
"""Whether the app is currently running in VR."""
warnings.warn(
'app.vr_mode is deprecated; use app.env.vr',
DeprecationWarning,
stacklevel=2,
)
return self.env.vr
# __SPINOFF_REQUIRE_UI_V1_BEGIN__
@property
def toolbar_test(self) -> bool:
"""(internal)."""
warnings.warn(
'app.toolbar_test is deprecated; use app.ui_v1.use_toolbars',
DeprecationWarning,
stacklevel=2,
)
return self.ui_v1.use_toolbars
# __SPINOFF_REQUIRE_UI_V1_END__
@property
def arcade_mode(self) -> bool:
"""Whether the app is currently running on arcade hardware."""
warnings.warn(
'app.arcade_mode is deprecated; use app.env.arcade',
DeprecationWarning,
stacklevel=2,
)
return self.env.arcade
@property
def headless_mode(self) -> bool:
"""Whether the app is running headlessly."""
warnings.warn(
'app.headless_mode is deprecated; use app.env.headless',
DeprecationWarning,
stacklevel=2,
)
return self.env.headless
@property
def demo_mode(self) -> bool:
"""Whether the app is targeting a demo experience."""
warnings.warn(
'app.demo_mode is deprecated; use app.env.demo',
DeprecationWarning,
stacklevel=2,
)
return self.env.demo
# __SPINOFF_REQUIRE_SCENE_V1_BEGIN__
@property
def protocol_version(self) -> int:
"""(internal)."""
# pylint: disable=cyclic-import
import bascenev1
warnings.warn(
'app.protocol_version is deprecated;'
' use bascenev1.protocol_version()',
DeprecationWarning,
stacklevel=2,
)
return bascenev1.protocol_version()
# __SPINOFF_REQUIRE_SCENE_V1_END__

View file

@ -101,15 +101,13 @@ class AppConfig(dict):
self.commit() self.commit()
def read_app_config() -> tuple[AppConfig, bool]: def read_app_config() -> AppConfig:
"""Read the app config.""" """Read the app config."""
import os import os
import json import json
config_file_healthy = False # NOTE: it is assumed that this only gets called once and the config
# object will not change from here on out
# NOTE: it is assumed that this only gets called once and the
# config object will not change from here on out
config_file_path = _babase.app.env.config_file_path config_file_path = _babase.app.env.config_file_path
config_contents = '' config_contents = ''
try: try:
@ -119,20 +117,16 @@ def read_app_config() -> tuple[AppConfig, bool]:
config = AppConfig(json.loads(config_contents)) config = AppConfig(json.loads(config_contents))
else: else:
config = AppConfig() config = AppConfig()
config_file_healthy = True
except Exception: except Exception:
logging.exception( logging.exception(
"Error reading config file at time %.3f: '%s'.", "Error reading config file '%s' at time %.3f.\n"
"Backing up broken config to'%s.broken'.",
config_file_path,
_babase.apptime(), _babase.apptime(),
config_file_path, config_file_path,
) )
# Whenever this happens lets back up the broken one just in case it
# gets overwritten accidentally.
logging.info(
"Backing up current config file to '%s.broken'", config_file_path
)
try: try:
import shutil import shutil
@ -141,23 +135,10 @@ def read_app_config() -> tuple[AppConfig, bool]:
logging.exception('Error copying broken config.') logging.exception('Error copying broken config.')
config = AppConfig() config = AppConfig()
# Now attempt to read one of our 'prev' backup copies. return config
prev_path = config_file_path + '.prev'
try:
if os.path.exists(prev_path):
with open(prev_path, encoding='utf-8') as infile:
config_contents = infile.read()
config = AppConfig(json.loads(config_contents))
else:
config = AppConfig()
config_file_healthy = True
logging.info('Successfully read backup config.')
except Exception:
logging.exception('Error reading prev backup config.')
return config, config_file_healthy
def commit_app_config(force: bool = False) -> None: def commit_app_config() -> None:
"""Commit the config to persistent storage. """Commit the config to persistent storage.
Category: **General Utility Functions** Category: **General Utility Functions**
@ -167,10 +148,4 @@ def commit_app_config(force: bool = False) -> None:
plus = _babase.app.plus plus = _babase.app.plus
assert plus is not None assert plus is not None
if not _babase.app.config_file_healthy and not force:
logging.warning(
'Current config file is broken; '
'skipping write to avoid losing settings.'
)
return
plus.mark_config_dirty() plus.mark_config_dirty()

View file

@ -31,6 +31,7 @@ class AppMode:
AppExperience associated with the AppMode must be supported by AppExperience associated with the AppMode must be supported by
the current app and runtime environment. the current app and runtime environment.
""" """
# FIXME: check AppExperience.
return cls._supports_intent(intent) return cls._supports_intent(intent)
@classmethod @classmethod

View file

@ -39,10 +39,10 @@ class AppSubsystem:
def on_app_running(self) -> None: def on_app_running(self) -> None:
"""Called when the app reaches the running state.""" """Called when the app reaches the running state."""
def on_app_pause(self) -> None: def on_app_suspend(self) -> None:
"""Called when the app enters the paused state.""" """Called when the app enters the paused state."""
def on_app_resume(self) -> None: def on_app_unsuspend(self) -> None:
"""Called when the app exits the paused state.""" """Called when the app exits the paused state."""
def on_app_shutdown(self) -> None: def on_app_shutdown(self) -> None:

View file

@ -64,7 +64,9 @@ def get_remote_app_name() -> babase.Lstr:
def should_submit_debug_info() -> bool: def should_submit_debug_info() -> bool:
"""(internal)""" """(internal)"""
return _babase.app.config.get('Submit Debug Info', True) val = _babase.app.config.get('Submit Debug Info', True)
assert isinstance(val, bool)
return val
def handle_v1_cloud_log() -> None: def handle_v1_cloud_log() -> None:
@ -323,7 +325,7 @@ def dump_app_state(
) )
def log_dumped_app_state() -> None: def log_dumped_app_state(from_previous_run: bool = False) -> None:
"""If an app-state dump exists, log it and clear it. No-op otherwise.""" """If an app-state dump exists, log it and clear it. No-op otherwise."""
try: try:
@ -350,8 +352,13 @@ def log_dumped_app_state() -> None:
metadata = dataclass_from_json(DumpedAppStateMetadata, appstatedata) metadata = dataclass_from_json(DumpedAppStateMetadata, appstatedata)
header = (
'Found app state dump from previous app run'
if from_previous_run
else 'App state dump'
)
out += ( out += (
f'App state dump:\nReason: {metadata.reason}\n' f'{header}:\nReason: {metadata.reason}\n'
f'Time: {metadata.app_time:.2f}' f'Time: {metadata.app_time:.2f}'
) )
tbpath = os.path.join( tbpath = os.path.join(
@ -381,9 +388,10 @@ class AppHealthMonitor(AppSubsystem):
def on_app_loading(self) -> None: def on_app_loading(self) -> None:
# If any traceback dumps happened last run, log and clear them. # If any traceback dumps happened last run, log and clear them.
log_dumped_app_state() log_dumped_app_state(from_previous_run=True)
def _app_monitor_thread_main(self) -> None: def _app_monitor_thread_main(self) -> None:
_babase.set_thread_name('ballistica app-monitor')
try: try:
self._monitor_app() self._monitor_app()
except Exception: except Exception:
@ -441,10 +449,10 @@ class AppHealthMonitor(AppSubsystem):
self._first_check = False self._first_check = False
def on_app_pause(self) -> None: def on_app_suspend(self) -> None:
assert _babase.in_logic_thread() assert _babase.in_logic_thread()
self._running = False self._running = False
def on_app_resume(self) -> None: def on_app_unsuspend(self) -> None:
assert _babase.in_logic_thread() assert _babase.in_logic_thread()
self._running = True self._running = True

View file

@ -26,6 +26,11 @@ DEBUG_LOG = False
class CloudSubsystem(AppSubsystem): class CloudSubsystem(AppSubsystem):
"""Manages communication with cloud components.""" """Manages communication with cloud components."""
@property
def connected(self) -> bool:
"""Property equivalent of CloudSubsystem.is_connected()."""
return self.is_connected()
def is_connected(self) -> bool: def is_connected(self) -> bool:
"""Return whether a connection to the cloud is present. """Return whether a connection to the cloud is present.

View file

@ -0,0 +1,188 @@
# Released under the MIT License. See LICENSE for details.
#
"""Dev-Console functionality."""
from __future__ import annotations
import os
from typing import TYPE_CHECKING
from dataclasses import dataclass
import logging
import _babase
if TYPE_CHECKING:
from typing import Callable, Any, Literal
class DevConsoleTab:
"""Defines behavior for a tab in the dev-console."""
def refresh(self) -> None:
"""Called when the tab should refresh itself."""
def request_refresh(self) -> None:
"""The tab can call this to request that it be refreshed."""
_babase.dev_console_request_refresh()
def button(
self,
label: str,
pos: tuple[float, float],
size: tuple[float, float],
call: Callable[[], Any] | None = None,
h_anchor: Literal['left', 'center', 'right'] = 'center',
label_scale: float = 1.0,
corner_radius: float = 8.0,
style: Literal['normal', 'dark'] = 'normal',
) -> None:
"""Add a button to the tab being refreshed."""
assert _babase.app.devconsole.is_refreshing
_babase.dev_console_add_button(
label,
pos[0],
pos[1],
size[0],
size[1],
call,
h_anchor,
label_scale,
corner_radius,
style,
)
def text(
self,
text: str,
pos: tuple[float, float],
h_anchor: Literal['left', 'center', 'right'] = 'center',
h_align: Literal['left', 'center', 'right'] = 'center',
v_align: Literal['top', 'center', 'bottom', 'none'] = 'center',
scale: float = 1.0,
) -> None:
"""Add a button to the tab being refreshed."""
assert _babase.app.devconsole.is_refreshing
_babase.dev_console_add_text(
text, pos[0], pos[1], h_anchor, h_align, v_align, scale
)
def python_terminal(self) -> None:
"""Add a Python Terminal to the tab being refreshed."""
assert _babase.app.devconsole.is_refreshing
_babase.dev_console_add_python_terminal()
@property
def width(self) -> float:
"""Return the current tab width. Only call during refreshes."""
assert _babase.app.devconsole.is_refreshing
return _babase.dev_console_tab_width()
@property
def height(self) -> float:
"""Return the current tab height. Only call during refreshes."""
assert _babase.app.devconsole.is_refreshing
return _babase.dev_console_tab_height()
@property
def base_scale(self) -> float:
"""A scale value set depending on the app's UI scale.
Dev-console tabs can incorporate this into their UI sizes and
positions if they desire. This must be done manually however.
"""
assert _babase.app.devconsole.is_refreshing
return _babase.dev_console_base_scale()
class DevConsoleTabPython(DevConsoleTab):
"""The Python dev-console tab."""
def refresh(self) -> None:
self.python_terminal()
class DevConsoleTabTest(DevConsoleTab):
"""Test dev-console tab."""
def refresh(self) -> None:
import random
self.button(
f'FLOOP-{random.randrange(200)}',
pos=(10, 10),
size=(100, 30),
h_anchor='left',
label_scale=0.6,
call=self.request_refresh,
)
self.button(
f'FLOOP2-{random.randrange(200)}',
pos=(120, 10),
size=(100, 30),
h_anchor='left',
label_scale=0.6,
style='dark',
)
self.text(
'TestText',
scale=0.8,
pos=(15, 50),
h_anchor='left',
h_align='left',
v_align='none',
)
@dataclass
class DevConsoleTabEntry:
"""Represents a distinct tab in the dev-console."""
name: str
factory: Callable[[], DevConsoleTab]
class DevConsoleSubsystem:
"""Subsystem for wrangling the dev console.
The single instance of this class can be found at
babase.app.devconsole. The dev-console is a simple always-available
UI intended for use by developers; not end users. Traditionally it
is available by typing a backtick (`) key on a keyboard, but now can
be accessed via an on-screen button (see settings/advanced to enable
said button).
"""
def __init__(self) -> None:
# All tabs in the dev-console. Add your own stuff here via
# plugins or whatnot.
self.tabs: list[DevConsoleTabEntry] = [
DevConsoleTabEntry('Python', DevConsoleTabPython)
]
if os.environ.get('BA_DEV_CONSOLE_TEST_TAB', '0') == '1':
self.tabs.append(DevConsoleTabEntry('Test', DevConsoleTabTest))
self.is_refreshing = False
def do_refresh_tab(self, tabname: str) -> None:
"""Called by the C++ layer when a tab should be filled out."""
assert _babase.in_logic_thread()
# FIXME: We currently won't handle multiple tabs with the same
# name. We should give a clean error or something in that case.
tab: DevConsoleTab | None = None
for tabentry in self.tabs:
if tabentry.name == tabname:
tab = tabentry.factory()
break
if tab is None:
logging.error(
'DevConsole got refresh request for tab'
" '%s' which does not exist.",
tabname,
)
return
self.is_refreshing = True
try:
tab.refresh()
finally:
self.is_refreshing = False

View file

@ -40,6 +40,11 @@ def on_native_module_import() -> None:
if envconfig.log_handler is not None: if envconfig.log_handler is not None:
_feed_logs_to_babase(envconfig.log_handler) _feed_logs_to_babase(envconfig.log_handler)
# Also let's name the log-handler thread to help in profiling.
envconfig.log_handler.call_in_thread(
lambda: _babase.set_thread_name('ballistica logging')
)
env = _babase.pre_env() env = _babase.pre_env()
# Give a soft warning if we're being used with a different binary # Give a soft warning if we're being used with a different binary
@ -180,10 +185,8 @@ def _feed_logs_to_babase(log_handler: LogHandler) -> None:
def _on_log(entry: LogEntry) -> None: def _on_log(entry: LogEntry) -> None:
# Forward this along to the engine to display in the in-app # Forward this along to the engine to display in the in-app
# console, in the Android log, etc. # console, in the Android log, etc.
_babase.display_log( _babase.emit_log(
name=entry.name, name=entry.name, level=entry.level.name, message=entry.message
level=entry.level.name,
message=entry.message,
) )
# We also want to feed some logs to the old v1-cloud-log system. # We also want to feed some logs to the old v1-cloud-log system.

View file

@ -33,18 +33,47 @@ def reset_to_main_menu() -> None:
logging.warning('reset_to_main_menu: no-op due to classic not present.') logging.warning('reset_to_main_menu: no-op due to classic not present.')
def set_config_fullscreen_on() -> None: def get_v2_account_id() -> str | None:
"""Return the current V2 account id if signed in, or None if not."""
try:
plus = _babase.app.plus
if plus is not None:
account = plus.accounts.primary
if account is not None:
accountid = account.accountid
# (Avoids mypy complaints when plus is not present)
assert isinstance(accountid, (str, type(None)))
return accountid
return None
except Exception:
logging.exception('Error fetching v2 account id.')
return None
def store_config_fullscreen_on() -> None:
"""The OS has changed our fullscreen state and we should take note.""" """The OS has changed our fullscreen state and we should take note."""
_babase.app.config['Fullscreen'] = True _babase.app.config['Fullscreen'] = True
_babase.app.config.commit() _babase.app.config.commit()
def set_config_fullscreen_off() -> None: def store_config_fullscreen_off() -> None:
"""The OS has changed our fullscreen state and we should take note.""" """The OS has changed our fullscreen state and we should take note."""
_babase.app.config['Fullscreen'] = False _babase.app.config['Fullscreen'] = False
_babase.app.config.commit() _babase.app.config.commit()
def set_config_fullscreen_on() -> None:
"""Set and store fullscreen state"""
_babase.app.config['Fullscreen'] = True
_babase.app.config.apply_and_commit()
def set_config_fullscreen_off() -> None:
"""The OS has changed our fullscreen state and we should take note."""
_babase.app.config['Fullscreen'] = False
_babase.app.config.apply_and_commit()
def not_signed_in_screen_message() -> None: def not_signed_in_screen_message() -> None:
from babase._language import Lstr from babase._language import Lstr
@ -111,6 +140,14 @@ def error_message() -> None:
_babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0)) _babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
def success_message() -> None:
from babase._language import Lstr
if _babase.app.env.gui:
_babase.getsimplesound('dingSmall').play()
_babase.screenmessage(Lstr(resource='successText'), color=(0, 1, 0))
def purchase_not_valid_error() -> None: def purchase_not_valid_error() -> None:
from babase._language import Lstr from babase._language import Lstr
@ -300,6 +337,7 @@ def implicit_sign_in(
from bacommon.login import LoginType from bacommon.login import LoginType
assert _babase.app.plus is not None assert _babase.app.plus is not None
_babase.app.plus.accounts.on_implicit_sign_in( _babase.app.plus.accounts.on_implicit_sign_in(
login_type=LoginType(login_type_str), login_type=LoginType(login_type_str),
login_id=login_id, login_id=login_id,
@ -372,3 +410,22 @@ def string_edit_adapter_can_be_replaced(adapter: StringEditAdapter) -> bool:
assert isinstance(adapter, StringEditAdapter) assert isinstance(adapter, StringEditAdapter)
return adapter.can_be_replaced() return adapter.can_be_replaced()
def get_dev_console_tab_names() -> list[str]:
"""Return the current set of dev-console tab names."""
return [t.name for t in _babase.app.devconsole.tabs]
def unsupported_controller_message(name: str) -> None:
"""Print a message when an unsupported controller is connected."""
from babase._language import Lstr
# Ick; this can get called early in the bootstrapping process
# before we're allowed to load assets. Guard against that.
if _babase.asset_loads_allowed():
_babase.getsimplesound('error').play()
_babase.screenmessage(
Lstr(resource='unsupportedControllerText', subs=[('${NAME}', name)]),
color=(1, 0, 0),
)

View file

@ -20,6 +20,13 @@ if TYPE_CHECKING:
DEBUG_LOG = False DEBUG_LOG = False
@dataclass
class LoginInfo:
"""Basic info about a login available in the app.plus.accounts section."""
name: str
class LoginAdapter: class LoginAdapter:
"""Allows using implicit login types in an explicit way. """Allows using implicit login types in an explicit way.
@ -138,7 +145,7 @@ class LoginAdapter:
is actually being used by the app. It should therefore register is actually being used by the app. It should therefore register
unlocked achievements, leaderboard scores, allow viewing native unlocked achievements, leaderboard scores, allow viewing native
UIs, etc. When not active it should ignore everything and behave UIs, etc. When not active it should ignore everything and behave
as if logged out, even if it technically is still logged in. as if signed out, even if it technically is still signed in.
""" """
assert _babase.in_logic_thread() assert _babase.in_logic_thread()
del active # Unused. del active # Unused.
@ -149,7 +156,7 @@ class LoginAdapter:
result_cb: Callable[[LoginAdapter, SignInResult | Exception], None], result_cb: Callable[[LoginAdapter, SignInResult | Exception], None],
description: str, description: str,
) -> None: ) -> None:
"""Attempt an explicit sign in via this adapter. """Attempt to sign in via this adapter.
This can be called even if the back-end is not implicitly signed in; This can be called even if the back-end is not implicitly signed in;
the adapter will attempt to sign in if possible. An exception will the adapter will attempt to sign in if possible. An exception will
@ -161,7 +168,7 @@ class LoginAdapter:
# Have been seeing multiple sign-in attempts come through # Have been seeing multiple sign-in attempts come through
# nearly simultaneously which can be problematic server-side. # nearly simultaneously which can be problematic server-side.
# Let's error if a sign-in attempt is made within a few seconds # Let's error if a sign-in attempt is made within a few seconds
# of the last one to address this. # of the last one to try and address this.
now = time.monotonic() now = time.monotonic()
appnow = _babase.apptime() appnow = _babase.apptime()
if self._last_sign_in_time is not None: if self._last_sign_in_time is not None:
@ -229,6 +236,7 @@ class LoginAdapter:
def _got_sign_in_response( def _got_sign_in_response(
response: bacommon.cloud.SignInResponse | Exception, response: bacommon.cloud.SignInResponse | Exception,
) -> None: ) -> None:
# This likely means we couldn't communicate with the server.
if isinstance(response, Exception): if isinstance(response, Exception):
if DEBUG_LOG: if DEBUG_LOG:
logging.debug( logging.debug(
@ -238,6 +246,12 @@ class LoginAdapter:
response, response,
) )
_babase.pushcall(Call(result_cb, self, response)) _babase.pushcall(Call(result_cb, self, response))
else:
# This means our credentials were explicitly rejected.
if response.credentials is None:
result2: LoginAdapter.SignInResult | Exception = (
RuntimeError('Sign-in-token was rejected.')
)
else: else:
if DEBUG_LOG: if DEBUG_LOG:
logging.debug( logging.debug(
@ -245,14 +259,6 @@ class LoginAdapter:
' sign-in response', ' sign-in response',
self.login_type.name, self.login_type.name,
) )
if response.credentials is None:
result2: LoginAdapter.SignInResult | Exception = (
RuntimeError(
'No credentials returned after'
' submitting sign-in-token.'
)
)
else:
result2 = self.SignInResult( result2 = self.SignInResult(
credentials=response.credentials credentials=response.credentials
) )
@ -269,7 +275,7 @@ class LoginAdapter:
on_response=_got_sign_in_response, on_response=_got_sign_in_response,
) )
# Kick off the process by fetching a sign-in token. # Kick off the sign-in process by fetching a sign-in token.
self.get_sign_in_token(completion_cb=_got_sign_in_token_result) self.get_sign_in_token(completion_cb=_got_sign_in_token_result)
def is_back_end_active(self) -> bool: def is_back_end_active(self) -> bool:
@ -282,11 +288,10 @@ class LoginAdapter:
"""Get a sign-in token from the adapter back end. """Get a sign-in token from the adapter back end.
This token is then passed to the master-server to complete the This token is then passed to the master-server to complete the
login process. sign-in process. The adapter can use this opportunity to bring
The adapter can use this opportunity to bring up account creation up account creation UI, call its internal sign_in function, etc.
UI, call its internal sign_in function, etc. as needed. as needed. The provided completion_cb should then be called with
The provided completion_cb should then be called with either a token either a token or None if sign in failed or was cancelled.
or None if sign in failed or was cancelled.
""" """
from babase._general import Call from babase._general import Call
@ -295,7 +300,7 @@ class LoginAdapter:
def _update_implicit_login_state(self) -> None: def _update_implicit_login_state(self) -> None:
# If we've received an implicit login state, schedule it to be # If we've received an implicit login state, schedule it to be
# sent along to the app. We wait until on-app-launch has been # sent along to the app. We wait until on-app-loading has been
# called so that account-client-v2 has had a chance to load # called so that account-client-v2 has had a chance to load
# any existing state so it can properly respond to this. # any existing state so it can properly respond to this.
if self._implicit_login_state_dirty and self._on_app_loading_called: if self._implicit_login_state_dirty and self._on_app_loading_called:
@ -340,8 +345,8 @@ class LoginAdapter:
class LoginAdapterNative(LoginAdapter): class LoginAdapterNative(LoginAdapter):
"""A login adapter that does its work in the native layer.""" """A login adapter that does its work in the native layer."""
def __init__(self) -> None: def __init__(self, login_type: LoginType) -> None:
super().__init__(LoginType.GPGS) super().__init__(login_type)
# Store int ids for in-flight attempts since they may go through # Store int ids for in-flight attempts since they may go through
# various platform layers and back. # various platform layers and back.
@ -375,3 +380,13 @@ class LoginAdapterNative(LoginAdapter):
class LoginAdapterGPGS(LoginAdapterNative): class LoginAdapterGPGS(LoginAdapterNative):
"""Google Play Game Services adapter.""" """Google Play Game Services adapter."""
def __init__(self) -> None:
super().__init__(LoginType.GPGS)
class LoginAdapterGameCenter(LoginAdapterNative):
"""Apple Game Center adapter."""
def __init__(self) -> None:
super().__init__(LoginType.GAME_CENTER)

View file

@ -24,6 +24,8 @@ if TYPE_CHECKING:
# instead of these or to make the meta system aware of arbitrary classes. # instead of these or to make the meta system aware of arbitrary classes.
EXPORT_CLASS_NAME_SHORTCUTS: dict[str, str] = { EXPORT_CLASS_NAME_SHORTCUTS: dict[str, str] = {
'plugin': 'babase.Plugin', 'plugin': 'babase.Plugin',
# DEPRECATED as of 12/2023. Currently am warning if finding these
# but should take this out eventually.
'keyboard': 'babase.Keyboard', 'keyboard': 'babase.Keyboard',
} }
@ -414,25 +416,22 @@ class DirectoryScan:
if export_class_name is not None: if export_class_name is not None:
classname = modulename + '.' + export_class_name classname = modulename + '.' + export_class_name
# Since we'll soon have multiple versions of 'game' # Migrating away from the 'keyboard' name shortcut
# classes we need to migrate people to using base # since it's specific to bauiv1; warn if we find it.
# class names for them. if exporttypestr == 'keyboard':
if exporttypestr == 'game':
logging.warning( logging.warning(
"metascan: %s:%d: '# ba_meta export" "metascan: %s:%d: '# ba_meta export"
" game' tag should be replaced by '# ba_meta" " keyboard' tag should be replaced by '# ba_meta"
" export bascenev1.GameActivity'.", " export bauiv1.Keyboard'.",
subpath, subpath,
lindex + 1, lindex + 1,
) )
self.results.announce_errors_occurred = True self.results.announce_errors_occurred = True
else:
# If export type is one of our shortcuts, sub in the # If export type is one of our shortcuts, sub in the
# actual class path. Otherwise assume its a classpath # actual class path. Otherwise assume its a classpath
# itself. # itself.
exporttype = EXPORT_CLASS_NAME_SHORTCUTS.get( exporttype = EXPORT_CLASS_NAME_SHORTCUTS.get(exporttypestr)
exporttypestr
)
if exporttype is None: if exporttype is None:
exporttype = exporttypestr exporttype = exporttypestr
self.results.exports.setdefault(exporttype, []).append( self.results.exports.setdefault(exporttype, []).append(

View file

@ -38,6 +38,27 @@ class InputType(Enum):
DOWN_RELEASE = 26 DOWN_RELEASE = 26
class QuitType(Enum):
"""Types of input a controller can send to the game.
Category: Enums
'soft' may hide/reset the app but keep the process running, depending
on the platform.
'back' is a variant of 'soft' which may give 'back-button-pressed'
behavior depending on the platform. (returning to some previous
activity instead of dumping to the home screen, etc.)
'hard' leads to the process exiting. This generally should be avoided
on platforms such as mobile.
"""
SOFT = 0
BACK = 1
HARD = 2
class UIScale(Enum): class UIScale(Enum):
"""The overall scale the UI is being rendered for. Note that this is """The overall scale the UI is being rendered for. Note that this is
independent of pixel resolution. For example, a phone and a desktop PC independent of pixel resolution. For example, a phone and a desktop PC

View file

@ -170,23 +170,23 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_running()') _error.print_exception('Error in plugin on_app_running()')
def on_app_pause(self) -> None: def on_app_suspend(self) -> None:
for plugin in self.active_plugins: for plugin in self.active_plugins:
try: try:
plugin.on_app_pause() plugin.on_app_suspend()
except Exception: except Exception:
from babase import _error from babase import _error
_error.print_exception('Error in plugin on_app_pause()') _error.print_exception('Error in plugin on_app_suspend()')
def on_app_resume(self) -> None: def on_app_unsuspend(self) -> None:
for plugin in self.active_plugins: for plugin in self.active_plugins:
try: try:
plugin.on_app_resume() plugin.on_app_unsuspend()
except Exception: except Exception:
from babase import _error from babase import _error
_error.print_exception('Error in plugin on_app_resume()') _error.print_exception('Error in plugin on_app_unsuspend()')
def on_app_shutdown(self) -> None: def on_app_shutdown(self) -> None:
for plugin in self.active_plugins: for plugin in self.active_plugins:
@ -327,11 +327,11 @@ class Plugin:
def on_app_running(self) -> None: def on_app_running(self) -> None:
"""Called when the app reaches the running state.""" """Called when the app reaches the running state."""
def on_app_pause(self) -> None: def on_app_suspend(self) -> None:
"""Called when the app is switching to a paused state.""" """Called when the app enters the suspended state."""
def on_app_resume(self) -> None: def on_app_unsuspend(self) -> None:
"""Called when the app is resuming from a paused state.""" """Called when the app exits the suspended state."""
def on_app_shutdown(self) -> None: def on_app_shutdown(self) -> None:
"""Called when the app is beginning the shutdown process.""" """Called when the app is beginning the shutdown process."""

View file

@ -104,8 +104,8 @@ def show_user_scripts() -> None:
_error.print_exception('error writing about_this_folder stuff') _error.print_exception('error writing about_this_folder stuff')
# On a few platforms we try to open the dir in the UI. # On platforms that support it, open the dir in the UI.
if app.classic is not None and app.classic.platform in ['mac', 'windows']: if _babase.supports_open_dir_externally():
_babase.open_dir_externally(env.python_directory_user) _babase.open_dir_externally(env.python_directory_user)
# Otherwise we just print a pretty version of it. # Otherwise we just print a pretty version of it.

View file

@ -49,10 +49,10 @@ class AccountV1Subsystem:
babase.pushcall(do_auto_sign_in) babase.pushcall(do_auto_sign_in)
def on_app_pause(self) -> None: def on_app_suspend(self) -> None:
"""Should be called when app is pausing.""" """Should be called when app is pausing."""
def on_app_resume(self) -> None: def on_app_unsuspend(self) -> None:
"""Should be called when the app is resumed.""" """Should be called when the app is resumed."""
# Mark our cached tourneys as invalid so anyone using them knows # Mark our cached tourneys as invalid so anyone using them knows
@ -302,6 +302,11 @@ class AccountV1Subsystem:
"""(internal)""" """(internal)"""
plus = babase.app.plus plus = babase.app.plus
if plus is None: if plus is None:
import logging
logging.warning(
'Error adding pending promo code; plus not present.'
)
babase.screenmessage( babase.screenmessage(
babase.Lstr(resource='errorText'), color=(1, 0, 0) babase.Lstr(resource='errorText'), color=(1, 0, 0)
) )

View file

@ -4,10 +4,11 @@
from __future__ import annotations from __future__ import annotations
import time import time
import asyncio
import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import babase import babase
import bauiv1
import bascenev1 import bascenev1
if TYPE_CHECKING: if TYPE_CHECKING:
@ -31,6 +32,7 @@ class AdsSubsystem:
self.last_in_game_ad_remove_message_show_time: float | None = None self.last_in_game_ad_remove_message_show_time: float | None = None
self.last_ad_completion_time: float | None = None self.last_ad_completion_time: float | None = None
self.last_ad_was_short = False self.last_ad_was_short = False
self._fallback_task: asyncio.Task | None = None
def do_remove_in_game_ads_message(self) -> None: def do_remove_in_game_ads_message(self) -> None:
"""(internal)""" """(internal)"""
@ -69,7 +71,8 @@ class AdsSubsystem:
) -> None: ) -> None:
"""(internal)""" """(internal)"""
self.last_ad_purpose = purpose self.last_ad_purpose = purpose
bauiv1.show_ad(purpose, on_completion_call) assert babase.app.plus is not None
babase.app.plus.show_ad(purpose, on_completion_call)
def show_ad_2( def show_ad_2(
self, self,
@ -78,7 +81,8 @@ class AdsSubsystem:
) -> None: ) -> None:
"""(internal)""" """(internal)"""
self.last_ad_purpose = purpose self.last_ad_purpose = purpose
bauiv1.show_ad_2(purpose, on_completion_call) assert babase.app.plus is not None
babase.app.plus.show_ad_2(purpose, on_completion_call)
def call_after_ad(self, call: Callable[[], Any]) -> None: def call_after_ad(self, call: Callable[[], Any]) -> None:
"""Run a call after potentially showing an ad.""" """Run a call after potentially showing an ad."""
@ -94,7 +98,7 @@ class AdsSubsystem:
show = True show = True
# No ads without net-connections, etc. # No ads without net-connections, etc.
if not bauiv1.can_show_ad(): if not plus.can_show_ad():
show = False show = False
if classic.accounts.have_pro(): if classic.accounts.have_pro():
show = False # Pro disables interstitials. show = False # Pro disables interstitials.
@ -132,7 +136,7 @@ class AdsSubsystem:
# ad-show-threshold and see if we should *actually* show # ad-show-threshold and see if we should *actually* show
# (we reach our threshold faster the longer we've been # (we reach our threshold faster the longer we've been
# playing). # playing).
base = 'ads' if bauiv1.has_video_ads() else 'ads2' base = 'ads' if plus.has_video_ads() else 'ads2'
min_lc = plus.get_v1_account_misc_read_val(base + '.minLC', 0.0) min_lc = plus.get_v1_account_misc_read_val(base + '.minLC', 0.0)
max_lc = plus.get_v1_account_misc_read_val(base + '.maxLC', 5.0) max_lc = plus.get_v1_account_misc_read_val(base + '.maxLC', 5.0)
min_lc_scale = plus.get_v1_account_misc_read_val( min_lc_scale = plus.get_v1_account_misc_read_val(
@ -181,36 +185,53 @@ class AdsSubsystem:
# If we're *still* cleared to show, actually tell the system to show. # If we're *still* cleared to show, actually tell the system to show.
if show: if show:
# As a safety-check, set up an object that will run # As a safety-check, we set up an object that will run the
# the completion callback if we've returned and sat for 10 seconds # completion callback if we've returned and sat for several
# (in case some random ad network doesn't properly deliver its # seconds (in case some random ad network doesn't properly
# completion callback). # deliver its completion callback).
class _Payload: class _Payload:
def __init__(self, pcall: Callable[[], Any]): def __init__(self, pcall: Callable[[], Any]):
self._call = pcall self._call = pcall
self._ran = False self._ran = False
def run(self, fallback: bool = False) -> None: def run(self, fallback: bool = False) -> None:
"""Run fallback call (and issue a warning about it).""" """Run the payload."""
assert app.classic is not None assert app.classic is not None
if not self._ran: if not self._ran:
if fallback: if fallback:
lanst = app.classic.ads.last_ad_network_set_time lanst = app.classic.ads.last_ad_network_set_time
print( logging.error(
'ERROR: relying on fallback ad-callback! ' 'Relying on fallback ad-callback! '
'last network: ' 'last network: %s (set %s seconds ago);'
+ app.classic.ads.last_ad_network ' purpose=%s.',
+ ' (set ' app.classic.ads.last_ad_network,
+ str(int(time.time() - lanst)) time.time() - lanst,
+ 's ago); purpose=' app.classic.ads.last_ad_purpose,
+ app.classic.ads.last_ad_purpose
) )
babase.pushcall(self._call) babase.pushcall(self._call)
self._ran = True self._ran = True
payload = _Payload(call) payload = _Payload(call)
# Set up our backup.
with babase.ContextRef.empty(): with babase.ContextRef.empty():
babase.apptimer(5.0, lambda: payload.run(fallback=True)) # Note to self: Previously this was a simple 5 second
# timer because the app got totally suspended while ads
# were showing (which delayed the timer), but these days
# the app may continue to run, so we need to be more
# careful and only fire the fallback after we see that
# the app has been front-and-center for several seconds.
async def add_fallback_task() -> None:
activesecs = 5
while activesecs > 0:
if babase.app.active:
activesecs -= 1
await asyncio.sleep(1.0)
payload.run(fallback=True)
_fallback_task = babase.app.aioloop.create_task(
add_fallback_task()
)
self.show_ad('between_game', on_completion_call=payload.run) self.show_ad('between_game', on_completion_call=payload.run)
else: else:
babase.pushcall(call) # Just run the callback without the ad. babase.pushcall(call) # Just run the callback without the ad.

View file

@ -41,5 +41,6 @@ class AppDelegate:
sessiontype, sessiontype,
settings, settings,
completion_call=completion_call, completion_call=completion_call,
).get_root_widget() ).get_root_widget(),
from_window=False, # Disable check since we don't know.
) )

View file

@ -8,6 +8,7 @@ from typing import TYPE_CHECKING
import babase import babase
import bascenev1 import bascenev1
import _baclassic
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence from typing import Any, Sequence
@ -54,7 +55,6 @@ def run_stress_test(
round_duration: int = 30, round_duration: int = 30,
) -> None: ) -> None:
"""Run a stress test.""" """Run a stress test."""
from babase import modutils
babase.screenmessage( babase.screenmessage(
"Beginning stress test.. use 'End Test' to stop testing.", "Beginning stress test.. use 'End Test' to stop testing.",
@ -69,22 +69,12 @@ def run_stress_test(
'round_duration': round_duration, 'round_duration': round_duration,
} }
) )
babase.apptimer(
7.0,
babase.Call(
babase.screenmessage,
(
'stats will be written to '
+ modutils.get_human_readable_user_scripts_path()
+ '/stress_test_stats.csv'
),
),
)
def stop_stress_test() -> None: def stop_stress_test() -> None:
"""End a running stress test.""" """End a running stress test."""
babase.set_stress_testing(False, 0)
_baclassic.set_stress_testing(False, 0)
assert babase.app.classic is not None assert babase.app.classic is not None
try: try:
if babase.app.classic.stress_test_reset_timer is not None: if babase.app.classic.stress_test_reset_timer is not None:
@ -134,14 +124,14 @@ def start_stress_test(args: dict[str, Any]) -> None:
babase.Call(bascenev1.new_host_session, FreeForAllSession), babase.Call(bascenev1.new_host_session, FreeForAllSession),
), ),
) )
babase.set_stress_testing(True, args['player_count']) _baclassic.set_stress_testing(True, args['player_count'])
babase.app.classic.stress_test_reset_timer = babase.AppTimer( babase.app.classic.stress_test_reset_timer = babase.AppTimer(
args['round_duration'], babase.Call(_reset_stress_test, args) args['round_duration'], babase.Call(_reset_stress_test, args)
) )
def _reset_stress_test(args: dict[str, Any]) -> None: def _reset_stress_test(args: dict[str, Any]) -> None:
babase.set_stress_testing(False, args['player_count']) _baclassic.set_stress_testing(False, args['player_count'])
babase.screenmessage('Resetting stress test...') babase.screenmessage('Resetting stress test...')
session = bascenev1.get_foreground_host_session() session = bascenev1.get_foreground_host_session()
assert session is not None assert session is not None

View file

@ -20,7 +20,6 @@ def get_input_device_mapped_value(
This checks the user config and falls back to default values This checks the user config and falls back to default values
where available. where available.
""" """
# pylint: disable=too-many-statements
# pylint: disable=too-many-return-statements # pylint: disable=too-many-return-statements
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
@ -40,7 +39,14 @@ def get_input_device_mapped_value(
mapping = ccfgs[devicename][unique_id] mapping = ccfgs[devicename][unique_id]
elif 'default' in ccfgs[devicename]: elif 'default' in ccfgs[devicename]:
mapping = ccfgs[devicename]['default'] mapping = ccfgs[devicename]['default']
if mapping is not None:
# We now use the config mapping *only* if it is not empty.
# There have been cases of config writing code messing up
# and leaving empty dicts in the app config, which currently
# leaves the device unusable. Alternatively, we'd perhaps
# want to fall back to defaults for individual missing
# values, but that is a bigger change we can make later.
if isinstance(mapping, dict) and mapping:
return mapping.get(name, -1) return mapping.get(name, -1)
if platform == 'windows': if platform == 'windows':
@ -76,91 +82,6 @@ def get_input_device_mapped_value(
'triggerRun1': 5, 'triggerRun1': 5,
}.get(name, -1) }.get(name, -1)
# Look for some exact types.
if babase.is_running_on_fire_tv():
if devicename in ['Thunder', 'Amazon Fire Game Controller']:
return {
'triggerRun2': 23,
'unassignedButtonsRun': False,
'buttonPickUp': 101,
'buttonBomb': 98,
'buttonJump': 97,
'analogStickDeadZone': 0.0,
'startButtonActivatesDefaultWidget': False,
'buttonStart': 83,
'buttonPunch': 100,
'buttonRun2': 103,
'buttonRun1': 104,
'triggerRun1': 24,
}.get(name, -1)
if devicename == 'NYKO PLAYPAD PRO':
return {
'triggerRun2': 23,
'triggerRun1': 24,
'buttonPickUp': 101,
'buttonBomb': 98,
'buttonJump': 97,
'buttonUp': 20,
'buttonLeft': 22,
'buttonRight': 23,
'buttonStart': 83,
'buttonPunch': 100,
'buttonDown': 21,
}.get(name, -1)
if devicename == 'Logitech Dual Action':
return {
'triggerRun2': 23,
'triggerRun1': 24,
'buttonPickUp': 98,
'buttonBomb': 101,
'buttonJump': 100,
'buttonStart': 109,
'buttonPunch': 97,
}.get(name, -1)
if devicename == 'Xbox 360 Wireless Receiver':
return {
'triggerRun2': 23,
'triggerRun1': 24,
'buttonPickUp': 101,
'buttonBomb': 98,
'buttonJump': 97,
'buttonUp': 20,
'buttonLeft': 22,
'buttonRight': 23,
'buttonStart': 83,
'buttonPunch': 100,
'buttonDown': 21,
}.get(name, -1)
if devicename == 'Microsoft X-Box 360 pad':
return {
'triggerRun2': 23,
'triggerRun1': 24,
'buttonPickUp': 101,
'buttonBomb': 98,
'buttonJump': 97,
'buttonStart': 83,
'buttonPunch': 100,
}.get(name, -1)
if devicename in [
'Amazon Remote',
'Amazon Bluetooth Dev',
'Amazon Fire TV Remote',
]:
return {
'triggerRun2': 23,
'triggerRun1': 24,
'buttonPickUp': 24,
'buttonBomb': 91,
'buttonJump': 86,
'buttonUp': 20,
'buttonLeft': 22,
'startButtonActivatesDefaultWidget': False,
'buttonRight': 23,
'buttonStart': 83,
'buttonPunch': 90,
'buttonDown': 21,
}.get(name, -1)
elif 'NVIDIA SHIELD;' in useragentstring: elif 'NVIDIA SHIELD;' in useragentstring:
if 'NVIDIA Controller' in devicename: if 'NVIDIA Controller' in devicename:
return { return {
@ -175,112 +96,6 @@ def get_input_device_mapped_value(
'buttonIgnored': 184, 'buttonIgnored': 184,
'buttonIgnored2': 86, 'buttonIgnored2': 86,
}.get(name, -1) }.get(name, -1)
elif platform == 'mac':
if devicename == 'PLAYSTATION(R)3 Controller':
return {
'buttonLeft': 8,
'buttonUp': 5,
'buttonRight': 6,
'buttonDown': 7,
'buttonJump': 15,
'buttonPunch': 16,
'buttonBomb': 14,
'buttonPickUp': 13,
'buttonStart': 4,
'buttonIgnored': 17,
}.get(name, -1)
if devicename in ['Wireless 360 Controller', 'Controller']:
# Xbox360 gamepads
return {
'analogStickDeadZone': 1.2,
'buttonBomb': 13,
'buttonDown': 2,
'buttonJump': 12,
'buttonLeft': 3,
'buttonPickUp': 15,
'buttonPunch': 14,
'buttonRight': 4,
'buttonStart': 5,
'buttonUp': 1,
'triggerRun1': 5,
'triggerRun2': 6,
'buttonIgnored': 11,
}.get(name, -1)
if devicename in [
'Logitech Dual Action',
'Logitech Cordless RumblePad 2',
]:
return {
'buttonJump': 2,
'buttonPunch': 1,
'buttonBomb': 3,
'buttonPickUp': 4,
'buttonStart': 10,
}.get(name, -1)
# Old gravis gamepad.
if devicename == 'GamePad Pro USB ':
return {
'buttonJump': 2,
'buttonPunch': 1,
'buttonBomb': 3,
'buttonPickUp': 4,
'buttonStart': 10,
}.get(name, -1)
if devicename == 'Microsoft SideWinder Plug & Play Game Pad':
return {
'buttonJump': 1,
'buttonPunch': 3,
'buttonBomb': 2,
'buttonPickUp': 4,
'buttonStart': 6,
}.get(name, -1)
# Saitek P2500 Rumble Force Pad.. (hopefully works for others too?..)
if devicename == 'Saitek P2500 Rumble Force Pad':
return {
'buttonJump': 3,
'buttonPunch': 1,
'buttonBomb': 4,
'buttonPickUp': 2,
'buttonStart': 11,
}.get(name, -1)
# Some crazy 'Senze' dual gamepad.
if devicename == 'Twin USB Joystick':
return {
'analogStickLR': 3,
'analogStickLR_B': 7,
'analogStickUD': 4,
'analogStickUD_B': 8,
'buttonBomb': 2,
'buttonBomb_B': 14,
'buttonJump': 3,
'buttonJump_B': 15,
'buttonPickUp': 1,
'buttonPickUp_B': 13,
'buttonPunch': 4,
'buttonPunch_B': 16,
'buttonRun1': 7,
'buttonRun1_B': 19,
'buttonRun2': 8,
'buttonRun2_B': 20,
'buttonStart': 10,
'buttonStart_B': 22,
'enableSecondary': 1,
'unassignedButtonsRun': False,
}.get(name, -1)
if devicename == 'USB Gamepad ': # some weird 'JITE' gamepad
return {
'analogStickLR': 4,
'analogStickUD': 5,
'buttonJump': 3,
'buttonPunch': 4,
'buttonBomb': 2,
'buttonPickUp': 1,
'buttonStart': 10,
}.get(name, -1)
default_android_mapping = { default_android_mapping = {
'triggerRun2': 19, 'triggerRun2': 19,
@ -303,6 +118,41 @@ def get_input_device_mapped_value(
# Generic android... # Generic android...
if platform == 'android': if platform == 'android':
if devicename in ['Amazon Fire Game Controller']:
return {
'triggerRun2': 23,
'unassignedButtonsRun': False,
'buttonPickUp': 101,
'buttonBomb': 98,
'buttonJump': 97,
'analogStickDeadZone': 0.0,
'startButtonActivatesDefaultWidget': False,
'buttonStart': 83,
'buttonPunch': 100,
'buttonRun2': 103,
'buttonRun1': 104,
'triggerRun1': 24,
}.get(name, -1)
if devicename in [
'Amazon Remote',
'Amazon Bluetooth Dev',
'Amazon Fire TV Remote',
]:
return {
'triggerRun2': 23,
'triggerRun1': 24,
'buttonPickUp': 24,
'buttonBomb': 91,
'buttonJump': 86,
'buttonUp': 20,
'buttonLeft': 22,
'startButtonActivatesDefaultWidget': False,
'buttonRight': 23,
'buttonStart': 83,
'buttonPunch': 90,
'buttonDown': 21,
}.get(name, -1)
# Steelseries stratus xl. # Steelseries stratus xl.
if devicename == 'SteelSeries Stratus XL': if devicename == 'SteelSeries Stratus XL':
return { return {
@ -380,14 +230,6 @@ def get_input_device_mapped_value(
'uiOnly': True, 'uiOnly': True,
}.get(name, -1) }.get(name, -1)
# flag particular gamepads to use exact android defaults..
# (so they don't even ask to configure themselves)
if devicename in [
'Samsung Game Pad EI-GP20',
'ASUS Gamepad',
] or devicename.startswith('Freefly VR Glide'):
return default_android_mapping.get(name, -1)
# Nvidia controller is default, but gets some strange # Nvidia controller is default, but gets some strange
# keypresses we want to ignore.. touching the touchpad, # keypresses we want to ignore.. touching the touchpad,
# so lets ignore those. # so lets ignore those.
@ -445,76 +287,11 @@ def get_input_device_mapped_value(
'buttonRight': 100, 'buttonRight': 100,
}.get(name, -1) }.get(name, -1)
# Ok, this gamepad's not in our specific preset list; # Ok, this gamepad's not in our specific preset list; fall back to
# fall back to some (hopefully) reasonable defaults. # some (hopefully) reasonable defaults.
# Leaving these in here for now but not gonna add any more now that we have
# fancy-pants config sharing across the internet.
if platform == 'mac':
if 'PLAYSTATION' in devicename: # ps3 gamepad?..
return {
'buttonLeft': 8,
'buttonUp': 5,
'buttonRight': 6,
'buttonDown': 7,
'buttonJump': 15,
'buttonPunch': 16,
'buttonBomb': 14,
'buttonPickUp': 13,
'buttonStart': 4,
}.get(name, -1)
# Dual Action Config - hopefully applies to more...
if 'Logitech' in devicename:
return {
'buttonJump': 2,
'buttonPunch': 1,
'buttonBomb': 3,
'buttonPickUp': 4,
'buttonStart': 10,
}.get(name, -1)
# Saitek P2500 Rumble Force Pad.. (hopefully works for others too?..)
if 'Saitek' in devicename:
return {
'buttonJump': 3,
'buttonPunch': 1,
'buttonBomb': 4,
'buttonPickUp': 2,
'buttonStart': 11,
}.get(name, -1)
# Gravis stuff?...
if 'GamePad' in devicename:
return {
'buttonJump': 2,
'buttonPunch': 1,
'buttonBomb': 3,
'buttonPickUp': 4,
'buttonStart': 10,
}.get(name, -1)
# Reasonable defaults. # Reasonable defaults.
if platform == 'android': if platform == 'android':
if babase.is_running_on_fire_tv():
# Mostly same as default firetv controller.
return {
'triggerRun2': 23,
'triggerRun1': 24,
'buttonPickUp': 101,
'buttonBomb': 98,
'buttonJump': 97,
'buttonStart': 83,
'buttonPunch': 100,
'buttonDown': 21,
'buttonUp': 20,
'buttonLeft': 22,
'buttonRight': 23,
'startButtonActivatesDefaultWidget': False,
}.get(name, -1)
# Mostly same as 'Gamepad' except with 'menu' for default start
# button instead of 'mode'.
return default_android_mapping.get(name, -1) return default_android_mapping.get(name, -1)
# Is there a point to any sort of fallbacks here?.. should check. # Is there a point to any sort of fallbacks here?.. should check.
@ -533,9 +310,9 @@ def _gen_android_input_hash() -> str:
md5 = hashlib.md5() md5 = hashlib.md5()
# Currently we just do a single hash of *all* inputs on android # Currently we just do a single hash of *all* inputs on android and
# and that's it.. good enough. # that's it. Good enough. (grabbing mappings for a specific device
# (grabbing mappings for a specific device looks to be non-trivial) # looks to be non-trivial)
for dirname in [ for dirname in [
'/system/usr/keylayout', '/system/usr/keylayout',
'/data/usr/keylayout', '/data/usr/keylayout',
@ -544,9 +321,9 @@ def _gen_android_input_hash() -> str:
try: try:
if os.path.isdir(dirname): if os.path.isdir(dirname):
for f_name in os.listdir(dirname): for f_name in os.listdir(dirname):
# This is usually volume keys and stuff; # This is usually volume keys and stuff; assume we
# assume we can skip it?.. # can skip it?.. (since it'll vary a lot across
# (since it'll vary a lot across devices) # devices)
if f_name == 'gpio-keys.kl': if f_name == 'gpio-keys.kl':
continue continue
try: try:
@ -569,8 +346,8 @@ def get_input_device_map_hash() -> str:
""" """
app = babase.app app = babase.app
# Currently only using this when classic is present. # Currently only using this when classic is present. Need to replace
# Need to replace with a modern equivalent. # with a modern equivalent.
if app.classic is not None: if app.classic is not None:
try: try:
if app.classic.input_map_hash is None: if app.classic.input_map_hash is None:

View file

@ -165,15 +165,16 @@ class MusicSubsystem:
def supports_soundtrack_entry_type(self, entry_type: str) -> bool: def supports_soundtrack_entry_type(self, entry_type: str) -> bool:
"""Return whether provided soundtrack entry type is supported here.""" """Return whether provided soundtrack entry type is supported here."""
uas = babase.env()['legacy_user_agent_string'] # Note to self; can't access babase.app.classic here because
assert isinstance(uas, str) # we are called during its construction.
env = babase.env()
# FIXME: Generalize this. platform = env.get('platform')
assert isinstance(platform, str)
if entry_type == 'iTunesPlaylist': if entry_type == 'iTunesPlaylist':
return 'Mac' in uas return platform == 'mac' and babase.is_xcode_build()
if entry_type in ('musicFile', 'musicFolder'): if entry_type in ('musicFile', 'musicFolder'):
return ( return (
'android' in uas platform == 'android'
and babase.android_get_external_files_dir() is not None and babase.android_get_external_files_dir() is not None
) )
if entry_type == 'default': if entry_type == 'default':
@ -239,7 +240,7 @@ class MusicSubsystem:
logging.exception('Error in get_soundtrack_entry_name.') logging.exception('Error in get_soundtrack_entry_name.')
return 'default' return 'default'
def on_app_resume(self) -> None: def on_app_unsuspend(self) -> None:
"""Should be run when the app resumes from a suspended state.""" """Should be run when the app resumes from a suspended state."""
if babase.is_os_playing_music(): if babase.is_os_playing_music():
self.do_play_music(None) self.do_play_music(None)

View file

@ -423,6 +423,10 @@ class ServerController:
bascenev1.set_public_party_stats_url(self._config.stats_url) bascenev1.set_public_party_stats_url(self._config.stats_url)
bascenev1.set_public_party_enabled(self._config.party_is_public) bascenev1.set_public_party_enabled(self._config.party_is_public)
bascenev1.set_player_rejoin_cooldown(
self._config.player_rejoin_cooldown
)
# And here.. we.. go. # And here.. we.. go.
if self._config.stress_test_players is not None: if self._config.stress_test_players is not None:
# Special case: run a stress test. # Special case: run a stress test.

View file

@ -229,12 +229,12 @@ class ClassicSubsystem(babase.AppSubsystem):
self.accounts.on_app_loading() self.accounts.on_app_loading()
def on_app_pause(self) -> None: def on_app_suspend(self) -> None:
self.accounts.on_app_pause() self.accounts.on_app_suspend()
def on_app_resume(self) -> None: def on_app_unsuspend(self) -> None:
self.accounts.on_app_resume() self.accounts.on_app_unsuspend()
self.music.on_app_resume() self.music.on_app_unsuspend()
def on_app_shutdown(self) -> None: def on_app_shutdown(self) -> None:
self.music.on_app_shutdown() self.music.on_app_shutdown()
@ -451,15 +451,6 @@ class ClassicSubsystem(babase.AppSubsystem):
if playtype in val.get_play_types() if playtype in val.get_play_types()
) )
def show_online_score_ui(
self,
show: str = 'general',
game: str | None = None,
game_version: str | None = None,
) -> None:
"""(internal)"""
bauiv1.show_online_score_ui(show, game, game_version)
def game_begin_analytics(self) -> None: def game_begin_analytics(self) -> None:
"""(internal)""" """(internal)"""
from baclassic import _analytics from baclassic import _analytics
@ -627,15 +618,6 @@ class ClassicSubsystem(babase.AppSubsystem):
"""(internal)""" """(internal)"""
return bascenev1.get_foreground_host_activity() return bascenev1.get_foreground_host_activity()
def show_config_error_window(self) -> bool:
"""(internal)"""
if self.platform in ('mac', 'linux', 'windows'):
from bauiv1lib.configerror import ConfigErrorWindow
babase.pushcall(ConfigErrorWindow)
return True
return False
def value_test( def value_test(
self, self,
arg: str, arg: str,
@ -701,11 +683,11 @@ class ClassicSubsystem(babase.AppSubsystem):
ShowURLWindow(address) ShowURLWindow(address)
def quit_window(self) -> None: def quit_window(self, quit_type: babase.QuitType) -> None:
"""(internal)""" """(internal)"""
from bauiv1lib.confirm import QuitWindow from bauiv1lib.confirm import QuitWindow
QuitWindow() QuitWindow(quit_type)
def tournament_entry_window( def tournament_entry_window(
self, self,
@ -809,5 +791,6 @@ class ClassicSubsystem(babase.AppSubsystem):
bauiv1.getsound('swish').play() bauiv1.getsound('swish').play()
babase.app.ui_v1.set_main_menu_window( babase.app.ui_v1.set_main_menu_window(
MainMenuWindow().get_root_widget() MainMenuWindow().get_root_widget(),
from_window=False, # Disable check here.
) )

View file

@ -80,14 +80,13 @@ class _MacMusicAppThread(threading.Thread):
def run(self) -> None: def run(self) -> None:
"""Run the Music.app thread.""" """Run the Music.app thread."""
babase.set_thread_name('BA_MacMusicAppThread') babase.set_thread_name('BA_MacMusicAppThread')
babase.mac_music_app_init()
# Let's mention to the user we're launching Music.app in case # Let's mention to the user we're launching Music.app in case
# it causes any funny business (this used to background the app # it causes any funny business (this used to background the app
# sometimes, though I think that is fixed now) # sometimes, though I think that is fixed now)
def do_print() -> None: def do_print() -> None:
babase.apptimer( babase.apptimer(
1.0, 0.5,
babase.Call( babase.Call(
babase.screenmessage, babase.screenmessage,
babase.Lstr(resource='usingItunesText'), babase.Lstr(resource='usingItunesText'),
@ -97,9 +96,8 @@ class _MacMusicAppThread(threading.Thread):
babase.pushcall(do_print, from_other_thread=True) babase.pushcall(do_print, from_other_thread=True)
# Here we grab this to force the actual launch. babase.mac_music_app_init()
babase.mac_music_app_get_volume()
babase.mac_music_app_get_library_source()
done = False done = False
while not done: while not done:
self._commands_available.wait() self._commands_available.wait()

View file

@ -5,22 +5,49 @@
from __future__ import annotations from __future__ import annotations
from enum import Enum from enum import Enum
from typing import TYPE_CHECKING from dataclasses import dataclass
from typing import TYPE_CHECKING, Annotated
from efro.dataclassio import ioprepped, IOAttrs
if TYPE_CHECKING: if TYPE_CHECKING:
pass pass
class AppExperience(Enum): class AppInterfaceIdiom(Enum):
"""Overall experience that can be provided by a Ballistica app. """A general form-factor or way of experiencing a Ballistica app.
This corresponds generally, but not exactly, to distinct apps built Note that it is possible for a running app to switch idioms (for
with Ballistica. However, a single app may support multiple experiences, instance if a mobile device or computer is connected to a TV).
or there may be multiple apps targeting one experience. Cloud components
such as leagues are generally associated with an AppExperience.
""" """
# A special experience category that is supported everywhere. Used PHONE = 'phone'
TABLET = 'tablet'
DESKTOP = 'desktop'
TV = 'tv'
XR = 'xr'
class AppExperience(Enum):
"""A particular experience that can be provided by a Ballistica app.
This is one metric used to isolate different playerbases from
eachother where there might be no technical barriers doing so.
For example, a casual one-hand-playable phone game and an augmented
reality tabletop game may both use the same scene-versions and
networking-protocols and whatnot, but it would make no sense to
allow players of one join servers for the other. AppExperience can
be used to keep these player bases separate.
Generally a single Ballistica app targets a single AppExperience.
This is not a technical requirement, however. A single app may
support multiple experiences, or there may be multiple apps
targeting one experience. Cloud components such as leagues are
generally associated with an AppExperience so that they are only
visible to client apps designed for that play style.
"""
# An experience that is supported everywhere. Used
# for the default empty AppMode when starting the app, etc. # for the default empty AppMode when starting the app, etc.
EMPTY = 'empty' EMPTY = 'empty'
@ -33,3 +60,79 @@ class AppExperience(Enum):
# touch-screen allowing a mobile device to be used as a game # touch-screen allowing a mobile device to be used as a game
# controller. # controller.
REMOTE = 'remote' REMOTE = 'remote'
class AppArchitecture(Enum):
"""Processor architecture the App is running on."""
ARM = 'arm'
ARM64 = 'arm64'
X86 = 'x86'
X86_64 = 'x86_64'
class AppPlatform(Enum):
"""Overall platform a Ballistica build can be targeting.
Each distinct flavor of an app has a unique combination
of AppPlatform and AppVariant. Generally platform describes
a set of hardware, while variant describes a destination or
purpose for the build.
"""
MAC = 'mac'
WINDOWS = 'windows'
LINUX = 'linux'
ANDROID = 'android'
IOS = 'ios'
TVOS = 'tvos'
class AppVariant(Enum):
"""A unique Ballistica build type within a single platform.
Each distinct flavor of an app has a unique combination
of AppPlatform and AppVariant. Generally platform describes
a set of hardware, while variant describes a destination or
purpose for the build.
"""
# Default builds.
GENERIC = 'generic'
# Builds intended for public testing (may have some extra checks
# or logging enabled).
TEST = 'test'
# Various stores.
AMAZON_APPSTORE = 'amazon_appstore'
GOOGLE_PLAY = 'google_play'
APP_STORE = 'app_store'
WINDOWS_STORE = 'windows_store'
STEAM = 'steam'
META = 'meta'
EPIC_GAMES_STORE = 'epic_games_store'
# Other.
ARCADE = 'arcade'
DEMO = 'demo'
@ioprepped
@dataclass
class AppInstanceInfo:
"""General info about an individual running app."""
name = Annotated[str, IOAttrs('n')]
version = Annotated[str, IOAttrs('v')]
build = Annotated[int, IOAttrs('b')]
platform = Annotated[AppPlatform, IOAttrs('p')]
variant = Annotated[AppVariant, IOAttrs('va')]
architecture = Annotated[AppArchitecture, IOAttrs('a')]
os_version = Annotated[str | None, IOAttrs('o')]
interface_idiom: Annotated[AppInterfaceIdiom, IOAttrs('i')]
locale: Annotated[str, IOAttrs('l')]
device: Annotated[str | None, IOAttrs('d')]

View file

@ -11,6 +11,12 @@ if TYPE_CHECKING:
pass pass
# NOTE TO SELF:
# Whenever adding login types here, make sure to update all
# basn nodes before trying to send values through to bamaster,
# as they need to be extractable by basn en route.
class LoginType(Enum): class LoginType(Enum):
"""Types of logins available.""" """Types of logins available."""
@ -20,6 +26,9 @@ class LoginType(Enum):
# Google Play Game Services # Google Play Game Services
GPGS = 'gpgs' GPGS = 'gpgs'
# Apple's Game Center
GAME_CENTER = 'game_center'
@property @property
def displayname(self) -> str: def displayname(self) -> str:
"""Human readable name for this value.""" """Human readable name for this value."""
@ -29,3 +38,5 @@ class LoginType(Enum):
return 'Email/Password' return 'Email/Password'
case cls.GPGS: case cls.GPGS:
return 'Google Play Games' return 'Google Play Games'
case cls.GAME_CENTER:
return 'Game Center'

View file

@ -143,9 +143,20 @@ class ServerConfig:
# queue spamming attacks. # queue spamming attacks.
enable_queue: bool = True enable_queue: bool = True
# Protocol version we host with. Currently the default is 33 which
# still allows older 1.4 game clients to connect. Explicitly setting
# to 35 no longer allows those clients but adds/fixes a few things
# such as making camera shake properly work in net games.
protocol_version: int | None = None
# (internal) stress-testing mode. # (internal) stress-testing mode.
stress_test_players: int | None = None stress_test_players: int | None = None
# How many seconds individual players from a given account must wait
# before rejoining the game. This can help suppress exploits
# involving leaving and rejoining or switching teams rapidly.
player_rejoin_cooldown: float = 10.0
# NOTE: as much as possible, communication from the server-manager to the # NOTE: as much as possible, communication from the server-manager to the
# child-process should go through these and not ad-hoc Python string commands # child-process should go through these and not ad-hoc Python string commands

View file

@ -40,7 +40,7 @@ if TYPE_CHECKING:
# the last load. Either way, however, multiple execs will happen in some # the last load. Either way, however, multiple execs will happen in some
# form. # form.
# #
# So we need to do a few things to handle that situation gracefully. # To handle that situation gracefully, we need to do a few things:
# #
# - First, we need to store any mutable global state in the __main__ # - First, we need to store any mutable global state in the __main__
# module; not in ourself. This way, alternate versions of ourself will # module; not in ourself. This way, alternate versions of ourself will
@ -48,12 +48,12 @@ if TYPE_CHECKING:
# #
# - Second, we should avoid the use of isinstance and similar calls for # - Second, we should avoid the use of isinstance and similar calls for
# our types. An EnvConfig we create would technically be a different # our types. An EnvConfig we create would technically be a different
# type than that created by an alternate baenv. # type than an EnvConfig created by an alternate baenv.
# Build number and version of the ballistica binary we expect to be # Build number and version of the ballistica binary we expect to be
# using. # using.
TARGET_BALLISTICA_BUILD = 21397 TARGET_BALLISTICA_BUILD = 21739
TARGET_BALLISTICA_VERSION = '1.7.28' TARGET_BALLISTICA_VERSION = '1.7.32'
@dataclass @dataclass

View file

@ -1,6 +1,6 @@
# Released under the MIT License. See LICENSE for details. # Released under the MIT License. See LICENSE for details.
# #
"""Provides classic app subsystem.""" """Provides plus app subsystem."""
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -249,3 +249,41 @@ class PlusSubsystem(AppSubsystem):
) -> None: ) -> None:
"""(internal)""" """(internal)"""
return _baplus.tournament_query(callback, args) return _baplus.tournament_query(callback, args)
@staticmethod
def have_incentivized_ad() -> bool:
"""Is an incentivized ad available?"""
return _baplus.have_incentivized_ad()
@staticmethod
def has_video_ads() -> bool:
"""Are video ads available?"""
return _baplus.has_video_ads()
@staticmethod
def can_show_ad() -> bool:
"""Can we show an ad?"""
return _baplus.can_show_ad()
@staticmethod
def show_ad(
purpose: str, on_completion_call: Callable[[], None] | None = None
) -> None:
"""Show an ad."""
_baplus.show_ad(purpose, on_completion_call)
@staticmethod
def show_ad_2(
purpose: str, on_completion_call: Callable[[bool], None] | None = None
) -> None:
"""Show an ad."""
_baplus.show_ad_2(purpose, on_completion_call)
@staticmethod
def show_game_service_ui(
show: str = 'general',
game: str | None = None,
game_version: str | None = None,
) -> None:
"""Show game-service provided UI."""
_baplus.show_game_service_ui(show, game, game_version)

View file

@ -78,6 +78,7 @@ from _bascenev1 import (
end_host_scanning, end_host_scanning,
get_chat_messages, get_chat_messages,
get_connection_to_host_info, get_connection_to_host_info,
get_connection_to_host_info_2,
get_foreground_host_activity, get_foreground_host_activity,
get_foreground_host_session, get_foreground_host_session,
get_game_port, get_game_port,
@ -202,6 +203,7 @@ from bascenev1._multiteamsession import (
DEFAULT_TEAM_NAMES, DEFAULT_TEAM_NAMES,
) )
from bascenev1._music import MusicType, setmusic from bascenev1._music import MusicType, setmusic
from bascenev1._net import HostInfo
from bascenev1._nodeactor import NodeActor from bascenev1._nodeactor import NodeActor
from bascenev1._powerup import get_default_powerup_distribution from bascenev1._powerup import get_default_powerup_distribution
from bascenev1._profile import ( from bascenev1._profile import (
@ -226,7 +228,7 @@ from bascenev1._settings import (
IntSetting, IntSetting,
Setting, Setting,
) )
from bascenev1._session import Session from bascenev1._session import Session, set_player_rejoin_cooldown
from bascenev1._stats import PlayerScoredMessage, PlayerRecord, Stats from bascenev1._stats import PlayerScoredMessage, PlayerRecord, Stats
from bascenev1._team import SessionTeam, Team, EmptyTeam from bascenev1._team import SessionTeam, Team, EmptyTeam
from bascenev1._teamgame import TeamGameActivity from bascenev1._teamgame import TeamGameActivity
@ -303,6 +305,7 @@ __all__ = [
'GameTip', 'GameTip',
'get_chat_messages', 'get_chat_messages',
'get_connection_to_host_info', 'get_connection_to_host_info',
'get_connection_to_host_info_2',
'get_default_free_for_all_playlist', 'get_default_free_for_all_playlist',
'get_default_teams_playlist', 'get_default_teams_playlist',
'get_default_powerup_distribution', 'get_default_powerup_distribution',
@ -338,6 +341,7 @@ __all__ = [
'have_connected_clients', 'have_connected_clients',
'have_touchscreen_input', 'have_touchscreen_input',
'HitMessage', 'HitMessage',
'HostInfo',
'host_scan_cycle', 'host_scan_cycle',
'ImpactDamageMessage', 'ImpactDamageMessage',
'increment_analytics_count', 'increment_analytics_count',
@ -415,6 +419,7 @@ __all__ = [
'set_public_party_name', 'set_public_party_name',
'set_public_party_queue_enabled', 'set_public_party_queue_enabled',
'set_public_party_stats_url', 'set_public_party_stats_url',
'set_player_rejoin_cooldown',
'set_replay_speed_exponent', 'set_replay_speed_exponent',
'set_touchscreen_editing', 'set_touchscreen_editing',
'setmusic', 'setmusic',

View file

@ -87,7 +87,9 @@ class Campaign:
def get_selected_level(self) -> str: def get_selected_level(self) -> str:
"""Return the name of the Level currently selected in the UI.""" """Return the name of the Level currently selected in the UI."""
return self.configdict.get('Selection', self._levels[0].name) val = self.configdict.get('Selection', self._levels[0].name)
assert isinstance(val, str)
return val
@property @property
def configdict(self) -> dict[str, Any]: def configdict(self) -> dict[str, Any]:

View file

@ -438,10 +438,16 @@ class GameActivity(Activity[PlayerT, TeamT]):
assert classic is not None assert classic is not None
continues_window = classic.continues_window continues_window = classic.continues_window
# Turning these off. I want to migrate towards monetization that
# feels less pay-to-win-ish.
allow_continues = False
plus = babase.app.plus plus = babase.app.plus
try: try:
if plus is not None and plus.get_v1_account_misc_read_val( if (
'enableContinues', False plus is not None
and plus.get_v1_account_misc_read_val('enableContinues', False)
and allow_continues
): ):
session = self.session session = self.session

View file

@ -105,7 +105,9 @@ class Level:
def complete(self) -> bool: def complete(self) -> bool:
"""Whether this Level has been completed.""" """Whether this Level has been completed."""
config = self._get_config_dict() config = self._get_config_dict()
return config.get('Complete', False) val = config.get('Complete', False)
assert isinstance(val, bool)
return val
def set_complete(self, val: bool) -> None: def set_complete(self, val: bool) -> None:
"""Set whether or not this level is complete.""" """Set whether or not this level is complete."""
@ -147,7 +149,9 @@ class Level:
@property @property
def rating(self) -> float: def rating(self) -> float:
"""The current rating for this Level.""" """The current rating for this Level."""
return self._get_config_dict().get('Rating', 0.0) val = self._get_config_dict().get('Rating', 0.0)
assert isinstance(val, float)
return val
def set_rating(self, rating: float) -> None: def set_rating(self, rating: float) -> None:
"""Set a rating for this Level, replacing the old ONLY IF higher.""" """Set a rating for this Level, replacing the old ONLY IF higher."""

View file

@ -170,8 +170,11 @@ class MultiTeamSession(Session):
def get_max_players(self) -> int: def get_max_players(self) -> int:
"""Return max number of Players allowed to join the game at once.""" """Return max number of Players allowed to join the game at once."""
if self.use_teams: if self.use_teams:
return babase.app.config.get('Team Game Max Players', 8) val = babase.app.config.get('Team Game Max Players', 8)
return babase.app.config.get('Free-for-All Max Players', 8) else:
val = babase.app.config.get('Free-for-All Max Players', 8)
assert isinstance(val, int)
return val
def _instantiate_next_game(self) -> None: def _instantiate_next_game(self) -> None:
self._next_game_instance = _bascenev1.newactivity( self._next_game_instance = _bascenev1.newactivity(

24
dist/ba_data/python/bascenev1/_net.py vendored Normal file
View file

@ -0,0 +1,24 @@
# Released under the MIT License. See LICENSE for details.
#
"""Functionality related to net play."""
from __future__ import annotations
from typing import TYPE_CHECKING
from dataclasses import dataclass
if TYPE_CHECKING:
pass
@dataclass
class HostInfo:
"""Info about a host."""
name: str
build_number: int
# Note this can be None for non-ip hosts such as bluetooth.
address: str | None
# Note this can be None for non-ip hosts such as bluetooth.
port: int | None

View file

@ -3,6 +3,7 @@
"""Defines base session class.""" """Defines base session class."""
from __future__ import annotations from __future__ import annotations
import math
import weakref import weakref
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -17,6 +18,17 @@ if TYPE_CHECKING:
import bascenev1 import bascenev1
# How many seconds someone who left the session (but not the party) must
# wait to rejoin the session again. Intended to prevent game exploits
# such as skipping respawn waits.
_g_player_rejoin_cooldown: float = 0.0
def set_player_rejoin_cooldown(cooldown: float) -> None:
"""Set the cooldown for individual players rejoining after leaving."""
global _g_player_rejoin_cooldown # pylint: disable=global-statement
_g_player_rejoin_cooldown = max(0.0, cooldown)
class Session: class Session:
"""Defines a high level series of bascenev1.Activity-es. """Defines a high level series of bascenev1.Activity-es.
@ -203,6 +215,11 @@ class Session:
# Instantiate our session globals node which will apply its settings. # Instantiate our session globals node which will apply its settings.
self._sessionglobalsnode = _bascenev1.newnode('sessionglobals') self._sessionglobalsnode = _bascenev1.newnode('sessionglobals')
# Rejoin cooldown stuff.
self._players_on_wait: dict = {}
self._player_requested_identifiers: dict = {}
self._waitlist_timers: dict = {}
@property @property
def context(self) -> bascenev1.ContextRef: def context(self) -> bascenev1.ContextRef:
"""A context-ref pointing at this activity.""" """A context-ref pointing at this activity."""
@ -253,6 +270,33 @@ class Session:
) )
return False return False
# Rejoin cooldown.
identifier = player.get_v1_account_id()
if identifier:
leave_time = self._players_on_wait.get(identifier)
if leave_time:
diff = str(
math.ceil(
_g_player_rejoin_cooldown
- babase.apptime()
+ leave_time
)
)
_bascenev1.broadcastmessage(
babase.Lstr(
translate=(
'serverResponses',
'You can join in ${COUNT} seconds.',
),
subs=[('${COUNT}', diff)],
),
color=(1, 1, 0),
clients=[player.inputdevice.client_id],
transient=True,
)
return False
self._player_requested_identifiers[player.id] = identifier
_bascenev1.getsound('dripity').play() _bascenev1.getsound('dripity').play()
return True return True
@ -270,6 +314,16 @@ class Session:
activity = self._activity_weak() activity = self._activity_weak()
# Rejoin cooldown.
identifier = self._player_requested_identifiers.get(sessionplayer.id)
if identifier:
self._players_on_wait[identifier] = babase.apptime()
with babase.ContextRef.empty():
self._waitlist_timers[identifier] = babase.AppTimer(
_g_player_rejoin_cooldown,
babase.Call(self._remove_player_from_waitlist, identifier),
)
if not sessionplayer.in_game: if not sessionplayer.in_game:
# Ok, the player is still in the lobby; simply remove them. # Ok, the player is still in the lobby; simply remove them.
with self.context: with self.context:
@ -770,3 +824,9 @@ class Session:
if pass_to_activity: if pass_to_activity:
activity.add_player(sessionplayer) activity.add_player(sessionplayer)
return sessionplayer return sessionplayer
def _remove_player_from_waitlist(self, identifier: str) -> None:
try:
self._players_on_wait.pop(identifier)
except KeyError:
pass

View file

@ -9,6 +9,7 @@ import random
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from bacommon.login import LoginType
import bascenev1 as bs import bascenev1 as bs
import bauiv1 as bui import bauiv1 as bui
@ -59,29 +60,25 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
) )
) )
self._account_type = (
plus.get_v1_account_type()
if plus.get_v1_account_state() == 'signed_in'
else None
)
self._game_service_icon_color: Sequence[float] | None self._game_service_icon_color: Sequence[float] | None
self._game_service_achievements_texture: bui.Texture | None self._game_service_achievements_texture: bui.Texture | None
self._game_service_leaderboards_texture: bui.Texture | None self._game_service_leaderboards_texture: bui.Texture | None
if self._account_type == 'Game Center': # Tie in to specific game services if they are active.
adapter = plus.accounts.login_adapters.get(LoginType.GPGS)
gpgs_active = adapter is not None and adapter.is_back_end_active()
adapter = plus.accounts.login_adapters.get(LoginType.GAME_CENTER)
game_center_active = (
adapter is not None and adapter.is_back_end_active()
)
if game_center_active:
self._game_service_icon_color = (1.0, 1.0, 1.0) self._game_service_icon_color = (1.0, 1.0, 1.0)
icon = bui.gettexture('gameCenterIcon') icon = bui.gettexture('gameCenterIcon')
self._game_service_achievements_texture = icon self._game_service_achievements_texture = icon
self._game_service_leaderboards_texture = icon self._game_service_leaderboards_texture = icon
self._account_has_achievements = True self._account_has_achievements = True
elif self._account_type == 'Game Circle': elif gpgs_active:
icon = bui.gettexture('gameCircleIcon')
self._game_service_icon_color = (1, 1, 1)
self._game_service_achievements_texture = icon
self._game_service_leaderboards_texture = icon
self._account_has_achievements = True
elif self._account_type == 'Google Play':
self._game_service_icon_color = (0.8, 1.0, 0.6) self._game_service_icon_color = (0.8, 1.0, 0.6)
self._game_service_achievements_texture = bui.gettexture( self._game_service_achievements_texture = bui.gettexture(
'googlePlayAchievementsIcon' 'googlePlayAchievementsIcon'
@ -193,7 +190,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
super().__del__() super().__del__()
# If our UI is still up, kill it. # If our UI is still up, kill it.
if self._root_ui: if self._root_ui and not self._root_ui.transitioning_out:
with bui.ContextRef.empty(): with bui.ContextRef.empty():
bui.containerwidget(edit=self._root_ui, transition='out_left') bui.containerwidget(edit=self._root_ui, transition='out_left')
@ -287,20 +284,20 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
self.end({'outcome': 'next_level'}) self.end({'outcome': 'next_level'})
def _ui_gc(self) -> None: def _ui_gc(self) -> None:
if bs.app.classic is not None: if bs.app.plus is not None:
bs.app.classic.show_online_score_ui( bs.app.plus.show_game_service_ui(
'leaderboard', 'leaderboard',
game=self._game_name_str, game=self._game_name_str,
game_version=self._game_config_str, game_version=self._game_config_str,
) )
else: else:
logging.warning('show_online_score_ui requires classic') logging.warning('show_game_service_ui requires plus feature-set')
def _ui_show_achievements(self) -> None: def _ui_show_achievements(self) -> None:
if bs.app.classic is not None: if bs.app.plus is not None:
bs.app.classic.show_online_score_ui('achievements') bs.app.plus.show_game_service_ui('achievements')
else: else:
logging.warning('show_online_score_ui requires classic') logging.warning('show_game_service_ui requires plus feature-set')
def _ui_worlds_best(self) -> None: def _ui_worlds_best(self) -> None:
if self._score_link is None: if self._score_link is None:

View file

@ -35,7 +35,7 @@ class ControlsGuide(bs.Actor):
delay: is the time in seconds before the overlay fades in. delay: is the time in seconds before the overlay fades in.
lifespan: if not None, the overlay will fade back out and die after lifespan: if not None, the overlay will fade back out and die after
that long (in milliseconds). that long (in seconds).
bright: if True, brighter colors will be used; handy when showing bright: if True, brighter colors will be used; handy when showing
over gameplay but may be too bright for join-screens, etc. over gameplay but may be too bright for join-screens, etc.
@ -50,6 +50,7 @@ class ControlsGuide(bs.Actor):
offs5 = 43.0 * scale offs5 = 43.0 * scale
ouya = False ouya = False
maxw = 50 maxw = 50
xtweak = -2.8 * scale
self._lifespan = lifespan self._lifespan = lifespan
self._dead = False self._dead = False
self._bright = bright self._bright = bright
@ -117,7 +118,7 @@ class ControlsGuide(bs.Actor):
'host_only': True, 'host_only': True,
'shadow': 1.0, 'shadow': 1.0,
'maxwidth': maxw, 'maxwidth': maxw,
'position': (pos[0], pos[1] - offs5), 'position': (pos[0] + xtweak, pos[1] - offs5),
'color': clr, 'color': clr,
}, },
) )
@ -145,7 +146,7 @@ class ControlsGuide(bs.Actor):
'host_only': True, 'host_only': True,
'shadow': 1.0, 'shadow': 1.0,
'maxwidth': maxw, 'maxwidth': maxw,
'position': (pos[0], pos[1] - offs5), 'position': (pos[0] + xtweak, pos[1] - offs5),
'color': clr, 'color': clr,
}, },
) )
@ -173,7 +174,7 @@ class ControlsGuide(bs.Actor):
'host_only': True, 'host_only': True,
'shadow': 1.0, 'shadow': 1.0,
'maxwidth': maxw, 'maxwidth': maxw,
'position': (pos[0], pos[1] - offs5), 'position': (pos[0] + xtweak, pos[1] - offs5),
'color': clr, 'color': clr,
}, },
) )
@ -201,7 +202,7 @@ class ControlsGuide(bs.Actor):
'host_only': True, 'host_only': True,
'shadow': 1.0, 'shadow': 1.0,
'maxwidth': maxw, 'maxwidth': maxw,
'position': (pos[0], pos[1] - offs5), 'position': (pos[0] + xtweak, pos[1] - offs5),
'color': clr, 'color': clr,
}, },
) )
@ -264,10 +265,19 @@ class ControlsGuide(bs.Actor):
bs.timer(delay, bs.WeakCall(self._start_updating)) bs.timer(delay, bs.WeakCall(self._start_updating))
@staticmethod @staticmethod
def _meaningful_button_name(device: bs.InputDevice, button: int) -> str: def _meaningful_button_name(
device: bs.InputDevice, button_name: str
) -> str:
"""Return a flattened string button name; empty for non-meaningful.""" """Return a flattened string button name; empty for non-meaningful."""
if not device.has_meaningful_button_names: if not device.has_meaningful_button_names:
return '' return ''
assert bs.app.classic is not None
button = bs.app.classic.get_input_device_mapped_value(
device, button_name
)
# -1 means unset; let's show that.
if button == -1:
return bs.Lstr(resource='configGamepadWindow.unsetText').evaluate()
return device.get_button_name(button).evaluate() return device.get_button_name(button).evaluate()
def _start_updating(self) -> None: def _start_updating(self) -> None:
@ -289,10 +299,10 @@ class ControlsGuide(bs.Actor):
def _check_fade_in(self) -> None: def _check_fade_in(self) -> None:
assert bs.app.classic is not None assert bs.app.classic is not None
# If we have a touchscreen, we only fade in if we have a player with # If we have a touchscreen, we only fade in if we have a player
# an input device that is *not* the touchscreen. # with an input device that is *not* the touchscreen. Otherwise
# (otherwise it is confusing to see the touchscreen buttons right # it is confusing to see the touchscreen buttons right next to
# next to our display buttons) # our display buttons.
touchscreen: bs.InputDevice | None = bs.getinputdevice( touchscreen: bs.InputDevice | None = bs.getinputdevice(
'TouchScreen', '#1', doraise=False 'TouchScreen', '#1', doraise=False
) )
@ -318,15 +328,7 @@ class ControlsGuide(bs.Actor):
'buttonBomb', 'buttonBomb',
'buttonPickUp', 'buttonPickUp',
): ):
if ( if self._meaningful_button_name(device, name) != '':
self._meaningful_button_name(
device,
bs.app.classic.get_input_device_mapped_value(
device, name
),
)
!= ''
):
fade_in = True fade_in = True
break break
if fade_in: if fade_in:
@ -401,58 +403,30 @@ class ControlsGuide(bs.Actor):
# We only care about movement buttons in the case of keyboards. # We only care about movement buttons in the case of keyboards.
if all_keyboards: if all_keyboards:
right_button_names.add( right_button_names.add(
device.get_button_name( self._meaningful_button_name(device, 'buttonRight')
classic.get_input_device_mapped_value(
device, 'buttonRight'
)
)
) )
left_button_names.add( left_button_names.add(
device.get_button_name( self._meaningful_button_name(device, 'buttonLeft')
classic.get_input_device_mapped_value(
device, 'buttonLeft'
)
)
) )
down_button_names.add( down_button_names.add(
device.get_button_name( self._meaningful_button_name(device, 'buttonDown')
classic.get_input_device_mapped_value(
device, 'buttonDown'
)
)
) )
up_button_names.add( up_button_names.add(
device.get_button_name( self._meaningful_button_name(device, 'buttonUp')
classic.get_input_device_mapped_value(
device, 'buttonUp'
)
)
) )
# Ignore empty values; things like the remote app or # Ignore empty values; things like the remote app or
# wiimotes can return these. # wiimotes can return these.
bname = self._meaningful_button_name( bname = self._meaningful_button_name(device, 'buttonPunch')
device,
classic.get_input_device_mapped_value(device, 'buttonPunch'),
)
if bname != '': if bname != '':
punch_button_names.add(bname) punch_button_names.add(bname)
bname = self._meaningful_button_name( bname = self._meaningful_button_name(device, 'buttonJump')
device,
classic.get_input_device_mapped_value(device, 'buttonJump'),
)
if bname != '': if bname != '':
jump_button_names.add(bname) jump_button_names.add(bname)
bname = self._meaningful_button_name( bname = self._meaningful_button_name(device, 'buttonBomb')
device,
classic.get_input_device_mapped_value(device, 'buttonBomb'),
)
if bname != '': if bname != '':
bomb_button_names.add(bname) bomb_button_names.add(bname)
bname = self._meaningful_button_name( bname = self._meaningful_button_name(device, 'buttonPickUp')
device,
classic.get_input_device_mapped_value(device, 'buttonPickUp'),
)
if bname != '': if bname != '':
pickup_button_names.add(bname) pickup_button_names.add(bname)
@ -582,8 +556,8 @@ class ControlsGuide(bs.Actor):
if msg.immediate: if msg.immediate:
self._die() self._die()
else: else:
# If they don't need immediate, # If they don't need immediate, fade out our nodes and
# fade out our nodes and die later. # die later.
for node in self._nodes: for node in self._nodes:
bs.animate(node, 'opacity', {0: node.opacity, 3.0: 0.0}) bs.animate(node, 'opacity', {0: node.opacity, 3.0: 0.0})
bs.timer(3.1, bs.WeakCall(self._die)) bs.timer(3.1, bs.WeakCall(self._die))

View file

@ -41,17 +41,17 @@ class Spawner:
self, self,
spawner: Spawner, spawner: Spawner,
data: Any, data: Any,
pt: Sequence[float], # pylint: disable=invalid-name pt: Sequence[float],
): ):
"""Instantiate with the given values.""" """Instantiate with the given values."""
self.spawner = spawner self.spawner = spawner
self.data = data self.data = data
self.pt = pt # pylint: disable=invalid-name self.pt = pt
def __init__( def __init__(
self, self,
data: Any = None, data: Any = None,
pt: Sequence[float] = (0, 0, 0), # pylint: disable=invalid-name pt: Sequence[float] = (0, 0, 0),
spawn_time: float = 1.0, spawn_time: float = 1.0,
send_spawn_message: bool = True, send_spawn_message: bool = True,
spawn_callback: Callable[[], Any] | None = None, spawn_callback: Callable[[], Any] | None = None,

View file

@ -624,7 +624,7 @@ class Spaz(bs.Actor):
1000.0 * (tval + self.curse_time) 1000.0 * (tval + self.curse_time)
) )
self._curse_timer = bs.Timer( self._curse_timer = bs.Timer(
5.0, bs.WeakCall(self.curse_explode) 5.0, bs.WeakCall(self.handlemessage, CurseExplodeMessage())
) )
def equip_boxing_gloves(self) -> None: def equip_boxing_gloves(self) -> None:
@ -1136,7 +1136,7 @@ class Spaz(bs.Actor):
if self.hitpoints > 0: if self.hitpoints > 0:
# It's kinda crappy to die from impacts, so lets reduce # It's kinda crappy to die from impacts, so lets reduce
# impact damage by a reasonable amount *if* it'll keep us alive. # impact damage by a reasonable amount *if* it'll keep us alive.
if msg.hit_type == 'impact' and damage > self.hitpoints: if msg.hit_type == 'impact' and damage >= self.hitpoints:
# Drop damage to whatever puts us at 10 hit points, # Drop damage to whatever puts us at 10 hit points,
# or 200 less than it used to be whichever is greater # or 200 less than it used to be whichever is greater
# (so it *can* still kill us if its high enough). # (so it *can* still kill us if its high enough).

View file

@ -122,7 +122,6 @@ def register_appearances() -> None:
"""Register our builtin spaz appearances.""" """Register our builtin spaz appearances."""
# This is quite ugly but will be going away so not worth cleaning up. # This is quite ugly but will be going away so not worth cleaning up.
# pylint: disable=invalid-name
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
# pylint: disable=too-many-statements # pylint: disable=too-many-statements

View file

@ -14,13 +14,12 @@ from bascenev1lib.actor.flag import Flag
from bascenev1lib.actor.scoreboard import Scoreboard from bascenev1lib.actor.scoreboard import Scoreboard
from bascenev1lib.actor.playerspaz import PlayerSpaz from bascenev1lib.actor.playerspaz import PlayerSpaz
from bascenev1lib.gameutils import SharedObjects from bascenev1lib.gameutils import SharedObjects
from bascenev1lib.actor.respawnicon import RespawnIcon
import bascenev1 as bs import bascenev1 as bs
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any, Sequence from typing import Any, Sequence
from bascenev1lib.actor.respawnicon import RespawnIcon
class ConquestFlag(Flag): class ConquestFlag(Flag):
"""A custom flag for use with Conquest games.""" """A custom flag for use with Conquest games."""
@ -49,7 +48,9 @@ class Player(bs.Player['Team']):
@property @property
def respawn_timer(self) -> bs.Timer | None: def respawn_timer(self) -> bs.Timer | None:
"""Type safe access to standard respawn timer.""" """Type safe access to standard respawn timer."""
return self.customdata.get('respawn_timer', None) val = self.customdata.get('respawn_timer', None)
assert isinstance(val, (bs.Timer, type(None)))
return val
@respawn_timer.setter @respawn_timer.setter
def respawn_timer(self, value: bs.Timer | None) -> None: def respawn_timer(self, value: bs.Timer | None) -> None:
@ -58,7 +59,9 @@ class Player(bs.Player['Team']):
@property @property
def respawn_icon(self) -> RespawnIcon | None: def respawn_icon(self) -> RespawnIcon | None:
"""Type safe access to standard respawn icon.""" """Type safe access to standard respawn icon."""
return self.customdata.get('respawn_icon', None) val = self.customdata.get('respawn_icon', None)
assert isinstance(val, (RespawnIcon, type(None)))
return val
@respawn_icon.setter @respawn_icon.setter
def respawn_icon(self, value: RespawnIcon | None) -> None: def respawn_icon(self, value: RespawnIcon | None) -> None:

View file

@ -300,7 +300,10 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
from bauiv1lib import specialoffer from bauiv1lib import specialoffer
assert bs.app.classic is not None assert bs.app.classic is not None
if bool(False): if bui.app.env.headless:
# UI stuff fails now in headless builds; avoid it.
pass
elif bool(False):
uicontroller = bs.app.ui_v1.controller uicontroller = bs.app.ui_v1.controller
assert uicontroller is not None assert uicontroller is not None
uicontroller.show_main_menu() uicontroller.show_main_menu()
@ -314,7 +317,8 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
from bauiv1lib.kiosk import KioskWindow from bauiv1lib.kiosk import KioskWindow
bs.app.ui_v1.set_main_menu_window( bs.app.ui_v1.set_main_menu_window(
KioskWindow().get_root_widget() KioskWindow().get_root_widget(),
from_window=False, # Disable check here.
) )
# ..or in normal cases go back to the main menu # ..or in normal cases go back to the main menu
else: else:
@ -323,14 +327,16 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
from bauiv1lib.gather import GatherWindow from bauiv1lib.gather import GatherWindow
bs.app.ui_v1.set_main_menu_window( bs.app.ui_v1.set_main_menu_window(
GatherWindow(transition=None).get_root_widget() GatherWindow(transition=None).get_root_widget(),
from_window=False, # Disable check here.
) )
elif main_menu_location == 'Watch': elif main_menu_location == 'Watch':
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.watch import WatchWindow from bauiv1lib.watch import WatchWindow
bs.app.ui_v1.set_main_menu_window( bs.app.ui_v1.set_main_menu_window(
WatchWindow(transition=None).get_root_widget() WatchWindow(transition=None).get_root_widget(),
from_window=False, # Disable check here.
) )
elif main_menu_location == 'Team Game Select': elif main_menu_location == 'Team Game Select':
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
@ -341,7 +347,8 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
bs.app.ui_v1.set_main_menu_window( bs.app.ui_v1.set_main_menu_window(
PlaylistBrowserWindow( PlaylistBrowserWindow(
sessiontype=bs.DualTeamSession, transition=None sessiontype=bs.DualTeamSession, transition=None
).get_root_widget() ).get_root_widget(),
from_window=False, # Disable check here.
) )
elif main_menu_location == 'Free-for-All Game Select': elif main_menu_location == 'Free-for-All Game Select':
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
@ -353,28 +360,34 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
PlaylistBrowserWindow( PlaylistBrowserWindow(
sessiontype=bs.FreeForAllSession, sessiontype=bs.FreeForAllSession,
transition=None, transition=None,
).get_root_widget() ).get_root_widget(),
from_window=False, # Disable check here.
) )
elif main_menu_location == 'Coop Select': elif main_menu_location == 'Coop Select':
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.coop.browser import CoopBrowserWindow from bauiv1lib.coop.browser import CoopBrowserWindow
bs.app.ui_v1.set_main_menu_window( bs.app.ui_v1.set_main_menu_window(
CoopBrowserWindow(transition=None).get_root_widget() CoopBrowserWindow(
transition=None
).get_root_widget(),
from_window=False, # Disable check here.
) )
elif main_menu_location == 'Benchmarks & Stress Tests': elif main_menu_location == 'Benchmarks & Stress Tests':
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.debug import DebugWindow from bauiv1lib.debug import DebugWindow
bs.app.ui_v1.set_main_menu_window( bs.app.ui_v1.set_main_menu_window(
DebugWindow(transition=None).get_root_widget() DebugWindow(transition=None).get_root_widget(),
from_window=False, # Disable check here.
) )
else: else:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.mainmenu import MainMenuWindow from bauiv1lib.mainmenu import MainMenuWindow
bs.app.ui_v1.set_main_menu_window( bs.app.ui_v1.set_main_menu_window(
MainMenuWindow(transition=None).get_root_widget() MainMenuWindow(transition=None).get_root_widget(),
from_window=None,
) )
# attempt to show any pending offers immediately. # attempt to show any pending offers immediately.

View file

@ -8,7 +8,6 @@
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
# pylint: disable=too-many-lines # pylint: disable=too-many-lines
# pylint: disable=missing-function-docstring, missing-class-docstring # pylint: disable=missing-function-docstring, missing-class-docstring
# pylint: disable=invalid-name
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
# pylint: disable=unused-argument # pylint: disable=unused-argument
# pylint: disable=unused-variable # pylint: disable=unused-variable

View file

@ -31,7 +31,10 @@ from babase import (
apptimer, apptimer,
AppTimer, AppTimer,
Call, Call,
can_toggle_fullscreen, fullscreen_control_available,
fullscreen_control_get,
fullscreen_control_key_shortcut,
fullscreen_control_set,
charstr, charstr,
clipboard_is_supported, clipboard_is_supported,
clipboard_set_text, clipboard_set_text,
@ -57,18 +60,21 @@ from babase import (
in_logic_thread, in_logic_thread,
increment_analytics_count, increment_analytics_count,
is_browser_likely_available, is_browser_likely_available,
is_running_on_fire_tv,
is_xcode_build, is_xcode_build,
Keyboard,
lock_all_input, lock_all_input,
LoginAdapter, LoginAdapter,
LoginInfo,
Lstr, Lstr,
native_review_request,
native_review_request_supported,
NotFoundError, NotFoundError,
open_file_externally,
Permission, Permission,
Plugin, Plugin,
PluginSpec, PluginSpec,
pushcall, pushcall,
quit, quit,
QuitType,
request_permission, request_permission,
safecolor, safecolor,
screenmessage, screenmessage,
@ -87,7 +93,6 @@ from babase import (
from _bauiv1 import ( from _bauiv1 import (
buttonwidget, buttonwidget,
can_show_ad,
checkboxwidget, checkboxwidget,
columnwidget, columnwidget,
containerwidget, containerwidget,
@ -96,21 +101,15 @@ from _bauiv1 import (
getmesh, getmesh,
getsound, getsound,
gettexture, gettexture,
has_video_ads,
have_incentivized_ad,
hscrollwidget, hscrollwidget,
imagewidget, imagewidget,
is_party_icon_visible, is_party_icon_visible,
Mesh, Mesh,
open_file_externally,
open_url, open_url,
rowwidget, rowwidget,
scrollwidget, scrollwidget,
set_party_icon_always_visible, set_party_icon_always_visible,
set_party_window_open, set_party_window_open,
show_ad,
show_ad_2,
show_online_score_ui,
Sound, Sound,
Texture, Texture,
textwidget, textwidget,
@ -118,6 +117,7 @@ from _bauiv1 import (
Widget, Widget,
widget, widget,
) )
from bauiv1._keyboard import Keyboard
from bauiv1._uitypes import Window, uicleanupcheck from bauiv1._uitypes import Window, uicleanupcheck
from bauiv1._subsystem import UIV1Subsystem from bauiv1._subsystem import UIV1Subsystem
@ -137,8 +137,10 @@ __all__ = [
'AppTimer', 'AppTimer',
'buttonwidget', 'buttonwidget',
'Call', 'Call',
'can_show_ad', 'fullscreen_control_available',
'can_toggle_fullscreen', 'fullscreen_control_get',
'fullscreen_control_key_shortcut',
'fullscreen_control_set',
'charstr', 'charstr',
'checkboxwidget', 'checkboxwidget',
'clipboard_is_supported', 'clipboard_is_supported',
@ -168,8 +170,6 @@ __all__ = [
'getmesh', 'getmesh',
'getsound', 'getsound',
'gettexture', 'gettexture',
'has_video_ads',
'have_incentivized_ad',
'have_permission', 'have_permission',
'hscrollwidget', 'hscrollwidget',
'imagewidget', 'imagewidget',
@ -177,13 +177,15 @@ __all__ = [
'increment_analytics_count', 'increment_analytics_count',
'is_browser_likely_available', 'is_browser_likely_available',
'is_party_icon_visible', 'is_party_icon_visible',
'is_running_on_fire_tv',
'is_xcode_build', 'is_xcode_build',
'Keyboard', 'Keyboard',
'lock_all_input', 'lock_all_input',
'LoginAdapter', 'LoginAdapter',
'LoginInfo',
'Lstr', 'Lstr',
'Mesh', 'Mesh',
'native_review_request',
'native_review_request_supported',
'NotFoundError', 'NotFoundError',
'open_file_externally', 'open_file_externally',
'open_url', 'open_url',
@ -192,6 +194,7 @@ __all__ = [
'PluginSpec', 'PluginSpec',
'pushcall', 'pushcall',
'quit', 'quit',
'QuitType',
'request_permission', 'request_permission',
'rowwidget', 'rowwidget',
'safecolor', 'safecolor',
@ -202,9 +205,6 @@ __all__ = [
'set_party_icon_always_visible', 'set_party_icon_always_visible',
'set_party_window_open', 'set_party_window_open',
'set_ui_input_device', 'set_ui_input_device',
'show_ad',
'show_ad_2',
'show_online_score_ui',
'Sound', 'Sound',
'SpecialChar', 'SpecialChar',
'supports_max_fps', 'supports_max_fps',

View file

@ -6,6 +6,7 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
import inspect
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _bauiv1 import _bauiv1
@ -13,6 +14,8 @@ import _bauiv1
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Sequence from typing import Sequence
import babase
def ticket_icon_press() -> None: def ticket_icon_press() -> None:
from babase import app from babase import app
@ -57,14 +60,14 @@ def party_icon_activate(origin: Sequence[float]) -> None:
logging.warning('party_icon_activate: no classic.') logging.warning('party_icon_activate: no classic.')
def quit_window() -> None: def quit_window(quit_type: babase.QuitType) -> None:
from babase import app from babase import app
if app.classic is None: if app.classic is None:
logging.exception('Classic not present.') logging.exception('Classic not present.')
return return
app.classic.quit_window() app.classic.quit_window(quit_type)
def device_menu_press(device_id: int | None) -> None: def device_menu_press(device_id: int | None) -> None:
@ -85,3 +88,19 @@ def show_url_window(address: str) -> None:
return return
app.classic.show_url_window(address) app.classic.show_url_window(address)
def double_transition_out_warning() -> None:
"""Called if a widget is set to transition out twice."""
caller_frame = inspect.stack()[1]
caller_filename = caller_frame.filename
caller_line_number = caller_frame.lineno
logging.warning(
'ContainerWidget was set to transition out twice;'
' this often implies buggy code (%s line %s).\n'
' Generally you should check the value of'
' _root_widget.transitioning_out and perform no actions if that'
' is True.',
caller_filename,
caller_line_number,
)

33
dist/ba_data/python/bauiv1/_keyboard.py vendored Normal file
View file

@ -0,0 +1,33 @@
# Released under the MIT License. See LICENSE for details.
#
"""On-screen Keyboard related functionality."""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
pass
class Keyboard:
"""Chars definitions for on-screen keyboard.
Category: **App Classes**
Keyboards are discoverable by the meta-tag system
and the user can select which one they want to use.
On-screen keyboard uses chars from active babase.Keyboard.
"""
name: str
"""Displays when user selecting this keyboard."""
chars: list[tuple[str, ...]]
"""Used for row/column lengths."""
pages: dict[str, tuple[str, ...]]
"""Extra chars like emojis."""
nums: tuple[str, ...]
"""The 'num' page."""

View file

@ -5,6 +5,7 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
import inspect
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import babase import babase
@ -66,6 +67,16 @@ class UIV1Subsystem(babase.AppSubsystem):
# a more elegant way once we revamp high level UI stuff a bit. # a more elegant way once we revamp high level UI stuff a bit.
self.selecting_private_party_playlist: bool = False self.selecting_private_party_playlist: bool = False
@property
def available(self) -> bool:
"""Can uiv1 currently be used?
Code that may run in headless mode, before the UI has been spun up,
while other ui systems are active, etc. can check this to avoid
likely erroring.
"""
return _bauiv1.is_available()
@property @property
def uiscale(self) -> babase.UIScale: def uiscale(self) -> babase.UIScale:
"""Current ui scale for the app.""" """Current ui scale for the app."""
@ -106,21 +117,69 @@ class UIV1Subsystem(babase.AppSubsystem):
# FIXME: Can probably kill this if we do immediate UI death checks. # FIXME: Can probably kill this if we do immediate UI death checks.
self.upkeeptimer = babase.AppTimer(2.6543, ui_upkeep, repeat=True) self.upkeeptimer = babase.AppTimer(2.6543, ui_upkeep, repeat=True)
def set_main_menu_window(self, window: bauiv1.Widget) -> None: def set_main_menu_window(
"""Set the current 'main' window, replacing any existing.""" self,
window: bauiv1.Widget,
from_window: bauiv1.Widget | None | bool = True,
) -> None:
"""Set the current 'main' window, replacing any existing.
If 'from_window' is passed as a bauiv1.Widget or None, a warning
will be issued if it that value does not match the current main
window. This can help clean up flawed code that can lead to bad
UI states. A value of False will disable the check.
"""
existing = self._main_menu_window existing = self._main_menu_window
from inspect import currentframe, getframeinfo
try:
if isinstance(from_window, bool):
# For default val True we warn that the arg wasn't
# passed. False can be explicitly passed to disable this
# check.
if from_window is True:
caller_frame = inspect.stack()[1]
caller_filename = caller_frame.filename
caller_line_number = caller_frame.lineno
logging.warning(
'set_main_menu_window() should be passed a'
" 'from_window' value to help ensure proper UI behavior"
' (%s line %i).',
caller_filename,
caller_line_number,
)
else:
# For everything else, warn if what they passed wasn't
# the previous main menu widget.
if from_window is not existing:
caller_frame = inspect.stack()[1]
caller_filename = caller_frame.filename
caller_line_number = caller_frame.lineno
logging.warning(
"set_main_menu_window() was passed 'from_window' %s"
' but existing main-menu-window is %s. (%s line %i).',
from_window,
existing,
caller_filename,
caller_line_number,
)
except Exception:
# Prevent any bugs in these checks from causing problems.
logging.exception('Error checking from_window')
# Once the above code leads to us fixing all leftover window bugs
# at the source, we can kill the code below.
# Let's grab the location where we were called from to report # Let's grab the location where we were called from to report
# if we have to force-kill the existing window (which normally # if we have to force-kill the existing window (which normally
# should not happen). # should not happen).
frameline = None frameline = None
try: try:
frame = currentframe() frame = inspect.currentframe()
if frame is not None: if frame is not None:
frame = frame.f_back frame = frame.f_back
if frame is not None: if frame is not None:
frameinfo = getframeinfo(frame) frameinfo = inspect.getframeinfo(frame)
frameline = f'{frameinfo.filename} {frameinfo.lineno}' frameline = f'{frameinfo.filename} {frameinfo.lineno}'
except Exception: except Exception:
logging.exception('Error calcing line for set_main_menu_window') logging.exception('Error calcing line for set_main_menu_window')
@ -150,13 +209,18 @@ class UIV1Subsystem(babase.AppSubsystem):
def clear_main_menu_window(self, transition: str | None = None) -> None: def clear_main_menu_window(self, transition: str | None = None) -> None:
"""Clear any existing 'main' window with the provided transition.""" """Clear any existing 'main' window with the provided transition."""
assert transition is None or not transition.endswith('_in')
if self._main_menu_window: if self._main_menu_window:
if transition is not None: if (
transition is not None
and not self._main_menu_window.transitioning_out
):
_bauiv1.containerwidget( _bauiv1.containerwidget(
edit=self._main_menu_window, transition=transition edit=self._main_menu_window, transition=transition
) )
else: else:
self._main_menu_window.delete() self._main_menu_window.delete()
self._main_menu_window = None
def add_main_menu_close_callback(self, call: Callable[[], Any]) -> None: def add_main_menu_close_callback(self, call: Callable[[], Any]) -> None:
"""(internal)""" """(internal)"""

View file

@ -12,6 +12,7 @@ from typing import TYPE_CHECKING
import babase import babase
import _bauiv1 import _bauiv1
from bauiv1._keyboard import Keyboard
from bauiv1._uitypes import Window from bauiv1._uitypes import Window
if TYPE_CHECKING: if TYPE_CHECKING:
@ -51,6 +52,19 @@ class OnScreenKeyboardWindow(Window):
else (0, 0), else (0, 0),
) )
) )
self._cancel_button = _bauiv1.buttonwidget(
parent=self._root_widget,
scale=0.5,
position=(30, self._height - 55),
size=(60, 60),
label='',
enable_sound=False,
on_activate_call=self._cancel,
autoselect=True,
color=(0.55, 0.5, 0.6),
icon=_bauiv1.gettexture('crossOut'),
iconscale=1.2,
)
self._done_button = _bauiv1.buttonwidget( self._done_button = _bauiv1.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
position=(self._width - 200, 44), position=(self._width - 200, 44),
@ -240,9 +254,7 @@ class OnScreenKeyboardWindow(Window):
# Show change instructions only if we have more than one # Show change instructions only if we have more than one
# keyboard option. # keyboard option.
keyboards = ( keyboards = (
babase.app.meta.scanresults.exports_of_class( babase.app.meta.scanresults.exports_of_class(Keyboard)
babase.Keyboard
)
if babase.app.meta.scanresults is not None if babase.app.meta.scanresults is not None
else [] else []
) )
@ -274,10 +286,10 @@ class OnScreenKeyboardWindow(Window):
def _get_keyboard(self) -> bui.Keyboard: def _get_keyboard(self) -> bui.Keyboard:
assert babase.app.meta.scanresults is not None assert babase.app.meta.scanresults is not None
classname = babase.app.meta.scanresults.exports_of_class( classname = babase.app.meta.scanresults.exports_of_class(Keyboard)[
babase.Keyboard self._keyboard_index
)[self._keyboard_index] ]
kbclass = babase.getclass(classname, babase.Keyboard) kbclass = babase.getclass(classname, Keyboard)
return kbclass() return kbclass()
def _refresh(self) -> None: def _refresh(self) -> None:
@ -372,9 +384,7 @@ class OnScreenKeyboardWindow(Window):
def _next_keyboard(self) -> None: def _next_keyboard(self) -> None:
assert babase.app.meta.scanresults is not None assert babase.app.meta.scanresults is not None
kbexports = babase.app.meta.scanresults.exports_of_class( kbexports = babase.app.meta.scanresults.exports_of_class(Keyboard)
babase.Keyboard
)
self._keyboard_index = (self._keyboard_index + 1) % len(kbexports) self._keyboard_index = (self._keyboard_index + 1) % len(kbexports)
self._load_keyboard() self._load_keyboard()

View file

@ -63,20 +63,14 @@ class AccountSettingsWindow(bui.Window):
1.0, bui.WeakCall(self._update), repeat=True 1.0, bui.WeakCall(self._update), repeat=True
) )
# Currently we can only reset achievements on game-center. self._can_reset_achievements = False
v1_account_type: str | None
if self._v1_signed_in:
v1_account_type = plus.get_v1_account_type()
else:
v1_account_type = None
self._can_reset_achievements = v1_account_type == 'Game Center'
app = bui.app app = bui.app
assert app.classic is not None assert app.classic is not None
uiscale = app.ui_v1.uiscale uiscale = app.ui_v1.uiscale
self._width = 760 if uiscale is bui.UIScale.SMALL else 660 self._width = 860 if uiscale is bui.UIScale.SMALL else 660
x_offs = 50 if uiscale is bui.UIScale.SMALL else 0 x_offs = 100 if uiscale is bui.UIScale.SMALL else 0
self._height = ( self._height = (
390 390
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
@ -98,6 +92,9 @@ class AccountSettingsWindow(bui.Window):
if LoginType.GPGS in plus.accounts.login_adapters: if LoginType.GPGS in plus.accounts.login_adapters:
self._show_sign_in_buttons.append('Google Play') self._show_sign_in_buttons.append('Google Play')
if LoginType.GAME_CENTER in plus.accounts.login_adapters:
self._show_sign_in_buttons.append('Game Center')
# Always want to show our web-based v2 login option. # Always want to show our web-based v2 login option.
self._show_sign_in_buttons.append('V2Proxy') self._show_sign_in_buttons.append('V2Proxy')
@ -227,6 +224,8 @@ class AccountSettingsWindow(bui.Window):
plus = bui.app.plus plus = bui.app.plus
assert plus is not None assert plus is not None
via_lines: list[str] = []
primary_v2_account = plus.accounts.primary primary_v2_account = plus.accounts.primary
v1_state = plus.get_v1_account_state() v1_state = plus.get_v1_account_state()
@ -237,14 +236,55 @@ class AccountSettingsWindow(bui.Window):
# We expose GPGS-specific functionality only if it is 'active' # We expose GPGS-specific functionality only if it is 'active'
# (meaning the current GPGS player matches one of our account's # (meaning the current GPGS player matches one of our account's
# logins). # logins).
gpgs_adapter = plus.accounts.login_adapters.get(LoginType.GPGS) adapter = plus.accounts.login_adapters.get(LoginType.GPGS)
is_gpgs = ( gpgs_active = adapter is not None and adapter.is_back_end_active()
False if gpgs_adapter is None else gpgs_adapter.is_back_end_active()
# Ditto for Game Center.
adapter = plus.accounts.login_adapters.get(LoginType.GAME_CENTER)
game_center_active = (
adapter is not None and adapter.is_back_end_active()
) )
show_signed_in_as = self._v1_signed_in show_signed_in_as = self._v1_signed_in
signed_in_as_space = 95.0 signed_in_as_space = 95.0
# To reduce confusion about the whole V2 account situation for
# people used to seeing their Google Play Games or Game Center
# account name and icon and whatnot, let's show those underneath
# the V2 tag to help communicate that they are in fact logged in
# through that account.
via_space = 25.0
if show_signed_in_as and bui.app.plus is not None:
accounts = bui.app.plus.accounts
if accounts.primary is not None:
# For these login types, we show 'via' IF there is a
# login of that type attached to our account AND it is
# currently active (We don't want to show 'via Game
# Center' if we're signed out of Game Center or
# currently running on Steam, even if there is a Game
# Center login attached to our account).
for ltype, lchar in [
(LoginType.GPGS, bui.SpecialChar.GOOGLE_PLAY_GAMES_LOGO),
(LoginType.GAME_CENTER, bui.SpecialChar.GAME_CENTER_LOGO),
]:
linfo = accounts.primary.logins.get(ltype)
ladapter = accounts.login_adapters.get(ltype)
if (
linfo is not None
and ladapter is not None
and ladapter.is_back_end_active()
):
via_lines.append(f'{bui.charstr(lchar)}{linfo.name}')
# TEMP TESTING
if bool(False):
icontxt = bui.charstr(bui.SpecialChar.GAME_CENTER_LOGO)
via_lines.append(f'{icontxt}FloofDibble')
icontxt = bui.charstr(
bui.SpecialChar.GOOGLE_PLAY_GAMES_LOGO
)
via_lines.append(f'{icontxt}StinkBobble')
show_sign_in_benefits = not self._v1_signed_in show_sign_in_benefits = not self._v1_signed_in
sign_in_benefits_space = 80.0 sign_in_benefits_space = 80.0
@ -258,6 +298,11 @@ class AccountSettingsWindow(bui.Window):
and self._signing_in_adapter is None and self._signing_in_adapter is None
and 'Google Play' in self._show_sign_in_buttons and 'Google Play' in self._show_sign_in_buttons
) )
show_game_center_sign_in_button = (
v1_state == 'signed_out'
and self._signing_in_adapter is None
and 'Game Center' in self._show_sign_in_buttons
)
show_v2_proxy_sign_in_button = ( show_v2_proxy_sign_in_button = (
v1_state == 'signed_out' v1_state == 'signed_out'
and self._signing_in_adapter is None and self._signing_in_adapter is None
@ -271,9 +316,8 @@ class AccountSettingsWindow(bui.Window):
sign_in_button_space = 70.0 sign_in_button_space = 70.0
deprecated_space = 60 deprecated_space = 60
show_game_service_button = self._v1_signed_in and v1_account_type in [ # Game Center currently has a single UI for everything.
'Game Center' show_game_service_button = game_center_active
]
game_service_button_space = 60.0 game_service_button_space = 60.0
show_what_is_v2 = self._v1_signed_in and v1_account_type == 'V2' show_what_is_v2 = self._v1_signed_in and v1_account_type == 'V2'
@ -281,11 +325,9 @@ class AccountSettingsWindow(bui.Window):
show_linked_accounts_text = self._v1_signed_in show_linked_accounts_text = self._v1_signed_in
linked_accounts_text_space = 60.0 linked_accounts_text_space = 60.0
show_achievements_button = self._v1_signed_in and v1_account_type in ( # Always show achievements except in the game-center case where
'Google Play', # its unified UI covers them.
'Local', show_achievements_button = self._v1_signed_in and not game_center_active
'V2',
)
achievements_button_space = 60.0 achievements_button_space = 60.0
show_achievements_text = ( show_achievements_text = (
@ -293,7 +335,7 @@ class AccountSettingsWindow(bui.Window):
) )
achievements_text_space = 27.0 achievements_text_space = 27.0
show_leaderboards_button = self._v1_signed_in and is_gpgs show_leaderboards_button = self._v1_signed_in and gpgs_active
leaderboards_button_space = 60.0 leaderboards_button_space = 60.0
show_campaign_progress = self._v1_signed_in show_campaign_progress = self._v1_signed_in
@ -330,7 +372,6 @@ class AccountSettingsWindow(bui.Window):
show_sign_out_button = self._v1_signed_in and v1_account_type in [ show_sign_out_button = self._v1_signed_in and v1_account_type in [
'Local', 'Local',
'Google Play',
'V2', 'V2',
] ]
sign_out_button_space = 70.0 sign_out_button_space = 70.0
@ -349,10 +390,13 @@ class AccountSettingsWindow(bui.Window):
self._sub_height = 60.0 self._sub_height = 60.0
if show_signed_in_as: if show_signed_in_as:
self._sub_height += signed_in_as_space self._sub_height += signed_in_as_space
self._sub_height += via_space * len(via_lines)
if show_signing_in_text: if show_signing_in_text:
self._sub_height += signing_in_text_space self._sub_height += signing_in_text_space
if show_google_play_sign_in_button: if show_google_play_sign_in_button:
self._sub_height += sign_in_button_space self._sub_height += sign_in_button_space
if show_game_center_sign_in_button:
self._sub_height += sign_in_button_space
if show_v2_proxy_sign_in_button: if show_v2_proxy_sign_in_button:
self._sub_height += sign_in_button_space self._sub_height += sign_in_button_space
if show_device_sign_in_button: if show_device_sign_in_button:
@ -442,20 +486,21 @@ class AccountSettingsWindow(bui.Window):
self._account_name_what_is_text = bui.textwidget( self._account_name_what_is_text = bui.textwidget(
parent=self._subcontainer, parent=self._subcontainer,
position=(0.0, self._account_name_what_is_y), position=(0.0, self._account_name_what_is_y),
size=(200.0, 60), size=(220.0, 60),
text=bui.Lstr( text=bui.Lstr(
value='${WHAT} -->', value='${WHAT} -->',
subs=[('${WHAT}', bui.Lstr(resource='whatIsThisText'))], subs=[('${WHAT}', bui.Lstr(resource='whatIsThisText'))],
), ),
scale=0.6, scale=0.6,
color=(0.3, 0.7, 0.05), color=(0.3, 0.7, 0.05),
maxwidth=200.0, maxwidth=130.0,
h_align='right', h_align='right',
v_align='center', v_align='center',
autoselect=True, autoselect=True,
selectable=True, selectable=True,
on_activate_call=show_what_is_v2_page, on_activate_call=show_what_is_v2_page,
click_activate=True, click_activate=True,
glow_type='uniform',
) )
if first_selectable is None: if first_selectable is None:
first_selectable = self._account_name_what_is_text first_selectable = self._account_name_what_is_text
@ -466,6 +511,54 @@ class AccountSettingsWindow(bui.Window):
v -= signed_in_as_space * 0.4 v -= signed_in_as_space * 0.4
for via in via_lines:
v -= via_space * 0.1
sscale = 0.7
swidth = (
bui.get_string_width(via, suppress_warning=True) * sscale
)
bui.textwidget(
parent=self._subcontainer,
position=(self._sub_width * 0.5, v),
size=(0, 0),
text=via,
scale=sscale,
color=(0.6, 0.6, 0.6),
flatness=1.0,
shadow=0.0,
h_align='center',
v_align='center',
)
bui.textwidget(
parent=self._subcontainer,
position=(self._sub_width * 0.5 - swidth * 0.5 - 5, v),
size=(0, 0),
text=bui.Lstr(
value='(${VIA}',
subs=[('${VIA}', bui.Lstr(resource='viaText'))],
),
scale=0.5,
color=(0.4, 0.6, 0.4, 0.5),
flatness=1.0,
shadow=0.0,
h_align='right',
v_align='center',
)
bui.textwidget(
parent=self._subcontainer,
position=(self._sub_width * 0.5 + swidth * 0.5 + 10, v),
size=(0, 0),
text=')',
scale=0.5,
color=(0.4, 0.6, 0.4, 0.5),
flatness=1.0,
shadow=0.0,
h_align='right',
v_align='center',
)
v -= via_space * 0.9
else: else:
self._account_name_text = None self._account_name_text = None
self._account_name_what_is_text = None self._account_name_what_is_text = None
@ -477,22 +570,6 @@ class AccountSettingsWindow(bui.Window):
if show_sign_in_benefits: if show_sign_in_benefits:
v -= sign_in_benefits_space v -= sign_in_benefits_space
app = bui.app
assert app.classic is not None
extra: str | bui.Lstr | None
if (
app.classic.platform in ['mac', 'ios']
and app.classic.subplatform == 'appstore'
):
extra = bui.Lstr(
value='\n${S}',
subs=[
('${S}', bui.Lstr(resource='signInWithGameCenterText'))
],
)
else:
extra = ''
bui.textwidget( bui.textwidget(
parent=self._subcontainer, parent=self._subcontainer,
position=( position=(
@ -500,16 +577,7 @@ class AccountSettingsWindow(bui.Window):
v + sign_in_benefits_space * 0.4, v + sign_in_benefits_space * 0.4,
), ),
size=(0, 0), size=(0, 0),
text=bui.Lstr( text=bui.Lstr(resource=self._r + '.signInInfoText'),
value='${A}${B}',
subs=[
(
'${A}',
bui.Lstr(resource=self._r + '.signInInfoText'),
),
('${B}', extra),
],
),
max_height=sign_in_benefits_space * 0.9, max_height=sign_in_benefits_space * 0.9,
scale=0.9, scale=0.9,
color=(0.75, 0.7, 0.8), color=(0.75, 0.7, 0.8),
@ -554,7 +622,13 @@ class AccountSettingsWindow(bui.Window):
( (
'${B}', '${B}',
bui.Lstr( bui.Lstr(
resource=self._r + '.signInWithGooglePlayText' resource=self._r + '.signInWithText',
subs=[
(
'${SERVICE}',
bui.Lstr(resource='googlePlayText'),
)
],
), ),
), ),
], ],
@ -572,6 +646,48 @@ class AccountSettingsWindow(bui.Window):
bui.widget(edit=btn, show_buffer_bottom=40, show_buffer_top=100) bui.widget(edit=btn, show_buffer_bottom=40, show_buffer_top=100)
self._sign_in_text = None self._sign_in_text = None
if show_game_center_sign_in_button:
button_width = 350
v -= sign_in_button_space
self._sign_in_google_play_button = btn = bui.buttonwidget(
parent=self._subcontainer,
position=((self._sub_width - button_width) * 0.5, v - 20),
autoselect=True,
size=(button_width, 60),
# Note: Apparently Game Center is just called 'Game Center'
# in all languages. Can revisit if not true.
# https://developer.apple.com/forums/thread/725779
label=bui.Lstr(
value='${A}${B}',
subs=[
(
'${A}',
bui.charstr(bui.SpecialChar.GAME_CENTER_LOGO),
),
(
'${B}',
bui.Lstr(
resource=self._r + '.signInWithText',
subs=[('${SERVICE}', 'Game Center')],
),
),
],
),
on_activate_call=lambda: self._sign_in_press(
LoginType.GAME_CENTER
),
)
if first_selectable is None:
first_selectable = btn
if bui.app.ui_v1.use_toolbars:
bui.widget(
edit=btn,
right_widget=bui.get_special_widget('party_button'),
)
bui.widget(edit=btn, left_widget=bbtn)
bui.widget(edit=btn, show_buffer_bottom=40, show_buffer_top=100)
self._sign_in_text = None
if show_v2_proxy_sign_in_button: if show_v2_proxy_sign_in_button:
button_width = 350 button_width = 350
v -= sign_in_button_space v -= sign_in_button_space
@ -704,7 +820,7 @@ class AccountSettingsWindow(bui.Window):
position=((self._sub_width - button_width) * 0.5, v + 30), position=((self._sub_width - button_width) * 0.5, v + 30),
autoselect=True, autoselect=True,
size=(button_width, 60), size=(button_width, 60),
label=bui.Lstr(resource=self._r + '.manageAccountText'), label=bui.Lstr(resource=f'{self._r}.manageAccountText'),
color=(0.55, 0.5, 0.6), color=(0.55, 0.5, 0.6),
icon=bui.gettexture('settingsIcon'), icon=bui.gettexture('settingsIcon'),
textcolor=(0.75, 0.7, 0.8), textcolor=(0.75, 0.7, 0.8),
@ -745,10 +861,15 @@ class AccountSettingsWindow(bui.Window):
# the button to go to OS-Specific leaderboards/high-score-lists/etc. # the button to go to OS-Specific leaderboards/high-score-lists/etc.
if show_game_service_button: if show_game_service_button:
button_width = 300 button_width = 300
v -= game_service_button_space * 0.85 v -= game_service_button_space * 0.6
v1_account_type = plus.get_v1_account_type() if game_center_active:
if v1_account_type == 'Game Center': # Note: Apparently Game Center is just called 'Game Center'
v1_account_type_name = bui.Lstr(resource='gameCenterText') # in all languages. Can revisit if not true.
# https://developer.apple.com/forums/thread/725779
game_service_button_label = bui.Lstr(
value=bui.charstr(bui.SpecialChar.GAME_CENTER_LOGO)
+ 'Game Center'
)
else: else:
raise ValueError( raise ValueError(
"unknown account type: '" + str(v1_account_type) + "'" "unknown account type: '" + str(v1_account_type) + "'"
@ -761,7 +882,7 @@ class AccountSettingsWindow(bui.Window):
autoselect=True, autoselect=True,
on_activate_call=self._on_game_service_button_press, on_activate_call=self._on_game_service_button_press,
size=(button_width, 50), size=(button_width, 50),
label=v1_account_type_name, label=game_service_button_label,
) )
if first_selectable is None: if first_selectable is None:
first_selectable = btn first_selectable = btn
@ -771,7 +892,7 @@ class AccountSettingsWindow(bui.Window):
right_widget=bui.get_special_widget('party_button'), right_widget=bui.get_special_widget('party_button'),
) )
bui.widget(edit=btn, left_widget=bbtn) bui.widget(edit=btn, left_widget=bbtn)
v -= game_service_button_space * 0.15 v -= game_service_button_space * 0.4
else: else:
self.game_service_button = None self.game_service_button = None
@ -804,13 +925,15 @@ class AccountSettingsWindow(bui.Window):
autoselect=True, autoselect=True,
icon=bui.gettexture( icon=bui.gettexture(
'googlePlayAchievementsIcon' 'googlePlayAchievementsIcon'
if is_gpgs if gpgs_active
else 'achievementsIcon' else 'achievementsIcon'
), ),
icon_color=(0.8, 0.95, 0.7) if is_gpgs else (0.85, 0.8, 0.9), icon_color=(0.8, 0.95, 0.7)
if gpgs_active
else (0.85, 0.8, 0.9),
on_activate_call=( on_activate_call=(
self._on_custom_achievements_press self._on_custom_achievements_press
if is_gpgs if gpgs_active
else self._on_achievements_press else self._on_achievements_press
), ),
size=(button_width, 50), size=(button_width, 50),
@ -1135,19 +1258,21 @@ class AccountSettingsWindow(bui.Window):
self._needs_refresh = False self._needs_refresh = False
def _on_game_service_button_press(self) -> None: def _on_game_service_button_press(self) -> None:
if bui.app.classic is not None: if bui.app.plus is not None:
bui.app.classic.show_online_score_ui() bui.app.plus.show_game_service_ui()
else: else:
logging.warning('game service ui not available without classic.') logging.warning(
'game-service-ui not available without plus feature-set.'
)
def _on_custom_achievements_press(self) -> None: def _on_custom_achievements_press(self) -> None:
if bui.app.classic is not None: if bui.app.plus is not None:
bui.apptimer( bui.apptimer(
0.15, 0.15,
bui.Call(bui.app.classic.show_online_score_ui, 'achievements'), bui.Call(bui.app.plus.show_game_service_ui, 'achievements'),
) )
else: else:
logging.warning('show_online_score_ui requires classic') logging.warning('show_game_service_ui requires plus feature-set.')
def _on_achievements_press(self) -> None: def _on_achievements_press(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
@ -1162,11 +1287,21 @@ class AccountSettingsWindow(bui.Window):
show_what_is_v2_page() show_what_is_v2_page()
def _on_manage_account_press(self) -> None: def _on_manage_account_press(self) -> None:
bui.screenmessage(bui.Lstr(resource='oneMomentText'))
plus = bui.app.plus plus = bui.app.plus
assert plus is not None assert plus is not None
# Preemptively fail if it looks like we won't be able to talk to
# the server anyway.
if not plus.cloud.connected:
bui.screenmessage(
bui.Lstr(resource='internal.unavailableNoConnectionText'),
color=(1, 0, 0),
)
bui.getsound('error').play()
return
bui.screenmessage(bui.Lstr(resource='oneMomentText'))
# We expect to have a v2 account signed in if we get here. # We expect to have a v2 account signed in if we get here.
if plus.accounts.primary is None: if plus.accounts.primary is None:
logging.exception( logging.exception(
@ -1184,6 +1319,9 @@ class AccountSettingsWindow(bui.Window):
self, response: bacommon.cloud.ManageAccountResponse | Exception self, response: bacommon.cloud.ManageAccountResponse | Exception
) -> None: ) -> None:
if isinstance(response, Exception) or response.url is None: if isinstance(response, Exception) or response.url is None:
logging.warning(
'Got error in manage-account-response: %s.', response
)
bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0)) bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0))
bui.getsound('error').play() bui.getsound('error').play()
return return
@ -1191,13 +1329,13 @@ class AccountSettingsWindow(bui.Window):
bui.open_url(response.url) bui.open_url(response.url)
def _on_leaderboards_press(self) -> None: def _on_leaderboards_press(self) -> None:
if bui.app.classic is not None: if bui.app.plus is not None:
bui.apptimer( bui.apptimer(
0.15, 0.15,
bui.Call(bui.app.classic.show_online_score_ui, 'leaderboards'), bui.Call(bui.app.plus.show_game_service_ui, 'leaderboards'),
) )
else: else:
logging.warning('show_online_score_ui requires classic') logging.warning('show_game_service_ui requires classic')
def _have_unlinkable_v1_accounts(self) -> bool: def _have_unlinkable_v1_accounts(self) -> bool:
plus = bui.app.plus plus = bui.app.plus
@ -1323,7 +1461,7 @@ class AccountSettingsWindow(bui.Window):
swidth = bui.get_string_width(name_str, suppress_warning=True) swidth = bui.get_string_width(name_str, suppress_warning=True)
# Eww; number-fudging. Need to recalibrate this if # Eww; number-fudging. Need to recalibrate this if
# account name scaling changes. # account name scaling changes.
x = self._sub_width * 0.5 - swidth * 0.75 - 170 x = self._sub_width * 0.5 - swidth * 0.75 - 190
bui.textwidget( bui.textwidget(
edit=self._account_name_what_is_text, edit=self._account_name_what_is_text,
@ -1371,9 +1509,18 @@ class AccountSettingsWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.profile.browser import ProfileBrowserWindow from bauiv1lib.profile.browser import ProfileBrowserWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
ProfileBrowserWindow(origin_widget=self._player_profiles_button) bui.app.ui_v1.set_main_menu_window(
ProfileBrowserWindow(
origin_widget=self._player_profiles_button
).get_root_widget(),
from_window=self._root_widget,
)
def _cancel_sign_in_press(self) -> None: def _cancel_sign_in_press(self) -> None:
# If we're waiting on an adapter to give us credentials, abort. # If we're waiting on an adapter to give us credentials, abort.
@ -1466,7 +1613,11 @@ class AccountSettingsWindow(bui.Window):
if isinstance(result, Exception): if isinstance(result, Exception):
# For now just make a bit of noise if anything went wrong; # For now just make a bit of noise if anything went wrong;
# can get more specific as needed later. # can get more specific as needed later.
bui.screenmessage(bui.Lstr(resource='errorText'), color=(1, 0, 0)) logging.warning('Got error in v2 sign-in result: %s', result)
bui.screenmessage(
bui.Lstr(resource='internal.signInNoConnectionText'),
color=(1, 0, 0),
)
bui.getsound('error').play() bui.getsound('error').play()
else: else:
# Success! Plug in these credentials which will begin # Success! Plug in these credentials which will begin
@ -1530,6 +1681,10 @@ class AccountSettingsWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.mainmenu import MainMenuWindow from bauiv1lib.mainmenu import MainMenuWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, transition=self._transition_out edit=self._root_widget, transition=self._transition_out
@ -1538,7 +1693,8 @@ class AccountSettingsWindow(bui.Window):
if not self._modal: if not self._modal:
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
MainMenuWindow(transition='in_left').get_root_widget() MainMenuWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )
def _save_state(self) -> None: def _save_state(self) -> None:

View file

@ -62,11 +62,8 @@ class V2ProxySignInWindow(bui.Window):
label=bui.Lstr(resource='cancelText'), label=bui.Lstr(resource='cancelText'),
on_activate_call=self._done, on_activate_call=self._done,
autoselect=True, autoselect=True,
color=(0.55, 0.5, 0.6),
textcolor=(0.75, 0.7, 0.8),
) )
if bool(False):
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, cancel_button=self._cancel_button edit=self._root_widget, cancel_button=self._cancel_button
) )
@ -131,14 +128,17 @@ class V2ProxySignInWindow(bui.Window):
else: else:
bui.textwidget( bui.textwidget(
parent=self._root_widget, parent=self._root_widget,
position=(self._width * 0.5, self._height - 145), position=(self._width * 0.5 - 200, self._height - 180),
size=(0, 0), size=(button_width - 50, 50),
text=bui.Lstr(value=address_pretty), text=bui.Lstr(value=address_pretty),
flatness=1.0, flatness=1.0,
maxwidth=self._width, maxwidth=self._width,
scale=0.75, scale=0.75,
h_align='center', h_align='center',
v_align='center', v_align='center',
autoselect=True,
on_activate_call=bui.Call(self._copy_link, address_pretty),
selectable=True,
) )
qroffs = 20.0 qroffs = 20.0
@ -231,5 +231,15 @@ class V2ProxySignInWindow(bui.Window):
# We could do something smart like retry on exceptions here, but # We could do something smart like retry on exceptions here, but
# this isn't critical so we'll just let anything slide. # this isn't critical so we'll just let anything slide.
def _copy_link(self, link: str) -> None:
if bui.clipboard_is_supported():
bui.clipboard_set_text(link)
bui.screenmessage(
bui.Lstr(resource='copyConfirmText'), color=(0, 1, 0)
)
def _done(self) -> None: def _done(self) -> None:
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
bui.containerwidget(edit=self._root_widget, transition='out_scale') bui.containerwidget(edit=self._root_widget, transition='out_scale')

View file

@ -93,6 +93,7 @@ class ConfigNumberEdit:
displayname: str | bui.Lstr | None = None, displayname: str | bui.Lstr | None = None,
changesound: bool = True, changesound: bool = True,
textscale: float = 1.0, textscale: float = 1.0,
as_percent: bool = False,
): ):
if displayname is None: if displayname is None:
displayname = configkey displayname = configkey
@ -103,6 +104,7 @@ class ConfigNumberEdit:
self._increment = increment self._increment = increment
self._callback = callback self._callback = callback
self._value = bui.app.config.resolve(configkey) self._value = bui.app.config.resolve(configkey)
self._as_percent = as_percent
self.nametext = bui.textwidget( self.nametext = bui.textwidget(
parent=parent, parent=parent,
@ -166,4 +168,8 @@ class ConfigNumberEdit:
bui.app.config.apply_and_commit() bui.app.config.apply_and_commit()
def _update_display(self) -> None: def _update_display(self) -> None:
bui.textwidget(edit=self.valuetext, text=f'{self._value:.1f}') if self._as_percent:
val = f'{round(self._value*100.0)}%'
else:
val = f'{self._value:.1f}'
bui.textwidget(edit=self.valuetext, text=val)

View file

@ -153,15 +153,15 @@ class QuitWindow:
def __init__( def __init__(
self, self,
quit_type: bui.QuitType | None = None,
swish: bool = False, swish: bool = False,
back: bool = False,
origin_widget: bui.Widget | None = None, origin_widget: bui.Widget | None = None,
): ):
classic = bui.app.classic classic = bui.app.classic
assert classic is not None assert classic is not None
ui = bui.app.ui_v1 ui = bui.app.ui_v1
app = bui.app app = bui.app
self._back = back self._quit_type = quit_type
# If there's already one of us up somewhere, kill it. # If there's already one of us up somewhere, kill it.
if ui.quit_window is not None: if ui.quit_window is not None:
@ -187,29 +187,8 @@ class QuitWindow:
resource=quit_resource, resource=quit_resource,
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
), ),
self._fade_and_quit, lambda: bui.quit(confirm=False, quit_type=self._quit_type)
if self._quit_type is not None
else bui.quit(confirm=False),
origin_widget=origin_widget, origin_widget=origin_widget,
).root_widget ).root_widget
def _fade_and_quit(self) -> None:
bui.fade_screen(
False,
time=0.2,
endcall=lambda: bui.quit(soft=True, back=self._back),
)
# Prevent the user from doing anything else while we're on our
# way out.
bui.lock_all_input()
# On systems supporting soft-quit, unlock and fade back in shortly
# (soft-quit basically just backgrounds/hides the app).
if bui.app.env.supports_soft_quit:
# Unlock and fade back in shortly. Just in case something goes
# wrong (or on Android where quit just backs out of our activity
# and we may come back after).
def _come_back() -> None:
bui.unlock_all_input()
bui.fade_screen(True)
bui.apptimer(0.5, _come_back)

View file

@ -85,8 +85,8 @@ class CoopBrowserWindow(bui.Window):
assert bui.app.classic is not None assert bui.app.classic is not None
uiscale = bui.app.ui_v1.uiscale uiscale = bui.app.ui_v1.uiscale
self._width = 1320 if uiscale is bui.UIScale.SMALL else 1120 self._width = 1520 if uiscale is bui.UIScale.SMALL else 1120
self._x_inset = x_inset = 100 if uiscale is bui.UIScale.SMALL else 0 self._x_inset = x_inset = 200 if uiscale is bui.UIScale.SMALL else 0
self._height = ( self._height = (
657 657
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
@ -415,7 +415,7 @@ class CoopBrowserWindow(bui.Window):
) )
# Decrement time on our tournament buttons. # Decrement time on our tournament buttons.
ads_enabled = bui.have_incentivized_ad() ads_enabled = plus.have_incentivized_ad()
for tbtn in self._tournament_buttons: for tbtn in self._tournament_buttons:
tbtn.time_remaining = max(0, tbtn.time_remaining - 1) tbtn.time_remaining = max(0, tbtn.time_remaining - 1)
if tbtn.time_remaining_value_text is not None: if tbtn.time_remaining_value_text is not None:
@ -430,7 +430,7 @@ class CoopBrowserWindow(bui.Window):
) )
# Also adjust the ad icon visibility. # Also adjust the ad icon visibility.
if tbtn.allow_ads and bui.has_video_ads(): if tbtn.allow_ads and plus.has_video_ads():
bui.imagewidget( bui.imagewidget(
edit=tbtn.entry_fee_ad_image, edit=tbtn.entry_fee_ad_image,
opacity=1.0 if ads_enabled else 0.25, opacity=1.0 if ads_enabled else 0.25,
@ -1019,6 +1019,10 @@ class CoopBrowserWindow(bui.Window):
from bauiv1lib.account import show_sign_in_prompt from bauiv1lib.account import show_sign_in_prompt
from bauiv1lib.league.rankwindow import LeagueRankWindow from bauiv1lib.league.rankwindow import LeagueRankWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
plus = bui.app.plus plus = bui.app.plus
assert plus is not None assert plus is not None
@ -1032,7 +1036,8 @@ class CoopBrowserWindow(bui.Window):
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
LeagueRankWindow( LeagueRankWindow(
origin_widget=self._league_rank_button.get_button() origin_widget=self._league_rank_button.get_button()
).get_root_widget() ).get_root_widget(),
from_window=self._root_widget,
) )
def _switch_to_score( def _switch_to_score(
@ -1043,6 +1048,10 @@ class CoopBrowserWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.account import show_sign_in_prompt from bauiv1lib.account import show_sign_in_prompt
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
plus = bui.app.plus plus = bui.app.plus
assert plus is not None assert plus is not None
@ -1058,7 +1067,8 @@ class CoopBrowserWindow(bui.Window):
origin_widget=self._store_button.get_button(), origin_widget=self._store_button.get_button(),
show_tab=show_tab, show_tab=show_tab,
back_location='CoopBrowserWindow', back_location='CoopBrowserWindow',
).get_root_widget() ).get_root_widget(),
from_window=self._root_widget,
) )
def is_tourney_data_up_to_date(self) -> bool: def is_tourney_data_up_to_date(self) -> bool:
@ -1218,6 +1228,10 @@ class CoopBrowserWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.play import PlayWindow from bauiv1lib.play import PlayWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
# If something is selected, store it. # If something is selected, store it.
self._save_state() self._save_state()
bui.containerwidget( bui.containerwidget(
@ -1225,7 +1239,8 @@ class CoopBrowserWindow(bui.Window):
) )
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
PlayWindow(transition='in_left').get_root_widget() PlayWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )
def _save_state(self) -> None: def _save_state(self) -> None:

View file

@ -638,8 +638,8 @@ class TournamentButton:
# Now, if this fee allows ads and we support video ads, show # Now, if this fee allows ads and we support video ads, show
# the 'or ad' version. # the 'or ad' version.
if allow_ads and bui.has_video_ads(): if allow_ads and plus.has_video_ads():
ads_enabled = bui.have_incentivized_ad() ads_enabled = plus.have_incentivized_ad()
bui.imagewidget( bui.imagewidget(
edit=self.entry_fee_ad_image, edit=self.entry_fee_ad_image,
opacity=1.0 if ads_enabled else 0.25, opacity=1.0 if ads_enabled else 0.25,

View file

@ -359,10 +359,15 @@ class CreditsListWindow(bui.Window):
def _back(self) -> None: def _back(self) -> None:
from bauiv1lib.mainmenu import MainMenuWindow from bauiv1lib.mainmenu import MainMenuWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, transition=self._transition_out edit=self._root_widget, transition=self._transition_out
) )
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
MainMenuWindow(transition='in_left').get_root_widget() MainMenuWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )

View file

@ -379,8 +379,13 @@ class DebugWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.settings.advanced import AdvancedSettingsWindow from bauiv1lib.settings.advanced import AdvancedSettingsWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
bui.containerwidget(edit=self._root_widget, transition='out_right') bui.containerwidget(edit=self._root_widget, transition='out_right')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
AdvancedSettingsWindow(transition='in_left').get_root_widget() AdvancedSettingsWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )

133
dist/ba_data/python/bauiv1lib/discord.py vendored Normal file
View file

@ -0,0 +1,133 @@
# Released under the MIT License. See LICENSE for details.
#
"""UI functionality for the Discord window."""
from __future__ import annotations
import bauiv1 as bui
class DiscordWindow(bui.Window):
"""Window for joining the Discord."""
def __init__(
self,
transition: str = 'in_right',
origin_widget: bui.Widget | None = None,
):
if bui.app.classic is None:
raise RuntimeError('This requires classic support.')
app = bui.app
assert app.classic is not None
# If they provided an origin-widget, scale up from that.
scale_origin: tuple[float, float] | None
if origin_widget is not None:
self._transition_out = 'out_scale'
scale_origin = origin_widget.get_screen_space_center()
transition = 'in_scale'
else:
self._transition_out = 'out_right'
scale_origin = None
uiscale = bui.app.ui_v1.uiscale
self._width = 800
x_inset = 100 if uiscale is bui.UIScale.SMALL else 0
self._height = 320
top_extra = 10 if uiscale is bui.UIScale.SMALL else 0
super().__init__(
root_widget=bui.containerwidget(
size=(self._width, self._height + top_extra),
transition=transition,
toolbar_visibility='menu_minimal',
scale_origin_stack_offset=scale_origin,
scale=(
1.6
if uiscale is bui.UIScale.SMALL
else 1.3
if uiscale is bui.UIScale.MEDIUM
else 1.0
),
stack_offset=(0, 5) if uiscale is bui.UIScale.SMALL else (0, 0),
)
)
if app.ui_v1.use_toolbars and uiscale is bui.UIScale.SMALL:
bui.containerwidget(
edit=self._root_widget, on_cancel_call=self._do_back
)
self._back_button = None
else:
self._back_button = bui.buttonwidget(
parent=self._root_widget,
position=(53 + x_inset, self._height - 60),
size=(140, 60),
scale=0.8,
autoselect=True,
label=bui.Lstr(resource='backText'),
button_type='back',
on_activate_call=self._do_back,
)
bui.containerwidget(
edit=self._root_widget, cancel_button=self._back_button
)
# Do we need to translate 'Discord'? Or is that always the name?
self._title_text = bui.textwidget(
parent=self._root_widget,
position=(0, self._height - 52),
size=(self._width, 25),
text='Discord',
color=app.ui_v1.title_color,
h_align='center',
v_align='top',
)
min_size = min(self._width - 25, self._height - 25)
bui.imagewidget(
parent=self._root_widget,
position=(40, -15),
size=(min_size, min_size),
texture=bui.gettexture('discordServer'),
)
# Hmm should we translate this? The discord server is mostly
# English so being able to read this might be a good screening
# process?..
bui.textwidget(
parent=self._root_widget,
position=(self._width / 2 - 60, self._height - 100),
text='We have our own Discord server where you can:\n- Find new'
' friends and people to play with\n- Participate in Office'
' Hours/Coffee with Eric\n- Share mods, plugins, art, and'
' memes\n- Report bugs and make feature suggestions\n'
'- Troubleshoot issues',
maxwidth=(self._width - 10) / 2,
color=(1, 1, 1, 1),
h_align='left',
v_align='top',
)
bui.buttonwidget(
parent=self._root_widget,
position=(self._width / 2 - 30, 20),
size=(self._width / 2 - 60, 60),
autoselect=True,
label=bui.Lstr(resource='discordJoinText'),
text_scale=1.0,
on_activate_call=bui.Call(
bui.open_url, 'https://ballistica.net/discord'
),
)
if self._back_button is not None:
bui.buttonwidget(
edit=self._back_button,
button_type='backSmall',
size=(60, 60),
label=bui.charstr(bui.SpecialChar.BACK),
)
def _do_back(self) -> None:
bui.containerwidget(edit=self._root_widget, transition='out_scale')

View file

@ -94,8 +94,8 @@ class GatherWindow(bui.Window):
bui.app.ui_v1.set_main_menu_location('Gather') bui.app.ui_v1.set_main_menu_location('Gather')
bui.set_party_icon_always_visible(True) bui.set_party_icon_always_visible(True)
uiscale = bui.app.ui_v1.uiscale uiscale = bui.app.ui_v1.uiscale
self._width = 1240 if uiscale is bui.UIScale.SMALL else 1040 self._width = 1440 if uiscale is bui.UIScale.SMALL else 1040
x_offs = 100 if uiscale is bui.UIScale.SMALL else 0 x_offs = 200 if uiscale is bui.UIScale.SMALL else 0
self._height = ( self._height = (
582 582
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
@ -270,12 +270,17 @@ class GatherWindow(bui.Window):
"""Called by the private-hosting tab to select a playlist.""" """Called by the private-hosting tab to select a playlist."""
from bauiv1lib.play import PlayWindow from bauiv1lib.play import PlayWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.selecting_private_party_playlist = True bui.app.ui_v1.selecting_private_party_playlist = True
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
PlayWindow(origin_widget=origin_widget).get_root_widget() PlayWindow(origin_widget=origin_widget).get_root_widget(),
from_window=self._root_widget,
) )
def _set_tab(self, tab_id: TabID) -> None: def _set_tab(self, tab_id: TabID) -> None:
@ -383,11 +388,16 @@ class GatherWindow(bui.Window):
def _back(self) -> None: def _back(self) -> None:
from bauiv1lib.mainmenu import MainMenuWindow from bauiv1lib.mainmenu import MainMenuWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, transition=self._transition_out edit=self._root_widget, transition=self._transition_out
) )
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
MainMenuWindow(transition='in_left').get_root_widget() MainMenuWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )

View file

@ -16,10 +16,6 @@ if TYPE_CHECKING:
class AboutGatherTab(GatherTab): class AboutGatherTab(GatherTab):
"""The about tab in the gather UI""" """The about tab in the gather UI"""
def __init__(self, window: GatherWindow) -> None:
super().__init__(window)
self._container: bui.Widget | None = None
def on_activate( def on_activate(
self, self,
parent_widget: bui.Widget, parent_widget: bui.Widget,
@ -29,9 +25,45 @@ class AboutGatherTab(GatherTab):
region_left: float, region_left: float,
region_bottom: float, region_bottom: float,
) -> bui.Widget: ) -> bui.Widget:
# pylint: disable=too-many-locals
plus = bui.app.plus plus = bui.app.plus
assert plus is not None assert plus is not None
try_tickets = plus.get_v1_account_misc_read_val(
'friendTryTickets', None
)
show_message = True
# Squish message as needed to get things to fit nicely at
# various scales.
uiscale = bui.app.ui_v1.uiscale
message_height = (
210
if uiscale is bui.UIScale.SMALL
else 305
if uiscale is bui.UIScale.MEDIUM
else 370
)
# Let's not talk about sharing in vr-mode; its tricky to fit more
# than one head in a VR-headset.
show_message_extra = not bui.app.env.vr
message_extra_height = 60
show_invite = try_tickets is not None
invite_height = 80
show_discord = True
discord_height = 80
c_height = 0
if show_message:
c_height += message_height
if show_message_extra:
c_height += message_extra_height
if show_invite:
c_height += invite_height
if show_discord:
c_height += discord_height
party_button_label = bui.charstr(bui.SpecialChar.TOP_BUTTON) party_button_label = bui.charstr(bui.SpecialChar.TOP_BUTTON)
message = bui.Lstr( message = bui.Lstr(
resource='gatherWindow.aboutDescriptionText', resource='gatherWindow.aboutDescriptionText',
@ -41,9 +73,7 @@ class AboutGatherTab(GatherTab):
], ],
) )
# Let's not talk about sharing in vr-mode; its tricky to fit more if show_message_extra:
# than one head in a VR-headset ;-)
if not bui.app.env.vr:
message = bui.Lstr( message = bui.Lstr(
value='${A}\n\n${B}', value='${A}\n\n${B}',
subs=[ subs=[
@ -57,47 +87,52 @@ class AboutGatherTab(GatherTab):
), ),
], ],
) )
string_height = 400
include_invite = True scroll_widget = bui.scrollwidget(
msc_scale = 1.1
c_height_2 = min(region_height, string_height * msc_scale + 100)
try_tickets = plus.get_v1_account_misc_read_val(
'friendTryTickets', None
)
if try_tickets is None:
include_invite = False
self._container = bui.containerwidget(
parent=parent_widget, parent=parent_widget,
position=(region_left, region_bottom),
size=(region_width, region_height),
highlight=False,
border_opacity=0,
)
msc_scale = 1.1
container = bui.containerwidget(
parent=scroll_widget,
position=( position=(
region_left, region_left,
region_bottom + (region_height - c_height_2) * 0.5, region_bottom + (region_height - c_height) * 0.5,
), ),
size=(region_width, c_height_2), size=(region_width, c_height),
background=False, background=False,
selectable=include_invite, selectable=show_invite or show_discord,
) )
bui.widget(edit=self._container, up_widget=tab_button) # Allows escaping if we select the container somehow (though
# shouldn't be possible when buttons are present).
bui.widget(edit=container, up_widget=tab_button)
y = c_height - 30
if show_message:
bui.textwidget( bui.textwidget(
parent=self._container, parent=container,
position=( position=(region_width * 0.5, y),
region_width * 0.5,
c_height_2 * (0.58 if include_invite else 0.5),
),
color=(0.6, 1.0, 0.6), color=(0.6, 1.0, 0.6),
scale=msc_scale, scale=msc_scale,
size=(0, 0), size=(0, 0),
maxwidth=region_width * 0.9, maxwidth=region_width * 0.9,
max_height=c_height_2 * (0.7 if include_invite else 0.9), max_height=message_height,
h_align='center', h_align='center',
v_align='center', v_align='top',
text=message, text=message,
) )
y -= message_height
if show_message_extra:
y -= message_extra_height
if include_invite: if show_invite:
bui.textwidget( bui.textwidget(
parent=self._container, parent=container,
position=(region_width * 0.57, 35), position=(region_width * 0.57, y),
color=(0, 1, 0), color=(0, 1, 0),
scale=0.6, scale=0.6,
size=(0, 0), size=(0, 0),
@ -110,9 +145,9 @@ class AboutGatherTab(GatherTab):
subs=[('${COUNT}', str(try_tickets))], subs=[('${COUNT}', str(try_tickets))],
), ),
) )
bui.buttonwidget( invite_button = bui.buttonwidget(
parent=self._container, parent=container,
position=(region_width * 0.59, 10), position=(region_width * 0.59, y - 25),
size=(230, 50), size=(230, 50),
color=(0.54, 0.42, 0.56), color=(0.54, 0.42, 0.56),
textcolor=(0, 1, 0), textcolor=(0, 1, 0),
@ -124,7 +159,44 @@ class AboutGatherTab(GatherTab):
on_activate_call=bui.WeakCall(self._invite_to_try_press), on_activate_call=bui.WeakCall(self._invite_to_try_press),
up_widget=tab_button, up_widget=tab_button,
) )
return self._container y -= invite_height
else:
invite_button = None
if show_discord:
bui.textwidget(
parent=container,
position=(region_width * 0.57, y),
color=(0.6, 0.6, 1),
scale=0.6,
size=(0, 0),
maxwidth=region_width * 0.5,
h_align='right',
v_align='center',
flatness=1.0,
text=bui.Lstr(resource='discordFriendsText'),
)
discord_button = bui.buttonwidget(
parent=container,
position=(region_width * 0.59, y - 25),
size=(230, 50),
color=(0.54, 0.42, 0.56),
textcolor=(0.6, 0.6, 1),
label=bui.Lstr(resource='discordJoinText'),
autoselect=True,
on_activate_call=bui.WeakCall(self._join_the_discord_press),
up_widget=(
invite_button if invite_button is not None else tab_button
),
)
y -= discord_height
else:
discord_button = None
if discord_button is not None:
pass
return scroll_widget
def _invite_to_try_press(self) -> None: def _invite_to_try_press(self) -> None:
from bauiv1lib.account import show_sign_in_prompt from bauiv1lib.account import show_sign_in_prompt
@ -137,3 +209,10 @@ class AboutGatherTab(GatherTab):
show_sign_in_prompt() show_sign_in_prompt()
return return
handle_app_invites_press() handle_app_invites_press()
def _join_the_discord_press(self) -> None:
# pylint: disable=cyclic-import
from bauiv1lib.discord import DiscordWindow
assert bui.app.classic is not None
DiscordWindow().get_root_widget()

View file

@ -99,6 +99,7 @@ class ManualGatherTab(GatherTab):
self._party_edit_name_text: bui.Widget | None = None self._party_edit_name_text: bui.Widget | None = None
self._party_edit_addr_text: bui.Widget | None = None self._party_edit_addr_text: bui.Widget | None = None
self._party_edit_port_text: bui.Widget | None = None self._party_edit_port_text: bui.Widget | None = None
self._no_parties_added_text: bui.Widget | None = None
def on_activate( def on_activate(
self, self,
@ -142,6 +143,7 @@ class ManualGatherTab(GatherTab):
playsound=True, playsound=True,
), ),
text=bui.Lstr(resource='gatherWindow.manualJoinSectionText'), text=bui.Lstr(resource='gatherWindow.manualJoinSectionText'),
glow_type='uniform',
) )
self._favorites_text = bui.textwidget( self._favorites_text = bui.textwidget(
parent=self._container, parent=self._container,
@ -162,6 +164,7 @@ class ManualGatherTab(GatherTab):
playsound=True, playsound=True,
), ),
text=bui.Lstr(resource='gatherWindow.favoritesText'), text=bui.Lstr(resource='gatherWindow.favoritesText'),
glow_type='uniform',
) )
bui.widget(edit=self._join_by_address_text, up_widget=tab_button) bui.widget(edit=self._join_by_address_text, up_widget=tab_button)
bui.widget( bui.widget(
@ -316,7 +319,7 @@ class ManualGatherTab(GatherTab):
self._check_button = bui.textwidget( self._check_button = bui.textwidget(
parent=self._container, parent=self._container,
size=(250, 60), size=(250, 60),
text=bui.Lstr(resource='gatherWindow.' 'showMyAddressText'), text=bui.Lstr(resource='gatherWindow.showMyAddressText'),
v_align='center', v_align='center',
h_align='center', h_align='center',
click_activate=True, click_activate=True,
@ -331,6 +334,7 @@ class ManualGatherTab(GatherTab):
self._container, self._container,
c_width, c_width,
), ),
glow_type='uniform',
) )
bui.widget(edit=self._check_button, up_widget=btn) bui.widget(edit=self._check_button, up_widget=btn)
@ -453,6 +457,24 @@ class ManualGatherTab(GatherTab):
claims_left_right=True, claims_left_right=True,
) )
self._no_parties_added_text = bui.textwidget(
parent=self._container,
size=(0, 0),
h_align='center',
v_align='center',
text='',
color=(0.6, 0.6, 0.6),
scale=1.2,
position=(
(
(190 if uiscale is bui.UIScale.SMALL else 225)
+ sub_scroll_width * 0.5
),
v + sub_scroll_height * 0.5,
),
glow_type='uniform',
)
self._favorite_selected = None self._favorite_selected = None
self._refresh_favorites() self._refresh_favorites()
@ -695,6 +717,12 @@ class ManualGatherTab(GatherTab):
assert self._favorites_scroll_width is not None assert self._favorites_scroll_width is not None
assert self._favorites_connect_button is not None assert self._favorites_connect_button is not None
bui.textwidget(
edit=self._no_parties_added_text,
text='',
)
num_of_fav = 0
for i, server in enumerate(servers): for i, server in enumerate(servers):
txt = bui.textwidget( txt = bui.textwidget(
parent=self._columnwidget, parent=self._columnwidget,
@ -718,11 +746,13 @@ class ManualGatherTab(GatherTab):
) )
if i == 0: if i == 0:
bui.widget(edit=txt, up_widget=self._favorites_text) bui.widget(edit=txt, up_widget=self._favorites_text)
self._favorite_selected = server
bui.widget( bui.widget(
edit=txt, edit=txt,
left_widget=self._favorites_connect_button, left_widget=self._favorites_connect_button,
right_widget=txt, right_widget=txt,
) )
num_of_fav = num_of_fav + 1
# If there's no servers, allow selecting out of the scroll area # If there's no servers, allow selecting out of the scroll area
bui.containerwidget( bui.containerwidget(
@ -735,6 +765,11 @@ class ManualGatherTab(GatherTab):
up_widget=self._favorites_text, up_widget=self._favorites_text,
left_widget=self._favorites_connect_button, left_widget=self._favorites_connect_button,
) )
if num_of_fav == 0:
bui.textwidget(
edit=self._no_parties_added_text,
text=bui.Lstr(resource='gatherWindow.noPartiesAddedText'),
)
def on_deactivate(self) -> None: def on_deactivate(self) -> None:
self._access_check_timer = None self._access_check_timer = None
@ -800,8 +835,17 @@ class ManualGatherTab(GatherTab):
} }
config.commit() config.commit()
bui.getsound('gunCocking').play() bui.getsound('gunCocking').play()
bui.screenmessage(
bui.Lstr(
resource='addedToFavoritesText', subs=[('${NAME}', addr)]
),
color=(0, 1, 0),
)
else: else:
bui.screenmessage('Invalid Address', color=(1, 0, 0)) bui.screenmessage(
bui.Lstr(resource='internal.invalidAddressErrorText'),
color=(1, 0, 0),
)
bui.getsound('error').play() bui.getsound('error').play()
def _host_lookup_result( def _host_lookup_result(

View file

@ -120,6 +120,7 @@ class PrivateGatherTab(GatherTab):
playsound=True, playsound=True,
), ),
text=bui.Lstr(resource='gatherWindow.privatePartyJoinText'), text=bui.Lstr(resource='gatherWindow.privatePartyJoinText'),
glow_type='uniform',
) )
self._host_sub_tab_text = bui.textwidget( self._host_sub_tab_text = bui.textwidget(
parent=self._container, parent=self._container,
@ -138,6 +139,7 @@ class PrivateGatherTab(GatherTab):
playsound=True, playsound=True,
), ),
text=bui.Lstr(resource='gatherWindow.privatePartyHostText'), text=bui.Lstr(resource='gatherWindow.privatePartyHostText'),
glow_type='uniform',
) )
bui.widget(edit=self._join_sub_tab_text, up_widget=tab_button) bui.widget(edit=self._join_sub_tab_text, up_widget=tab_button)
bui.widget( bui.widget(
@ -458,9 +460,9 @@ class PrivateGatherTab(GatherTab):
scale=1.5, scale=1.5,
size=(300, 50), size=(300, 50),
editable=True, editable=True,
max_chars=20,
description=bui.Lstr(resource='gatherWindow.partyCodeText'), description=bui.Lstr(resource='gatherWindow.partyCodeText'),
autoselect=True, autoselect=True,
maxwidth=250,
h_align='left', h_align='left',
v_align='center', v_align='center',
text='', text='',
@ -962,7 +964,7 @@ class PrivateGatherTab(GatherTab):
code = cast(str, bui.textwidget(query=self._join_party_code_text)) code = cast(str, bui.textwidget(query=self._join_party_code_text))
if not code: if not code:
bui.screenmessage( bui.screenmessage(
bui.Lstr(resource='internal.invalidAddressErrorText'), bui.Lstr(translate=('serverResponses', 'Invalid code.')),
color=(1, 0, 0), color=(1, 0, 0),
) )
bui.getsound('error').play() bui.getsound('error').play()

View file

@ -114,7 +114,7 @@ class UIRow:
self._name_widget = bui.textwidget( self._name_widget = bui.textwidget(
text=bui.Lstr(value=party.name), text=bui.Lstr(value=party.name),
parent=columnwidget, parent=columnwidget,
size=(sub_scroll_width * 0.63, 20), size=(sub_scroll_width * 0.46, 20),
position=(0 + hpos, 4 + vpos), position=(0 + hpos, 4 + vpos),
selectable=True, selectable=True,
on_select_call=bui.WeakCall( on_select_call=bui.WeakCall(
@ -248,6 +248,7 @@ class AddrFetchThread(Thread):
self._call = call self._call = call
def run(self) -> None: def run(self) -> None:
sock: socket.socket | None = None
try: try:
# FIXME: Update this to work with IPv6 at some point. # FIXME: Update this to work with IPv6 at some point.
import socket import socket
@ -255,7 +256,6 @@ class AddrFetchThread(Thread):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect(('8.8.8.8', 80)) sock.connect(('8.8.8.8', 80))
val = sock.getsockname()[0] val = sock.getsockname()[0]
sock.close()
bui.pushcall(bui.Call(self._call, val), from_other_thread=True) bui.pushcall(bui.Call(self._call, val), from_other_thread=True)
except Exception as exc: except Exception as exc:
from efro.error import is_udp_communication_error from efro.error import is_udp_communication_error
@ -265,6 +265,9 @@ class AddrFetchThread(Thread):
pass pass
else: else:
logging.exception('Error in addr-fetch-thread') logging.exception('Error in addr-fetch-thread')
finally:
if sock is not None:
sock.close()
class PingThread(Thread): class PingThread(Thread):
@ -361,6 +364,7 @@ class PublicGatherTab(GatherTab):
self._last_server_list_query_time: float | None = None self._last_server_list_query_time: float | None = None
self._join_list_column: bui.Widget | None = None self._join_list_column: bui.Widget | None = None
self._join_status_text: bui.Widget | None = None self._join_status_text: bui.Widget | None = None
self._no_servers_found_text: bui.Widget | None = None
self._host_max_party_size_value: bui.Widget | None = None self._host_max_party_size_value: bui.Widget | None = None
self._host_max_party_size_minus_button: (bui.Widget | None) = None self._host_max_party_size_minus_button: (bui.Widget | None) = None
self._host_max_party_size_plus_button: (bui.Widget | None) = None self._host_max_party_size_plus_button: (bui.Widget | None) = None
@ -431,6 +435,7 @@ class PublicGatherTab(GatherTab):
text=bui.Lstr( text=bui.Lstr(
resource='gatherWindow.' 'joinPublicPartyDescriptionText' resource='gatherWindow.' 'joinPublicPartyDescriptionText'
), ),
glow_type='uniform',
) )
self._host_text = bui.textwidget( self._host_text = bui.textwidget(
parent=self._container, parent=self._container,
@ -453,6 +458,7 @@ class PublicGatherTab(GatherTab):
text=bui.Lstr( text=bui.Lstr(
resource='gatherWindow.' 'hostPublicPartyDescriptionText' resource='gatherWindow.' 'hostPublicPartyDescriptionText'
), ),
glow_type='uniform',
) )
bui.widget(edit=self._join_text, up_widget=tab_button) bui.widget(edit=self._join_text, up_widget=tab_button)
bui.widget( bui.widget(
@ -658,6 +664,18 @@ class PublicGatherTab(GatherTab):
color=(0.6, 0.6, 0.6), color=(0.6, 0.6, 0.6),
position=(c_width * 0.5, c_height * 0.5), position=(c_width * 0.5, c_height * 0.5),
) )
self._no_servers_found_text = bui.textwidget(
parent=self._container,
text='',
size=(0, 0),
scale=0.9,
flatness=1.0,
shadow=0.0,
h_align='center',
v_align='top',
color=(0.6, 0.6, 0.6),
position=(c_width * 0.5, c_height * 0.5),
)
def _build_host_tab( def _build_host_tab(
self, region_width: float, region_height: float self, region_width: float, region_height: float
@ -950,6 +968,9 @@ class PublicGatherTab(GatherTab):
self._update_party_rows() self._update_party_rows()
def _update_party_rows(self) -> None: def _update_party_rows(self) -> None:
plus = bui.app.plus
assert plus is not None
columnwidget = self._join_list_column columnwidget = self._join_list_column
if not columnwidget: if not columnwidget:
return return
@ -963,6 +984,7 @@ class PublicGatherTab(GatherTab):
edit=self._host_scrollwidget, edit=self._host_scrollwidget,
claims_up_down=(len(self._parties_displayed) > 0), claims_up_down=(len(self._parties_displayed) > 0),
) )
bui.textwidget(edit=self._no_servers_found_text, text='')
# Clip if we have more UI rows than parties to show. # Clip if we have more UI rows than parties to show.
clipcount = len(self._ui_rows) - len(self._parties_displayed) clipcount = len(self._ui_rows) - len(self._parties_displayed)
@ -972,6 +994,15 @@ class PublicGatherTab(GatherTab):
# If we have no parties to show, we're done. # If we have no parties to show, we're done.
if not self._parties_displayed: if not self._parties_displayed:
text = self._join_status_text
if (
plus.get_v1_account_state() == 'signed_in'
and cast(str, bui.textwidget(query=text)) == ''
):
bui.textwidget(
edit=self._no_servers_found_text,
text=bui.Lstr(resource='noServersFoundText'),
)
return return
sub_scroll_width = 830 sub_scroll_width = 830

View file

@ -334,7 +334,7 @@ class GetCurrencyWindow(bui.Window):
tex_scale=1.2, tex_scale=1.2,
) # 19.99-ish ) # 19.99-ish
self._enable_ad_button = bui.has_video_ads() self._enable_ad_button = plus.has_video_ads()
h = self._width * 0.5 + 110.0 h = self._width * 0.5 + 110.0
v = self._height - b_size[1] - 115.0 v = self._height - b_size[1] - 115.0
@ -561,7 +561,7 @@ class GetCurrencyWindow(bui.Window):
next_reward_ad_time next_reward_ad_time
) )
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow()
if bui.have_incentivized_ad() and ( if plus.have_incentivized_ad() and (
next_reward_ad_time is None or next_reward_ad_time <= now next_reward_ad_time is None or next_reward_ad_time <= now
): ):
self._ad_button_greyed = False self._ad_button_greyed = False
@ -732,8 +732,13 @@ class GetCurrencyWindow(bui.Window):
def _back(self) -> None: def _back(self) -> None:
from bauiv1lib.store import browser from bauiv1lib.store import browser
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
if self._transitioning_out: if self._transitioning_out:
return return
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, transition=self._transition_out edit=self._root_widget, transition=self._transition_out
) )
@ -745,7 +750,9 @@ class GetCurrencyWindow(bui.Window):
).get_root_widget() ).get_root_widget()
if not self._from_modal_store: if not self._from_modal_store:
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window(window) bui.app.ui_v1.set_main_menu_window(
window, from_window=self._root_widget
)
self._transitioning_out = True self._transitioning_out = True

View file

@ -36,8 +36,8 @@ class HelpWindow(bui.Window):
self._main_menu = main_menu self._main_menu = main_menu
assert bui.app.classic is not None assert bui.app.classic is not None
uiscale = bui.app.ui_v1.uiscale uiscale = bui.app.ui_v1.uiscale
width = 950 if uiscale is bui.UIScale.SMALL else 750 width = 1050 if uiscale is bui.UIScale.SMALL else 750
x_offs = 100 if uiscale is bui.UIScale.SMALL else 0 x_offs = 150 if uiscale is bui.UIScale.SMALL else 0
height = ( height = (
460 460
if uiscale is bui.UIScale.SMALL if uiscale is bui.UIScale.SMALL
@ -645,11 +645,16 @@ class HelpWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.mainmenu import MainMenuWindow from bauiv1lib.mainmenu import MainMenuWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, transition=self._transition_out edit=self._root_widget, transition=self._transition_out
) )
if self._main_menu: if self._main_menu:
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
MainMenuWindow(transition='in_left').get_root_widget() MainMenuWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )

View file

@ -9,7 +9,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import babase import bauiv1 as bui
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Iterable from typing import Iterable
@ -33,15 +33,15 @@ def split(chars: Iterable[str], maxlen: int) -> list[list[str]]:
def generate_emojis(maxlen: int) -> list[list[str]]: def generate_emojis(maxlen: int) -> list[list[str]]:
"""Generates a lot of UTF8 emojis prepared for babase.Keyboard pages""" """Generates a lot of UTF8 emojis prepared for bui.Keyboard pages"""
all_emojis = split([chr(i) for i in range(0x1F601, 0x1F650)], maxlen) all_emojis = split([chr(i) for i in range(0x1F601, 0x1F650)], maxlen)
all_emojis += split([chr(i) for i in range(0x2702, 0x27B1)], maxlen) all_emojis += split([chr(i) for i in range(0x2702, 0x27B1)], maxlen)
all_emojis += split([chr(i) for i in range(0x1F680, 0x1F6C1)], maxlen) all_emojis += split([chr(i) for i in range(0x1F680, 0x1F6C1)], maxlen)
return all_emojis return all_emojis
# ba_meta export keyboard # ba_meta export bauiv1.Keyboard
class EnglishKeyboard(babase.Keyboard): class EnglishKeyboard(bui.Keyboard):
"""Default English keyboard.""" """Default English keyboard."""
name = 'English' name = 'English'

View file

@ -21,7 +21,7 @@ class KioskWindow(bui.Window):
self._height = 340.0 self._height = 340.0
def _do_cancel() -> None: def _do_cancel() -> None:
QuitWindow(swish=True, back=True) QuitWindow(swish=True, quit_type=bui.QuitType.BACK)
super().__init__( super().__init__(
root_widget=bui.containerwidget( root_widget=bui.containerwidget(
@ -501,9 +501,15 @@ class KioskWindow(bui.Window):
def _do_full_menu(self) -> None: def _do_full_menu(self) -> None:
from bauiv1lib.mainmenu import MainMenuWindow from bauiv1lib.mainmenu import MainMenuWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
assert bui.app.classic is not None assert bui.app.classic is not None
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
bui.app.classic.did_menu_intro = True # prevent delayed transition-in bui.app.classic.did_menu_intro = True # prevent delayed transition-in
bui.app.ui_v1.set_main_menu_window(MainMenuWindow().get_root_widget()) bui.app.ui_v1.set_main_menu_window(
MainMenuWindow().get_root_widget(), from_window=self._root_widget
)

View file

@ -1142,6 +1142,10 @@ class LeagueRankWindow(bui.Window):
def _back(self) -> None: def _back(self) -> None:
from bauiv1lib.coop.browser import CoopBrowserWindow from bauiv1lib.coop.browser import CoopBrowserWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, transition=self._transition_out edit=self._root_widget, transition=self._transition_out
@ -1149,5 +1153,6 @@ class LeagueRankWindow(bui.Window):
if not self._modal: if not self._modal:
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
CoopBrowserWindow(transition='in_left').get_root_widget() CoopBrowserWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )

View file

@ -190,7 +190,6 @@ class MainMenuWindow(bui.Window):
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
from bauiv1lib.confirm import QuitWindow
from bauiv1lib.store.button import StoreButton from bauiv1lib.store.button import StoreButton
plus = bui.app.plus plus = bui.app.plus
@ -312,8 +311,8 @@ class MainMenuWindow(bui.Window):
else self._confirm_end_game else self._confirm_end_game
), ),
) )
# Assume we're in a client-session.
else: else:
# Assume we're in a client-session.
bui.buttonwidget( bui.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
position=(h - self._button_width * 0.5 * scale, v), position=(h - self._button_width * 0.5 * scale, v),
@ -361,7 +360,6 @@ class MainMenuWindow(bui.Window):
tilt_scale=0.0, tilt_scale=0.0,
draw_controller=store_button, draw_controller=store_button,
) )
self._tdelay += self._t_delay_inc self._tdelay += self._t_delay_inc
else: else:
self._store_button = None self._store_button = None
@ -422,7 +420,7 @@ class MainMenuWindow(bui.Window):
): ):
def _do_quit() -> None: def _do_quit() -> None:
QuitWindow(swish=True, back=True) bui.quit(confirm=True, quit_type=bui.QuitType.BACK)
bui.containerwidget( bui.containerwidget(
edit=self._root_widget, on_cancel_call=_do_quit edit=self._root_widget, on_cancel_call=_do_quit
@ -1040,30 +1038,47 @@ class MainMenuWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.confirm import QuitWindow from bauiv1lib.confirm import QuitWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
# Note: Normally we should go through bui.quit(confirm=True) but
# invoking the window directly lets us scale it up from the
# button.
QuitWindow(origin_widget=self._quit_button) QuitWindow(origin_widget=self._quit_button)
def _demo_menu_press(self) -> None: def _demo_menu_press(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.kiosk import KioskWindow from bauiv1lib.kiosk import KioskWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_right') bui.containerwidget(edit=self._root_widget, transition='out_right')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
KioskWindow(transition='in_left').get_root_widget() KioskWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
) )
def _show_account_window(self) -> None: def _show_account_window(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.account.settings import AccountSettingsWindow from bauiv1lib.account.settings import AccountSettingsWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
AccountSettingsWindow( AccountSettingsWindow(
origin_widget=self._account_button origin_widget=self._account_button
).get_root_widget() ).get_root_widget(),
from_window=self._root_widget,
) )
def _on_store_pressed(self) -> None: def _on_store_pressed(self) -> None:
@ -1071,6 +1086,10 @@ class MainMenuWindow(bui.Window):
from bauiv1lib.store.browser import StoreBrowserWindow from bauiv1lib.store.browser import StoreBrowserWindow
from bauiv1lib.account import show_sign_in_prompt from bauiv1lib.account import show_sign_in_prompt
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
plus = bui.app.plus plus = bui.app.plus
assert plus is not None assert plus is not None
@ -1083,7 +1102,8 @@ class MainMenuWindow(bui.Window):
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
StoreBrowserWindow( StoreBrowserWindow(
origin_widget=self._store_button origin_widget=self._store_button
).get_root_widget() ).get_root_widget(),
from_window=self._root_widget,
) )
def _is_benchmark(self) -> bool: def _is_benchmark(self) -> bool:
@ -1148,8 +1168,11 @@ class MainMenuWindow(bui.Window):
def _end_game(self) -> None: def _end_game(self) -> None:
assert bui.app.classic is not None assert bui.app.classic is not None
if not self._root_widget:
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return return
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
bui.app.classic.return_to_main_menu_session_gracefully(reset_ui=False) bui.app.classic.return_to_main_menu_session_gracefully(reset_ui=False)
@ -1165,39 +1188,54 @@ class MainMenuWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.creditslist import CreditsListWindow from bauiv1lib.creditslist import CreditsListWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
CreditsListWindow( CreditsListWindow(
origin_widget=self._credits_button origin_widget=self._credits_button
).get_root_widget() ).get_root_widget(),
from_window=self._root_widget,
) )
def _howtoplay(self) -> None: def _howtoplay(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.helpui import HelpWindow from bauiv1lib.helpui import HelpWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
HelpWindow( HelpWindow(
main_menu=True, origin_widget=self._how_to_play_button main_menu=True, origin_widget=self._how_to_play_button
).get_root_widget() ).get_root_widget(),
from_window=self._root_widget,
) )
def _settings(self) -> None: def _settings(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.settings.allsettings import AllSettingsWindow from bauiv1lib.settings.allsettings import AllSettingsWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
AllSettingsWindow( AllSettingsWindow(
origin_widget=self._settings_button origin_widget=self._settings_button
).get_root_widget() ).get_root_widget(),
from_window=self._root_widget,
) )
def _resume_and_call(self, call: Callable[[], Any]) -> None: def _resume_and_call(self, call: Callable[[], Any]) -> None:
@ -1206,10 +1244,12 @@ class MainMenuWindow(bui.Window):
def _do_game_service_press(self) -> None: def _do_game_service_press(self) -> None:
self._save_state() self._save_state()
if bui.app.classic is not None: if bui.app.plus is not None:
bui.app.classic.show_online_score_ui() bui.app.plus.show_game_service_ui()
else: else:
logging.warning('classic is required to show game service ui') logging.warning(
'plus feature-set is required to show game service ui'
)
def _save_state(self) -> None: def _save_state(self) -> None:
# Don't do this for the in-game menu. # Don't do this for the in-game menu.
@ -1280,35 +1320,50 @@ class MainMenuWindow(bui.Window):
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.gather import GatherWindow from bauiv1lib.gather import GatherWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
GatherWindow(origin_widget=self._gather_button).get_root_widget() GatherWindow(origin_widget=self._gather_button).get_root_widget(),
from_window=self._root_widget,
) )
def _watch_press(self) -> None: def _watch_press(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.watch import WatchWindow from bauiv1lib.watch import WatchWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
WatchWindow(origin_widget=self._watch_button).get_root_widget() WatchWindow(origin_widget=self._watch_button).get_root_widget(),
from_window=self._root_widget,
) )
def _play_press(self) -> None: def _play_press(self) -> None:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.play import PlayWindow from bauiv1lib.play import PlayWindow
# no-op if our underlying widget is dead or on its way out.
if not self._root_widget or self._root_widget.transitioning_out:
return
self._save_state() self._save_state()
bui.containerwidget(edit=self._root_widget, transition='out_left') bui.containerwidget(edit=self._root_widget, transition='out_left')
assert bui.app.classic is not None assert bui.app.classic is not None
bui.app.ui_v1.selecting_private_party_playlist = False bui.app.ui_v1.selecting_private_party_playlist = False
bui.app.ui_v1.set_main_menu_window( bui.app.ui_v1.set_main_menu_window(
PlayWindow(origin_widget=self._start_button).get_root_widget() PlayWindow(origin_widget=self._start_button).get_root_widget(),
from_window=self._root_widget,
) )
def _resume(self) -> None: def _resume(self) -> None:
@ -1316,7 +1371,7 @@ class MainMenuWindow(bui.Window):
bui.app.classic.resume() bui.app.classic.resume()
if self._root_widget: if self._root_widget:
bui.containerwidget(edit=self._root_widget, transition='out_right') bui.containerwidget(edit=self._root_widget, transition='out_right')
bui.app.ui_v1.clear_main_menu_window() bui.app.ui_v1.clear_main_menu_window(transition='out_right')
# If there's callbacks waiting for this window to go away, call them. # If there's callbacks waiting for this window to go away, call them.
for call in bui.app.ui_v1.main_menu_resume_callbacks: for call in bui.app.ui_v1.main_menu_resume_callbacks:

Some files were not shown because too many files have changed in this diff Show more