- Add two airports (north/south) with full geometry: runways, taxiways,
aprons, terminals, hangars, stands, and helipads; walkable airport
grounds extend beyond city bounds.
- Introduce ATC AI agent ("Torre de Controle City10") using AI_ATC_MODEL
to generate takeoff clearances; includes dispatch endpoint with
30-second cooldown and deterministic fallback on failure.
- Implement AI model fallback chain: preferred model → AI_FALLBACK_MODEL
before failing, applied in ChatController and PersonTalkController.
- Add luminous sign labels (letreiros) for plazas, beach, food, hospital,
school, city hall, and airports with day/night glow.
- Fix city presence cache: compute is_me per viewer instead of baking
into shared per-second cache to prevent cross-user flag leakage.
- Add tests: AirportTest, CityPresenceTest, SignLabelsTest, and
PersonTalkTest fallback model retry scenario.
264 lines
14 KiB
JSON
Executable File
264 lines
14 KiB
JSON
Executable File
{
|
|
"Login": "Iniciar sesión",
|
|
"Logout": "Cerrar sesión",
|
|
"Register": "Registrarse",
|
|
"Dashboard": "Panel",
|
|
"Email": "Correo electrónico",
|
|
"Password": "Contraseña",
|
|
"Password Confirmation": "Confirmar contraseña",
|
|
"Remember Me": "Recuérdame",
|
|
"Name": "Nombre",
|
|
"Save": "Guardar",
|
|
"Cancel": "Cancelar",
|
|
"Delete": "Eliminar",
|
|
"Edit": "Editar",
|
|
"Create": "Crear",
|
|
"Search": "Buscar",
|
|
"Back": "Volver",
|
|
"Welcome": "Bienvenido a City10",
|
|
"auth.failed": "Las credenciales proporcionadas no coinciden con nuestros registros.",
|
|
"auth.disabled": "Esta cuenta ha sido desactivada. Contacte al administrador.",
|
|
"auth.forbidden": "No tiene permiso para acceder a este recurso.",
|
|
"auth.logged_out": "Sesión cerrada exitosamente.",
|
|
"auth.throttle": "Demasiados intentos. Intente de nuevo en :seconds segundos.",
|
|
"legal.accept_required": "Debe aceptar los Términos de Uso y la Política de Privacidad antes de continuar.",
|
|
"legal.accepted": "Términos aceptados exitosamente.",
|
|
"legal.must_accept_terms": "Debe aceptar los Términos de Uso.",
|
|
"legal.must_accept_privacy": "Debe aceptar la Política de Privacidad.",
|
|
"legal.must_accept_cookies": "Debe aceptar la Política de Cookies.",
|
|
"validation.captcha_required": "Resuelva la verificación matemática.",
|
|
"validation.captcha_failed": "La respuesta de la verificación matemática es incorrecta.",
|
|
"validation.model_not_allowed": "El modelo de IA seleccionado no está en la lista de permitidos.",
|
|
"users.cannot_deactivate_self": "No puede desactivar su propia cuenta.",
|
|
"users.deactivated": "Cuenta desactivada exitosamente.",
|
|
"stores.deleted": "Tienda eliminada exitosamente.",
|
|
"agents.deleted": "Agente eliminado exitosamente.",
|
|
"welcome.tagline": "Una ciudad 3D viva en tu navegador, con agentes de IA autónomos — Alcalde, peatones, comerciantes y vehículos — decidiendo en tiempo real a través de OpenRouter.ai.",
|
|
"welcome.card1.title": "🌐 Ciudad 3D en Tiempo Real",
|
|
"welcome.card1.desc": "Explora calles, avenidas, puentes, ríos, plazas y edificios renderizados con Three.js directamente en tu navegador.",
|
|
"welcome.card2.title": "🤖 Agentes de IA",
|
|
"welcome.card2.desc": "El alcalde, los peatones y los comerciantes toman decisiones estratégicas usando modelos gratuitos de OpenRouter.ai.",
|
|
"welcome.card3.title": "🔒 Seguro y LGPD",
|
|
"welcome.card3.desc": "Autenticación diferenciada (Admin/User), CAPTCHA matemático y consentimiento auditado de términos conforme la legislación brasileña.",
|
|
"welcome.city.title": "🗺️ Elementos de la Ciudad (Fase 1)",
|
|
"welcome.city.desc": "La base de datos ya modela casas, edificios, escuelas, parques, plazas, semáforos, calles, avenidas, puentes, aeropuertos, ríos, industrias, tiendas y comerciantes — todos con coordenadas 3D (X, Y, Z) listas para el motor de renderizado.",
|
|
"welcome.no_account": "¿No tienes cuenta?",
|
|
"welcome.has_account": "¿Ya tienes cuenta?",
|
|
"nav.city": "Ciudad 3D",
|
|
"nav.admin": "Administración",
|
|
"dashboard.open_viewer": "Abrir visor 3D",
|
|
"dashboard.viewer_desc": "Explora el suelo de la ciudad, tiendas y agentes con cámara controlable.",
|
|
"dashboard.stores_title": "Tiendas",
|
|
"dashboard.stores_desc": "Tiendas registradas en la ciudad 3D.",
|
|
"dashboard.legal_title": "Consentimientos",
|
|
"dashboard.consent_history": "Ver historial de aceptaciones",
|
|
"legal.terms_label": "Términos",
|
|
"legal.privacy_label": "Privacidad",
|
|
"legal.cookies_label": "Cookies",
|
|
"admin.stores.title": "Gestionar Tiendas",
|
|
"admin.stores.manage": "Gestionar tiendas",
|
|
"admin.stores.admin_desc": "Crea tiendas y define su posición 3D en la ciudad.",
|
|
"admin.stores.new": "Nueva tienda",
|
|
"admin.stores.created": "Tienda creada exitosamente.",
|
|
"admin.stores.updated": "Tienda actualizada exitosamente.",
|
|
"admin.stores.edit_title": "Editar tienda",
|
|
"admin.stores.create_title": "Nueva tienda",
|
|
"admin.stores.empty": "Aún no hay tiendas registradas.",
|
|
"admin.stores.position": "Posición 3D en la ciudad",
|
|
"admin.stores.position_hint": "Haz clic en el suelo para fijar X/Z o escribe las coordenadas. Usa los controles para rotar/zoom.",
|
|
"admin.stores.pos_x": "Posición X",
|
|
"admin.stores.pos_y": "Altura Y (suelo = 0)",
|
|
"admin.stores.pos_z": "Posición Z",
|
|
"admin.stores.dimensions": "Dimensiones del edificio",
|
|
"admin.stores.width": "Ancho",
|
|
"admin.stores.height": "Alto",
|
|
"admin.stores.depth": "Profundidad",
|
|
"admin.stores.type": "Tipo de tienda",
|
|
"admin.stores.description": "Descripción",
|
|
"admin.stores.owner": "Dueño (usuario)",
|
|
"admin.stores.agent": "Agente de IA (comerciante)",
|
|
"admin.stores.is_open": "Tienda abierta",
|
|
"admin.stores.no_owner": "Sin dueño",
|
|
"admin.stores.no_agent": "Sin agente",
|
|
"admin.stores.actions": "Acciones",
|
|
"admin.stores.coords": "Coordenadas",
|
|
"admin.stores.confirm_delete": "¿Eliminar esta tienda de la ciudad?",
|
|
"city.title": "Visor 3D de la Ciudad",
|
|
"city.loading": "Cargando ciudad…",
|
|
"city.error": "Error al cargar los datos de la ciudad.",
|
|
"city.stores_count": "tiendas",
|
|
"city.agents_count": "agentes",
|
|
"city.hint": "Haz clic en la escena para controlar · WASD para caminar · Ratón para mirar · Esc para salir · Acércate a alguien para hablar",
|
|
"city.refresh": "Recargar",
|
|
"city.selected": "Seleccionada",
|
|
"city.open": "Abierta",
|
|
"city.closed": "Cerrada",
|
|
"city.hint_fps": "WASD para caminar · Ratón para mirar · Esc para salir · Clic en un NPC para chatear",
|
|
"city.position": "POSICIÓN",
|
|
"city.on_ground": "en el suelo",
|
|
"city.triangles": "tris de colisión",
|
|
"city.chat_placeholder": "Escribe tu mensaje…",
|
|
"city.chat_thinking": "pensando…",
|
|
"city.chat_responding": "respondiendo…",
|
|
"city.chat_accepted": "Mensaje enviado al agente.",
|
|
"city.chat_error": "Lo siento, no puedo responder ahora. Inténtalo de nuevo.",
|
|
"city.talk_ratelimited": "Muchos mensajes — espera un instante e inténtalo de nuevo.",
|
|
"city.chat_send": "Enviar",
|
|
"city.chat_with": "Chateando con",
|
|
"city.clock": "Hora",
|
|
"city.weather": "Clima",
|
|
"city.weather_clear": "Soleado",
|
|
"city.weather_cloudy": "Nublado",
|
|
"city.weather_rain": "Lluvia",
|
|
"city.weather_storm": "Tormenta",
|
|
"city.vehicles_count": "vehículos",
|
|
"city.pedestrians_count": "peatones",
|
|
"auth.pending": "Su cuenta espera la aprobación del administrador.",
|
|
"auth.pending_title": "Esperando aprobación",
|
|
"auth.pending_body": "Su registro fue recibido. Un administrador debe aprobar su cuenta antes de entrar a la ciudad. Puede cerrar esta página e intentar más tarde.",
|
|
"admin.citizens.title": "Ciudadanos",
|
|
"admin.citizens.hint": "Apruebe cuentas pendientes para crear su personaje en la ciudad.",
|
|
"admin.citizens.name": "Nombre",
|
|
"admin.citizens.status": "Estado",
|
|
"admin.citizens.character": "Personaje",
|
|
"admin.citizens.actions": "Acciones",
|
|
"admin.citizens.approve": "Aprobar",
|
|
"admin.citizens.approved": "Ciudadano aprobado y personaje creado.",
|
|
"admin.citizens.ban": "Banear",
|
|
"admin.citizens.banned": "Ciudadano baneado.",
|
|
"admin.citizens.cannot_ban_self": "No puede banear su propia cuenta.",
|
|
"admin.cities.title": "Ciudades y territorio",
|
|
"admin.cities.hint": "Cree nuevas ciudades o expanda el territorio (+40 por cuadra).",
|
|
"admin.cities.name": "Nombre de la ciudad",
|
|
"admin.cities.create": "Crear ciudad",
|
|
"admin.cities.created": "Ciudad creada.",
|
|
"admin.cities.bounds": "Límites",
|
|
"admin.cities.expansions": "Expansiones",
|
|
"admin.cities.expand": "Expandir",
|
|
"admin.cities.expanded": "Territorio expandido.",
|
|
"admin.cities.max_expansions": "Límite de expansiones alcanzado.",
|
|
"nav.citizens": "Ciudadanos",
|
|
"nav.cities": "Ciudades",
|
|
"city.action_unknown": "Acción desconocida.",
|
|
"city.action_ok": "Acción realizada.",
|
|
"city.no_food": "No tiene comida en el inventario.",
|
|
"city.no_water": "No tiene agua en el inventario.",
|
|
"city.no_house": "Necesita una casa terminada para dormir.",
|
|
"city.no_job": "No tiene empleo. Solicite una vacante.",
|
|
"city.no_school": "No hay escuela disponible en esta ciudad.",
|
|
"city.job_other_city": "Esa vacante es de otra ciudad.",
|
|
"city.job_education": "Educación insuficiente para esta vacante.",
|
|
"city.no_money": "Dinero insuficiente.",
|
|
"city.no_inventory": "Cantidad insuficiente en el inventario.",
|
|
"city.out_of_bounds": "Posición fuera de los límites de la ciudad.",
|
|
"city.no_materials": "Necesita 50 materiales para construir.",
|
|
"city.site_taken": "Este terreno ya está ocupado.",
|
|
"city.build_started": "Construcción iniciada. El ticker termina la casa.",
|
|
"city.social_unknown": "Acción social desconocida.",
|
|
"city.social_self": "No puede hacer eso consigo mismo.",
|
|
"city.social_exists": "La relación ya existe o está pendiente.",
|
|
"city.social_friend_sent": "Solicitud de amistad enviada.",
|
|
"city.social_friend_ok": "Amistad aceptada.",
|
|
"city.social_need_friend": "Primero deben ser amigos aceptados.",
|
|
"city.social_married": "Ya está casado(a).",
|
|
"city.social_married_ok": "Matrimonio realizado.",
|
|
"city.social_need_spouse": "Debe estar casado(a) para tener un hijo.",
|
|
"city.social_child_ok": "¡Nació un hijo en la ciudad!",
|
|
"city.chat_sent": "Mensaje enviado.",
|
|
"city.hud_hunger": "Hambre",
|
|
"city.hud_thirst": "Sed",
|
|
"city.hud_energy": "Energía",
|
|
"city.hud_money": "Dinero",
|
|
"city.hud_state": "Estado",
|
|
"city.hud_education": "Educación",
|
|
"city.hud_inventory": "Inventario",
|
|
"city.hud_jobs": "Empleos",
|
|
"city.hud_actions": "Acciones",
|
|
"city.hud_social": "Social",
|
|
"city.act_eat": "Comer",
|
|
"city.act_drink": "Beber",
|
|
"city.act_sleep": "Dormir",
|
|
"city.act_wake": "Despertar",
|
|
"city.act_work": "Trabajar",
|
|
"city.act_stop": "Parar",
|
|
"city.act_study": "Estudiar",
|
|
"city.act_buy": "Comprar kit",
|
|
"city.act_sell_v": "Vender producto",
|
|
"city.act_build": "Construir casa (50 mat.)",
|
|
"city.act_apply": "Solicitar",
|
|
"city.act_friend": "Amistad",
|
|
"city.act_marry": "Casarse",
|
|
"city.act_child": "Hijo",
|
|
"city.me": "Mi personaje",
|
|
"city.citizens_near": "Ciudadanos",
|
|
"city.apply_job": "Solicitar",
|
|
"city.buy_hint": "Compra 1 comida + 1 agua + 10 materiales",
|
|
"city.hospital_hit": "¡Te atropelló un vehículo! Internado en el hospital por 1 hora.",
|
|
"city.hospital_already": "Ya está internado en el hospital.",
|
|
"city.hospital_blocked": "Está internado y no puede hacer eso ahora.",
|
|
"city.hospital_bed": "Internado en el hospital",
|
|
"city.hospital_released": "Alta del hospital: libre para salir.",
|
|
"city.hospital_title": "Hospitalizado",
|
|
"city.hospital_left": "Alta en",
|
|
"city.audio": "Audio",
|
|
"city.vol_master": "General",
|
|
"city.vol_music": "Música",
|
|
"city.vol_sfx": "Efectos",
|
|
"city.mute": "Silenciar",
|
|
"city.audio_hint": "Volumen guardado en este dispositivo.",
|
|
"city.hud_health": "Salud",
|
|
"city.hud_exercise": "Ejercicios",
|
|
"city.exercise_use": "Pulse E para ejercitarse",
|
|
"city.exercise_active": "Ejercitándose",
|
|
"city.exercise_stopHint": "para parar",
|
|
"city.exercise_ok": "¡Bien! +2 de salud.",
|
|
"city.beach_need": "Para relajar, ve a la playa.",
|
|
"city.beach_ok": "¡Relajaste en la playa y recuperaste energía!",
|
|
"city.beach_full": "La energía y la salud ya están al máximo.",
|
|
"city.beach_busy": "Termina el ejercicio actual primero.",
|
|
"city.beach_start": "Descansando en la arena…",
|
|
"city.beach_prompt": "Relajar en la playa",
|
|
"city.beach_active": "Relajándote en la playa",
|
|
"city.atc_missing": "Ninguna torre de control configurada.",
|
|
"city.sign_plaza": "Plaza",
|
|
"city.sign_beach": "Playa",
|
|
"city.sign_food": "Comida",
|
|
"city.sign_hospital": "Hospital",
|
|
"city.sign_school": "Escuela",
|
|
"city.sign_cityhall": "Alcaldía",
|
|
"city.exercise_need_equipment": "Acérquese a un equipo de la plaza.",
|
|
"city.exercise_need_awake": "Debe estar despierto para ejercitarse.",
|
|
"city.exercise_tired": "Está demasiado cansado para ejercitarse.",
|
|
"city.exercise_max_health": "¡La salud ya está en el máximo!",
|
|
"city.exerciseStart": "Empezando a ejercitarse…",
|
|
"city.exerciseStop": "Ejercicio terminado.",
|
|
"city.ped_red": "Semáforo de peatón en rojo — espere la señal verde.",
|
|
"nav.world": "Mundo",
|
|
"admin.world.title": "Panel del mundo",
|
|
"admin.world.hint": "Métricas en vivo de la plataforma persistente.",
|
|
"admin.world.users": "Usuarios",
|
|
"admin.world.characters": "Personajes",
|
|
"admin.world.economy": "Economía",
|
|
"admin.world.trade_volume": "Volumen de trueques",
|
|
"admin.world.world": "Casas terminadas",
|
|
"admin.world.market": "Mercado",
|
|
"admin.world.missions": "Misiones",
|
|
"admin.world.health": "Salud media",
|
|
"admin.world.education": "Educación media",
|
|
"city.customize_saved": "Apariencia actualizada.",
|
|
"city.market_listed": "Anuncio publicado en el mercado.",
|
|
"city.market_bought": "¡Compra realizada!",
|
|
"city.market_unavailable": "Anuncio no disponible.",
|
|
"city.ride_need_stop": "Acérquese a una vía (autobús) o a los raíles (tren).",
|
|
"city.ride_bus_ok": "¡Has subido al autobús!",
|
|
"city.ride_train_ok": "¡Has subido al tren!",
|
|
"city.missions_done": "Misión completada",
|
|
"city.act_market": "Mercado",
|
|
"city.act_customize": "Apariencia",
|
|
"city.act_ride_bus": "Autobús",
|
|
"city.act_ride_train": "Tren",
|
|
"city.hud_minimap": "Mapa",
|
|
"city.online_now": "en línea",
|
|
"city.marketBuy": "Comprar"
|
|
}
|