Compare commits

...
9 Commits
Author SHA1 Message Date
tresabhi 0368e9ceda feat: pink bot 2025-03-31 17:44:08 -05:00
tresabhi 28f365f762 fix: no class list 2025-03-31 17:39:42 -05:00
tresabhi 40a81f6b1b fix: class list 2025-03-31 17:39:01 -05:00
tresabhi 9475d22472 feat: uh hahaha you'll see ... again! 2025-03-31 17:36:40 -05:00
tresabhi 9538a03afb feat: uh hahaha you'll see 2025-03-31 16:54:32 -05:00
tresabhi d5d171bea6 4 2025-03-30 14:37:40 -05:00
tresabhi a9c9a90ac1 fix: disable /auction 2025-03-30 12:53:14 -05:00
tresabhi f7c562f8b6 fix: detect invalid 0-length translations 2025-03-30 12:51:34 -05:00
TrèsAbhi 836cf69f01 New Crowdin updates (#149)
* New translations en.json (Russian)

* New translations en.json (Ukrainian)

* New translations en.json (Spanish)

* New translations en.json (Chinese Simplified)
2025-03-26 14:37:29 -05:00
20 changed files with 461 additions and 217 deletions

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "blitzkit",
"private": true,
"version": "1.27.3",
"version": "1.27.4",
"description": "🎉 Tools for everything World of Tanks Blitz",
"type": "module",
"types": "./types.d.ts",
@@ -17,7 +17,6 @@ export function CommandWrapper({ children, fat }: CommandWrapperProps) {
width: '100%',
color: theme.colors.textHighContrast,
position: 'relative',
background: theme.colors.appBackground1,
}}
>
{children}
@@ -15,7 +15,8 @@ export function localizationObject(
(localizations, locale) => {
const { strings } = translator(locale);
const translation = literalsFunc(path(strings), literals);
const isValid = !strict || validNameRegex.test(translation);
const isValid =
(!strict || validNameRegex.test(translation)) && translation.length > 0;
if (!isValid) {
console.warn(
@@ -1,64 +0,0 @@
import {
ActionRowBuilder,
AttachmentBuilder,
ButtonBuilder,
EmbedBuilder,
InteractionEditReplyOptions,
InteractionReplyOptions,
MessageEditOptions,
} from 'discord.js';
import { InteractionReturnable } from '../../events/interactionCreate';
import { Writeable } from '../../types/writable';
import { jsxToPngThreaded } from '../blitzkit/jsxToPngThreaded';
import { RenderConfiguration } from '../blitzkit/renderConfiguration';
export async function normalizeInteractionReturnable(
returnable: InteractionReturnable,
) {
const images: [number, Buffer][] = [];
const reply: InteractionEditReplyOptions &
InteractionReplyOptions &
MessageEditOptions = {};
const awaitedReturnable = await returnable;
const normalizedReturnable = Array.isArray(awaitedReturnable)
? awaitedReturnable
: [awaitedReturnable];
let renderConfiguration = new RenderConfiguration();
await Promise.all(
normalizedReturnable.map(async (item, index) => {
if (typeof item === 'string') {
reply.content = item;
} else if (item instanceof EmbedBuilder) {
if (!reply.embeds) reply.embeds = [];
(reply.embeds as Writeable<typeof reply.embeds>).push(item);
} else if (item instanceof ButtonBuilder) {
if (!reply.components)
reply.components = [new ActionRowBuilder<ButtonBuilder>()];
(reply.components[0] as ActionRowBuilder<ButtonBuilder>).addComponents(
item,
);
} else if (item instanceof AttachmentBuilder) {
if (!reply.files) reply.files = [];
(reply.files as Writeable<typeof reply.files>).push(item);
} else if (item instanceof RenderConfiguration) {
renderConfiguration = item;
} else if (item === null) {
return;
} else {
const image = await jsxToPngThreaded(item, renderConfiguration);
images.push([index, image]);
}
}),
);
if (images.length > 0) {
images.sort(([a], [b]) => b - a);
if (!reply.files) reply.files = [];
images.forEach(([, image]) =>
(reply.files as Writeable<typeof reply.files>)?.push(image),
);
}
return reply;
}
@@ -0,0 +1,137 @@
import { imgur, isFunny } from '@blitzkit/core';
import {
ActionRowBuilder,
AttachmentBuilder,
ButtonBuilder,
EmbedBuilder,
InteractionEditReplyOptions,
InteractionReplyOptions,
MessageEditOptions,
} from 'discord.js';
import { InteractionReturnable } from '../../events/interactionCreate';
import { theme } from '../../stitches.config';
import { Writeable } from '../../types/writable';
import { jsxToPngThreaded } from '../blitzkit/jsxToPngThreaded';
import { RenderConfiguration } from '../blitzkit/renderConfiguration';
export async function normalizeInteractionReturnable(
returnable: InteractionReturnable,
) {
const images: [number, Buffer][] = [];
const reply: InteractionEditReplyOptions &
InteractionReplyOptions &
MessageEditOptions = {};
const awaitedReturnable = await returnable;
const normalizedReturnable = Array.isArray(awaitedReturnable)
? awaitedReturnable
: [awaitedReturnable];
let renderConfiguration = new RenderConfiguration();
await Promise.all(
normalizedReturnable.map(async (item, index) => {
if (typeof item === 'string') {
reply.content = item;
} else if (item instanceof EmbedBuilder) {
if (!reply.embeds) reply.embeds = [];
(reply.embeds as Writeable<typeof reply.embeds>).push(item);
} else if (item instanceof ButtonBuilder) {
if (!reply.components)
reply.components = [new ActionRowBuilder<ButtonBuilder>()];
(reply.components[0] as ActionRowBuilder<ButtonBuilder>).addComponents(
item,
);
} else if (item instanceof AttachmentBuilder) {
if (!reply.files) reply.files = [];
(reply.files as Writeable<typeof reply.files>).push(item);
} else if (item instanceof RenderConfiguration) {
renderConfiguration = item;
} else if (item === null) {
return;
} else {
let jsx: JSX.Element;
if (isFunny()) {
const angle = (Math.random() * 2 - 1) * 10;
jsx = (
<div
style={{
display: 'flex',
transform: `rotate(${angle}deg)`,
backgroundColor: theme.colors.appBackground1,
position: 'relative',
}}
>
{item}
<img
src={imgur('MWEny5u')}
style={{
display: 'block',
position: 'absolute',
top: 250,
left: '10%',
width: 100,
transform: 'translateY(-50%)',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
zIndex: 3,
}}
/>
<img
src={imgur('SboPMXY')}
style={{
position: 'absolute',
top: 280,
width: 80,
left: '50%',
transform: 'translate(-50%, -50%)',
}}
/>
<img
src={imgur('MWEny5u')}
style={{
display: 'block',
position: 'absolute',
top: 250,
right: '10%',
width: 100,
transform: 'translateY(-50%)',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
zIndex: 3,
}}
/>
</div>
);
} else {
jsx = (
<div
style={{
display: 'flex',
position: 'relative',
backgroundColor: theme.colors.appBackground1,
}}
>
{item}
</div>
);
}
const image = await jsxToPngThreaded(jsx, renderConfiguration);
images.push([index, image]);
}
}),
);
if (images.length > 0) {
images.sort(([a], [b]) => b - a);
if (!reply.files) reply.files = [];
images.forEach(([, image]) =>
(reply.files as Writeable<typeof reply.files>)?.push(image),
);
}
return reply;
}
@@ -1,3 +1,4 @@
import { isFunny } from '@blitzkit/core';
import {
ActionRowBuilder,
AttachmentBuilder,
@@ -16,14 +17,42 @@ import { psa } from '../../../core/discord/psa';
import { translator } from '../../../core/localization/translator';
import { Writeable } from '../../../types/writable';
const funnyResponses = [
"your dwecisions were calculawed buw man, you're bad at math 🥀🥀",
'senpai, have you consiwered not lacking 😳',
'let shoow a guess cutie... it was your team? 🤬🤬🤬',
'confiwence is key. unforwunawely you lost whe lock 🔒💔',
"when they say live green, they dwn't mean your 🌳 winrate 🌳",
'daddy viewing your swats, hewe? you really are brawe 😎',
'no surrie! your numwers are swill 💔',
"i would giwe you awvice, you won'w understand 🥀🥀",
"i diwn'w beliewe in negawive numwers unwil i saw your stats 😳😳😳",
'yeah daddy, use me more 🤤',
'uwu, hewe are your swaws... uwu 😋😋😋',
'hehehehe it tickles 😻',
'yeeeeeeeeeeeeahhhhhh that hits the spot 😳',
'ooooh yesss my circuits are starting to hurt yeeeeeeee 💥',
'wawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawawaw',
'https://tenor.com/tre3NETle2e.gif',
];
export async function handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>,
) {
await interaction.deferReply();
if (isFunny()) {
const response =
funnyResponses[Math.floor(Math.random() * funnyResponses.length)];
const waitTime = response.length * 60;
await interaction.editReply(response);
await new Promise((resolve) => setTimeout(resolve, waitTime));
}
const awaitedCommands = await commands;
const registry = awaitedCommands[interaction.commandName];
await interaction.deferReply();
try {
const returnable = await registry.handler(interaction);
@@ -15,7 +15,6 @@ import {
SlashCommandSubcommandsOnlyBuilder,
} from 'discord.js';
import { aboutCommand } from '../../commands/about';
import { auctionCommand } from '../../commands/auction';
import { breakdownCommand } from '../../commands/breakdown';
import { debugCommand } from '../../commands/debug';
import { evolutionCommand } from '../../commands/evolution';
@@ -80,7 +79,7 @@ interface CommandRegistryExplicit extends CommandRegistryBase {
export type CommandRegistry = CommandRegistryImplicit | CommandRegistryExplicit;
export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
auctionCommand,
// auctionCommand,
permissionsCommand,
debugCommand,
aboutCommand,
+9 -2
View File
@@ -1,4 +1,4 @@
import { assertSecret } from '@blitzkit/core';
import { assertSecret, isFunny } from '@blitzkit/core';
import { ActivityType, ShardingManager } from 'discord.js';
import {
discoveredIdsDefinitions,
@@ -45,7 +45,7 @@ const interval = setInterval(async () => {
const usernames = awaitedDiscoveredIdsDefinitions.count;
manager.broadcastEval(
(client, { servers, users, channels, tanks, usernames }) => {
async (client, { servers, users, channels, tanks, usernames }) => {
const bios = [
`Living in ${servers.toLocaleString()} servers`,
`Serving ${users.toLocaleString()} users`,
@@ -62,6 +62,13 @@ const interval = setInterval(async () => {
},
],
});
for (const guild of client.guilds.cache.values()) {
try {
const botMember = await guild.members.fetch(client.user.id);
await botMember.setNickname(isFunny ? 'FreakKit' : 'BlitzKit');
} catch {}
}
},
{ context: { servers, channels, users, tanks, usernames } },
);
+16 -1
View File
@@ -18,12 +18,27 @@ import {
} from '@radix-ui/colors';
import { createBorderStyles, createColors, createSpaces } from 'bepaint';
const funnyColors = {
pink1: crimsonDark.crimson5,
pink2: crimsonDark.crimson5,
pink3: crimsonDark.crimson5,
pink4: crimsonDark.crimson6,
pink5: crimsonDark.crimson6,
pink6: crimsonDark.crimson7,
pink7: crimsonDark.crimson7,
pink8: crimsonDark.crimson8,
pink9: crimsonDark.crimson9,
pink10: crimsonDark.crimson10,
pink11: crimsonDark.crimson11,
pink12: crimsonDark.crimson12,
};
// this isn't really a stitches config, but the object is compliant
export const theme = {
spaces: createSpaces(),
colors: {
...createColors(slateDark),
...createColors(funnyColors),
...createColors(slateDarkA, 'alpha'),
...createColors(slate, 'light'),
+1
View File
@@ -44,6 +44,7 @@ export * from './unwrapBlitzkitResponse';
export * from './votes';
// export * from './withCORSProxy';
export * from './createDefaultProvisions';
export * from './isFunny';
export * from './metaSortTank';
export * from './romanize';
export * from './youtubers';
+17
View File
@@ -0,0 +1,17 @@
const FUNNY_DATES: [number, number][] = [
[4, 1],
[4, 2],
[4, 3],
];
export function isFunny() {
return true;
const now = new Date();
return (
FUNNY_DATES.some(
([month, day]) => now.getMonth() === month - 1 && now.getDate() === day,
) || import.meta.env.DEBUG_FUNNY === 'true'
);
}
+105 -105
View File
@@ -843,105 +843,105 @@
},
"tech_tree": {
"title": "Árbol tecnológico",
"battle": "1 battle",
"battles": "%s1 battles",
"route": "Route %s1 of %s2"
"battle": "1 batalla",
"battles": "%s1 batallas",
"route": "Ruta %s1 de %s2"
},
"game_modes": {
"title": "Game mode abilities"
"title": "Habilidades del modo de juego"
},
"review": {
"title": "Review videos",
"title": "Vídeos de reseña",
"disclaimer": "BlitzKit no respalda ningún vídeo de reseñas.",
"join": "Apply to %s1 YouTuber program"
"join": "Aplica para el programa de YouTube de %s1"
},
"configuration": {
"title": "",
"modules": {
"title": "Modules",
"stock": "Stock",
"upgrade": "Upgrade"
"title": "Módulos",
"stock": "Base",
"upgrade": "Mejorar"
},
"equipment": {
"title": "Equipment",
"clear": "Clear"
"title": "Equipo",
"clear": "Limpiar"
},
"provisions": {
"title": "Provisiones",
"clear": "Limpiar"
},
"consumables": {
"title": "Consumables",
"clear": "Clear",
"info": "Yellow consumables do not affect the statistics."
"title": "Consumibles",
"clear": "Limpiar",
"info": "Consumibles amarillos no afectan las estadísticas."
},
"skills": {
"title": "Crew skills",
"clear": "Clear",
"maximize": "Maximize",
"info": "Yellow skills only apply under special circumstances. Hold Space to quickly toggle between level 0 and 7."
"title": "Habilidades de tripulación",
"clear": "Limpiar",
"maximize": "Maximizar",
"info": "Las habilidades en amarillo solo se aplican en circunstancias especiales. Mantenga el espacio para cambiar rápidamente entre los niveles 0 y 7."
},
"miscellaneous": {
"title": "Misceláneo"
}
},
"characteristics": {
"title": "Characteristics",
"title": "Características",
"compare": {
"label": "Compare against",
"class": "Tier %s1 %s2",
"tier": "All of tier %s1",
"all": "All tanks"
"label": "Comparar con",
"class": "Nivel %s1 - %s2",
"tier": "Todos de nivel %s1",
"all": "Todos los tanques"
},
"values": {
"shell_index": "Shell %s1",
"at_distance": "At %s1m",
"at_distance_slider_label": "Distance",
"dispersion_at_distance": "Dispersion at %s1m",
"gun_flexibility": "Gun flexibility",
"speed": "Speed",
"terrain_coefficients": "Terrain coefficients",
"raw_terrain_coefficients": "Raw terrain coefficients",
"power_to_weight_ratio": "Power to weight ratio",
"hull_traverse_speed": "Hull traverse speed",
"camouflage": "Camouflage",
"reload": "Reload",
"crewCount": "Crew count",
"shell_index": "Proyectil %s1",
"at_distance": "A %s1m",
"at_distance_slider_label": "Distancia",
"dispersion_at_distance": "Dispersión a %s1m",
"gun_flexibility": "Flexibilidad del arma",
"speed": "Velocidad",
"terrain_coefficients": "Coeficientes de terreno",
"raw_terrain_coefficients": "Coeficientes de terreno en bruto",
"power_to_weight_ratio": "Relación peso-potencia",
"hull_traverse_speed": "Velocidad de rotación del casco",
"camouflage": "Camuflaje",
"reload": "Recarga",
"crewCount": "Cantidad de tripulantes",
"shellNormalization": "Normalización",
"shellRicochet": "Rebote",
"dpm": "DPM",
"dpmEffective": "Effective at 60s",
"shells": "Shells",
"mostOptimalShellIndex": "Most optimal shell",
"shellReloads": "Shell reloads",
"shellReload": "Shell reload",
"shells": "Proyectiles",
"mostOptimalShellIndex": "Proyectil más óptimo",
"shellReloads": "Tiempos de recarga",
"shellReload": "Tiempo de recarga",
"intraClip": "Intra-clip",
"caliber": "Calibre",
"penetration": "Penetración",
"damage": "Daño",
"clipDamage": "Clipping potential",
"moduleDamage": "Module damage",
"moduleDamage": "Daño a módulos",
"explosionRadius": "Radio de Explosión",
"shellVelocity": "Shell velocity",
"aimTime": "Aim time",
"dispersion": "Still",
"dispersionMoving": "Moving",
"shellVelocity": "Velocidad del proyectil",
"aimTime": "Tiempo de apuntado",
"dispersion": "Quieto",
"dispersionMoving": "En movimiento",
"dispersionHullTraversing": "Hull traversing",
"dispersionTurretTraversing": "Turret traversing",
"dispersionShooting": "Shooting",
"dispersionGunDamaged": "Gun damaged",
"gunDepression": "Depression",
"gunElevation": "Elevation",
"gunFrontalDepression": "Frontal depression",
"gunFrontalElevation": "Frontal elevation",
"gunRearDepression": "Rear depression",
"gunRearElevation": "Rear elevation",
"dispersionShooting": "Disparando",
"dispersionGunDamaged": "Arma dañada",
"gunDepression": "Depresión",
"gunElevation": "Elevación",
"gunFrontalDepression": "Depresión frontal",
"gunFrontalElevation": "Elevación frontal",
"gunRearDepression": "Depresión trasera",
"gunRearElevation": "Elevación trasera",
"azimuthLeft": "Azimuth left",
"azimuthRight": "Azimuth right",
"speedForwards": "Forwards",
"speedBackwards": "Backwards",
"hardTerrainCoefficient": "Hard",
"hardTerrainCoefficientRaw": "Hard",
"speedForwards": "Avance",
"speedBackwards": "Marcha atrás",
"hardTerrainCoefficient": "Duro",
"hardTerrainCoefficientRaw": "Duro",
"mediumTerrainCoefficient": "Medio",
"mediumTerrainCoefficientRaw": "Medio",
"softTerrainCoefficient": "Suave",
@@ -1026,7 +1026,7 @@
"maximize": "Maximizar"
},
"modules": {
"stock": "Stock",
"stock": "Base",
"upgrade": "Mejorar"
},
"provisions": {
@@ -1107,22 +1107,22 @@
},
"no_battles": {
"title": "No battles",
"hint": "Go ahead and play a game"
"hint": "Sigue adelante y juega una partida"
},
"table": {
"tank": "Tanque",
"total": "Total",
"remove": "Remove"
"remove": "Remover"
}
},
"tier_list": {
"name": "Tier list",
"button": "Rank tanks",
"description": "Rank Blitz tanks",
"seo_description": "Explore tier lists ranking tanks from best to worst, based on player ratings and statistical performance in World of Tanks Blitz",
"seo_description": "Explora las listas de clasificación de los tanques de mejor a peor, basadas en las calificaciones de los jugadores y el rendimiento estadístico en World of Tanks Blitz",
"buttons": {
"reset": "Restablecer",
"share": "Share"
"share": "Compartir"
}
},
"embed": {
@@ -1131,54 +1131,54 @@
"description": "Embeds for streaming",
"seo_description": "Create embeds for streaming World of Tanks Blitz with extreme customization",
"coming_soon": "More embeds coming soon.",
"suggest": "Suggest ideas.",
"suggest": "Sugerir ideas.",
"preview": {
"title": "Example preview",
"upload": "Upload test background"
},
"configuration": {
"import": {
"title": "Import",
"description": "Paste your current URL if you have one already to import your settings",
"hint": "Paste URL...",
"apply": "Apply",
"idiot_title": "Invalid URL",
"idiot_description": "Try pasting the URL that BlitzKit previously generated, you silly goose!",
"title": "Importar",
"description": "Pega tu URL actual si ya tienes una para importar la configuración",
"hint": "Pegar URL...",
"apply": "Aplicar",
"idiot_title": "URL inválida",
"idiot_description": "Intenta pegar la URL que BlitzKit generó anteriormente, ¡Torpe!",
"idiot_button": "Okay, my bad"
},
"export": {
"title": "Export",
"description": "Copy all properties for you streaming software",
"title": "Exportar",
"description": "Copiar todas las propiedades para tu software de streaming",
"generate": {
"button": "Generate URL",
"title": "Generate URL",
"subtitle": "Search an account to track",
"cancel": "Cancel",
"button": "Generar URL",
"title": "Generar URL",
"subtitle": "Buscar una cuenta para seguir",
"cancel": "Cancelar",
"success": {
"title": "Copy URL",
"info": "Generated the URL for %s1. The embed will start tracking as soon as the URL is pasted. Reset at any time by right-clicking on PC or long-pressing on mobile and then selecting \"Reset\".",
"title": "Copiar URL",
"info": "Se generó la URL para %s1. El embebido comenzará a rastrear tan pronto como se pegue. Restablece en cualquier momento haciendo clic derecho en PC o manteniendo presionado en móvil y luego seleccionando \"Restablecer\".",
"back": "Volver",
"copy": "Copy URL"
"copy": "Copiar URL"
}
},
"css": "Copy CSS",
"width": "Copy Width",
"height": "Copy Height",
"css": "Copiar CSS",
"width": "Copiar ancho",
"height": "Copiar altura",
"framerate": "Copy Framerate"
},
"customize": {
"title": "Customize",
"title": "Personalizar",
"reset": "Restablecer",
"description": "Bells and whistles of your embed"
}
},
"types": {
"breakdown": {
"name": "Breakdown",
"name": "Desglose",
"options": {
"width": "Ancho",
"height": "Altura",
"showTotal": "Show total",
"showTotal": "Mostrar total",
"listGap": "List gap",
"listMaxTanks": "Max tanks",
"cardRadius": "Card radius",
@@ -1189,25 +1189,25 @@
"cardTitleClassIcon": "Card title class icon",
"cardBodyBackgroundColor": "Card body background color",
"cardBodyPadding": "Card body padding",
"columnGap": "Column gap",
"columnValue": "Column value",
"columnLabel": "Column label",
"column1": "Column 1",
"column2": "Column 2",
"column3": "Column 3",
"column4": "Column 4",
"column1CustomLabel": "Column 1 label",
"column2CustomLabel": "Column 2 label",
"column3CustomLabel": "Column 3 label"
"columnGap": "Espacio entre columnas",
"columnValue": "Valor de columna",
"columnLabel": "Etiqueta de columna",
"column1": "Columna 1",
"column2": "Columna 2",
"column3": "Columna 3",
"column4": "Columna 4",
"column1CustomLabel": "Etiqueta de la columna 1",
"column2CustomLabel": "Etiqueta de la columna 2",
"column3CustomLabel": "Etiqueta de la columna 3"
}
}
}
},
"charts": {
"name": "Charts",
"name": "Gráficos",
"button": "Nerd out",
"description": "Lots of graphs",
"seo_description": "Charts and graphs on anything and everything about tanks, players, and events in World of Tanks Blitz"
"seo_description": "Gráficos y tablas sobre todo lo relacionado con tanques, jugadores y eventos en World of Tanks Blitz"
},
"rating": {
"name": "Rating",
@@ -1218,11 +1218,11 @@
"discord": {
"name": "Discord bot",
"button": "Install now",
"description": "Stats right in Discord",
"seo_description": "Get stats right in Discord with BlitzKit's Discord bot"
"description": "Estadísticas en Discord",
"seo_description": "Obtén estadísticas en Discord con el bot de Discord de BlitzKit"
},
"more": {
"name": "More coming soon",
"name": "Más próximamente",
"button": "Join Discord",
"description": "What we're making",
"seo_description": "What we're making with BlitzKit"
@@ -1241,7 +1241,7 @@
},
"blitz_analysis": {
"name": "BlitzAnalysis[]",
"button": "Analyze now",
"button": "Analizar ahora",
"description": "Rich historic average stats",
"seo_description": "Rich historic average stats in World of Tanks Blitz"
},
@@ -1253,19 +1253,19 @@
}
},
"footer": {
"motto": "Everything World of Tanks Blitz",
"copyright": "Unaffiliated with Wargaming or any service",
"motto": "Todo sobre World of Tanks Blitz",
"copyright": "No afiliado con Wargaming u otros servicios",
"about": {
"title": "About",
"credits": "Credits",
"discord": "Discord",
"github": "GitHub",
"patches": "Patches"
"patches": "Parches"
},
"legal": {
"title": "Legal",
"privacy": "Privacy policy",
"terms": "Terms of service"
"privacy": "Política de Privacidad",
"terms": "Términos del servicio"
}
}
}
+3 -3
View File
@@ -716,7 +716,7 @@
"label": "Сортировка",
"fire": "Стрельба",
"maneuverability": "Манёвренность",
"survivability": "Живучесть"
"survivability": "Выживаемость"
},
"direction": {
"label": "Направление",
@@ -975,7 +975,7 @@
}
},
"firepower": {
"title": "Огневая мощь"
"title": "Стрельба"
},
"crew": {
"title": "Мастерство экипажа",
@@ -991,7 +991,7 @@
"title": "Манёвренность"
},
"survivability": {
"title": "Живучесть"
"title": "Выживаемость"
}
},
"compare": {
+12 -12
View File
@@ -86,14 +86,14 @@
"other": "Збірна нація"
},
"nations_adjectives": {
"ussr": "Радянська",
"germany": "Німецька",
"usa": "Американська",
"china": "Китайська",
"uk": "Британська",
"france": "Французька",
"japan": "Японська",
"european": "Європейська",
"ussr": "Радянський",
"germany": "Німецький",
"usa": "Американський",
"china": "Китайський",
"uk": "Британський",
"france": "Французький",
"japan": "Японський",
"european": "Європейський",
"other": "Гібрид"
},
"tank_class_short": {
@@ -363,8 +363,8 @@
"tier_1": "# %s1 це рівень I\n\nТанки рівню I завжди відкриті для всіх гравців безкоштовно.",
"already_researched": "# %s1 уже досліджено!\n\nСпробуйте забезпечити `starting-tank` коли використовуєте команду щоб подивитись підсумки гілки, яку ви вже дослідили.",
"start_end_equal": "# %s1 було надано двічі\n\nПереконайся, що `starting-tank` та `target-tank` різні.",
"tanks_not_on_line": "# %s1 and %s2 are not on the same line\n\nMake sure `starting-tank` and `target-tank` are on the same tech-tree line.",
"unordered": "# %s1 higher tiered to %s2\n\nMake sure to provide %s3 as the `starting-tank` instead as it is the lower tiered tank."
"tanks_not_on_line": ".",
"unordered": ""
}
},
"about": {
@@ -544,7 +544,7 @@
"options": {
"limit": {
"name": "ліміт",
"description": "How many neighbors to display (default: %s1)"
"description": ""
},
"season": {
"name": "season",
@@ -594,7 +594,7 @@
}
},
"ping": {
"name": "ping",
"name": "",
"description": "Check wether the bot is alive.",
"body": {
"pong": "Pong 🏓",
+21 -21
View File
@@ -754,7 +754,7 @@
"tank_seo_description": "%s1-Tier %s2 %s3 %s4 | %s5 Tankopedia | 戰車世界閃擊戰 (WoTB)",
"sandbox": {
"poses": {
"hull_down": "坦克下部",
"hull_down": "戰車下部",
"face_hug": "面部色调",
"default": "預設"
},
@@ -897,21 +897,21 @@
"shell_index": "炮弹 %s1",
"at_distance": "在 %s1m",
"at_distance_slider_label": "距离",
"dispersion_at_distance": "%s1米的散射度",
"dispersion_at_distance": "%s1公尺擴散度",
"gun_flexibility": "炮控灵活度",
"speed": "速度",
"terrain_coefficients": "地势系数",
"raw_terrain_coefficients": "原始地形系数",
"power_to_weight_ratio": "推重比",
"hull_traverse_speed": "炮塔旋转速度",
"camouflage": "伪装",
"camouflage": "偽裝",
"reload": "裝填",
"crewCount": "乘员人数",
"shellNormalization": "轉正",
"shellRicochet": "跳彈",
"dpm": "每分钟伤害",
"dpm": "每分鍾傷害血量",
"dpmEffective": "60秒内生效",
"shells": "炮弹 ",
"shells": "砲彈",
"mostOptimalShellIndex": "最优炮弹",
"shellReloads": "炮弹重装",
"shellReload": "炮弹重装",
@@ -1040,19 +1040,19 @@
"performance": {
"name": "性能表现",
"button": "查看坦克",
"description": "坦克性能统计",
"seo_description": "最好的坦克及其在世界坦克闪电战中的表现",
"description": "戰車性能統計",
"seo_description": "最好的戰車及其在戰車世界閃擊戰中的表現",
"estimation": {
"body": "基于 %s1个玩家的估计数据。更新 %s2 之前。",
"hours": "%s1 小时",
"minutes": "%s1 分钟"
"hours": "%s1 小時",
"minutes": "%s1 分鐘"
},
"player_count": {
"label": "玩家数量"
},
"table": {
"tanks": {
"header": "坦克",
"header": "戰車",
"total": "全部"
},
"stats": {
@@ -1068,15 +1068,15 @@
"hits": "命中數",
"damage_ratio": "伤害效率",
"damage_taken": "伤害值",
"capture_points": "占领值"
"capture_points": "佔領點數"
}
}
},
"gallery": {
"name": "图库",
"button": "浏览全部",
"description": "Blitz玩家头像",
"seo_description": "所有坦克闪电战玩家头像",
"name": "圖庫",
"button": "瀏覽所有",
"description": "Blitz 玩家頭像",
"seo_description": "所有戰車世界閃擊戰玩家頭像",
"last_updated": "最後更新於 %s1",
"search": {
"hint": "搜尋頭像……",
@@ -1131,17 +1131,17 @@
"description": "串流嵌入功能",
"seo_description": "創建具有極高自訂化的《戰車世界:閃擊戰》串流嵌入功能",
"coming_soon": "更多嵌入功能即將推出。",
"suggest": "建议与想法",
"suggest": "建議與想法。",
"preview": {
"title": "示例预览",
"upload": "上传测试背景"
"title": "範例",
"upload": "上傳測試背景"
},
"configuration": {
"import": {
"title": "导入",
"title": "導入",
"description": "如果您已经有一个要导入您的设置,请粘贴您当前的 URL",
"hint": "粘贴链接...",
"apply": "应用",
"hint": "貼上 URL……",
"apply": "套用",
"idiot_title": "無效的 URL",
"idiot_description": "試著貼上 BlitzKit 先前生成的網址吧,你這隻傻鵝!",
"idiot_button": "好吧,我的錯"
@@ -0,0 +1,37 @@
<script>
function funnify() {
document.body.querySelectorAll('*').forEach((element) => {
element.childNodes.forEach((node) => {
if (node.nodeType !== 3 || !node.textContent) return;
node.textContent = node.textContent
.replaceAll(/[tdkqgp]/g, 'w')
.replaceAll(/[TDKQGP]/g, 'W');
});
});
}
funnify();
setInterval(funnify, 1000);
let mouseDown = false;
document.addEventListener('mousedown', () => (mouseDown = true));
document.addEventListener('mouseup', () => (mouseDown = false));
document.addEventListener('mousemove', (e) => {
if (mouseDown) return;
const star = document.createElement('div');
star.classList.add('star');
star.innerHTML = '⭐';
document.body.appendChild(star);
star.style.left = `${e.clientX}px`;
star.style.top = `${e.clientY}px`;
setTimeout(() => {
star.remove();
}, 600);
});
</script>
@@ -7,6 +7,7 @@ import Navbar from '../components/Navbar.astro';
import Party3 from '../components/Party3.astro';
import './base.css';
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
import Funny from '../components/Funny.astro';
export interface Props {
noFooter?: boolean;
@@ -23,6 +24,10 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
<link rel="icon" type="image/x-icon" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="sitemap" href="/sitemap-index.xml" />
<link
href="https://fonts.googleapis.com/css2?family=Schoolbell&display=swap"
rel="stylesheet"
/>
<Party3 />
@@ -55,6 +60,8 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
</head>
<body>
<Funny />
<BlitzKitTheme>
<Flex direction="column" minHeight="100vh">
<Navbar />
+44
View File
@@ -2,4 +2,48 @@
body {
margin: 0;
cursor:
url(https://i.imgur.com/MeQQWCX.png) 16 16,
auto;
}
* {
font-family: 'Schoolbell', cursive !important;
}
.radix-themes {
--gray-1: var(--crimson-5);
--gray-2: var(--crimson-5);
--gray-3: var(--crimson-5);
--gray-4: var(--crimson-6);
--gray-5: var(--crimson-6);
--gray-6: var(--crimson-7);
--gray-7: var(--crimson-7);
--gray-8: var(--crimson-8);
--gray-9: var(--crimson-9);
--gray-10: var(--crimson-10);
--gray-11: var(--crimson-11);
--gray-12: var(--crimson-12);
}
.star {
position: fixed;
color: yellow;
font-size: 20px;
pointer-events: none;
animation:
fade-out 0.6s ease-out forwards,
move-up 0.6s ease-out forwards;
}
@keyframes fade-out {
to {
opacity: 0;
}
}
@keyframes move-up {
to {
transform: translateY(20px);
}
}
@@ -1,7 +1,8 @@
---
import { assertSecret } from '@blitzkit/core';
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '@blitzkit/i18n';
import { Box, Flex, Heading, Link } from '@radix-ui/themes';
import { literals } from '@blitzkit/i18n/src/literals';
import { Box, Flex, Heading, Link, Quote } from '@radix-ui/themes';
import type { GetStaticPaths } from 'astro';
import { AesonPlug } from '../../components/AesonPlug';
import { HomeLocaleSwitcher } from '../../components/Home/HomeLocaleSwitcher';
@@ -21,7 +22,6 @@ import {
tierListTool,
} from '../../constants/tools';
import { getStrings } from '../../core/i18n/getStrings';
import { literals } from '@blitzkit/i18n/src/literals';
import BaseLayout from '../../layouts/BaseLayout.astro';
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
@@ -45,6 +45,20 @@ export const getStaticPaths = (() => {
<BaseLayout>
<HomeHero />
<Flex justify="center" pt="6" px="8">
<Flex flexGrow="1" maxWidth="32rem" justify="center">
<Quote
className="no-funny"
style={{
fontSize: '1.3em',
}}
>
It has come to our attention that tanks are very harsh objects. To even
it out, we made the website a pretty pretty princess {'<'}3
</Quote>
</Flex>
</Flex>
<HomeLocaleSwitcher {locale} client:load />
{
Submodule submodules/CUE4Parse added at 624e07c8c3.