---@class RuntimeI18n local i18n = {} local default_locale = "zh-Hans" local current_locale = default_locale local messages = { ["zh-Hans"] = { title = "Lua 飞行棋", roll_button = "掷骰子", dice_empty = "骰子: -", dice_value = "骰子: {value}", current_player = "当前玩家: {player}", ["player.red"] = "红方", ["player.blue"] = "蓝方", ["toast.move_first"] = "请先移动棋子", ["toast.no_movable_piece"] = "无可移动棋子", ["toast.invalid_piece"] = "该棋子不能移动" }, en = { title = "Lua Ludo", roll_button = "Roll", dice_empty = "Dice: -", dice_value = "Dice: {value}", current_player = "Current player: {player}", ["player.red"] = "Red", ["player.blue"] = "Blue", ["toast.move_first"] = "Move a piece first", ["toast.no_movable_piece"] = "No movable pieces", ["toast.invalid_piece"] = "This piece cannot move" } } ---@param locale? string ---@return string local function normalize_locale(locale) if type(locale) ~= "string" or locale == "" then return default_locale end locale = string.gsub(locale, "_", "-") if messages[locale] ~= nil then return locale end local language = string.match(locale, "^([A-Za-z]+)") if language ~= nil and messages[language] ~= nil then return language end return default_locale end ---@param value string ---@return string local function escape_pattern(value) return string.gsub(value, "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1") end ---@param template string ---@param vars? table ---@return string local function interpolate(template, vars) if vars == nil then return template end local result = template for key, value in pairs(vars) do result = string.gsub(result, "{" .. escape_pattern(key) .. "}", tostring(value)) end return result end ---@param ctx? RuntimeContext function i18n.configure(ctx) local locale = nil if ctx ~= nil and ctx.locale ~= nil then locale = ctx.locale.resolved or ctx.locale.requested or ctx.locale.default end current_locale = normalize_locale(locale) end ---@return string function i18n.locale() return current_locale end ---@param key string ---@param vars? table ---@return string function i18n.t(key, vars) local bundle = messages[current_locale] or messages[default_locale] local fallback = messages[default_locale] local value = bundle[key] or fallback[key] or key return interpolate(value, vars) end ---@param color PlayerColor ---@return string function i18n.player(color) return i18n.t("player." .. color) end return i18n