﻿---@diagnostic disable: undefined-global

local ADDON_NAME = ...

local TARGET_ADDONS = {
    [string.lower(ADDON_NAME or "")] = true,
    ["exboss"] = true,
    ["exbossdata"] = true,
    ["exboss-exwind"] = true,
    ["exwindcore"] = true,
    ["exwindtools"] = true,
}

local MAP_NAME_TRANSLATIONS = {
    ["è¨éš†çŸ¿å‘"] = "Pit of Saron",
    ["é€šå¤©å³°"] = "Skyreach",
    ["æ‰§æ”¿å›¢ä¹‹åº§"] = "Seat of the Triumvirate",
    ["è‰¾æ°æ–¯äºšå­¦é™¢"] = "Algeth'ar Academy",
    ["é£Žè¡Œè€…ä¹‹å¡”"] = "Windrunner Spire",
    ["é­”å¯¼å¸ˆå¹³å°"] = "Magisters' Terrace",
    ["è¿ˆè¨æ‹‰æ´žçªŸ"] = "Maisara Caverns",
    ["è™šå½±å°–å¡”"] = "The Voidspire",
    ["è¿›å†›å¥Žå°”ä¸¹çº³æ–¯"] = "March on Quel'Danas",
    ["èŠ‚ç‚¹å¸Œçº³æ–¯"] = "Nexus-Point Xenas",
    ["æ¢¦å¢ƒè£‚éš™"] = "The Dreamrift",
    ["ç£¨éš¾é«˜åœ°"] = "Priory of the Sacred Flame",
    ["Algeth'ar Academy"] = "Algeth'ar Academy",
    ["Windrunner Spire"] = "Windrunner Spire",
    ["Magisters' Terrace"] = "Magisters' Terrace",
    ["Maisara Caverns"] = "Maisara Caverns",
    ["Nexus-Point Xenas"] = "Nexus-Point Xenas",
    ["The Violet Hold"] = "The Voidspire",
}

local CANONICAL_MAP_NAME_TRANSLATIONS = {
    ["艾杰斯亚学院"] = "Algeth'ar Academy",
    ["萨隆矿坑"] = "Pit of Saron",
    ["通天峰"] = "Skyreach",
    ["执政团之座"] = "Seat of the Triumvirate",
    ["风行者之塔"] = "Windrunner Spire",
    ["魔导师平台"] = "Magisters' Terrace",
    ["迈萨拉洞穴"] = "Maisara Caverns",
    ["节点希纳斯"] = "Nexus-Point Xenas",
    ["Algeth'ar Academy"] = "Algeth'ar Academy",
    ["Pit of Saron"] = "Pit of Saron",
    ["Skyreach"] = "Skyreach",
    ["Seat of the Triumvirate"] = "Seat of the Triumvirate",
    ["Windrunner Spire"] = "Windrunner Spire",
    ["Magister's Terrace"] = "Magisters' Terrace",
    ["Magisters' Terrace"] = "Magisters' Terrace",
    ["Maisara Caverns"] = "Maisara Caverns",
    ["Nexus-Point Xenas"] = "Nexus-Point Xenas",
    ["Eco-Dome Al'dani"] = "Algeth'ar Academy",
    ["The Dawnbreaker"] = "Windrunner Spire",
    ["Ara-Kara, City of Echoes"] = "Maisara Caverns",
    ["Operation: Floodgate"] = "Nexus-Point Xenas",
}

local function TranslateMapName(name)
    local mapName = (type(name) == "string" and name ~= "") and name or nil

    if not mapName then
        return name
    end

    local canonical = CANONICAL_MAP_NAME_TRANSLATIONS[mapName]
    if canonical and canonical ~= "" then
        return canonical
    end

    local translated = MAP_NAME_TRANSLATIONS[mapName]
    if translated and translated ~= "" then
        return translated
    end

    return name
end

local function SafeNonEmptyString(value)
    if type(value) == "string" and value ~= "" then
        return value
    end
    return nil
end

local function SafeString(value)
    if type(value) == "string" then
        return value
    end
    return nil
end

local function GetTranslatableString(value)
    if type(value) ~= "string" then
        return nil
    end
    -- gsub is safe in Lua as long as input is string and pattern is valid
    local text = string.gsub(value, "^", "")
    if type(text) == "string" then
        return text
    end
    return nil
end

local function SafeLower(value)
    local text = SafeNonEmptyString(value)
    if not text then
        return nil
    end
    -- string.lower is safe in Lua as long as input is string
    return string.lower(text)
end

local FAST_EXACT_REPLACEMENTS = {
    ["启用"] = "Enable",
    ["启用颜色覆盖"] = "Enable Color Overlay",
    ["其他方案"] = "Other Scheme",
    ["中央文本"] = "Center Text",
    ["中央警告"] = "Center Warning",
    ["施法开始"] = "Cast Start",
    ["提前"] = "Early",
    ["提前(秒)"] = "Pre-Alert (sec)",
    ["提前5秒"] = "Pre-Alert 5s",
    ["中央文本内容（可用 {name}）"] = "Center Text Content (supports {name})",
    ["(可用 {name})"] = "(supports {name})",
    ["计时条改名"] = "Rename Timer Bar",
    ["语音设置"] = "Voice Settings",
    ["文本设置"] = "Text Settings",
    ["语音来源"] = "Voice Source",
    ["语音标签"] = "Voice Label",
    ["语音包标签"] = "Voice Pack Label",
    ["LSM音效"] = "LSM Sound",
    ["自定义路径"] = "Custom Path",
    ["文件路径"] = "File Path",
    ["试听"] = "Preview",
    ["秒"] = "sec",
    ["高级条件（事件窗口 + BOSS读条）"] = "Advanced Conditions (Event Window + Boss Cast)",
    ["启用高级条件"] = "Enable Advanced Conditions",
    ["窗口前(秒)"] = "Window Before (sec)",
    ["窗口后(秒)"] = "Window After (sec)",
    ["命中后显示圆环"] = "Show Ring After Hit",
    ["12.0大秘境"] = "12.0 Mythic+",
    ["12.0团本"] = "12.0 Raid",
    ["解放安德麦"] = "Liberation of Undermine",
    ["尼鲁巴尔王宫"] = "Nerub-ar Palace",
    ["永恒王宫"] = "The Eternal Palace",
    ["团本坦克"] = "Raid Tank",
    ["团本DPS"] = "Raid DPS",
    ["团本治疗"] = "Raid Healer",
    ["大米坦克"] = "Mythic+ Tank",
    ["大米DPS"] = "Mythic+ DPS",
    ["大米治疗"] = "Mythic+ Healer",
    ["团本方案"] = "Raid Profiles",
    ["大米方案"] = "Mythic+ Profiles",
    ["团本首领战"] = "Raid Boss Encounter",
    ["团本首领"] = "Raid Boss",
    ["其他"] = "Other",
    ["副本切换"] = "Dungeon Switch",
    ["首领列表"] = "Boss List",
    ["轴模式"] = "Timeline Mode",
    ["自动"] = "Auto",
    ["固定时间轴"] = "Fixed Timeline",
    ["暴雪原生"] = "Blizzard Default",
    ["测开"] = "Test On",
    ["测关"] = "Test Off",
    ["该分类无副本数据"] = "No dungeon data in this category",
    ["当前副本暂无 BOSS 数据"] = "No boss data for the current dungeon",
    ["选择语音包"] = "Select Voice Pack",
    ["当前语音包"] = "Current Voice Pack",
    ["简介"] = "Description",
    ["作者"] = "Author",
    ["版本"] = "Version",
    ["缺少语音"] = "Missing Labels",
    ["● 当前使用中"] = "● Active",
    ["配置方案"] = "Profile Slots",
    ["团本方案"] = "Raid Profiles",
    ["大米方案"] = "Mythic+ Profiles",
    ["提示：当前是什么职责，就自动使用并编辑对应的团本/大米方案。"] = "Alert: the active role automatically selects and edits the matching Raid / Mythic+ Profiles.",
    ["当前职责进入团本时自动使用。"] = "Automatically used when entering raids with the current role.",
    ["当前职责进入大米时自动使用。"] = "Automatically used when entering Mythic+ with the current role.",
    ["请选择..."] = "Please select...",
    ["暂无描述。"] = "No description available.",
    ["点击上方法术卡片后，可在此查看法术描述。"] = "Click a spell card above to view its description here.",
    ["无动态头像"] = "No Dynamic Portrait",
    ["未选择法术"] = "No Spell Selected",
    ["未知事件"] = "Unknown Event",
    ["未知首领"] = "Unknown Boss",
    ["未知副本"] = "Unknown Dungeon",
    ["事件 "] = "Event ",
    ["首领 "] = "Boss ",
    ["副本 "] = "Dungeon ",
    ["法术 "] = "Spell ",
    ["技能 "] = "Skill ",
    ["私"] = "PA",
    ["VOICE / PROFILE"] = "VOICE / PROFILES",
    ["VOICE / PROFILESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"] = "VOICE / PROFILES",
    ["VOICE / PROFILESSSS"] = "VOICE / PROFILES",
    ["VOICE / PROFILESSSSS"] = "VOICE / PROFILES",
    ["The D"] = "WS",
    ["The V"] = "Void",
    ["Pit o"] = "POS",
    ["Skyre"] = "Sky",
    ["Seat "] = "Seat",
    ["Eco-D"] = "AA",
    ["Ara-K"] = "MC",
    ["Magis"] = "MGT",
    ["Dungeon Switch"] = "Dungeon Switch",
    ["萨隆矿坑"] = "Pit of Saron",
    ["通天峰"] = "Skyreach",
    ["执政团之座"] = "Seat of the Triumvirate",
    ["艾杰斯亚学院"] = "Algeth'ar Academy",
    ["风行者之塔"] = "Windrunner Spire",
    ["魔导师平台"] = "Magisters' Terrace",
    ["迈萨拉洞窟"] = "Maisara Caverns",
    ["节点希纳斯"] = "Nexus-Point Xenas",
    ["学院"] = "AA",
    ["洞窟"] = "MC",
    ["节点"] = "Nexus",
}

local EVENT_TYPE_TRANSLATIONS = {
    ["å¦å…‹"] = "Tank",
    ["æ²»ç–—"] = "Heal",
    ["æœºåˆ¶"] = "Mechanic",
    ["å…¶ä»–"] = "Other",
    ["??"] = "Other",
    -- Properly-encoded Chinese event types
    ["坦克"] = "Tank",
    ["治疗"] = "Heal",
    ["机制"] = "Mechanic",
    ["其他"] = "Other",
}

local EVENT_TYPE_SCHEMES = {
    ["Tank"] = "tank",
    ["Heal"] = "heal",
    ["Mechanic"] = "mechanic",
    ["Other"] = "cooldown",
}

local SOUND_ALIASES = {
    { "å‡†å¤‡AOE", "Prepare AOE", "prepare-aoe.ogg" },
    { "å‡†å¤‡å¼•çº¿", "Prepare Beam", "prepare-beam.ogg" },
    { "å‡†å¤‡æ‰“æ–­", "Prepare Interrupt", "prepare-interrupt.ogg" },
    { "å‡†å¤‡æ‹‰äºº", "Prepare Grip", "prepare-pull.ogg" },
    { "å‡†å¤‡æŒ¡çº¿", "Prepare Line Block", "prepare-block-line.ogg" },
    { "å‡†å¤‡æŽ¥åœˆ", "Prepare Soak", "prepare-soak.ogg" },
    { "å‡†å¤‡æ¶ˆå±‚", "Prepare Clear Stack", "prepare-clear-stack.ogg" },
    { "å‡†å¤‡ç‚¹å", "Prepare Target", "prepare-target.ogg" },
    { "å‡†å¤‡è¸©ç®­", "Prepare Arrow", "prepare-arrow.ogg" },
    { "å‡†å¤‡è¿›åœˆ", "Prepare Enter Circle", "prepare-enter-circle.ogg" },
    { "å‡†å¤‡è¿žçº¿", "Prepare Link", "prepare-link.ogg" },
    { "å‡†å¤‡é€çƒ", "Prepare Orb Pass", "prepare-ball.ogg" },
    { "å‡†å¤‡é’©äºº", "Prepare Hook", "prepare-hook.ogg" },
    { "å‡†å¤‡é›†åˆ", "Prepare Stack", "prepare-stack.ogg" },
    { "å‡†å¤‡é©±æ•£", "Prepare Dispel", "prepare-dispel.ogg" },
    { "åŽ»æ’žåˆ†èº«", "Hit Clone", "hit-clone.ogg" },
    { "å¦å…‹å°–åˆº", "Tank Buster", "tank-buster.ogg" },
    { "å¿«å¡è§†è§’", "Fix Camera", "fix-camera.ogg" },
    { "å¿«åŽ»æ¶ˆæ°´", "Clear Water", "clear-water.ogg" },
    { "å¿«æ‰¾å…‰æŸ±", "Find Beacon", "find-beacon.ogg" },
    { "å¿«è¸©é™·é˜±", "Step Trap", "step-trap.ogg" },
    { "æ— ", "None", "none.ogg" },
    { "æ³¨æ„å‡»é€€", "Watch Knockback", "watch-knockback.ogg" },
    { "æ³¨æ„å¤´å‰", "Watch Frontal", "watch-frontal.ogg" },
    { "æ³¨æ„æŒ¡çƒ", "Block Orb", "block-ball.ogg" },
    { "æ³¨æ„æ¶ˆçƒ", "Clear Orb", "clear-ball.ogg" },
    { "æ³¨æ„èº²é¿", "Watch Dodge", "watch-dodge.ogg" },
    { "ç‚¹åå¤´å‰", "Target Frontal", "target-frontal.ogg" },
    { "ç‚¹åæ”¾æ°´", "Target Drop Water", "target-drop-water.ogg" },
    { "ç‚¹åæ¶ˆçº¿", "Target Clear Line", "target-clear-line.ogg" },
    { "èº²å¼€å¤´å‰", "Dodge Frontal", "dodge-frontal.ogg" },
    { "è½¬ç«å°æ€ª", "Switch Add", "switch-add.ogg" },
    { "è½¬é˜¶æ®µ", "Phase Change", "phase-change.ogg" },
    { "è¿œç¦»BOSS", "Away Boss", "away-boss.ogg" },
    { "é è¿‘åˆ†æ•£", "Spread Close", "spread-close.ogg" },
    { "é£Žç­å°æ€ª", "Kite Add", "kite-add.ogg" },
    { "Bossç‹‚æš´", "Boss Enrage", "boss-enrage.ogg" },
    { "Bossæ˜“ä¼¤", "Boss Vulnerability", "boss-vuln.ogg" },
    { "ä½ æ˜¯ç™½è‰²", "You Are White", "you-white.ogg" },
    { "ä½ æ˜¯é»‘è‰²", "You Are Black", "you-black.ogg" },
    { "å‡†å¤‡AOE(æ–­æ¡)", "Prepare AOE (Break)", "prepare-aoe-break.ogg" },
    { "å‡†å¤‡å¸çƒ", "Prepare Absorb Orb", "prepare-absorb-ball.ogg" },
    { "å‡ºåŽ»æ”¾æ°´", "Drop Water", "drop-water.ogg" },
    { "åŽ»æŽ¥å°æ€ª", "Intercept Add", "intercept-add.ogg" },
    { "å°„çº¿ç‚¹ä½ ", "Beam On You", "beam-on-you.ogg" },
    { "å°å¿ƒå†²å‡»æ³¢", "Watch Shockwave", "watch-shockwave.ogg" },
    { "å°å¿ƒå‡»é£ž", "Watch Launch", "watch-launch.ogg" },
    { "å¼ºåŒ–å¥¶éª‘", "Empower Holy Paladin", "empower-hpal.ogg" },
    { "å¼ºåŒ–æƒ©æˆ’éª‘", "Empower Retribution Paladin", "empower-ret.ogg" },
    { "å¼ºåŒ–é˜²éª‘", "Empower Protection Paladin", "empower-prot.ogg" },
    { "å¿«åˆ†æ•£", "Spread Now", "spread-now.ogg" },
    { "å¿«æ‰“æ–­", "Interrupt Now", "interrupt-now.ogg" },
    { "å¿«æ•‘äºº", "Rescue Now", "rescue-now.ogg" },
    { "å¿«ç ´ç›¾", "Break Shield", "break-shield.ogg" },
    { "å¿«è¿›ç½©å­", "Enter Bubble", "enter-bubble.ogg" },
    { "æ‹‰æ–­è¿žçº¿", "Break Link", "break-link.ogg" },
    { "æ˜“ä¼¤çˆ†å‘", "Burst Vulnerability", "vuln-burst.ogg" },
    { "æ³¨æ„å‡ä¼¤", "Use Defensive", "use-defensive.ogg" },
    { "æ³¨æ„æ²»ç–—", "Watch Healing", "watch-healing.ogg" },
    { "ç‰¹æ®ŠæŠ€èƒ½", "Special Mechanic", "special-mechanic.ogg" },
    { "è½¬ç«å¤§æ€ª", "Switch Boss", "switch-boss.ogg" },
    { "è¿œç¦»å¤§æ€ª", "Away Add", "away-add.ogg" },
    { "é›†åˆåˆ†æ‘Š", "Stack Share", "stack-share.ogg" },
    { "å€’æ•°5", "Countdown 5", "countdown-5.ogg" },
    { "å€’æ•°4", "Countdown 4", "countdown-4.ogg" },
    { "å€’æ•°3", "Countdown 3", "countdown-3.ogg" },
    { "å€’æ•°2", "Countdown 2", "countdown-2.ogg" },
    { "å€’æ•°1", "Countdown 1", "countdown-1.ogg" },
    { "å‡†å¤‡è¿½äºº", "Prepare Chase", "prepare-target.ogg" },
    { "å¬å”¤å°æ€ª", "Summon Add", "switch-add.ogg" },
    { "å¦å…‹å‡»é€€", "Tank Knockback", "watch-knockback.ogg" },
    { "é›†åˆæ”¾åœˆ", "Stack Drop Circle", "stack-share.ogg" },
}

local LABEL_TRANSLATIONS = {}
local ENGLISH_LABELS = {}
local SOUND_FILE_BY_LABEL = {}
for i = 1, #SOUND_ALIASES do
    local zhLabel, enLabel, fileName = SOUND_ALIASES[i][1], SOUND_ALIASES[i][2], SOUND_ALIASES[i][3]
    LABEL_TRANSLATIONS[zhLabel] = enLabel
    ENGLISH_LABELS[#ENGLISH_LABELS + 1] = enLabel
    SOUND_FILE_BY_LABEL[zhLabel] = fileName
end


local function CopyStringArray(list)
    if type(list) ~= "table" then
        return {}
    end

    local out = {}
    for i = 1, #list do
        out[i] = list[i]
    end
    return out
end

local function ForceEnglishVoiceLabels()
    local labels = CopyStringArray(ENGLISH_LABELS)
    _G.EXBV_LABELS = labels
    _G.EXBOSSEXWIND_LABELS = CopyStringArray(labels)
    return labels
end

local function RefreshDynamicLabelTranslations()
    local function ApplyFromList(list)
        if type(list) ~= "table" then
            return
        end

        for i = 1, math.min(#list, #SOUND_ALIASES) do
            local actualLabel = SafeNonEmptyString(list[i])
            local englishLabel = ENGLISH_LABELS[i]
            local soundFile = SOUND_ALIASES[i] and SOUND_ALIASES[i][3]
            if actualLabel and englishLabel then
                LABEL_TRANSLATIONS[actualLabel] = englishLabel
                -- Voice labels kept in Chinese (not added to FAST_EXACT)
                if soundFile and soundFile ~= "" then
                    SOUND_FILE_BY_LABEL[actualLabel] = soundFile
                end
            end
        end
    end

    ApplyFromList(_G.EXBV_LABELS)
    ApplyFromList(_G.EXBOSSEXWIND_LABELS)
end

local CUSTOM_VOICE_PACK_NAME = "Causese English"
local CUSTOM_SOUND_BASE_PATH = "Interface\\AddOns\\EXwindtools_EXboss_EnglishPatch\\sound\\"
local DEFAULT_VOICE_PACK_NAMES = {
    "EXWIND (Default)",
    "EXWIND(é»˜è®¤)",
    CUSTOM_VOICE_PACK_NAME,
}
local CUSTOM_SOUND_BY_LABEL = {
    ["Prepare AOE"] = "AoE.ogg",
    ["Prepare Beam"] = "Beam.ogg",
    ["Prepare Interrupt"] = "Interrupt.ogg",
    ["Prepare Grip"] = "Grip.ogg",
    ["Prepare Line Block"] = "Line.ogg",
    ["Prepare Soak"] = "Soak.ogg",
    ["Prepare Clear Stack"] = "Clear.ogg",
    ["Prepare Target"] = "Targeted.ogg",
    ["Prepare Arrow"] = "Trap.ogg",
    ["Prepare Enter Circle"] = "In.ogg",
    ["Prepare Link"] = "Link.ogg",
    ["Prepare Orb Pass"] = "Orb.ogg",
    ["Prepare Hook"] = "Grip.ogg",
    ["Prepare Stack"] = "Gather.ogg",
    ["Prepare Dispel"] = "Dispell.ogg",
    ["Hit Clone"] = "Charge.ogg",
    ["Tank Buster"] = "Defensive.ogg",
    ["Fix Camera"] = "LoS.ogg",
    ["Clear Water"] = "Clear.ogg",
    ["Find Beacon"] = "Beam.ogg",
    ["Step Trap"] = "Trap.ogg",
    ["None"] = "Check.ogg",
    ["Watch Knockback"] = "Knock.ogg",
    ["Watch Frontal"] = "Front.ogg",
    ["Block Orb"] = "Soak.ogg",
    ["Clear Orb"] = "Clear.ogg",
    ["Watch Dodge"] = "Dodge.ogg",
    ["Target Frontal"] = "Front.ogg",
    ["Target Drop Water"] = "Drop.ogg",
    ["Target Clear Line"] = "Line.ogg",
    ["Dodge Frontal"] = "Dodge.ogg",
    ["Switch Add"] = "Adds.ogg",
    ["Phase Change"] = "Transition.ogg",
    ["Away Boss"] = "Out.ogg",
    ["Spread Close"] = "Spread.ogg",
    ["Kite Add"] = "Kite.ogg",
    ["Boss Enrage"] = "Boss.ogg",
    ["Boss Vulnerability"] = "Nuke.ogg",
    ["You Are White"] = "Blue.ogg",
    ["You Are Black"] = "Purple.ogg",
    ["Prepare AOE (Break)"] = "AoE.ogg",
    ["Prepare Absorb Orb"] = "Orb.ogg",
    ["Drop Water"] = "Drop.ogg",
    ["Intercept Add"] = "Add.ogg",
    ["Beam On You"] = "Beam.ogg",
    ["Watch Shockwave"] = "Wave.ogg",
    ["Watch Launch"] = "Knock.ogg",
    ["Empower Holy Paladin"] = "Angel.ogg",
    ["Empower Retribution Paladin"] = "Sac.ogg",
    ["Empower Protection Paladin"] = "Protection.ogg",
    ["Spread Now"] = "Spread.ogg",
    ["Interrupt Now"] = "Interrupt.ogg",
    ["Rescue Now"] = "Rescue.ogg",
    ["Break Shield"] = "Break.ogg",
    ["Enter Bubble"] = "Enter.ogg",
    ["Break Link"] = "Break.ogg",
    ["Burst Vulnerability"] = "Nuke.ogg",
    ["Use Defensive"] = "Defensive.ogg",
    ["Watch Healing"] = "Healcd.ogg",
    ["Special Mechanic"] = "Check.ogg",
    ["Switch Boss"] = "Boss.ogg",
    ["Away Add"] = "Out.ogg",
    ["Stack Share"] = "Stack.ogg",
    ["Countdown 5"] = "5.ogg",
    ["Countdown 4"] = "4.ogg",
    ["Countdown 3"] = "3.ogg",
    ["Countdown 2"] = "2.ogg",
    ["Countdown 1"] = "1.ogg",
    ["Prepare Chase"] = "Fixate.ogg",
    ["Summon Add"] = "Spawn.ogg",
    ["Tank Knockback"] = "Knock.ogg",
    ["Stack Drop Circle"] = "Drop.ogg",
}
local TEXT_REPLACEMENTS = {
    { "EXWIND(é»˜è®¤)", "EXWIND (Default)" },
    { "EXWIND (é»˜è®¤ / Default)", "EXWIND (Default)" },
    { "EXWIND(é»˜è®¤ / Default)", "EXWIND (Default)" },
    { "é¦–é¡µ(å ä½)", "Home (Stub)" },
    { "é¦–é¡µï¼ˆå ä½ï¼‰", "Home (Stub)" },
    { "è¯­éŸ³ / é…ç½®", "Voice / Profiles" },
    { "è¯­éŸ³/é…ç½®", "Voice / Profiles" },
    { "å‰¯æœ¬", "Dungeons" },
    { "è®¾ç½®", "Settings" },
    { "å¯¼å…¥å¯¼å‡º", "Import / Export" },
    { "å¯¼å…¥/å¯¼å‡º", "Import / Export" },
    { "æ—¶é—´è½´", "Timeline" },
    { "è¯¥ Boss æ— å›ºå®šæ—¶é—´è½´æŠ€èƒ½æ•°æ®", "This boss has no fixed timeline spell data" },
    { "é€‰æ‹© Boss", "Select Boss" },
    { "æŠ€èƒ½åç§°", "Spell Name" },
    { "æŸçŠ¶æ¡", "Bun Bar" },
    { "è®¡æ—¶æ¡", "Timer Bar" },
    { "通用设置", "General Settings" },
    { "通用颜色方案", "General Color Schemes" },
    { "束状条", "Bun Bar" },
    { "倒计时", "Countdown" },
    { "文字公告", "Center Text" },
    { "圆环进度", "Ring Progress" },
    { "语音注册监控", "Voice Registration Monitor" },
    { "私人光环监控", "Private Aura Monitor" },
    { "重置设置", "Reset Settings" },
    { "倒计时设置", "Countdown Settings" },
    { "技能预警时在屏幕中央显示5秒倒数文字。", "Shows a 5-second center-screen countdown when a spell alert triggers." },
    { "%s = 技能名称 %t = 倒计时数字", "%s = Spell Name  %t = Countdown Number" },
    { "显示图标", "Show Icon" },
    { "显示小数点", "Show Decimal" },
    { "图标大小", "Icon Size" },
    { "模板", "Template" },
    { "预览：", "Preview:" },
    { "预览", "Preview" },
    { "提示文字字体 (%s)", "Alert Text Font (%s)" },
    { "提示文字", "Alert Text" },
    { "倒计时数字字体 (%t)", "Countdown Number Font (%t)" },
    { "倒计时数字", "Countdown Number" },
    { "更新日志", "Changelog" },
    { "通用", "General" },
    { "显示名称", "Show Name" },
    { "显示时间", "Show Time" },
    { "条增长方式", "Bar Fill Mode" },
    { "左到右填充", "Left to Right Fill" },
    { "左到右消退", "Left to Right Fade" },
    { "右到左填充", "Right to Left Fill" },
    { "右到左消退", "Right to Left Fade" },
    { "间距", "Spacing" },
    { "最大显示数量", "Maximum Visible Bars" },
    { "增长方向", "Growth Direction" },
    { "计时条设置", "Timer Bar Settings" },
    { "计时条所有外观的设置", "All appearance settings for the timer bar." },
    { "计时条外观", "Timer Bar Appearance" },
    { "法术名称", "Spell Name" },
    { "时间文本", "Time Text" },
    { "水平位置 (X)", "Horizontal Position (X)" },
    { "垂直位置 (Y)", "Vertical Position (Y)" },
    { "重置位置", "Reset Position" },
    { "新组件", "New Component" },
    { "束状条设置", "Bun Bar Settings" },
    { "轨道宽度", "Track Width" },
    { "轨道高度", "Track Height" },
    { "移动方向", "Movement Direction" },
    { "向上", "Up" },
    { "向下", "Down" },
    { "显示背景", "Show Background" },
    { "显示边框", "Show Border" },
    { "图案倒数时间", "Pattern Countdown Time" },
    { "背景线粗细", "Background Line Width" },
    { "背景线颜色", "Background Line Color" },
    { "5秒线粗细", "5s Line Width" },
    { "5秒线颜色", "5s Line Color" },
    { "名称位置", "Name Position" },
    { "图标左边", "Left of Icon" },
    { "图标右边", "Right of Icon" },
    { "背景材质", "Background Texture" },
    { "背景颜色", "Background Color" },
    { "边框材质", "Border Texture" },
    { "边框颜色", "Border Color" },
    { "边框粗细", "Border Width" },
    { "边框内距", "Border Inset" },
    { "背景设置", "Background Settings" },
    { "通用设置页未就绪", "General Settings page is not ready." },
    { "导入导出页未就绪", "Import / Export page is not ready." },
    { "BOSS技能页未就绪", "Boss Skill page is not ready." },
    { "固定时间轴预览页未就绪", "Fixed Timeline preview page is not ready." },
    { "å±å¹•è­¦å‘Š", "Screen Alert" },
    { "é¢„è­¦(ç§’)", "Pre-Alert (sec)" },
    { "æå‰(ç§’)", "Pre-Alert (sec)" },
    { "é‡ç½®", "Reset" },
    { "é€šç”¨è®¾ç½®", "General Settings" },
    { "é€šç”¨Settings", "General Settings" },
    { "è¿™é‡Œç»Ÿä¸€ç®¡ç† EXBoss çš„å…¨å±€æ˜¾ç¤ºæ¨¡å¼ä¸Žè¯­éŸ³è¾“å‡º", "This page manages EXBoss global display mode and voice output." },
    { "å…¨å±€æ˜¾ç¤ºæ¨¡å¼ä¸Žè¯­éŸ³è¾“å‡ºã€‚", "Global display mode and voice output." },
    { "è½½å…¥è®¾ç½®", "Load Settings" },
    { "è½½å…¥Settings", "Load Settings" },
    { "éŸ³é¢‘è¾“å‡ºé€‰é¡¹", "Audio Output Options" },
    { "è¾“å‡ºé€šé“", "Audio Channel" },
    { "å€’è®¡æ—¶", "Countdown" },
    { "æ–‡å­—å…¬å‘Š", "Flash Text" },
    { "åœ†çŽ¯è¿›åº¦", "Ring Progress" },
    { "è¯­éŸ³æ³¨å†Œç›‘æŽ§", "Voice Registration Monitor" },
    { "ç§äººå…‰çŽ¯ç›‘æŽ§", "Private Aura Monitor" },
    { "æ—¶é—´è½´å¯ç”¨æ–¹æ¡ˆ", "Timeline Display Mode" },
    { "TimelineEnableProfile", "Timeline Display Mode" },
    { "ä»…æŸçŠ¶æ¡", "Bun Bar Only" },
    { "ä»…è®¡æ—¶æ¡", "Timer Bar Only" },
    { "ä»…Bun Bar", "Bun Bar Only" },
    { "ä»…Timer Bar", "Timer Bar Only" },
    { "å…¨éƒ¨å¯ç”¨", "Enable Both" },
    { "å…¨éƒ¨éšè—", "Hide Both" },
    { "å¯ç”¨å¤§ç§˜å¢ƒé¦–é¢†æç¤º", "Enable Mythic+ Boss Alerts" },
    { "å¯ç”¨å›¢æœ¬é¦–é¢†æç¤º", "Enable Raid Boss Alerts" },
    { "å…³é—­æš´é›ªåŽŸç”Ÿè®¡æ—¶æ¡", "Disable Blizzard Encounter Timeline" },
    { "Closeæš´é›ªåŽŸç”ŸTimer Bar", "Disable Blizzard Encounter Timeline" },
    { "é¦–é¢†æˆ˜æ—¶è‡ªåŠ¨å…³é—­æˆ˜æ–—éŸ³é¢‘é¢„è­¦", "Mute Combat Audio Alerts During Boss Fights" },
    { "å¼€å¯æš´é›ªä¸­å¤®æ–‡å­—é¢„è­¦ï¼ˆæ³¨æ„ï¼šå¦‚æžœå…³é—­ä¼šå¯¼è‡´è¯­éŸ³ä¸å·¥ä½œï¼‰", "Enable Blizzard Center-Screen Warnings (required for voice alerts)" },
    { "å…¨å±€è¯­éŸ³è¾“å‡º", "Global Voice Output" },
    { "å…¨å±€éŸ³é‡", "Global Volume" },
    { "DPSé€šé“", "Audio Channel" },
    { "å½“å‰è¯­éŸ³æ³¨å†ŒçŠ¶æ€", "Current Voice Registration State" },
    { "æœ€è¿‘åˆ·æ–°: -", "Last Refresh: -" },
    { "æœ€è¿‘åˆ·æ–°:", "Last Refresh:" },
    { "æš‚æ— å·²æ³¨å†ŒBOSS", "No registered bosses" },
    { "é€šç”¨é¢œè‰²æ–¹æ¡ˆ", "General Color Schemes" },
    { "Boss æŠ€èƒ½é¡µä¼šç›´æŽ¥è¯»å–è¿™é‡Œçš„é…è‰²æ–¹æ¡ˆã€‚çŽ°åœ¨è¿™é¡µä¹Ÿèµ° Gridï¼Œå¯æ‹–æ‹½å¸ƒå±€ï¼›é¢œè‰²ç¼–è¾‘èµ°æŒ‰é’®æ‰“å¼€å–è‰²å™¨ã€‚", "The Boss spell page reads these color schemes directly. This page now also uses Grid, supports drag layout, and opens the color picker from the button." },
    { "å›ºå®šæ–¹æ¡ˆ", "Fixed Schemes" },
    { "ç¼–è¾‘é¢œè‰²", "Edit Color" },
    { "è‡ªå®šä¹‰æ–¹æ¡ˆ", "Custom Scheme" },
    { "æ–¹æ¡ˆåç§°", "Scheme Name" },
    { "é¢å¤–æ–¹æ¡ˆï¼ˆæœ€å¤š3ä¸ªï¼‰", "Extra Schemes (up to 3)" },
    { "é¢å¤–æ–¹æ¡ˆ", "Extra Schemes" },
    { "å¯ç”¨", "Enable" },
    { "é‡ç½®è®¾ç½®", "Reset Settings" },
    { "ResetSettings", "Reset Settings" },
    { "ä»…é‡ç½®å¤–è§‚è®¾ç½®", "Reset Appearance Only" },
    { "é‡ç½®æ‰€æœ‰é…ç½®ï¼ˆä¸åŒ…å«å¤–è§‚ï¼‰", "Reset All Settings (Keep Appearance)" },
    { "æ¸…é™¤å…¨éƒ¨è®¾ç½®ï¼ˆåŒ…å«å¤–è§‚ï¼‰", "Wipe Everything (Including Appearance)" },
    { "å…¨å±€æ¡æ˜¾ç¤ºæ¨¡å¼", "Global Bar Display Mode" },
    { "æŽ§åˆ¶å…¨å±€æ˜¾ç¤ºï¼šä»…è®¡æ—¶æ¡ / ä»…æŸçŠ¶æ¡ / ä¸¤è€…éƒ½å¯ç”¨ / ä¸¤è€…éƒ½éšè—ã€‚\nå¯å•ç‹¬å…³é—­å¤§ç§˜å¢ƒæˆ–å›¢æœ¬é¦–é¢†æç¤ºï¼›å…³é—­åŽå°†æ•´ä½“ç¦ç”¨è¯¥åœºæ™¯çš„ Boss è®¡æ—¶ã€ä¸­å¤®æ–‡å­—ã€è¯­éŸ³ä¸Žé¢œè‰²è¦†ç›–ã€‚\nå¯é€‰ï¼šé¦–é¢†æˆ˜ä¸­è‡ªåŠ¨å°†æˆ˜æ–—éŸ³é¢‘é¢„è­¦åˆ†ç±»éŸ³é‡é™éŸ³ï¼ˆ0ï¼‰ï¼Œè„±æˆ˜æ¢å¤åŽŸå€¼ã€‚", "Controls the global display mode: Timer Bar only / Bun Bar only / both / hidden.\nYou can disable Mythic+ or Raid boss alerts separately; disabling them also disables timers, center text, voice and color overlays for that scene.\nOptional: mute Combat Audio Alert categories during boss fights and restore them afterward." },
    { "BossæŠ€èƒ½é¡µæœªå°±ç»ª", "Boss spell page is not ready." },
    { "å›ºå®šæ—¶é—´è½´é¢„è§ˆé¡µæœªå°±ç»ª", "Fixed timeline preview page is not ready." },
    { "MDTé¡µæœªå°±ç»ª", "MDT page is not ready." },
    { "æŸçŠ¶æ¡è®¾ç½®", "Bun Bar Settings" },
    { "è®¡æ—¶æ¡è®¾ç½®", "Timer Bar Settings" },
    { "å€’è®¡æ—¶è®¾ç½®", "Countdown Settings" },
    { "é¦–é¡µï¼ˆå ä½ï¼‰", "Home (Stub)" },
    { "å‰¯æœ¬ / BOSS å¯¼èˆª\n(å¾…å¼€å‘)", "Dungeon / Boss Navigation\n(Pending)" },
    { "/exb  æ‰“å¼€/å…³é—­    |    /exb edit  ç¼–è¾‘æ¨¡å¼    |    /exb debug  è°ƒè¯•", "/exb open/close | /exb edit edit mode | /exb debug debug" },
    { "æ›´æ–°æ—¥å¿—", "Changelog" },
    { "å‰¯æœ¬åˆ‡æ¢", "Dungeon Switch" },
    { "è¯¥åˆ†ç±»æ— å‰¯æœ¬æ•°æ®", "No dungeon data in this category" },
    { "12.0å¤§ç§˜å¢ƒ", "12.0 Mythic+" },
    { "12.0å›¢æœ¬", "12.0 Raid" },
    { "é¦–é¢†åˆ—è¡¨", "Boss List" },
    { "å½“å‰å‰¯æœ¬æš‚æ—  BOSS æ•°æ®", "This dungeon has no boss data" },
    { "è½´æ¨¡å¼", "Timeline Mode" },
    { "è‡ªåŠ¨ -> å›ºå®šTimeline", "Auto -> Fixed Timeline" },
    { "æµ‹å¼€", "Start Test" },
    { "æµ‹å…³", "Stop Test" },
    { "ä¸­å¤®è­¦å‘Š", "Center Warning" },
    { "å¯ç”¨é¢œè‰²è¦†ç›–", "Enable Color Override" },
    { "Enableé¢œè‰²è¦†ç›–", "Enable Color Override" },
    { "å…¶ä»–æ–¹æ¡ˆ", "Other Scheme" },
    { "å…¶ä»–", "Other" },
    { "ä¸­å¤®æ–‡æœ¬", "Center Text" },
    { "æŠ€èƒ½è§¦å‘æ—¶åœ¨å±å¹•ä¸­å¤®æ˜¾ç¤ºæŠ€èƒ½åç§°ï¼ˆæ·¡å…¥ â†’ åœç•™ â†’ æ·¡å‡ºï¼‰ã€‚", "Shows the spell name in the center of the screen when triggered (fade in -> hold -> fade out)." },
    { "åŠŸèƒ½", "Function" },
    { "æŒç»­æ—¶é—´(ç§’)", "Duration (sec)" },
    { "ä¸­å¤®æ–‡æœ¬å†…å®¹ï¼ˆå¯ç”¨ {name}ï¼‰", "Center Text Content ({name} available)" },
    { "æå‰5ç§’", "Pre-Alert 5s" },
    { "Timer Baræ”¹å", "Timer Bar Rename" },
    { "æ–½æ³•å¼€å§‹", "Cast Start" },
    { "è¯­éŸ³æ¥æº", "Voice Source" },
    { "è¯­éŸ³labels", "Voice Labels" },
    { "è¯­éŸ³åŒ…labels", "Voice Pack Labels" },
    { "è¯•å¬", "Preview" },
    { "å»¶è¿Ÿ", "Delay" },
    { "ç‚¹å‡»ä¸Šæ–¹æ³•æœ¯å¡ç‰‡åŽï¼Œå¯åœ¨æ­¤æŸ¥çœ‹æ³•æœ¯æè¿°ã€‚", "Click a spell card above to view its description here." },
    { "ç‚¹å‡»ä¸Šæ–¹æ³•æœ¯å¡ç‰‡åŽï¼Œå¯åœ¨æ­¤é…ç½®å•æ³•æœ¯æé†’é€‰é¡¹ã€‚", "Click a spell card above to configure alert options for that spell." },
    { "è¯·é€‰æ‹©æœ‰æŠ€èƒ½æ•°æ®çš„ BOSS", "Select a boss with spell data" },
    { "æ˜¾ç¤ºå›¾æ ‡", "Show Icon" },
    { "æ˜¾ç¤ºåç§°", "Show Name" },
    { "æ˜¾ç¤ºæ—¶é—´", "Show Time" },
    { "è½¨é“å®½åº¦", "Track Width" },
    { "å›¾æ ‡å¤§å°", "Icon Size" },
    { "è½¨é“é«˜åº¦", "Track Height" },
    { "ç§»åŠ¨æ–¹å‘", "Move Direction" },
    { "å‘ä¸Š", "Up" },
    { "å‘ä¸‹", "Down" },
    { "æ˜¾ç¤ºèƒŒæ™¯", "Show Background" },
    { "æ˜¾ç¤ºè¾¹æ¡†", "Show Border" },
    { "æ³•æœ¯åç§°", "Spell Name" },
    { "å›¾æ¡ˆå€’æ•°æ—¶é—´", "Bar Countdown Time" },
    { "èƒŒæ™¯çº¿ç²—ç»†", "Background Line Width" },
    { "èƒŒæ™¯çº¿é¢œè‰²", "Background Line Color" },
    { "5ç§’çº¿ç²—ç»†", "5s Line Width" },
    { "5ç§’çº¿é¢œè‰²", "5s Line Color" },
    { "åç§°ä½ç½®", "Name Position" },
    { "å›¾æ ‡å·¦è¾¹", "Left of Icon" },
    { "å›¾æ ‡å³è¾¹", "Right of Icon" },
    { "èƒŒæ™¯æè´¨", "Background Texture" },
    { "èƒŒæ™¯é¢œè‰²", "Background Color" },
    { "è¾¹æ¡†æè´¨", "Border Texture" },
    { "è¾¹æ¡†é¢œè‰²", "Border Color" },
    { "è¾¹æ¡†ç²—ç»†", "Border Width" },
    { "è¾¹æ¡†å†…è·", "Border Inset" },
    { "èƒŒæ™¯è®¾ç½®", "Background Settings" },
    { "è®¡æ—¶æ¡æ‰€æœ‰å¤–è§‚çš„è®¾ç½®", "Settings for the full appearance of the timer bars." },
    { "æ¡å¢žé•¿æ–¹å¼", "Bar Fill Mode" },
    { "å·¦åˆ°å³å¡«å……", "Left to Right Fill" },
    { "å·¦åˆ°å³æ¶ˆé€€", "Left to Right Fade" },
    { "å³åˆ°å·¦å¡«å……", "Right to Left Fill" },
    { "å³åˆ°å·¦æ¶ˆé€€", "Right to Left Fade" },
    { "é—´è·", "Spacing" },
    { "æœ€å¤§æ˜¾ç¤ºæ•°é‡", "Maximum Visible Bars" },
    { "å¢žé•¿æ–¹å‘", "Growth Direction" },
    { "è®¡æ—¶æ¡å¤–è§‚", "Timer Bar Appearance" },
    { "æ—¶é—´æ–‡æœ¬", "Time Text" },
    { "é€šç”¨", "General" },
    { "æ–°ç»„ä»¶", "New Component" },
    { "æ˜¾ç¤ºå°æ•°ç‚¹", "Show Decimal" },
    { "æç¤ºæ–‡å­—æ¨¡æ¿", "Alert Text Template" },
    { "æ¨¡æ¿ï¼ˆ|cff00ff00%s|r=æŠ€èƒ½å  |cffffd100%t|r=å€’è®¡æ—¶æ•°å­—ï¼‰", "Template (|cff00ff00%s|r=spell name  |cffffd100%t|r=countdown number)" },
    { "æç¤ºæ–‡å­—å­—ä½“ï¼ˆ%sï¼‰", "Alert Text Font (%s)" },
    { "æç¤ºæ–‡å­—", "Alert Text" },
    { "å€’è®¡æ—¶æ•°å­—å­—ä½“ï¼ˆ%tï¼‰", "Countdown Number Font (%t)" },
    { "å€’è®¡æ—¶æ•°å­—", "Countdown Number" },
    { "åœºæ™¯é¢„è§ˆ", "Scene Preview" },
    { "åˆ‡æ¢ç¼–è¾‘æ¨¡å¼é¢„è§ˆ", "Toggle Edit-Mode Preview" },
    { "æµ‹è¯•å€’è®¡æ—¶", "Test Countdown" },
    { "é¢„è§ˆï¼š", "Preview:" },
    { "å¦å…‹å°–åˆº", "Tank Buster" },
    { "æ— ", "None" },
    { "é»˜è®¤", "Default" },
    { "æ— åŠ¨æ€å¤´åƒ", "No Dynamic Portrait" },
    { "åŠ è½½ä¸­", "Loading" },
    { "ç§äººå…‰çŽ¯æ³•æœ¯", "Private Aura Spell" },
    { "æ¥æºï¼š", "Source: " },
    { "æ¥æºNPCIDï¼š", "Source NPC ID: " },
    { "å½’å±žï¼š", "Owner: " },
    { "ExwindGrid ä¸å¯ç”¨ï¼Œæ— æ³•æ¸²æŸ“ç§äººå…‰çŽ¯è®¾ç½®ã€‚", "ExwindGrid is unavailable; private aura settings cannot be rendered." },
    { "ExwindGrid ä¸å¯ç”¨ï¼Œæ— æ³•æ¸²æŸ“è®¾ç½®åŒºã€‚", "ExwindGrid is unavailable; the settings pane cannot be rendered." },
    { "å›ºå®šæ—¶é—´è½´æ€»è§ˆ", "Fixed Timeline Overview" },
    { "æŒ‰é¦–é¢†æŸ¥çœ‹å›ºå®šè½´æŠ€èƒ½åœ¨å‰ 3 åˆ†é’Ÿå†…çš„å‡ºçŽ°èŠ‚ç‚¹ï¼Œä¾¿äºŽå¿«é€Ÿæ ¡å¯¹æ—¶é—´è½´èŠ‚å¥ã€‚", "Review when fixed-timeline skills occur during the first 3 minutes of each boss fight." },
    { "åˆ·æ–°", "Refresh" },
    { "å›ºå®šæ—¶é—´è½´é¢„è§ˆ", "Fixed Timeline Preview" },
    { "è¯·é€‰æ‹©å·¦ä¾§é¦–é¢†æŸ¥çœ‹ 3 åˆ†é’Ÿæ—¶é—´è½´ã€‚", "Select a boss on the left to view its 3-minute timeline." },
    { "æŠ€èƒ½:", "Skills:" },
    { "3åˆ†é’ŸèŠ‚ç‚¹:", "3-Minute Markers:" },
    { "æŠ€èƒ½", "Skill" },
    { "æ¬¡", "x" },
    { "é¦–è½®>3:00", "First Loop > 3:00" },
    { "å›ºå®šè½´é¦–é¢†:", "Fixed Bosses:" },
    { "æŠ€èƒ½æ€»æ•°:", "Total Skills:" },
    { "çª—å£:", "Window:" },
    { "èŠ‚ç‚¹:", "Markers:" },
    { "å¯¼å‡º", "Export" },
    { "å¯¼å…¥", "Import" },
    { "é…ç½®åç§°", "Profile Name" },
    { "æœªå‘½åé…ç½®", "Untitled Profile" },
    { "å¤‡æ³¨ï¼ˆå¯é€‰ï¼‰", "Notes (Optional)" },
    { "å¯¼å‡ºå†…å®¹", "Export Contents" },
    { "å¤–è§‚è®¾ç½®ï¼ˆè®¡æ—¶æ¡å¤–è§‚ç­‰ï¼‰", "Appearance Settings (Timer Bar Style, etc.)" },
    { "å¤–è§‚Settingsï¼ˆTimer Barå¤–è§‚ç­‰ï¼‰", "Appearance Settings (Timer Bar Style, etc.)" },
    { "è§£æž", "Parse" },
    { "ç²˜è´´å¯¼å‡ºå­—ç¬¦ä¸²", "Paste Export String" },
    { "è´´è´´Exportå­—ç¬¦ä¸²", "Paste Export String" },
    { "ç²˜è´´Exportå­—ç¬¦ä¸²", "Paste Export String" },
    { "å¯¼å…¥å†…å®¹", "Import Contents" },
    { "Importå†…å®¹", "Import Contents" },
    { "å¯¼å…¥å¤–è§‚è®¾ç½®ï¼ˆç«‹å³åº”ç”¨ï¼‰", "Import Appearance Settings (Apply Immediately)" },
    { "å¯¼å…¥å¤–è§‚Settingsï¼ˆç«‹å³åº”ç”¨ï¼‰", "Import Appearance Settings (Apply Immediately)" },
    { "Importå¤–è§‚Settingsï¼ˆç«‹å³åº”ç”¨ï¼‰", "Import Appearance Settings (Apply Immediately)" },
    { "å¯¼å…¥ä½œè€…åï¼ˆç•™ç©ºåˆ™ä½¿ç”¨é…ç½®åï¼‰", "Imported Author Name (blank = profile name)" },
    { "ImportAuthoråï¼ˆç•™ç©ºåˆ™ä½¿ç”¨é…ç½®åï¼‰", "Imported Author Name (blank = profile name)" },
    { "ImportAuthorå", "Imported Author Name" },
    { "æ‰§è¡Œå¯¼å…¥", "Run Import" },
    { "æ‰§è¡ŒImport", "Run Import" },
    { "é€‰æ‹©æ–¹æ¡ˆ", "Select Profile" },
    { "æ­¤åŒºåŸŸåªå±•ç¤ºå½“å‰ 6 ä¸ªæ§½ä½å¯¹åº”çš„ä½œè€…æ–¹æ¡ˆã€‚", "This area only shows the profiles currently assigned to the 6 slots." },
    { "é‡å‘½å", "Rename" },
    { "åˆ é™¤", "Delete" },
    { "å¯¼å…¥å¯¼å‡ºæ¨¡å—æœªåŠ è½½", "Import / Export module is not loaded" },
    { "è¯·è‡³å°‘å‹¾é€‰ä¸€é¡¹å¯¼å‡ºå†…å®¹", "Select at least one export item" },
    { "å¯¼å‡ºå¤±è´¥ï¼š", "Export failed: " },
    { "è¯·å…ˆç²˜è´´å¯¼å‡ºå­—ç¬¦ä¸²", "Paste an export string first" },
    { "è§£æžå¤±è´¥ï¼š", "Parse failed: " },
    { "è¯»å–æ‘˜è¦å¤±è´¥ï¼š", "Failed to read summary: " },
    { "å¯¼å‡ºè€…ï¼š", "Author: " },
    { "å¤‡æ³¨ï¼š", "Notes: " },
    { "è§£æžæˆåŠŸï¼Œé€‰æ‹©è¦å¯¼å…¥çš„å†…å®¹åŽç‚¹å‡»[æ‰§è¡Œå¯¼å…¥]", "Parse successful. Select what to import, then click [Run Import]." },
    { "è¯·å…ˆç‚¹å‡»[è§£æž]æŒ‰é’®", "Click [Parse] first" },
    { "è¯·è‡³å°‘å‹¾é€‰ä¸€é¡¹å¯¼å…¥å†…å®¹", "Select at least one import item" },
    { "å¯¼å…¥æˆåŠŸï¼š", "Import successful: " },
    { "å¯¼å…¥å¤±è´¥ï¼š", "Import failed: " },
    { "æ§½ä½ï¼š", "Slot: " },
    { "ä½œè€…æ–¹æ¡ˆï¼š", "Profile: " },
    { "æ§½ä½ä¸ºå›ºå®šç»“æž„ï¼Œè¯·åœ¨è¯­éŸ³/é…ç½®é¡µåˆ‡æ¢ä½œè€…æ–¹æ¡ˆã€‚", "These slots are fixed. Change author profiles in Voice / Profiles." },
    { "æ§½ä½ä¸ºå›ºå®šç»“æž„ï¼Œä¸æ”¯æŒåˆ é™¤ã€‚", "These slots are fixed and cannot be deleted." },
    { "å…¨é€‰å¤åˆ¶", "Select All" },
    { "å·²å¤åˆ¶åˆ°å‰ªè´´æ¿", "Copied to clipboard" },
    { "Ctrl+C å¤åˆ¶å¹¶è‡ªåŠ¨å…³é—­ï¼Œæˆ–ç‚¹å‡» å…¨é€‰å¤åˆ¶ æŒ‰é’®", "Press Ctrl+C to copy and close, or click Select All." },
    { "è¯­éŸ³åŒ…", "Voice Pack" },
    { "é€‰æ‹©è¯­éŸ³åŒ…", "Select Voice Pack" },
    { "å½“å‰è¯­éŸ³åŒ…", "Current Voice Pack" },
    { "ç®€ä»‹", "Description" },
    { "ä½œè€…", "Author" },
    { "ç‰ˆæœ¬", "Version" },
    { "ç¼ºå°‘è¯­éŸ³", "Missing Labels" },
    { "é…ç½®æ–¹æ¡ˆ", "Profile Slots" },
    { "AuthorProfile", "Author Profile" },
    { "ä½œè€…æ–¹æ¡ˆ", "Author Profile" },
    { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©ä½œè€…æ–¹æ¡ˆï¼›å‰¯æœ¬é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„å›¢æœ¬ / å¤§ç±³æ–¹æ¡ˆã€‚", "Choose author profiles for the 6 role slots; the dungeon page writes the matching Raid / Mythic+ profile automatically for the current role." },
    { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©Author Profileï¼›Dungeonsé¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„å›¢æœ¬ / Mythic+ Profileã€‚", "Choose author profiles for the 6 role slots; the Dungeons page writes the matching Raid / Mythic+ profile automatically for the current role." },
    { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©Author Profileï¼›Dungeonsé¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„å›¢æœ¬ / å¤§ç±³æ–¹æ¡ˆã€‚", "Choose author profiles for the 6 role slots; the Dungeons page writes the matching Raid / Mythic+ profile automatically for the current role." },
    { "å½“å‰èŒè´£è¿›å…¥å›¢æœ¬æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering raids with the current role." },
    { "å½“å‰èŒè´£è¿›å…¥å¤§ç±³æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering Mythic+ with the current role." },
    { "æ–¹æ¡ˆ", "Profile" },
    { "æç¤ºï¼šå½“å‰æ˜¯ä»€ä¹ˆèŒè´£ï¼Œå°±è‡ªåŠ¨ä½¿ç”¨å¹¶ç¼–è¾‘å¯¹åº”çš„å›¢æœ¬/å¤§ç±³æ–¹æ¡ˆã€‚", "Tip: the current role determines which Raid / Mythic+ profile is used and edited automatically." },
    { "æç¤ºï¼šå½“å‰æ˜¯ä»€ä¹ˆèŒè´£ï¼Œå°±è‡ªåŠ¨ä½¿ç”¨å¹¶ç¼–è¾‘å¯¹åº”çš„å›¢æœ¬/Mythic+ Profileã€‚", "Tip: the current role determines which Raid / Mythic+ profile is used and edited automatically." },
    { "å·¦ä¾§é€‰æ‹©è¯­éŸ³åŒ…ï¼Œå³ä¾§æŒ‰å›¢æœ¬ / å¤§ç±³é…ç½®ä½œè€…æ–¹æ¡ˆã€‚", "Choose a voice pack on the left, then configure Raid / Mythic+ author profiles on the right." },
    { "å·¦ä¾§é€‰æ‹©Voice Packï¼Œå³ä¾§æŒ‰å›¢æœ¬ / å¤§ç±³é…ç½® Author Profileã€‚", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." },
    { "â— å½“å‰ä½¿ç”¨ä¸­", "â— Active" },
    { "ç¼ºå°‘è¯­éŸ³ï¼š?", "Missing labels: ?" },
    { "ç¼ºå°‘è¯­éŸ³ï¼š0", "Missing labels: 0" },
    { "å›¢æœ¬æ–¹æ¡ˆ", "Raid Profiles" },
    { "å¤§ç±³æ–¹æ¡ˆ", "Mythic+ Profiles" },
    { "å½“å‰èŒè´£è¿›å…¥å›¢æœ¬æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used in raids for the current role." },
    { "å½“å‰èŒè´£è¿›å…¥å¤§ç±³æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used in Mythic+ for the current role." },
    { "é€šç”¨é¢œè‰²æ–¹æ¡ˆ", "General Color Schemes" },
    { "è‡ªå®šä¹‰é¢œè‰²", "Custom Colors" },
    { "å½“å‰å‰¯æœ¬ï¼š", "Dungeon: " },
    { "è·¯çº¿ï¼š", "Route: " },
    { "è·¯çº¿å¥—è£…", "Route Preset" },
    { "å½“å‰æ³¢æ¬¡ï¼š", "Current Pull: " },
    { "æ€ªç‰© / æ³•æœ¯", "Mobs / Spells" },
    { "å½“å‰æ³¢æ¬¡å›¾ç‰‡ï¼šæ— ", "Current Pull Image: None" },
    { "å½“å‰æ³¢æ¬¡å›¾ç‰‡ï¼š", "Current Pull Image: " },
    { "å½“å‰è¿›åº¦ï¼šæœªèŽ·å–", "Current Progress: Unavailable" },
    { "æ˜¾ç¤ºæ‰“æ–­æ€ª", "Show Casters" },
    { "åœ†çŽ¯è¿›åº¦è®¾ç½®", "Ring Progress Settings" },
    { "å±å¹•ä¸­å¤®æ˜¾ç¤ºåœ†çŽ¯è¿›åº¦", "Shows ring progress in the center of the screen." },
    { "åœ†çŽ¯æ ·å¼", "Ring Style" },
    { "ç»†çŽ¯ 1", "Thin Ring 1" },
    { "ç»†çŽ¯ 2", "Thin Ring 2" },
    { "æ ‡å‡†çŽ¯", "Classic Ring" },
    { "åœ†çŽ¯å°ºå¯¸", "Ring Size" },
    { "é¢œè‰²", "Color" },
    { "é€æ˜Žåº¦", "Opacity" },
    { "æµ‹è¯•åœ†çŽ¯(3ç§’)", "Test Ring (3s)" },
    { "ç›‘æŽ§çŽ©å®¶è‡ªèº«çš„3ä¸ªç§äººå…‰çŽ¯æ§½ä½ã€‚å¼€å¯åŽè¿›å…¥ç¼–è¾‘æ¨¡å¼å¯æ‹–åŠ¨è°ƒæ•´ä½ç½®ã€‚", "Monitors the player's 3 personal aura slots. Enable it and enter edit mode to drag the position." },
    { "å¯ç”¨ç§äººå…‰çŽ¯ç›‘æŽ§", "Enable Private Aura Monitor" },
    { "è¿›å…¥ç¼–è¾‘æ¨¡å¼", "Enter Edit Mode" },
    { "å›¾æ ‡å¤–è§‚", "Icon Appearance" },
    { "å›¾æ ‡é—´è·", "Icon Spacing" },
    { "æŽ’åˆ—æ–¹å‘", "Layout Direction" },
    { "å‘å³", "Right" },
    { "å‘å·¦", "Left" },
    { "è¾¹æ¡†ç¼©æ”¾", "Border Scale" },
    { "æ˜¾ç¤ºå†·å´åœˆ", "Show Cooldown Spiral" },
    { "æ˜¾ç¤ºæ•°å­—å€’è®¡æ—¶", "Show Numeric Countdown" },
    { "ä½ç½®", "Position" },
    { "é”šç‚¹", "Anchor Point" },
    { "å±å¹•ä¸­å¤®", "Screen Center" },
    { "å·¦ä¸Šè§’", "Top Left" },
    { "ä¸Šæ–¹ä¸­å¤®", "Top Center" },
    { "å³ä¸Šè§’", "Top Right" },
    { "å·¦ä¾§ä¸­å¤®", "Left Center" },
    { "å³ä¾§ä¸­å¤®", "Right Center" },
    { "å·¦ä¸‹è§’", "Bottom Left" },
    { "ä¸‹æ–¹ä¸­å¤®", "Bottom Center" },
    { "å³ä¸‹è§’", "Bottom Right" },
    { "ä¸­æ–‡é…éŸ³è¯­éŸ³åŒ…", "Chinese voice pack" },
    { "ExBoss å®˜æ–¹é»˜è®¤è¯­éŸ³åŒ…", "Official EXBoss default voice pack" },
    { "ExBoss å®˜æ–¹é»˜è®¤ Voice Pack", "Official EXBoss default Voice Pack" },
    { "è¦†ç›–å¸¸è§é¦–é¢†ä¸Žå¤§ç§˜å¢ƒè¯­éŸ³æ ‡ç­¾ï¼Œæ ‡å‡†å‚è€ƒå®žçŽ°ã€‚", "Covers standard raid and Mythic+ voice labels." },
    { "æ ‡ç­¾ç»“æž„ä¸Žé»˜è®¤åŒ…å…¼å®¹ã€‚", "Uses the same label structure as the default pack." },
    { "æ ‡ç­¾ä¸Žé»˜è®¤åŒ…å…¼å®¹ï¼Œå¯ç›´æŽ¥æ›¿æ¢å…¨å±€è¯­éŸ³ã€‚", "Compatible with the default label set and can replace the global voice pack." },
    { "åŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Includes standard labels and countdown lines." },
    { "æ¥æºç›®å½•ä¸ºç‰›å¸ˆå‚…ï¼ŒåŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Uses the standard label set and includes countdown lines." },
    { "Boss é…ç½®æ¨¡å—æœªåŠ è½½", "Boss config module not loaded" },
    { "æ ‡ç­¾ç›®å½•æœªåŠ è½½", "Label catalog not loaded" },
    { "ç¼ºå°‘è¯­éŸ³ï¼š", "Missing labels: " },
    { "å·²è¦†ç›–é»˜è®¤è¯­éŸ³æ ‡ç­¾", "Covers all default voice labels" },
    { "å½“å‰èŒè´£ï¼š", "Current role: " },
    { "å·²åˆ‡æ¢ ", "Switched " },
    { "åº”ç”¨å¤±è´¥ï¼š", "Apply failed: " },
    { "è¯·é€‰æ‹©é…ç½®", "Select profile" },
    { "6 æ§½ä½ä½œè€…æ–¹æ¡ˆå·²æŽ¥å…¥ï¼Œå‰¯æœ¬é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”æ–¹æ¡ˆã€‚", "6 slot author profiles are active; the dungeon page uses the current role automatically." },
    { "6 æ§½ä½Author Profileå·²æŽ¥å…¥ï¼ŒDungeonsé¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”Profileã€‚", "6 Author Profile slots are active; the Dungeons page uses the current role automatically." },
    { "è¯­éŸ³/é…ç½®é¡µé¢ä¾èµ– ExwindTools.UIï¼Œå½“å‰æœªå°±ç»ªã€‚è¯·ç¡®è®¤ ExwindCore å·²æ­£ç¡®åŠ è½½åŽé‡å¼€é¢æ¿ã€‚", "The Voice / Profiles page requires ExwindTools.UI. Make sure ExwindCore is loaded, then reopen the panel." },
    { "å½“å‰ä½¿ç”¨ä¸­", "Active" },
    { "æ ‡ç­¾", "labels" },
    { "é¢„è®¾é…ç½®", "Default Preset" },
    { "PresetConfig", "Default Preset" },
    { "å›ºå®šTimelineæ€»è§ˆ", "Fixed Timeline Overview" },
    { "æŒ‰é¦–é¢†æŸ¥çœ‹å›ºå®šè½´Skillåœ¨å‰ 3 åˆ†é’Ÿå†…çš„å‡ºçŽ°èŠ‚ç‚¹ï¼Œä¾¿äºŽå¿«é€Ÿæ ¡å¯¹TimelineèŠ‚å¥ã€‚", "Review when fixed-timeline skills occur during the first 3 minutes of each boss fight." },
    { "Skillæ€»æ•°", "Total Skills" },
    { "å›¢æœ¬å¦å…‹", "Raid Tank" },
    { "å›¢æœ¬DPS", "Raid DPS" },
    { "å›¢æœ¬æ²»ç–—", "Raid Healer" },
    { "å¤§ç±³å¦å…‹", "Mythic+ Tank" },
    { "å¤§ç±³DPS", "Mythic+ DPS" },
    { "å¤§ç±³æ²»ç–—", "Mythic+ Healer" },
    { "å›¢æœ¬Profile", "Raid Profile" },
    { "å¤§ç±³Profile", "Mythic+ Profile" },
    { "è¯­éŸ³ / é…ç½®", "Voice / Profiles" },
    { "é€‰æ‹© Boss", "Select Boss" },
    { "æŠ€èƒ½æ˜¾ç¤ºè®¾ç½®", "Spell Display Settings" },
    { "å‹¾é€‰æŽ§åˆ¶æ¯æ¡æŠ€èƒ½æ˜¯å¦åœ¨æŸçŠ¶æ¡/è®¡æ—¶æ¡/å±å¹•æ˜¾ç¤ºï¼Œé¢„è­¦ç§’æ•°å¯å•ç‹¬è°ƒæ•´ã€‚ç•™ç©º=ä½¿ç”¨æŠ€èƒ½é»˜è®¤å€¼ã€‚", "Toggle whether each spell appears in the bun bar, timer bar, and screen alerts. Pre-alert seconds can be adjusted per spell. Blank = use the spell default." },
    { "æŠ€èƒ½é¢„è­¦æ—¶åœ¨å±å¹•ä¸­å¤®æ˜¾ç¤º5ç§’å€’æ•°æ–‡å­—ã€‚\n", "Shows a 5-second countdown in the center of the screen for spell alerts.\n" },
    { "|cff00ff00%s|r = æŠ€èƒ½åç§°  |cffffd100%t|r = å€’è®¡æ—¶æ•°å­—", "|cff00ff00%s|r = Spell Name  |cffffd100%t|r = Countdown Number" },
    { "|cffaaaaffé¢„è§ˆï¼š|r\n", "|cffaaaaffPreview:|r\n" },
    { "æŠ€èƒ½åç§°æµ‹è¯•æ–‡å­—", "Spell Name Test Text" },
    { "å•æ¡", "Single Track" },
    { "åž‚ç›´", "Vertical" },
    { "å‘ä¸Š,å‘ä¸‹", "Up,Down" },
    { "åœ†çŽ¯è¿›åº¦è®¾ç½®", "Ring Progress Settings" },
    { "å±å¹•ä¸­å¤®æ˜¾ç¤ºåœ†çŽ¯è¿›åº¦", "Shows ring progress in the center of the screen." },
    { "åœ†çŽ¯æ ·å¼", "Ring Style" },
    { "ç»†çŽ¯ 1", "Thin Ring 1" },
    { "ç»†çŽ¯ 2", "Thin Ring 2" },
    { "æ ‡å‡†çŽ¯", "Classic Ring" },
    { "åœ†çŽ¯å°ºå¯¸", "Ring Size" },
    { "é¢œè‰²", "Color" },
    { "é€æ˜Žåº¦", "Opacity" },
    { "æµ‹è¯•åœ†çŽ¯(3ç§’)", "Test Ring (3s)" },
    { "ç›‘æŽ§çŽ©å®¶è‡ªèº«çš„3ä¸ªç§äººå…‰çŽ¯æ§½ä½ã€‚å¼€å¯åŽè¿›å…¥ç¼–è¾‘æ¨¡å¼å¯æ‹–åŠ¨è°ƒæ•´ä½ç½®ã€‚", "Monitors the player's 3 personal aura slots. Enable it and enter edit mode to drag the position." },
    { "å¯ç”¨ç§äººå…‰çŽ¯ç›‘æŽ§", "Enable Private Aura Monitor" },
    { "è¿›å…¥ç¼–è¾‘æ¨¡å¼", "Enter Edit Mode" },
    { "å›¾æ ‡å¤–è§‚", "Icon Appearance" },
    { "å›¾æ ‡é—´è·", "Icon Spacing" },
    { "æŽ’åˆ—æ–¹å‘", "Layout Direction" },
    { "å‘å³", "Right" },
    { "å‘å·¦", "Left" },
    { "è¾¹æ¡†ç¼©æ”¾", "Border Scale" },
    { "æ˜¾ç¤ºå†·å´åœˆ", "Show Cooldown Spiral" },
    { "æ˜¾ç¤ºæ•°å­—å€’è®¡æ—¶", "Show Numeric Countdown" },
    { "ä½ç½®", "Position" },
    { "é”šç‚¹", "Anchor Point" },
    { "å±å¹•ä¸­å¤®", "Screen Center" },
    { "å·¦ä¸Šè§’", "Top Left" },
    { "ä¸Šæ–¹ä¸­å¤®", "Top Center" },
    { "å³ä¸Šè§’", "Top Right" },
    { "å·¦ä¾§ä¸­å¤®", "Left Center" },
    { "å³ä¾§ä¸­å¤®", "Right Center" },
    { "å·¦ä¸‹è§’", "Bottom Left" },
    { "ä¸‹æ–¹ä¸­å¤®", "Bottom Center" },
    { "å³ä¸‹è§’", "Bottom Right" },
    { "å›ºå®šæ—¶é—´è½´é¢„è§ˆ", "Fixed Timeline Preview" },
    { "è¯·é€‰æ‹©å·¦ä¾§é¦–é¢†æŸ¥çœ‹ 3 åˆ†é’Ÿæ—¶é—´è½´ã€‚", "Select a boss on the left to view its 3-minute timeline." },
    { "æš‚æ— å›ºå®šæ—¶é—´è½´æ•°æ®", "No fixed timeline data available." },
    { "æš‚æ— æ—¶é—´è½´èŠ‚ç‚¹", "No timeline markers available." },
    { "|cff00ff00%s|r = æŠ€èƒ½åç§°  |cffffd100%t|r = å€’è®¡æ—¶æ•°å­—", "|cff00ff00%s|r = Spell Name  |cffffd100%t|r = Countdown Number" },
    { "|cffaaaaffé¢„è§ˆï¼š|r\n", "|cffaaaaffPreview:|r\n" },
    { "|cffff4400ExBoss|r BunBarPage: ExwindGrid ä¸å¯ç”¨", "|cffff4400ExBoss|r BunBarPage: ExwindGrid unavailable" },
    { "|cffff4400ExBoss|r CountdownPage: ExwindGrid ä¸å¯ç”¨", "|cffff4400ExBoss|r CountdownPage: ExwindGrid unavailable" },
    { "|cffff4400ExBoss|r FlashTextPage: ExwindGrid ä¸å¯ç”¨", "|cffff4400ExBoss|r FlashTextPage: ExwindGrid unavailable" },
    { "|cffff4400ExBoss|r TimerBarPage: ExwindGrid ä¸å¯ç”¨", "|cffff4400ExBoss|r TimerBarPage: ExwindGrid unavailable" },
    { "5ç§’çº¿ç²—ç»†", "5s Line Width" },
    { "5ç§’çº¿é¢œè‰²", "5s Line Color" },
    { "ä¸­å¤®æ–‡æœ¬", "Center Text" },
    { "ä½ç½®", "Position" },
    { "å€’è®¡æ—¶æ•°å­—", "Countdown Number" },
    { "å€’è®¡æ—¶æ•°å­—å­—ä½“ï¼ˆ%tï¼‰", "Countdown Number Font (%t)" },
    { "å€’è®¡æ—¶è®¾ç½®", "Countdown Settings" },
    { "åˆ‡æ¢ç¼–è¾‘æ¨¡å¼é¢„è§ˆ", "Toggle Edit-Mode Preview" },
    { "åŠŸèƒ½", "Function" },
    { "å•æ¡", "Single Track" },
    { "å³åˆ°å·¦å¡«å……", "Right to Left Fill" },
    { "å³åˆ°å·¦æ¶ˆé€€", "Right to Left Fade" },
    { "åç§°ä½ç½®", "Name Position" },
    { "å‘ä¸Š,å‘ä¸‹", "Up,Down" },
    { "å‘ä¸‹", "Down" },
    { "å›¾æ ‡å³è¾¹", "Right of Icon" },
    { "å›¾æ ‡å¤§å°", "Icon Size" },
    { "å›¾æ ‡å·¦è¾¹", "Left of Icon" },
    { "å›¾æ¡ˆå€’æ•°æ—¶é—´", "Bar Countdown Time" },
    { "åœºæ™¯é¢„è§ˆ", "Scene Preview" },
    { "å¦å…‹å°–åˆº", "Tank Buster" },
    { "å¦å…‹å°–åˆº|r", "Tank Buster|r" },
    { "åž‚ç›´", "Vertical" },
    { "åž‚ç›´ä½ç½® (Y)", "Vertical Position (Y)" },
    { "å¢žé•¿æ–¹å‘", "Growth Direction" },
    { "å·¦åˆ°å³å¡«å……", "Left to Right Fill" },
    { "å·¦åˆ°å³æ¶ˆé€€", "Left to Right Fade" },
    { "æŠ€èƒ½åç§°æµ‹è¯•æ–‡å­—", "Spell Name Test Text" },
    { "æŠ€èƒ½è§¦å‘æ—¶åœ¨å±å¹•ä¸­å¤®æ˜¾ç¤ºæŠ€èƒ½åç§°ï¼ˆæ·¡å…¥ â†’ åœç•™ â†’ æ·¡å‡ºï¼‰ã€‚", "Shows the spell name in the center of the screen when triggered (fade in -> hold -> fade out)." },
    { "æŠ€èƒ½é¢„è­¦æ—¶åœ¨å±å¹•ä¸­å¤®æ˜¾ç¤º5ç§’å€’æ•°æ–‡å­—ã€‚\n", "Shows a 5-second countdown in the center of the screen for spell alerts.\n" },
    { "æŒç»­æ—¶é—´(ç§’)", "Duration (sec)" },
    { "æç¤ºæ–‡å­—", "Alert Text" },
    { "æç¤ºæ–‡å­—å­—ä½“ï¼ˆ%sï¼‰", "Alert Text Font (%s)" },
    { "æç¤ºæ–‡å­—æ¨¡æ¿", "Alert Text Template" },
    { "æ–°ç»„ä»¶", "New Component" },
    { "æ—¶é—´æ–‡æœ¬", "Time Text" },
    { "æ˜¾ç¤ºåç§°", "Show Name" },
    { "æ˜¾ç¤ºå›¾æ ‡", "Show Icon" },
    { "æ˜¾ç¤ºå°æ•°ç‚¹", "Show Decimal" },
    { "æ˜¾ç¤ºæ—¶é—´", "Show Time" },
    { "æ˜¾ç¤ºèƒŒæ™¯", "Show Background" },
    { "æ˜¾ç¤ºè¾¹æ¡†", "Show Border" },
    { "æœ€å¤§æ˜¾ç¤ºæ•°é‡", "Maximum Visible Bars" },
    { "æŸçŠ¶æ¡è®¾ç½®", "Bun Bar Settings" },
    { "æ¡å¢žé•¿æ–¹å¼", "Bar Fill Mode" },
    { "æ¨¡æ¿ï¼ˆ|cff00ff00%s|r=æŠ€èƒ½å  |cffffd100%t|r=å€’è®¡æ—¶æ•°å­—ï¼‰", "Template (|cff00ff00%s|r=spell name  |cffffd100%t|r=countdown number)" },
    { "æ°´å¹³ä½ç½® (X)", "Horizontal Position (X)" },
    { "æ³•æœ¯åç§°", "Spell Name" },
    { "æµ‹è¯•å€’è®¡æ—¶", "Test Countdown" },
    { "ç§»åŠ¨æ–¹å‘", "Move Direction" },
    { "èƒŒæ™¯æè´¨", "Background Texture" },
    { "èƒŒæ™¯çº¿ç²—ç»†", "Background Line Width" },
    { "èƒŒæ™¯çº¿é¢œè‰²", "Background Line Color" },
    { "èƒŒæ™¯è®¾ç½®", "Background Settings" },
    { "èƒŒæ™¯é¢œè‰²", "Background Color" },
    { "è®¡æ—¶æ¡å¤–è§‚", "Timer Bar Appearance" },
    { "è®¡æ—¶æ¡æ‰€æœ‰å¤–è§‚çš„è®¾ç½®", "Settings for the full appearance of the timer bars." },
    { "è®¡æ—¶æ¡è®¾ç½®", "Timer Bar Settings" },
    { "è½¨é“å®½åº¦", "Track Width" },
    { "è½¨é“é«˜åº¦", "Track Height" },
    { "è¾¹æ¡†å†…è·", "Border Inset" },
    { "è¾¹æ¡†æè´¨", "Border Texture" },
    { "è¾¹æ¡†ç²—ç»†", "Border Width" },
    { "è¾¹æ¡†é¢œè‰²", "Border Color" },
    { "é€šç”¨", "General" },
    { "é€šç”¨è®¾ç½®", "General Settings" },
    { "é‡ç½®ä½ç½®", "Reset Position" },
    { "é—´è·", "Spacing" },
    { "é»˜è®¤", "Default" },
    { "å›¢æœ¬é¦–é¢†ï¼š%d  |  å¤§ç±³å‰¯æœ¬ï¼š%d", "Raid Bosses: %d  |  Mythic+ Dungeons: %d" },
    { "ç§äººå…‰çŽ¯", "Private Aura" },
    { "å¯¹è±¡åˆ—è¡¨", "Object List" },
    { "å½“å‰å¯¹è±¡æ²¡æœ‰ç§äººå…‰çŽ¯æ³•æœ¯ã€‚", "The current object has no private aura spells." },
    { "æ¡ä»¶ç³»ç»Ÿï¼ˆç¬¬ä¸€ç‰ˆï¼‰", "Conditions System (First Pass)" },
    { "å½“å‰åªå®žçŽ°ä¸€ä¸ªæ ¸å¿ƒè§„åˆ™ï¼šäº‹ä»¶ç»“æŸçª—å£ + BOSSè¯»æ¡ -> åœ†çŽ¯ã€‚å…ˆæŠŠè¿™æ¡é“¾è·‘é€šï¼Œä¸åš WA å¼ä¸‡èƒ½æ¡ä»¶ã€‚", "Currently only one core rule is implemented: event-end window + boss cast bar -> ring. The goal is to make this chain work first, not to build a full WA-style condition system." },
    { "å¯ç”¨æ¡ä»¶ç³»ç»Ÿè¿è¡Œæ—¶", "Enable Conditions Runtime" },
    { "è½½å…¥", "Load" },
    { "å·²åŠ è½½äº‹ä»¶ %d", "Loaded event %d" },
    { "eventID æ— æ•ˆ", "Invalid eventID" },
    { "å†™å…¥å¤±è´¥", "Write failed" },
    { "å·²ä¿å­˜äº‹ä»¶ %d çš„çª—å£è§„åˆ™", "Saved window rule for event %d" },
    { "å¯ç”¨â€œäº‹ä»¶ç»“æŸçª—å£ + BOSSè¯»æ¡â€è§„åˆ™", "Enable \"Event-End Window + Boss Cast\" Rule" },
    { "çª—å£å‰(ç§’)", "Window Before (sec)" },
    { "çª—å£åŽ(ç§’)", "Window After (sec)" },
    { "å‘½ä¸­åŽæ˜¾ç¤ºåœ†çŽ¯", "Show Ring On Match" },
    { "ä¿å­˜è§„åˆ™", "Save Rule" },
    { "å½“å‰æ¿€æ´»äº‹ä»¶ï¼ˆç‚¹ä¸€ä¸‹å¿«é€Ÿè½½å…¥ï¼‰", "Current Active Events (click to load quickly)" },
    { "å½“å‰æ²¡æœ‰æ¿€æ´»ä¸­çš„äº‹ä»¶è®¡æ—¶æ¡ã€‚å…ˆè¿›å…¥æˆ˜æ–—æˆ–å¯åŠ¨æµ‹è¯•ã€‚", "There are no active event timer bars right now. Enter combat or start a test first." },
    { "è¿è¡Œæ—¶çŠ¶æ€", "Runtime Status" },
    { "å½“å‰æ²¡æœ‰è¿è¡Œæ—¶çŠ¶æ€", "No runtime state right now" },
    { "å½“å‰æ²¡æœ‰å‘½ä¸­çª—å£åŒ¹é…", "No matching window right now" },
    { "å‘½ä¸­ä¸­", "Matched" },
    { "äº‹ä»¶", "Event" },
    { "è¯»æ¡", "Cast" },
    { "åå·®", "Offset" },
    { "å‰©ä½™", "Remaining" },
    { "è§„åˆ™è¯´æ˜Žï¼š\n1. ä»¥äº‹ä»¶ç»“æŸæ—¶é—´ä½œä¸ºé”šç‚¹\n2. åœ¨ [ç»“æŸå‰Xç§’, ç»“æŸåŽYç§’] çª—å£å†…\n3. åªè¦ boss1-boss5 æœ‰è¯»æ¡/å¼•å¯¼\n4. å°±æŠŠå½“å‰è¯»æ¡å‰©ä½™æ—¶é—´æ˜¾ç¤ºä¸ºåœ†çŽ¯\n\nè¿™ç‰ˆè¿˜æ²¡åšï¼šå€’æ•°ã€ä¸­å¤®æ–‡å­—ã€å¤šæ¡ä»¶æ ‘ã€å¤šåŠ¨ä½œç»„åˆã€‚", "Rule description:\n1. Uses the event end time as the anchor\n2. Works inside the [X sec before end, Y sec after end] window\n3. If boss1-boss5 has a cast/channel\n4. Shows the remaining cast time as a ring\n\nStill not implemented in this version: countdowns, center text, multi-condition trees, and combined actions." },
    { "ï¼ˆæ— æ ‡ç­¾ï¼‰", "(No Labels)" },
    { "ç¡®è®¤åˆ é™¤æ–¹æ¡ˆï¼š", "Delete profile: " },
    { "åˆ é™¤", "Delete" },
    { "å–æ¶ˆ", "Cancel" },
    { "å¯¼å‡ºæˆåŠŸ", "Export Successful" },
    { "å…¨é€‰å¤åˆ¶", "Select All" },
    { "å…³é—­", "Close" },
    { "æœªé€‰æ‹©å‰¯æœ¬", "No dungeon selected" },
    { "æœªçŸ¥å‰¯æœ¬", "Unknown dungeon" },
    { "æœªçŸ¥é¦–é¢†", "Unknown boss" },
    { "é¦–é¢† ", "Boss " },
    { "å‰¯æœ¬ ", "Dungeon " },
    { "4ä¸ªå›ºå®šé¢œè‰²æ–¹æ¡ˆ + 1ä¸ªè‡ªå®šä¹‰æ–¹æ¡ˆ + æœ€å¤š3ä¸ªé¢å¤–æ–¹æ¡ˆã€‚BossæŠ€èƒ½é¡µå¯ç›´æŽ¥é€‰æ‹©æ–¹æ¡ˆæˆ–è‡ªå®šä¹‰é¢œè‰²ã€‚", "4 fixed color profiles + 1 custom scheme + up to 3 extra schemes. The Boss Skills page can select a profile directly or use custom colors." },
    { "4ä¸ªå›ºå®šColorProfile + 1ä¸ªCustom Scheme + æœ€å¤š3ä¸ªExtra Schemesã€‚BossSkillé¡µå¯ç›´æŽ¥Select Profileæˆ–Custom Colorsã€‚", "4 fixed color profiles + 1 custom scheme + up to 3 extra schemes. The Boss Skills page can select a profile directly or use custom colors." },
    { "BossæŠ€èƒ½é¡µé¢å¯é€‰æ‹©ä¸‹åˆ—Profileï¼›é€‰æ‹©â€œCustom Colorsâ€æ—¶ä½¿ç”¨â€œCustom Schemeâ€ã€‚å‹¾é€‰Enableçš„Extra Schemesä¼šå‡ºçŽ°åœ¨Skillé¡µä¸‹æ‹‰ã€‚", "The Boss Skills page can select the profiles below. Choosing \"Custom Colors\" uses the \"Custom Scheme\". Enabled extra schemes appear in the Skill page dropdown." },
    { "BossæŠ€èƒ½é¡µé¢å¯é€‰æ‹©ä¸‹åˆ—æ–¹æ¡ˆï¼›é€‰æ‹©â€œè‡ªå®šä¹‰é¢œè‰²â€æ—¶ä½¿ç”¨â€œè‡ªå®šä¹‰æ–¹æ¡ˆâ€ã€‚å‹¾é€‰å¯ç”¨çš„é¢å¤–æ–¹æ¡ˆä¼šå‡ºçŽ°åœ¨æŠ€èƒ½é¡µä¸‹æ‹‰ã€‚", "The Boss Skills page can select the profiles below. Choosing \"Custom Colors\" uses the \"Custom Scheme\". Enabled extra schemes appear in the Skill page dropdown." },
    { "ColorProfile", "Color Profile" },
    { "BossSkillé¡µé¢", "Boss Skills page" },
    { "BossSkillé¡µ", "Boss Skills page" },
    { "Skillé¡µ", "Skill page" },
    { "Dungeonsé¡µ", "Dungeons page" },
    { "è½¬æ³•Skill", "Mechanic Profile" },
    { "è½¬æ³•æ–¹æ¡ˆ", "Mechanic Profile" },
    { "Custom Schemeå", "Custom Scheme Name" },
    { "å·¦ä¾§é€‰æ‹©Voice Packï¼Œå³ä¾§æŒ‰å›¢æœ¬ / å¤§ç±³é…ç½® Author Profileã€‚", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." },
    { "ExBoss å®˜æ–¹é»˜è®¤è¯­éŸ³åŒ…", "Official EXBoss default voice pack" },
    { "ExBoss å®˜æ–¹é»˜è®¤Voice Pack", "Official EXBoss default voice pack" },
    { "ExBoss å®˜æ–¹é»˜è®¤ Voice Pack", "Official EXBoss default voice pack" },
    { "Timer BarSettings", "Timer Bar Settings" },
    { "Timer Baræ‰€æœ‰å¤–è§‚çš„Settings", "Settings for the full appearance of the timer bars." },
    { "CountdownSettings", "Countdown Settings" },
    { "Skillé¢„è­¦æ—¶åœ¨Screen Centeræ˜¾ç¤º5ç§’å€’æ•°æ–‡å­—ã€‚", "Shows a 5-second countdown in the center of the screen for spell alerts." },
    { "æ¨¡æ¿ï¼ˆ%s=Skillå  %t=Countdownæ•°å­—ï¼‰", "Template (%s=spell name  %t=countdown number)" },
    { "Countdownæ•°å­—å­—ä½“ï¼ˆ%tï¼‰", "Countdown Number Font (%t)" },
    { "Countdownæ•°å­—", "Countdown Number" },
    { "Skillè§¦å‘æ—¶åœ¨Screen Centeræ˜¾ç¤ºSpell Nameï¼ˆæ·¡å…¥ -> åœç•™ -> æ·¡å‡ºï¼‰ã€‚", "Shows the spell name in the center of the screen when triggered (fade in -> hold -> fade out)." },
    { "Ring ProgressSettings", "Ring Progress Settings" },
    { "Screen Centeræ˜¾ç¤ºRing Progress", "Shows ring progress in the center of the screen." },
    { "æ°´å¹³Position (X)", "Horizontal Position (X)" },
    { "åž‚ç›´Position (Y)", "Vertical Position (Y)" },
    { "å½“å‰è¯­éŸ³æ³¨å†Œç»†èŠ‚ï¼ˆé»˜è®¤ä»…æ˜¾ç¤ºéžå›¢æœ¬ï¼‰ï¼šå‰¯æœ¬ > BOSSåç§°(æ•°é‡) + eventID(trigger0/1/2)ã€‚", "Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." },
    { "æŸ¥çœ‹å½“å‰è¯­éŸ³æ³¨å†Œç»†èŠ‚ï¼ˆDefaultä»…æ˜¾ç¤ºéžå›¢æœ¬ï¼‰ï¼šDungeons > BOSSåç§°(æ•°é‡) + eventID(trigger0/1/2)ã€‚", "Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." },
    { "è¯­éŸ³å¼•æ“Žæœªå°±ç»ªï¼Œæ— æ³•è¯»å–æ³¨å†ŒçŠ¶æ€ã€‚", "The voice engine is not ready, so the registration state cannot be read." },
    { "æ³¨å†Œå¿«ç…§ä¸ºç©ºã€‚", "The registration snapshot is empty." },
    { "éžå›¢æœ¬å·²æ³¨å†ŒBOSS: ", "Non-raid registered bosses: " },
    { "éžå›¢æœ¬äº‹ä»¶: ", "Non-raid events: " },
    { "éžå›¢æœ¬Event: ", "Non-raid events: " },
    { "è§¦å‘å™¨äº‹ä»¶(0/1/2): ", "Trigger events (0/1/2): " },
    { "è§¦å‘å™¨Event(0/1/2): ", "Trigger events (0/1/2): " },
    { "æš‚æ— éžå›¢æœ¬å·²æ³¨å†ŒBOSS", "No non-raid registered bosses" },
    { "æš‚æ— Noneéžå›¢æœ¬å·²æ³¨å†ŒBOSS", "No non-raid registered bosses" },
    { "å½“å‰è¯­éŸ³æ³¨å†ŒçŠ¶æ€", "Current Voice Registration State" },
    { "å·²æ³¨å†ŒBOSS: 0  |  å·²æ³¨å†Œäº‹ä»¶: 0", "Registered bosses: 0  |  Registered events: 0" },
    { "æš‚æ— å·²æ³¨å†ŒBOSS", "No registered bosses" },
    { "æä¾›ä¸‰ç§é‡ç½®æ–¹å¼ï¼š\n1) ä»…é‡ç½®å¤–è§‚è®¾ç½®\n2) é‡ç½®æ‰€æœ‰é…ç½®ï¼ˆä¸åŒ…å«å¤–è§‚ï¼‰\n3) æ¸…é™¤å…¨éƒ¨è®¾ç½®ï¼ˆåŒ…å«å¤–è§‚ï¼‰", "Three reset modes are available:\n1) Reset appearance only\n2) Reset all settings (keep appearance)\n3) Wipe everything (including appearance)" },
    { "æŽ¨èå…ˆä½¿ç”¨â€œä»…é‡ç½®å¤–è§‚è®¾ç½®â€ï¼šåªé‡ç½®è®¡æ—¶æ¡/æŸçŠ¶æ¡/å€’è®¡æ—¶/æ–‡å­—å…¬å‘Šä¸Žé¢œè‰²æ–¹æ¡ˆã€‚\nâ€œé‡ç½®æ‰€æœ‰é…ç½®ï¼ˆä¸åŒ…å«å¤–è§‚ï¼‰â€ä¼šæ¸…ç©ºé€šç”¨è®¾ç½®ã€è¯­éŸ³é…ç½®ã€æŠ€èƒ½é…ç½®ä¸Žæ—¶é—´è½´è®¾ç½®ï¼Œä½†ä¿ç•™å¤–è§‚ã€‚\nâ€œæ¸…é™¤å…¨éƒ¨è®¾ç½®â€ä¼šæŠŠ EXBoss çš„å…¨éƒ¨é…ç½®éƒ½æ¢å¤åˆ°åˆå§‹çŠ¶æ€ã€‚", "Recommended first option: \"Reset appearance only\". This only resets timer bars, bun bars, countdowns, flash text, and color schemes.\n\"Reset all settings (keep appearance)\" clears general settings, voice settings, spell settings, and timeline settings, while keeping appearance.\n\"Wipe everything\" restores every EXBoss setting to its initial state." },
    { "ä»…é‡ç½®è®¡æ—¶æ¡/æŸçŠ¶æ¡/å€’è®¡æ—¶/æ–‡å­—å…¬å‘Šçš„å¤–è§‚æ ·å¼ï¼Œä¸åˆ é™¤æ³•æœ¯é…ç½®ã€‚æ˜¯å¦ç»§ç»­ï¼Ÿ", "Only resets the appearance of timer bars, bun bars, countdowns, and flash text. Spell configuration is kept. Continue?" },
    { "å°†æ¸…ç©º EXBoss çš„é€šç”¨è®¾ç½®ã€è¯­éŸ³é…ç½®ã€æŠ€èƒ½é…ç½®ä¸Žæ—¶é—´è½´è®¾ç½®ï¼Œä½†ä¿ç•™å¤–è§‚æ ·å¼ã€‚|r\nç¡®è®¤ç»§ç»­ï¼Ÿ", "This clears EXBoss general settings, voice settings, spell settings, and timeline settings, while keeping appearance styles.|r\nContinue?" },
    { "å±é™©ï¼šå°†æ¸…ç©º EXBoss çš„å…¨éƒ¨è®¾ç½®ï¼ˆåŒ…å«å¤–è§‚ï¼‰å¹¶é‡è½½ã€‚æ­¤æ“ä½œä¸å¯æ’¤é”€ã€‚|r\nç¡®è®¤ç»§ç»­ï¼Ÿ", "Danger: this wipes every EXBoss setting, including appearance, and reloads the UI. This cannot be undone.|r\nContinue?" },
    { "ç¡®å®šé‡ç½®", "Confirm Reset" },
    { "ç¡®å®šæ¸…ç©º", "Confirm Wipe" },
    { "æ˜¯å¦é€€å‡ºç¼–è¾‘æ¨¡å¼ï¼Ÿ", "Exit Edit Mode?" },
    { "ç¡®å®š", "OK" },
    { "æ§½ä½ç®¡ç†", "Slot Management" },
    { "å¤–è§‚Settings", "appearance settings" },
    { "Resetå¤–è§‚Settings", "reset appearance settings" },
    { "ä»…Resetå¤–è§‚Settings", "Reset Appearance Only" },
    { "Resetæ‰€æœ‰é…ç½®ï¼ˆä¸åŒ…å«å¤–è§‚ï¼‰", "Reset All Settings (Keep Appearance)" },
    { "æ¸…é™¤å…¨éƒ¨Settingsï¼ˆåŒ…å«å¤–è§‚ï¼‰", "Wipe Everything (Including Appearance)" },
    { "æœªçŸ¥èŒè´£", "Unknown Role" },
    { "å¦å…‹", "Tank" },
    { "æ²»ç–—", "Healer" },
    { "æœªçŸ¥", "Unknown" },
}

TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€‰æ‹©æ–¹æ¡ˆ", "Select Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ§½ä½ï¼š", "Slot:" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ–¹æ¡ˆï¼š", "Profile:" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬æ–¹æ¡ˆ", "Raid Profiles" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³æ–¹æ¡ˆ", "Mythic+ Profiles" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€‰æ‹©è¯­éŸ³åŒ…", "Select Voice Pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰è¯­éŸ³åŒ…", "Current Voice Pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰ä½¿ç”¨ä¸­", "Active" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç¼ºå°‘è¯­éŸ³", "Missing Labels" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç®€ä»‹", "Description" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œè€…", "Author" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç‰ˆæœ¬", "Version" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·¦ä¾§é€‰æ‹©è¯­éŸ³åŒ…ï¼Œå³ä¾§æŒ‰å›¢æœ¬ / å¤§ç±³é…ç½®ä½œè€…æ–¹æ¡ˆã€‚", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©ä½œè€…æ–¹æ¡ˆï¼›å‰¯æœ¬é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„å›¢æœ¬ / å¤§ç±³æ–¹æ¡ˆã€‚", "Choose author profiles for the 6 role slots. The Dungeons page automatically writes the matching Raid / Mythic+ profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹© Author Profileï¼›Dungeons é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„å›¢æœ¬ / Mythic+ Profileã€‚", "Choose author profiles for the 6 role slots. The Dungeons page automatically writes the matching Raid / Mythic+ profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥å›¢æœ¬æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering raids with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥å¤§ç±³æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering Mythic+ with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½ä½œè€…æ–¹æ¡ˆå·²æŽ¥å…¥ï¼Œå‰¯æœ¬é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”æ–¹æ¡ˆã€‚", "6 author profile slots are active. The Dungeons page automatically writes the matching profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½ Author Profile å·²æŽ¥å…¥ï¼ŒDungeons é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº” Profileã€‚", "6 author profile slots are active. The Dungeons page automatically writes the matching profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æç¤ºï¼šå½“å‰æ˜¯ä»€ä¹ˆèŒè´£ï¼Œå°±è‡ªåŠ¨ä½¿ç”¨å¹¶ç¼–è¾‘å¯¹åº”çš„å›¢æœ¬/å¤§ç±³æ–¹æ¡ˆã€‚", "Tip: the addon automatically uses and edits the matching Raid / Mythic+ profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰ä»…æ˜¾ç¤ºå·²åˆ†é…åˆ° 6 ä¸ªæ§½ä½çš„æ–¹æ¡ˆã€‚", "This area only shows the profiles currently assigned to the 6 slots." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯­éŸ³ / é…ç½®é¡µé¢ä¾èµ– ExwindTools.UIï¼Œå½“å‰æœªå°±ç»ªã€‚è¯·ç¡®è®¤ ExwindCore å·²æ­£ç¡®åŠ è½½åŽé‡å¼€é¢æ¿ã€‚", "The Voice / Profiles page depends on ExwindTools.UI, which is not ready yet. Make sure ExwindCore loaded correctly, then reopen the panel." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "VOICE / PROFILE", "VOICE / PROFILES" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Timer Baræ‰€æœ‰å¤–è§‚çš„Settings", "Settings for the full appearance of the timer bars." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è®¡æ—¶æ¡æ‰€æœ‰å¤–è§‚çš„è®¾ç½®", "Settings for the full appearance of the timer bars." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šTimelineæ€»è§ˆ", "Fixed Timeline Overview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šè½´æ€»è§ˆ", "Fixed Timeline Overview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰é¦–é¢†æŸ¥çœ‹å›ºå®šè½´æŠ€èƒ½åœ¨å‰ 3 åˆ†é’Ÿå†…çš„å‡ºçŽ°èŠ‚ç‚¹ï¼Œä¾¿äºŽå¿«é€Ÿæ ¡å¯¹TimelineèŠ‚å¥ã€‚", "Review fixed-timeline spell markers in the first 3 minutes for each boss so you can quickly verify the timeline pacing." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰é¦–é¢†æŸ¥çœ‹å›ºå®šè½´æŠ€èƒ½åœ¨å‰ 3 åˆ†é’Ÿå†…çš„å‡ºçŽ°èŠ‚ç‚¹ï¼Œä¾¿äºŽå¿«é€Ÿæ ¡å¯¹æ—¶é—´è½´èŠ‚å¥ã€‚", "Review fixed-timeline spell markers in the first 3 minutes for each boss so you can quickly verify the timeline pacing." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šè½´é¦–é¢†", "Fixed Bosses" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½æ€»æ•°", "Total Skills" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³å¦å…‹", "Mythic+ Tank" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³DPS", "Mythic+ DPS" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³æ²»ç–—", "Mythic+ Healer" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "EnableæŒ‡ç¤ºå™¨", "Enable Indicator" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¾å½¢æ ·å¼", "Shape Style" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è·ç¦»åˆ¤å®šæ³•æœ¯(ID)", "Range Check Spell (ID)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é»˜è®¤: ä¸“ç²¾é¢„è®¾", "Default: spec preset" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è§¦å‘åœºæ™¯", "Visibility Rules" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æˆ˜æ–—ä¸­æ˜¾ç¤º", "Show in Combat" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æˆ˜æ–—å¤–æ˜¾ç¤º", "Show out of Combat" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä»…å‰¯æœ¬å†…", "Only in Dungeons" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸“ç²¾è¿‡æ»¤ (ä»…åœ¨å‹¾é€‰çš„ä¸“ç²¾ä¸‹å¯ç”¨)", "Spec Filter (only enabled for checked specs)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¾é™„ç›®æ ‡", "Attach To" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¾é™„åˆ°ç›®æ ‡æ¡†æž¶çš„", "Attach to Target Frame" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸å¸é™„", "Do Not Attach" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§è„šä¸–ç•Œé¢‘é“", "World Channel" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "[æ— å¹¿å‘Š]æ­£åœ¨æ–½æ”¾%link , å‡†å¤‡ä¼ é€åˆ°\"%name\"", "[No spam] Casting %link, preparing to teleport to \"%name\"" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ–½æ³•å¼€å§‹", "Cast Start" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ–½æ³•æˆåŠŸ", "Cast Success" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸Šæ–¹", "Above" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸‹æ–¹", "Below" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç»†æè¾¹", "Thin" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç²—æè¾¹", "Thick" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ— é”¯é½¿", "Monochrome" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æˆ‘æ²¡æœ‰é—ª (%t)", "No Blink (%t)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æˆ‘æ²¡æœ‰é—ª(%t)", "No Blink (%t)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ²¡æœ‰å½±æ­¥ (%t)", "No Shadowstep (%t)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ²¡æœ‰çˆªé’© (%t)", "No Grappling Hook (%t)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æˆ‘æ²¡æœ‰é—ª", "No Blink" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€‰æ‹©è¦ç¼–è¾‘çš„è¡Œ", "Select Row to Edit" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸»å±žæ€§", "Primary Stat" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ˜¾ç¤ºåœºæ™¯", "Show Scenes" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Dungeonså†…", "In Dungeons" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Enable This Rowä¸»å±žæ€§", "Enable This Row: Primary Stat" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Value å¯¹é½", "Value Alignment" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "CENTER:å±…ä¸­", "CENTER: Center" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "LEFT:å·¦å¯¹é½", "LEFT: Align Left" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "RIGHT:å³å¯¹é½", "RIGHT: Align Right" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "çŽ©å®¶è§’è‰²å®šä½æ ‡è®°", "Player Position Marker" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¼˜å…ˆåŠ è½½æœ¬åœ°æè´¨(PNG).è‹¥æ–‡ä»¶ç¼ºå¤±, è‡ªåŠ¨å›žé€€åˆ°çº¯ä»£ç ç»˜å›¾æ¨¡å¼.", "Loads local PNG textures first. If the files are missing, it automatically falls back to the pure code-drawn mode." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è·ç¦»ç›‘æŽ§", "Range Check" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“è¶…å‡ºè·ç¦»æ—¶å›¾æ ‡å˜è‰² (ç©º=è‡ªåŠ¨ä½¿ç”¨ä¸“ç²¾é¢„è®¾)", "Changes the marker color when the target moves out of range (blank = automatically uses the spec preset)." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“è¶…å‡ºè·ç¦»æ—¶å›¾æ ‡å˜è‰²ï¼ˆç©º=è‡ªåŠ¨ä½¿ç”¨ä¸“ç²¾é¢„è®¾ï¼‰", "Changes the marker color when the target moves out of range (blank = automatically uses the spec preset)." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“è¶…å‡ºè·ç¦»æ—¶ å›¾æ ‡å˜è‰²ï¼ˆç©º=è‡ªåŠ¨ä½¿ç”¨ä¸“ç²¾é¢„è®¾ï¼‰", "Changes the marker color when the target moves out of range (blank = automatically uses the spec preset)." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ˜¾ç¤ºæ¡ä»¶", "Visibility Rules" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ­£å¸¸Color", "Normal Color" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¶…è·Color", "Out-of-Range Color" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æˆ˜æ–—ä¸­æ˜¾ç¤º,æˆ˜æ–—å¤–æ˜¾ç¤º,ä»…Dungeonså†…", "Show in Combat, Show out of Combat, Only in Dungeons" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸“ç²¾è¿‡æ»¤ (ä»…åœ¨å‹¾é€‰çš„ä¸“ç²¾ä¸‹Enable)", "Spec Filter (only enabled for checked specs)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å­¦é™¢", "EcoD" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é£Žè¡Œ", "Dawn" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ‰§æ”¿", "Seat" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€šå¤©", "Sky" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤©è¡—", "Streets" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "éšä¿®", "Priory" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç ´æ™¨", "Dawn" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é­”å¯¼", "MT" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å®å›¾", "Gambit" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¨éš†", "POS" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›žå“", "Echoes" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ´žçªŸ", "AraK" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç”Ÿæ€", "EcoD" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "èŠ‚ç‚¹", "Flood" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ°´é—¸", "Floodgate" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰è¯­éŸ³åŒ…", "Current Voice Pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·é€‰æ‹©...", "Select..." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç®€ä»‹", "Description" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œè€…", "Author" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç‰ˆæœ¬", "Version" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰ä½¿ç”¨ä¸­", "Active" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·¦ä¾§Select Voice Pack, å³ä¾§æŒ‰Raid / Mythic+é…ç½® Author Profile.", "Select a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©Author Profileï¼›Dungeonsé¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profiles.", "Choose Author Profiles for the 6 role slots; the Dungeons page automatically writes the matching Raid / Mythic+ Profiles for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥Raidæ—¶è‡ªåŠ¨ä½¿ç”¨.", "Automatically used when entering a Raid with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥Mythic+æ—¶è‡ªåŠ¨ä½¿ç”¨.", "Automatically used when entering Mythic+ with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½Author Profileå·²æŽ¥å…¥ï¼ŒDungeonsé¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profile.", "6 Author Profile slots are active. The Dungeons page automatically writes the matching Raid / Mythic+ Profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£:", "Current role:" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Alert: å½“å‰æ˜¯ä»€ä¹ˆèŒè´£ï¼Œå°±è‡ªåŠ¨ä½¿ç”¨å¹¶ç¼–è¾‘å¯¹åº”çš„Raid/Mythic+ Profiles.", "Alert: the current role automatically selects and edits the matching Raid / Mythic+ Profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¦†ç›–å¸¸è§Bossä¸ŽMythic+Voicelabels, æ ‡å‡†å‚è€ƒå®žçŽ°.", "Covers common Boss and Mythic+ voice labels with the standard reference implementation." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¦†ç›–å¸¸è§Bossä¸ŽMythic+Voicelabelsï¼Œæ ‡å‡†å‚è€ƒå®žçŽ°.", "Covers common Boss and Mythic+ voice labels with the standard reference implementation." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç¼ºå°‘è¯­éŸ³ï¼š", "Missing Labels: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·²è¦†ç›–é»˜è®¤è¯­éŸ³æ ‡ç­¾", "Covers all default voice labels" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½Author Profileå·²æŽ¥å…¥ï¼ŒDungeons pageä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profile.", "6 author profile slots are active. The Dungeons page automatically writes the matching Raid / Mythic+ profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é»˜è®¤ä»…æ˜¾ç¤ºéžå›¢æœ¬", "default = non-raid only" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·²æ³¨å†ŒBOSS: 0  |  å·²æ³¨å†Œäº‹ä»¶: 0", "Registered Bosses: 0  |  Registered Events: 0" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æš‚æ— å·²æ³¨å†ŒBOSS", "No registered bosses" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "éžå›¢æœ¬å·²æ³¨å†ŒBOSS", "Non-raid registered bosses" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "éžå›¢æœ¬äº‹ä»¶", "Non-raid events" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è§¦å‘å™¨äº‹ä»¶", "Trigger events" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœªåŒ¹é…BOSSäº‹ä»¶", "Unmatched boss events" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬å·²è¿‡æ»¤", "Raid filtered" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœ€è¿‘åˆ·æ–°", "Last Refresh" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœ€è¿‘é”™è¯¯", "Last error" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œç”¨åŸŸ", "Scope" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœªçŸ¥å‰¯æœ¬", "Unknown Dungeon" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœªçŸ¥é¦–é¢†", "Unknown Boss" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰å¯¹è±¡æ²¡æœ‰ç§äººå…‰çŽ¯æ³•æœ¯ã€‚", "The selected target has no private-aura spells." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·é€‰æ‹©å·¦ä¾§ä¸€ä¸ªç§äººå…‰çŽ¯å¯¹è±¡", "Select a private-aura target on the left." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¹è±¡åˆ—è¡¨", "Target List" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬é¦–é¢†æˆ˜  |  encounterID:%s  |  æ³•æœ¯æ•°:%d", "Raid Encounter  |  encounterID:%s  |  Spells:%d" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç§˜å¢ƒå‰¯æœ¬  |  æ³•æœ¯æ•°:%d  |  BOSSç»„:%d  |  å°æ€ªæ³•æœ¯:%d", "Mythic+ Dungeon  |  Spells:%d  |  Boss Groups:%d  |  Trash Spells:%d" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å°æ€ª", "Trash" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…±%dä¸ªç§äººå…‰çŽ¯æ³•æœ¯", "%d private-aura spells total" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å€’è®¡æ—¶è®¾ç½®", "Countdown Settings" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½é¢„è­¦æ—¶åœ¨å±å¹•ä¸­å¤®æ˜¾ç¤º5ç§’å€’æ•°æ–‡å­—ã€‚", "Shows a 5-second countdown in the center of the screen for incoming spell alerts." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ¨¡æ¿", "Format" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ¨¡æ¿ï¼ˆ|cff00ff00%s|r=æŠ€èƒ½å  |cffffd100%t|r=å€’è®¡æ—¶æ•°å­—ï¼‰", "Format (|cff00ff00%s|r = spell name  |cffffd100%t|r = countdown number)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æç¤ºæ–‡å­—å­—ä½“ï¼ˆ%sï¼‰", "Alert Text Font (%s)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å€’è®¡æ—¶æ•°å­—å­—ä½“ï¼ˆ%tï¼‰", "Countdown Number Font (%t)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åˆ‡æ¢ç¼–è¾‘æ¨¡å¼é¢„è§ˆ", "Toggle Edit-Mode Preview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æµ‹è¯•å€’è®¡æ—¶", "Test Countdown" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¦å…‹å°–åˆº", "Tank Buster" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é…ç½®åï¼š", "Profile Name: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å‡ºè€…ï¼š", "Exporter: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ—¶é—´ï¼š", "Time: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤‡æ³¨ï¼š", "Notes: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤–è§‚ï¼š", "Appearance: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³é…ç½®ï¼š", "Mythic+ Profiles: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬é…ç½®ï¼š", "Raid Profiles: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬å¦å…‹", "Raid Tank" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬DPS", "Raid DPS" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬æ²»ç–—", "Raid Healer" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³å¦å…‹", "Mythic+ Tank" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³DPS", "Mythic+ DPS" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³æ²»ç–—", "Mythic+ Healer" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç¡®è®¤åˆ é™¤æ–¹æ¡ˆï¼š", "Delete profile: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åˆ é™¤", "Delete" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…¨é€‰å¤åˆ¶", "Select All" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…³é—­", "Close" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·²å¤åˆ¶åˆ°å‰ªè´´æ¿", "Copied to clipboard" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·è‡³å°‘å‹¾é€‰ä¸€é¡¹å¯¼å‡ºå†…å®¹", "Select at least one export item." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·è‡³å°‘å‹¾é€‰ä¸€é¡¹å¯¼å…¥å†…å®¹", "Select at least one import item." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·å…ˆç‚¹å‡»[è§£æž]æŒ‰é’®", "Click [Parse] first." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šè½´é¦–é¢†: %d  |  æŠ€èƒ½æ€»æ•°: %d  |  çª—å£: %s", "Fixed Bosses: %d  |  Total Skills: %d  |  Window: %s" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "encounter:%d  |  æŠ€èƒ½:%d  |  èŠ‚ç‚¹:%d", "encounter:%d  |  Skills:%d  |  Markers:%d" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šè½´é¦–é¢†: 0", "Fixed Bosses: 0" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¦–è½®>3:00", "First cast > 3:00" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ³•æœ¯ ", "Spell " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { " æ¬¡", "x" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€šç”¨é¢œè‰²æ–¹æ¡ˆ", "General Color Schemes" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…¨å±€æ¡æ˜¾ç¤ºæ¨¡å¼", "Global Bar Display Mode" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ˜¾ç¤ºæ¨¡å¼", "Display Mode" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯ç”¨å¤§ç§˜å¢ƒé¦–é¢†æç¤º", "Enable Mythic+ Boss Alerts" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯ç”¨å›¢æœ¬é¦–é¢†æç¤º", "Enable Raid Boss Alerts" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¦–é¢†æˆ˜æ—¶è‡ªåŠ¨å…³é—­æˆ˜æ–—éŸ³é¢‘é¢„è­¦", "Mute Combat Audio Alerts During Boss Fights" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¼€å¯ä¸­å¤®æ–‡å­—é¢„è­¦ï¼ˆæ³¨æ„ï¼šå¦‚æžœå…³é—­ä¼šå¯¼è‡´è¯­éŸ³ä¸å·¥ä½œï¼‰", "Enable Blizzard Center-Screen Warnings (required for voice alerts)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…³é—­æš´é›ªåŽŸç”Ÿè®¡æ—¶æ¡", "Disable Blizzard Encounter Timeline" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŽ§åˆ¶å…¨å±€æ˜¾ç¤ºï¼šä»…è®¡æ—¶æ¡ / ä»…æŸçŠ¶æ¡ / ä¸¤è€…éƒ½å¯ç”¨ / ä¸¤è€…éƒ½éšè—ã€‚\nå¯å•ç‹¬å…³é—­å¤§ç§˜å¢ƒæˆ–å›¢æœ¬é¦–é¢†æç¤ºï¼›å…³é—­åŽå°†æ•´ä½“ç¦ç”¨è¯¥åœºæ™¯çš„ Boss è®¡æ—¶ã€ä¸­å¤®æ–‡å­—ã€è¯­éŸ³ä¸Žé¢œè‰²è¦†ç›–ã€‚\nå¯é€‰ï¼šé¦–é¢†æˆ˜ä¸­è‡ªåŠ¨å°†æˆ˜æ–—éŸ³é¢‘é¢„è­¦åˆ†ç±»éŸ³é‡é™éŸ³ï¼ˆ0ï¼‰ï¼Œè„±æˆ˜æ¢å¤åŽŸå€¼ã€‚", "Controls the global display mode: Timer Bar only / Bun Bar only / both enabled / both hidden.\nYou can disable Mythic+ or Raid boss alerts separately; doing so disables Boss timers, center text, voice, and color overlays for that scene.\nOptional: mute Combat Audio Alert category volume during boss fights and restore it after combat." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…¨å±€è¯­éŸ³è¾“å‡º", "Global Voice Output" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¾“å‡ºé€šé“", "Audio Channel" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…¨å±€éŸ³é‡", "Global Volume" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¾·é²ä¼Š", "Druid" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¹³è¡¡", "Balance" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ³•å¸ˆ", "Mage" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç›—è´¼", "Rogue" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ½œè¡Œè€…", "Rogue" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "[Noneå¹¿å‘Š]", "[No spam]" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "[æ— å¹¿å‘Š]", "[No spam]" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½åç§°ç¤ºä¾‹", "Spell Name Example" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½ç¤ºä¾‹ ", "Skill Example " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æµ‹è¯•æŠ€èƒ½ ", "Test Skill " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¢„è§ˆæŠ€èƒ½ ", "Preview Skill " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æµ‹è¯•æ–½æ³• ", "Test Cast " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¦å…‹å°–åˆº", "Tank Buster" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å°±ç»ª", "Ready" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·¦ä¾§Select Voice Pack, å³ä¾§æŒ‰Raid / Mythic+é…ç½® Author Profile.", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·¦ä¾§æŒ‰Select Voice Pack, å³ä¾§æŒ‰Raid / Mythic+é…ç½® Author Profile.", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©Author Profileï¼›Dungeons pageä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profiles.", "Choose author profiles for the 6 role slots; the Dungeons page writes the matching Raid / Mythic+ profiles automatically for the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©Author Profileï¼›Dungeons pageä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profile.", "Choose author profiles for the 6 role slots; the Dungeons page writes the matching Raid / Mythic+ profile automatically for the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥Raidæ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering raids with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥Mythic+æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering Mythic+ with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½Author Profileå·²æŽ¥å…¥ï¼ŒDungeons pageä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profile.", "6 author profile slots are active. The Dungeons page automatically writes the matching Raid / Mythic+ profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½Author Profileå·²æŽ¥å…¥ï¼ŒDungeons pageä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profiles.", "6 author profile slots are active. The Dungeons page automatically writes the matching Raid / Mythic+ profiles for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Alert: å½“å‰æ˜¯ä»€ä¹ˆèŒè´£ï¼Œå°±è‡ªåŠ¨ä½¿ç”¨å¹¶ç¼–è¾‘å¯¹åº”çš„Raid/Mythic+ Profiles.", "Alert: your current role automatically selects and edits the matching Raid / Mythic+ profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "EXBoss å®˜æ–¹é»˜è®¤è¯­éŸ³åŒ…", "Official EXBoss default voice pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¦†ç›–å¸¸è§Bossä¸ŽMythic+Voicelabelsï¼Œæ ‡å‡†å‚è€ƒå®žçŽ°ã€‚", "Covers standard raid and Mythic+ voice labels." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¦†ç›–å¸¸è§é¦–é¢†ä¸Žå¤§ç§˜å¢ƒè¯­éŸ³æ ‡ç­¾ï¼Œæ ‡å‡†å‚è€ƒå®žçŽ°ã€‚", "Covers standard raid and Mythic+ voice labels." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸­æ–‡é…éŸ³è¯­éŸ³åŒ…", "Chinese voice pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¿˜å¿§æ™¯ä¹…è¯­éŸ³åŒ…ï¼Œæ ‡ç­¾ä¸Žé»˜è®¤åŒ…å…¼å®¹ï¼Œå¯ç›´æŽ¥æ›¿æ¢å…¨å±€è¯­éŸ³ã€‚", "Wangyou Jingjiu voice pack. Compatible with the default label set and usable as a global replacement." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¡¾è¡£è¡¿å°‘å¥³éŸ³ç‰ˆæœ¬ï¼Œä¿ç•™åŒä¸€å¥—æ ‡ç­¾ç»“æž„ï¼Œä¾¿äºŽç»Ÿä¸€åˆ‡æ¢ã€‚", "Guyijin girl-voice pack. Keeps the same label set for easy switching." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¡¾è¡£è¡¿å¾¡å§éŸ³ç‰ˆæœ¬ï¼Œä¿æŒæ ‡ç­¾å…¼å®¹ï¼Œé€‚é…çŽ°æœ‰å‰¯æœ¬æ–¹æ¡ˆã€‚", "Guyijin lady-voice pack. Keeps label compatibility with existing dungeon profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Kele è¯­éŸ³åŒ…ï¼Œæ ‡ç­¾å…¼å®¹é»˜è®¤æ–¹æ¡ˆï¼Œå¯ç›´æŽ¥ç”¨äºŽå‰¯æœ¬é…ç½®ã€‚", "Kele voice pack. Compatible with the default labels and ready for dungeon profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤ä¸€å¯è¯­éŸ³åŒ…ï¼Œä¿æŒæ ‡å‡†æ ‡ç­¾å…¼å®¹ï¼Œå¯ç›´æŽ¥åˆ‡æ¢ä½¿ç”¨ã€‚", "Xiayike voice pack. Compatible with the standard label set and ready to use." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç„¶ç„¶è¯­éŸ³åŒ…ï¼ŒåŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Ranran voice pack with standard labels and countdown voice lines." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç³–ç³–é…±è¯­éŸ³åŒ…ï¼Œæ ‡ç­¾ç»“æž„ä¸Žé»˜è®¤åŒ…å…¼å®¹ã€‚", "Tangtangjiang voice pack. Compatible with the default label structure." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å°ç¾Š Yagi è¯­éŸ³åŒ…ï¼ŒåŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Yagi voice pack with standard labels and countdown voice lines." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½ å¥½ç‰›è¯­éŸ³åŒ…ï¼Œæ¥æºç›®å½•ä¸ºç‰›å¸ˆå‚…ï¼ŒåŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Niuniu voice pack with standard labels and countdown voice lines." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç»«é›¶è¯­éŸ³åŒ…ï¼Œä½¿ç”¨æ ‡å‡†æ ‡ç­¾ç»“æž„ï¼Œå…¼å®¹é»˜è®¤åŒ…é…ç½®ã€‚", "Ayarei voice pack using the standard label structure and default-profile compatibility." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "éœ²éœ²ç·¹å©­è¯­éŸ³åŒ…ï¼Œæ ‡ç­¾ç»“æž„ä¸Žé»˜è®¤åŒ…å…¼å®¹ã€‚", "Ruru Tia voice pack. Compatible with the default label structure." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£ï¼š", "Current role: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½ä½œè€…æ–¹æ¡ˆå·²æŽ¥å…¥ï¼Œå‰¯æœ¬é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”æ–¹æ¡ˆã€‚", "6 author profile slots are active. The dungeon page automatically writes the matching profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç¼ºå°‘è¯­éŸ³ï¼š", "Missing Labels: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·²è¦†ç›–é»˜è®¤è¯­éŸ³æ ‡ç­¾", "Covers all default voice labels" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ ‡ç­¾ç›®å½•æœªåŠ è½½", "Label catalog not loaded" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è½½å…¥Settings", "Load Settings" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¼€å¯æš´é›ªä¸­å¤®Texté¢„è­¦ï¼ˆæ³¨æ„:å¦‚æžœCloseä¼šå¯¼è‡´Voiceä¸å·¥ä½œï¼‰", "Enable Blizzard center-screen warnings (required for voice alerts)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¼€å¯æš´é›ªä¸­å¤®Texté¢„è­¦(æ³¨æ„:å¦‚æžœCloseä¼šå¯¼è‡´Voiceä¸å·¥ä½œ)", "Enable Blizzard center-screen warnings (required for voice alerts)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å‡ºæˆåŠŸ", "Export Successful" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å‡ºå¤±è´¥ï¼š", "Export failed: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å…¥å¯¼å‡ºæ¨¡å—æœªåŠ è½½", "Import / export module not loaded" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·è‡³å°‘å‹¾é€‰ä¸€é¡¹å¯¼å‡ºå†…å®¹", "Select at least one export option." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·å…ˆç²˜è´´å¯¼å‡ºå­—ç¬¦ä¸²", "Please paste an export string first." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è§£æžå¤±è´¥ï¼š", "Parse failed: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å‡ºè€…ï¼š", "Exporter: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ—¶é—´ï¼š", "Time: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤‡æ³¨ï¼š", "Notes: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤–è§‚ï¼š", "Appearance: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åŒ…å«", "Included" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ— ", "None" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³é…ç½®ï¼š", "Mythic+ Profiles: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬é…ç½®ï¼š", "Raid Profiles: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è§£æžæˆåŠŸï¼Œé€‰æ‹©è¦å¯¼å…¥çš„å†…å®¹åŽç‚¹å‡»[æ‰§è¡Œå¯¼å…¥]", "Parse successful. Select what to import, then click [Run Import]." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·å…ˆç‚¹å‡»[è§£æž]æŒ‰é’®", "Click [Parse] first." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·è‡³å°‘å‹¾é€‰ä¸€é¡¹å¯¼å…¥å†…å®¹", "Select at least one import option." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å…¥æˆåŠŸï¼š", "Import successful: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å…¥å¤±è´¥ï¼š", "Import failed: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç¡®è®¤åˆ é™¤æ–¹æ¡ˆï¼š", "Delete profile: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é…ç½®åç§°", "Profile Name" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœªå‘½åé…ç½®", "Untitled Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤‡æ³¨ï¼ˆå¯é€‰ï¼‰", "Notes (Optional)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤‡æ³¨(å¯é€‰)", "Notes (Optional)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å‡ºå†…å®¹", "Export Contents" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤–è§‚è®¾ç½®ï¼ˆè®¡æ—¶æ¡å¤–è§‚ç­‰ï¼‰", "Appearance Settings (Timer Bar Style, etc.)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤–è§‚Settings(Timer Bar Appearanceç­‰)", "Appearance Settings (Timer Bar Appearance, etc.)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤–è§‚Settingsï¼ˆTimer Bar Appearanceç­‰ï¼‰", "Appearance Settings (Timer Bar Appearance, etc.)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å‡º", "Export" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å…¥", "Import" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç²˜è´´å¯¼å‡ºå­—ç¬¦ä¸²", "Paste Export String" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è§£æž", "Parse" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å…¥å†…å®¹", "Import Contents" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å…¥å¤–è§‚è®¾ç½®ï¼ˆç«‹å³åº”ç”¨ï¼‰", "Import Appearance Settings (Apply Immediately)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Importå¤–è§‚Settings(ç«‹å³åº”ç”¨)", "Import Appearance Settings (Apply Immediately)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Importå¤–è§‚Settingsï¼ˆç«‹å³åº”ç”¨ï¼‰", "Import Appearance Settings (Apply Immediately)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¯¼å…¥ä½œè€…åï¼ˆç•™ç©ºåˆ™ä½¿ç”¨é…ç½®åï¼‰", "Imported Author Name (blank = profile name)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ImportAuthorå(ç•™ç©ºåˆ™ä½¿ç”¨é…ç½®å)", "Imported Author Name (blank = profile name)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ImportAuthoråï¼ˆç•™ç©ºåˆ™ä½¿ç”¨é…ç½®åï¼‰", "Imported Author Name (blank = profile name)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ‰§è¡Œå¯¼å…¥", "Run Import" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€‰æ‹©æ–¹æ¡ˆ", "Select Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ­¤åŒºåŸŸåªå±•ç¤ºå½“å‰ 6 ä¸ªæ§½ä½å¯¹åº”çš„ä½œè€…æ–¹æ¡ˆã€‚", "This area only shows the profiles currently assigned to the 6 slots." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ­¤åŒºåŸŸåªå±•ç¤ºå½“å‰ 6 ä¸ªæ§½ä½å¯¹åº”çš„Author Profile.", "This area only shows the Author Profiles currently assigned to the 6 slots." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ§½ä½ï¼š", "Slot: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œè€…æ–¹æ¡ˆï¼š", "Profile: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Author Profile:", "Profile:" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šæ—¶é—´è½´é¢„è§ˆ", "Fixed Timeline Preview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šæ—¶é—´è½´æ€»è§ˆ", "Fixed Timeline Overview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰é¦–é¢†æŸ¥çœ‹å›ºå®šè½´æŠ€èƒ½åœ¨å‰ 3 åˆ†é’Ÿå†…çš„å‡ºçŽ°èŠ‚ç‚¹ï¼Œä¾¿äºŽå¿«é€Ÿæ ¡å¯¹æ—¶é—´è½´èŠ‚å¥ã€‚", "Review when fixed-timeline skills occur during the first 3 minutes of each boss fight." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·é€‰æ‹©å·¦ä¾§é¦–é¢†æŸ¥çœ‹ 3 åˆ†é’Ÿæ—¶é—´è½´ã€‚", "Select a boss on the left to view the 3-minute timeline." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½:", "Skills: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "3åˆ†é’ŸèŠ‚ç‚¹:", "3-Minute Markers: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›ºå®šè½´é¦–é¢†:", "Fixed Bosses: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½æ€»æ•°:", "Total Skills: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "çª—å£:", "Window: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "èŠ‚ç‚¹:", "Markers: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¦–é¢†åˆ—è¡¨", "Boss List" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æš‚æ— å›ºå®šæ—¶é—´è½´æ•°æ®", "No fixed timeline data available." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æš‚æ— æ—¶é—´è½´èŠ‚ç‚¹", "No timeline markers available." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åˆ·æ–°", "Refresh" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½ ", "Skill " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœªå‘½åæŠ€èƒ½", "Unnamed Skill" }

TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¢â€”Â Ã¥Â½â€œÃ¥â€°ÂÃ¤Â½Â¿Ã§â€Â¨Ã¤Â¸Â­", "Active" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â½â€œÃ¥â€°ÂÃ¤Â½Â¿Ã§â€Â¨Ã¤Â¸Â­", "Active" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Â â€¡Ã§Â­Â¾", "labels" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©â€¦ÂÃ§Â½Â®Ã¦â€“Â¹Ã¦Â¡Ë†", "Profile Slots" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â€¦Â¨Ã¥Â±â‚¬Ã¦ËœÂ¾Ã§Â¤ÂºÃ¦Â¨Â¡Ã¥Â¼ÂÃ¤Â¸Å½Ã¨Â¯Â­Ã©Å¸Â³Ã¨Â¾â€œÃ¥â€¡ÂºÃ£â‚¬â€š", "Global display mode and voice output." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "4Ã¤Â¸ÂªÃ¥â€ºÂºÃ¥Â®Å¡Ã©Â¢Å“Ã¨â€°Â²Ã¦â€“Â¹Ã¦Â¡Ë† + 1Ã¤Â¸ÂªÃ¨â€¡ÂªÃ¥Â®Å¡Ã¤Â¹â€°Ã¦â€“Â¹Ã¦Â¡Ë† + Ã¦Å“â‚¬Ã¥Â¤Å¡3Ã¤Â¸ÂªÃ©Â¢ÂÃ¥Â¤â€“Ã¦â€“Â¹Ã¦Â¡Ë†Ã£â‚¬â€šBossÃ¦Å â‚¬Ã¨Æ’Â½Ã©Â¡ÂµÃ¥ÂÂ¯Ã§â€ºÂ´Ã¦Å½Â¥Ã©â‚¬â€°Ã¦â€¹Â©Ã¦â€“Â¹Ã¦Â¡Ë†Ã¦Ë†â€“Ã¨â€¡ÂªÃ¥Â®Å¡Ã¤Â¹â€°Ã©Â¢Å“Ã¨â€°Â²Ã£â‚¬â€š", "4 fixed color schemes + 1 custom scheme + up to 3 extra schemes. The Boss spell page can select a scheme directly or use custom colors." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "BossÃ¦Å â‚¬Ã¨Æ’Â½Ã©Â¡ÂµÃ©ÂÂ¢Ã¥ÂÂ¯Ã©â‚¬â€°Ã¦â€¹Â©Ã¤Â¸â€¹Ã¥Ë†â€”Ã¦â€“Â¹Ã¦Â¡Ë†Ã¯Â¼â€ºÃ©â‚¬â€°Ã¦â€¹Â©Ã¢â‚¬Å“Ã¨â€¡ÂªÃ¥Â®Å¡Ã¤Â¹â€°Ã©Â¢Å“Ã¨â€°Â²Ã¢â‚¬ÂÃ¦â€”Â¶Ã¤Â½Â¿Ã§â€Â¨Ã¢â‚¬Å“Ã¨â€¡ÂªÃ¥Â®Å¡Ã¤Â¹â€°Ã¦â€“Â¹Ã¦Â¡Ë†Ã¢â‚¬ÂÃ£â‚¬â€šÃ¥â€¹Â¾Ã©â‚¬â€°Ã¥ÂÂ¯Ã§â€Â¨Ã§Å¡â€žÃ©Â¢ÂÃ¥Â¤â€“Ã¦â€“Â¹Ã¦Â¡Ë†Ã¤Â¼Å¡Ã¥â€¡ÂºÃ§Å½Â°Ã¥Å“Â¨Ã¦Å â‚¬Ã¨Æ’Â½Ã©Â¡ÂµÃ¤Â¸â€¹Ã¦â€¹â€°Ã£â‚¬â€š", "The Boss spell page can use the schemes below. Selecting Custom Colors uses the Custom Scheme. Enabled extra schemes also appear in the spell-page dropdown." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¨â€¡ÂªÃ¥Â®Å¡Ã¤Â¹â€°Ã¦â€“Â¹Ã¦Â¡Ë†Ã¥ÂÂ", "Custom Scheme Name" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¨â€¡ÂªÃ¥Â®Å¡Ã¤Â¹â€°Ã¦â€“Â¹Ã¦Â¡Ë†Ã©Â¢Å“Ã¨â€°Â²", "Custom Scheme Color" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©Â¢ÂÃ¥Â¤â€“Ã¦â€“Â¹Ã¦Â¡Ë†Ã¯Â¼Ë†Ã¦Å“â‚¬Ã¥Â¤Å¡3Ã¤Â¸ÂªÃ¯Â¼â€°", "Extra Schemes (up to 3)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©Â¢ÂÃ¥Â¤â€“Ã¦â€“Â¹Ã¦Â¡Ë†1", "Extra Scheme 1" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©Â¢ÂÃ¥Â¤â€“Ã¦â€“Â¹Ã¦Â¡Ë†2", "Extra Scheme 2" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©Â¢ÂÃ¥Â¤â€“Ã¦â€“Â¹Ã¦Â¡Ë†3", "Extra Scheme 3" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¤Â¸Â­Ã¥Â¤Â®Ã¥â‚¬â€™Ã¦â€¢Â°Ã¦â€“â€¡Ã¥Â­â€”Ã¤Â¸Å½Ã¥Â­â€”Ã¤Â½â€œÃ£â‚¬ÂÃ¤Â½ÂÃ§Â½Â®Ã£â‚¬â€š", "Center countdown text, font and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¤Â¸Â­Ã¥Â¤Â®Ã¦â€“â€¡Ã¥Â­â€”Ã¥â€¦Â¬Ã¥â€˜Å Ã¦Â Â·Ã¥Â¼ÂÃ¤Â¸Å½Ã¤Â½ÂÃ§Â½Â®Ã£â‚¬â€š", "Center text style and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â±ÂÃ¥Â¹â€¢Ã¤Â¸Â­Ã¥Â¤Â®Ã¥Å“â€ Ã§Å½Â¯Ã¨Â¿â€ºÃ¥ÂºÂ¦Ã¦Â Â·Ã¥Â¼ÂÃ£â‚¬ÂÃ¥Â¤Â§Ã¥Â°ÂÃ£â‚¬ÂÃ¤Â½ÂÃ§Â½Â®Ã£â‚¬â€š", "Center-screen ring style, size and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å¸Â¥Ã§Å“â€¹Ã¥Â½â€œÃ¥â€°ÂÃ¨Â¯Â­Ã©Å¸Â³Ã¦Â³Â¨Ã¥â€ Å’Ã§Â»â€ Ã¨Å â€šÃ¯Â¼Ë†Ã©Â»ËœÃ¨Â®Â¤Ã¤Â»â€¦Ã¦ËœÂ¾Ã§Â¤ÂºÃ©ÂÅ¾Ã¥â€ºÂ¢Ã¦Å“Â¬Ã¯Â¼â€°Ã¯Â¼Å¡Ã¥â€°Â¯Ã¦Å“Â¬ > BOSSÃ¥ÂÂÃ§Â§Â°(Ã¦â€¢Â°Ã©â€¡Â) + eventID(trigger0/1/2)Ã£â‚¬â€š", "Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã§â€ºâ€˜Ã¦Å½Â§Ã§Å½Â©Ã¥Â®Â¶Ã¨â€¡ÂªÃ¨ÂºÂ«Ã§Å¡â€ž3Ã¤Â¸ÂªÃ§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯Ã¦Â§Â½Ã¤Â½ÂÃ¯Â¼Å’Ã¦â€Â¯Ã¦Å’ÂÃ¥â€ºÂ¾Ã¦Â â€¡Ã¥Â¤Â§Ã¥Â°ÂÃ£â‚¬ÂÃ¤Â½ÂÃ§Â½Â®Ã£â‚¬ÂÃ¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶Ã£â‚¬ÂÃ©Å¸Â³Ã¦â€¢Ë†Ã§Â­â€°Ã©â€¦ÂÃ§Â½Â®Ã£â‚¬â€š", "Monitors the player's 3 private aura slots, including icon size, position, countdown and sound settings." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦ÂÂÃ¤Â¾â€ºÃ¤Â¸â€°Ã§Â§ÂÃ©â€¡ÂÃ§Â½Â®Ã¦â€“Â¹Ã¥Â¼ÂÃ¯Â¼Å¡\n1) Ã¤Â»â€¦Ã©â€¡ÂÃ§Â½Â®Ã¥Â¤â€“Ã¨Â§â€šÃ¨Â®Â¾Ã§Â½Â®\n2) Ã©â€¡ÂÃ§Â½Â®Ã¦â€°â‚¬Ã¦Å“â€°Ã©â€¦ÂÃ§Â½Â®Ã¯Â¼Ë†Ã¤Â¸ÂÃ¥Å’â€¦Ã¥ÂÂ«Ã¥Â¤â€“Ã¨Â§â€šÃ¯Â¼â€°\n3) Ã¦Â¸â€¦Ã©â„¢Â¤Ã¥â€¦Â¨Ã©Æ’Â¨Ã¨Â®Â¾Ã§Â½Â®Ã¯Â¼Ë†Ã¥Å’â€¦Ã¥ÂÂ«Ã¥Â¤â€“Ã¨Â§â€šÃ¯Â¼â€°", "Provides three reset modes:\n1) Reset appearance only\n2) Reset all settings (keep appearance)\n3) Wipe everything (including appearance)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¨Â¯Â­Ã©Å¸Â³Ã¥Â¼â€¢Ã¦â€œÅ½Ã¦Å“ÂªÃ¥Â°Â±Ã§Â»ÂªÃ¯Â¼Å’Ã¦â€”Â Ã¦Â³â€¢Ã¨Â¯Â»Ã¥Ââ€“Ã¦Â³Â¨Ã¥â€ Å’Ã§Å Â¶Ã¦â‚¬ÂÃ£â‚¬â€š", "The voice engine is not ready, so registration status cannot be read." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Â³Â¨Ã¥â€ Å’Ã¥Â¿Â«Ã§â€¦Â§Ã¤Â¸ÂºÃ§Â©ÂºÃ£â‚¬â€š", "Registration snapshot is empty." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©ÂÅ¾Ã¥â€ºÂ¢Ã¦Å“Â¬Ã¥Â·Â²Ã¦Â³Â¨Ã¥â€ Å’BOSS: ", "Non-raid registered bosses: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©ÂÅ¾Ã¥â€ºÂ¢Ã¦Å“Â¬Ã¤Âºâ€¹Ã¤Â»Â¶: ", "Non-raid events: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¨Â§Â¦Ã¥Ââ€˜Ã¥â„¢Â¨Ã¤Âºâ€¹Ã¤Â»Â¶(0/1/2): ", "Trigger events (0/1/2): " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å“ÂªÃ¥Å’Â¹Ã©â€¦ÂBOSSÃ¤Âºâ€¹Ã¤Â»Â¶: ", "Unmatched boss events: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â€ºÂ¢Ã¦Å“Â¬Ã¥Â·Â²Ã¨Â¿â€¡Ã¦Â»Â¤: ", "Raid filtered: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å“â‚¬Ã¨Â¿â€˜Ã¥Ë†Â·Ã¦â€“Â°: ", "Last Refresh: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¤Â½Å“Ã§â€Â¨Ã¥Å¸Å¸: ", "Scope: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å¡â€šÃ¦â€”Â Ã©ÂÅ¾Ã¥â€ºÂ¢Ã¦Å“Â¬Ã¥Â·Â²Ã¦Â³Â¨Ã¥â€ Å’BOSS", "No non-raid registered bosses" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦â€”Â Ã¦â€¢Â°Ã¦ÂÂ®", "No data" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â€ºÂ¢Ã¦Å“Â¬Ã©Â¦â€“Ã©Â¢â€ Ã¯Â¼Å¡%d  |  Ã¥Â¤Â§Ã§Â±Â³Ã¥â€°Â¯Ã¦Å“Â¬Ã¯Â¼Å¡%d", "Raid Bosses: %d  |  Mythic+ Dungeons: %d" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "encounterID:%s  Ã¥â€¦Â±%dÃ¤Â¸ÂªÃ§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯Ã¦Â³â€¢Ã¦Å“Â¯", "encounterID:%s  |  %d private aura spells" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â€¦Â±%dÃ¤Â¸ÂªÃ§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯Ã¦Â³â€¢Ã¦Å“Â¯", "%d private aura spells total" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â€ºÂ¢Ã¦Å“Â¬Ã©Â¦â€“Ã©Â¢â€ Ã¦Ë†Ëœ  |  encounterID:%s  |  Ã¦Â³â€¢Ã¦Å“Â¯Ã¦â€¢Â°:%d", "Raid Encounter  |  encounterID:%s  |  Spells:%d" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â¤Â§Ã§Â§ËœÃ¥Â¢Æ’Ã¥â€°Â¯Ã¦Å“Â¬  |  Ã¦Â³â€¢Ã¦Å“Â¯Ã¦â€¢Â°:%d  |  BOSSÃ§Â»â€ž:%d  |  Ã¥Â°ÂÃ¦â‚¬ÂªÃ¦Â³â€¢Ã¦Å“Â¯:%d", "Mythic+ Dungeon  |  Spells:%d  |  Boss groups:%d  |  Trash spells:%d" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¨Â¯Â·Ã©â‚¬â€°Ã¦â€¹Â©Ã¥Â·Â¦Ã¤Â¾Â§Ã¤Â¸â‚¬Ã¤Â¸ÂªÃ§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯Ã¥Â¯Â¹Ã¨Â±Â¡", "Select a private-aura target on the left." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â½â€œÃ¥â€°ÂÃ¥Â¯Â¹Ã¨Â±Â¡Ã¦Â²Â¡Ã¦Å“â€°Ã§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯Ã¦Â³â€¢Ã¦Å“Â¯Ã£â‚¬â€š", "The selected target has no private-aura spells." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â¯Â¹Ã¨Â±Â¡Ã¥Ë†â€”Ã¨Â¡Â¨", "Target List" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯", "Private Auras" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã§â€ºâ€˜Ã¦Å½Â§Ã§Å½Â©Ã¥Â®Â¶Ã¨â€¡ÂªÃ¨ÂºÂ«Ã§Å¡â€ž3Ã¤Â¸ÂªÃ§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯Ã¦Â§Â½Ã¤Â½ÂÃ£â‚¬â€šÃ¥Â¼â‚¬Ã¥ÂÂ¯Ã¥ÂÅ½Ã¨Â¿â€ºÃ¥â€¦Â¥Ã§Â¼â€“Ã¨Â¾â€˜Ã¦Â¨Â¡Ã¥Â¼ÂÃ¥ÂÂ¯Ã¦â€¹â€“Ã¥Å Â¨Ã¨Â°Æ’Ã¦â€¢Â´Ã¤Â½ÂÃ§Â½Â®Ã£â‚¬â€š", "Monitors the player's 3 private aura slots. Enable it and enter edit mode to drag the position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥ÂÂ¯Ã§â€Â¨Ã§Â§ÂÃ¤ÂºÂºÃ¥â€¦â€°Ã§Å½Â¯Ã§â€ºâ€˜Ã¦Å½Â§", "Enable Private Aura Monitor" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¨Â¿â€ºÃ¥â€¦Â¥Ã§Â¼â€“Ã¨Â¾â€˜Ã¦Â¨Â¡Ã¥Â¼Â", "Enter Edit Mode" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â€ºÂ¾Ã¦Â â€¡Ã¥Â¤â€“Ã¨Â§â€š", "Icon Appearance" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å½â€™Ã¥Ë†â€”Ã¦â€“Â¹Ã¥Ââ€˜", "Growth Direction" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¨Â¾Â¹Ã¦Â¡â€ Ã§Â¼Â©Ã¦â€Â¾", "Border Scale" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦ËœÂ¾Ã§Â¤ÂºÃ¥â€ Â·Ã¥ÂÂ´Ã¥Å“Ë†", "Show Cooldown Spiral" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦ËœÂ¾Ã§Â¤ÂºÃ¦â€¢Â°Ã¥Â­â€”Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶", "Show Numeric Countdown" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã©â€Å¡Ã§â€šÂ¹", "Anchor Point" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â±ÂÃ¥Â¹â€¢Ã¤Â¸Â­Ã¥Â¤Â®", "Screen Center" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â·Â¦Ã¤Â¸Å Ã¨Â§â€™", "Top Left" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¤Â¸Å Ã¦â€“Â¹Ã¤Â¸Â­Ã¥Â¤Â®", "Top" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥ÂÂ³Ã¤Â¸Å Ã¨Â§â€™", "Top Right" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Â·Â¦Ã¤Â¸â€¹Ã¨Â§â€™", "Bottom Left" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¤Â¸â€¹Ã¦â€“Â¹Ã¤Â¸Â­Ã¥Â¤Â®", "Bottom" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥ÂÂ³Ã¤Â¸â€¹Ã¨Â§â€™", "Bottom Right" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å â‚¬Ã¨Æ’Â½Ã©Â¢â€žÃ¨Â­Â¦Ã¦â€”Â¶Ã¥Å“Â¨Ã¥Â±ÂÃ¥Â¹â€¢Ã¤Â¸Â­Ã¥Â¤Â®Ã¦ËœÂ¾Ã§Â¤Âº5Ã§Â§â€™Ã¥â‚¬â€™Ã¦â€¢Â°Ã¦â€“â€¡Ã¥Â­â€”Ã£â‚¬â€š\n|cff00ff00%s|r = Ã¦Å â‚¬Ã¨Æ’Â½Ã¥ÂÂÃ§Â§Â°  |cffffd100%t|r = Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶Ã¦â€¢Â°Ã¥Â­â€”", "Shows a 5-second center-screen countdown when a spell alert triggers.\n|cff00ff00%s|r = spell name  |cffffd100%t|r = countdown number" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦ÂÂÃ§Â¤ÂºÃ¦â€“â€¡Ã¥Â­â€”Ã¦Â¨Â¡Ã¦ÂÂ¿", "Alert Text Template" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Â¨Â¡Ã¦ÂÂ¿Ã¯Â¼Ë†|cff00ff00%s|r=Ã¦Å â‚¬Ã¨Æ’Â½Ã¥ÂÂ  |cffffd100%t|r=Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶Ã¦â€¢Â°Ã¥Â­â€”Ã¯Â¼â€°", "Template (|cff00ff00%s|r = spell name  |cffffd100%t|r = countdown number)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Å“ÂºÃ¦â„¢Â¯Ã©Â¢â€žÃ¨Â§Ë†", "Scene Preview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Ë†â€¡Ã¦ÂÂ¢Ã§Â¼â€“Ã¨Â¾â€˜Ã¦Â¨Â¡Ã¥Â¼ÂÃ©Â¢â€žÃ¨Â§Ë†", "Toggle Edit Mode Preview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Âµâ€¹Ã¨Â¯â€¢Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶", "Test Countdown" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦ÂÂÃ§Â¤ÂºÃ¦â€“â€¡Ã¥Â­â€”Ã¥Â­â€”Ã¤Â½â€œÃ¯Â¼Ë†%sÃ¯Â¼â€°", "Alert Text Font (%s)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶Ã¦â€¢Â°Ã¥Â­â€”Ã¥Â­â€”Ã¤Â½â€œÃ¯Â¼Ë†%tÃ¯Â¼â€°", "Countdown Number Font (%t)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦ÂÂÃ§Â¤ÂºÃ¦â€“â€¡Ã¥Â­â€”", "Alert Text" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶Ã¦â€¢Â°Ã¥Â­â€”", "Countdown Number" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å½Â¨Ã¨ÂÂÃ¥â€¦Ë†Ã¤Â½Â¿Ã§â€Â¨Ã¢â‚¬Å“Ã¤Â»â€¦Ã©â€¡ÂÃ§Â½Â®Ã¥Â¤â€“Ã¨Â§â€šÃ¨Â®Â¾Ã§Â½Â®Ã¢â‚¬ÂÃ¯Â¼Å¡Ã¥ÂÂªÃ©â€¡ÂÃ§Â½Â®Ã¨Â®Â¡Ã¦â€”Â¶Ã¦ÂÂ¡/Ã¦ÂÅ¸Ã§Å Â¶Ã¦ÂÂ¡/Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶/Ã¦â€“â€¡Ã¥Â­â€”Ã¥â€¦Â¬Ã¥â€˜Å Ã¤Â¸Å½Ã©Â¢Å“Ã¨â€°Â²Ã¦â€“Â¹Ã¦Â¡Ë†Ã£â‚¬â€š\nÃ¢â‚¬Å“Ã©â€¡ÂÃ§Â½Â®Ã¦â€°â‚¬Ã¦Å“â€°Ã©â€¦ÂÃ§Â½Â®Ã¯Â¼Ë†Ã¤Â¸ÂÃ¥Å’â€¦Ã¥ÂÂ«Ã¥Â¤â€“Ã¨Â§â€šÃ¯Â¼â€°Ã¢â‚¬ÂÃ¤Â¼Å¡Ã¦Â¸â€¦Ã§Â©ÂºÃ©â‚¬Å¡Ã§â€Â¨Ã¨Â®Â¾Ã§Â½Â®Ã£â‚¬ÂÃ¨Â¯Â­Ã©Å¸Â³Ã©â€¦ÂÃ§Â½Â®Ã£â‚¬ÂÃ¦Å â‚¬Ã¨Æ’Â½Ã©â€¦ÂÃ§Â½Â®Ã¤Â¸Å½Ã¦â€”Â¶Ã©â€”Â´Ã¨Â½Â´Ã¨Â®Â¾Ã§Â½Â®Ã¯Â¼Å’Ã¤Â½â€ Ã¤Â¿ÂÃ§â€¢â„¢Ã¥Â¤â€“Ã¨Â§â€šÃ£â‚¬â€š\nÃ¢â‚¬Å“Ã¦Â¸â€¦Ã©â„¢Â¤Ã¥â€¦Â¨Ã©Æ’Â¨Ã¨Â®Â¾Ã§Â½Â®Ã¢â‚¬ÂÃ¤Â¼Å¡Ã¦Å Å  EXBoss Ã§Å¡â€žÃ¥â€¦Â¨Ã©Æ’Â¨Ã©â€¦ÂÃ§Â½Â®Ã©Æ’Â½Ã¦ÂÂ¢Ã¥Â¤ÂÃ¥Ë†Â°Ã¥Ë†ÂÃ¥Â§â€¹Ã§Å Â¶Ã¦â‚¬ÂÃ£â‚¬â€š", "Recommended: use Reset Appearance Only first. It resets Timer Bar / Bun Bar / Countdown / Flash Text styles and color schemes only.\nReset All Settings (Keep Appearance) clears general settings, voice config, spell config and timeline settings, while keeping appearance.\nWipe Everything resets all EXBoss settings back to their defaults." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¤Â»â€¦Ã©â€¡ÂÃ§Â½Â®Ã¨Â®Â¡Ã¦â€”Â¶Ã¦ÂÂ¡/Ã¦ÂÅ¸Ã§Å Â¶Ã¦ÂÂ¡/Ã¥â‚¬â€™Ã¨Â®Â¡Ã¦â€”Â¶/Ã¦â€“â€¡Ã¥Â­â€”Ã¥â€¦Â¬Ã¥â€˜Å Ã§Å¡â€žÃ¥Â¤â€“Ã¨Â§â€šÃ¦Â Â·Ã¥Â¼ÂÃ¯Â¼Å’Ã¤Â¸ÂÃ¥Ë†Â Ã©â„¢Â¤Ã¦Â³â€¢Ã¦Å“Â¯Ã©â€¦ÂÃ§Â½Â®Ã£â‚¬â€šÃ¦ËœÂ¯Ã¥ÂÂ¦Ã§Â»Â§Ã§Â»Â­Ã¯Â¼Å¸", "This only resets Timer Bar / Bun Bar / Countdown / Flash Text styles and keeps spell configuration intact. Continue?" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "|cffffcc00Ã¥Â°â€ Ã¦Â¸â€¦Ã§Â©Âº EXBoss Ã§Å¡â€žÃ©â‚¬Å¡Ã§â€Â¨Ã¨Â®Â¾Ã§Â½Â®Ã£â‚¬ÂÃ¨Â¯Â­Ã©Å¸Â³Ã©â€¦ÂÃ§Â½Â®Ã£â‚¬ÂÃ¦Å â‚¬Ã¨Æ’Â½Ã©â€¦ÂÃ§Â½Â®Ã¤Â¸Å½Ã¦â€”Â¶Ã©â€”Â´Ã¨Â½Â´Ã¨Â®Â¾Ã§Â½Â®Ã¯Â¼Å’Ã¤Â½â€ Ã¤Â¿ÂÃ§â€¢â„¢Ã¥Â¤â€“Ã¨Â§â€šÃ¦Â Â·Ã¥Â¼ÂÃ£â‚¬â€š|r\nÃ§Â¡Â®Ã¨Â®Â¤Ã§Â»Â§Ã§Â»Â­Ã¯Â¼Å¸", "|cffffcc00This clears EXBoss general settings, voice config, spell config and timeline settings, while keeping appearance styles.|r\nContinue?" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "|cffff4444Ã¥ÂÂ±Ã©â„¢Â©Ã¯Â¼Å¡Ã¥Â°â€ Ã¦Â¸â€¦Ã§Â©Âº EXBoss Ã§Å¡â€žÃ¥â€¦Â¨Ã©Æ’Â¨Ã¨Â®Â¾Ã§Â½Â®Ã¯Â¼Ë†Ã¥Å’â€¦Ã¥ÂÂ«Ã¥Â¤â€“Ã¨Â§â€šÃ¯Â¼â€°Ã¥Â¹Â¶Ã©â€¡ÂÃ¨Â½Â½Ã£â‚¬â€šÃ¦Â­Â¤Ã¦â€œÂÃ¤Â½Å“Ã¤Â¸ÂÃ¥ÂÂ¯Ã¦â€™Â¤Ã©â€â‚¬Ã£â‚¬â€š|r\nÃ§Â¡Â®Ã¨Â®Â¤Ã§Â»Â§Ã§Â»Â­Ã¯Â¼Å¸", "|cffff4444Warning: this wipes every EXBoss setting, including appearance, and reloads the UI. This cannot be undone.|r\nContinue?" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã§Â¡Â®Ã¥Â®Å¡", "OK" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¥Ââ€“Ã¦Â¶Ë†", "Cancel" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã§Â¡Â®Ã¥Â®Å¡Ã©â€¡ÂÃ§Â½Â®", "Reset" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã§Â¡Â®Ã¥Â®Å¡Ã¦Â¸â€¦Ã§Â©Âº", "Wipe" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯­éŸ³ / é…ç½®", "Voice / Profiles" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·¦ä¾§é€‰æ‹©è¯­éŸ³åŒ…ï¼Œå³ä¾§æŒ‰å›¢æœ¬ / å¤§ç±³é…ç½®ä½œè€…æ–¹æ¡ˆã€‚", "Choose a Voice Pack on the left, then configure Raid / Mythic+ author profiles on the right." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·¦ä¾§Select Voice Pack, å³ä¾§æŒ‰Raid / Mythic+é…ç½® Author Profile.", "Choose a Voice Pack on the left, then configure Raid / Mythic+ author profiles on the right." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·¦ä¾§Select Voice Packï¼Œå³ä¾§æŒ‰Raid / Mythic+é…ç½® Author Profile.", "Choose a Voice Pack on the left, then configure Raid / Mythic+ author profiles on the right." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯­éŸ³åŒ…", "Voice Pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€‰æ‹©è¯­éŸ³åŒ…", "Select Voice Pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç®€ä»‹", "Description" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œè€…", "Author" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç‰ˆæœ¬", "Version" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ ‡ç­¾", "labels" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰ä½¿ç”¨ä¸­", "Active" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©ä½œè€…æ–¹æ¡ˆï¼›å‰¯æœ¬é¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„å›¢æœ¬ / å¤§ç±³æ–¹æ¡ˆã€‚", "Choose author profiles for the 6 role slots; the dungeon page automatically writes the matching Raid / Mythic+ profiles for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©Author Profileï¼›Dungeonsé¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profiles.", "Choose author profiles for the 6 role slots; the Dungeons page automatically writes the matching Raid / Mythic+ profiles for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰ 6 ä¸ªèŒè´£æ§½ä½é€‰æ‹©Author Profileï¼›Dungeonsé¡µä¼šæŒ‰å½“å‰èŒè´£è‡ªåŠ¨å†™å…¥å¯¹åº”çš„Raid / Mythic+ Profile.", "Choose author profiles for the 6 role slots; the Dungeons page automatically writes the matching Raid / Mythic+ profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥å›¢æœ¬æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering raids with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥å¤§ç±³æ—¶è‡ªåŠ¨ä½¿ç”¨ã€‚", "Automatically used when entering Mythic+ with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥Raidæ—¶è‡ªåŠ¨ä½¿ç”¨.", "Automatically used when entering raids with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£è¿›å…¥Mythic+æ—¶è‡ªåŠ¨ä½¿ç”¨.", "Automatically used when entering Mythic+ with the current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬æ–¹æ¡ˆ", "Raid Profiles" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³æ–¹æ¡ˆ", "Mythic+ Profiles" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬å¦å…‹", "Raid Tank" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬DPS", "Raid DPS" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¢æœ¬æ²»ç–—", "Raid Healer" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³å¦å…‹", "Mythic+ Tank" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³DPS", "Mythic+ DPS" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤§ç±³æ²»ç–—", "Mythic+ Healer" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æç¤ºï¼šå½“å‰æ˜¯ä»€ä¹ˆèŒè´£ï¼Œå°±è‡ªåŠ¨ä½¿ç”¨å¹¶ç¼–è¾‘å¯¹åº”çš„å›¢æœ¬/å¤§ç±³æ–¹æ¡ˆã€‚", "Alert: your current role automatically selects and edits the matching Raid / Mythic+ profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰èŒè´£ï¼š", "Current role: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å½“å‰ è Œè´£:", "Current role:" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½ ä½œè€…æ–¹æ¡ˆå·²æŽ¥å…¥ï¼Œå‰¯æœ¬é¡µä¼šæŒ‰å½“å‰ è Œè´£è‡ªåŠ¨å†™å…¥å¯¹åº”æ–¹æ¡ˆã€‚", "6 author profile slots are active. The dungeon page automatically writes the matching profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "6 æ§½ä½ Author Profileå·²æŽ¥å…¥ï¼ŒDungeonsé¡µä¼šæŒ‰å½“å‰ è Œè´£è‡ªåŠ¨å†™å…¥å¯¹åº”Profile.", "6 author profile slots are active. The Dungeons page automatically writes the matching profile for your current role." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å·²åˆ‡æ ¢ ", "Switched " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åº”ç”¨å¤±è´¥ï¼š", "Apply failed: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Ã¦Å¡â€šÃ¦â€”Â Ã©Â Å¾Ã¥â€ºÂ¢Ã¦Å“Â¬Ã¥Â·Â²Ã¦Â³Â¨Ã¥â€ Å’BOSS", "No non-raid registered bosses" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "当前波次打断怪", "Current Pull Interrupts" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "无可打断怪", "No interrupts needed" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "备注：无", "Note: None" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "备注：%s", "Note: %s" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "手动", "Manual" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "自动", "Auto" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "路线 %s", "Route %s" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "未找到可导入的MDT预设", "No importable MDT preset found" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "未检测到 MythicDungeonTools（MDT）", "MythicDungeonTools (MDT) not detected" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "未选择 MDT 副本", "No MDT dungeon selected" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "MDT 数据库不可用", "MDT database unavailable" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "该副本暂无可用路线", "No routes available for this dungeon" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "嗜血音效 (YY Sound)", "Bloodlust Sound" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "获得嗜血BUFF时 播放音效和倒数 该功能测试中", "Play sound & countdown on Heroism (Testing)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "图标设置", "Icon Settings" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "锁定图标位置", "Lock Icon Position" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "原生模式", "Native UI Mode" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "自定义模式", "Custom UI Mode" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开嗜血，注意流血debuff，减伤结束开矮人", "Heroism, watch bleed debuff, use dwarf racial after DR ends" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "注意流血层数", "Watch bleed stacks" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "靠左边走，如果有add则不要拉中间3只怪，进度可平替", "Keep left. If add pulled, skip middle 3 mobs, % is substitutable" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "大怪打掉推荐开火车", "Recommend chain pull after big mob dies" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "法系怪收掉推荐开火车", "Recommend chain pull after caster dies" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "优先打断嗜魔者，教科书可以控制/驱散", "Interrupt Mana Devourer first, Textbook can be CC'd/dispelled" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "主目标法系怪，boss激活时记得拉2只奥术抢劫者", "Focus caster, pull 2 Arcane Ravagers when boss active" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "记得拉两只奥术抢劫者", "Remember to pull 2 Arcane Ravagers" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "主目标法系怪", "Focus caster" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "主目标回声骑士，AOE 15s/25s", "Focus Echoing Knight, AOE 15s/25s" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开嗜血，左右两波征服者", "Heroism, both sides Conquerors" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "打boss过程记得拉一波破碎者，起手拉最好", "Pull Shatterer during boss, best on pull" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "注意守护者黑线，变粗有增伤，变细是正常", "Watch Guardian black line: thick=dmg buff, thin=normal" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "先拉征服者，最后聚在法系怪", "Pull Conqueror first, stack on caster" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "第九波剩下的精锐和猎手", "Remaining Elite and Hunter from 9th pull" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "饥饿者远离中场，避免激活boss", "Keep Hungerer away from mid to avoid pulling boss" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Boss开嗜血", "Heroism on Boss" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "主目标死了建议开火车", "Recommend chain pull after primary target dies" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "如果合波，先开15，过5秒再开16", "If combining, pull 15 first, wait 5s then pull 16" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人1、2，嗜血，注意不要add下方猎头", "Save 1&2, Heroism, avoid bottom Headhunter" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人3、4，考虑让队友帮拉大象", "Save 3&4, consider having team pull elephant" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人5，吃buff", "Save 5, get buff" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人6、7、8", "Save 6, 7, 8" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "注意不要add猎头和大象", "Avoid Headhunter and elephant" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "2头熊+面具带boss，boss打T可以矮人", "2 bears+mask with boss, dwarf racial for tank buster" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "嗜血，走侧面更好聚怪拉仇恨", "Heroism, flank for better gather/aggro" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "坦克单断裂魂", "Tank solo interrupts Soul Rending" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车，大怪/法系怪收掉开到13波", "Chain pull, after big mob/caster dies pull up to 13" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "剩防御者时去拉阴兵，收掉阴兵开boss", "Pull ghost when only Defender left, then boss" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "嗜血，起手直接去左下角拉暮刃，打完救人1", "Heroism, pull Twilight Blade bottom-left, save 1" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人2", "Save 2" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人3，注意场地地板，不要add", "Save 3, watch floor, don't add" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "打掉法系怪可以开火车", "Chain pull after caster dies" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人4", "Save 4" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "靠右边走，观察蝙蝠巡逻位置，不要add", "Keep right, watch bat patrol, don't add" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人7", "Save 7" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "救人8，打完从上方走", "Save 8, go top after" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "拉小怪时注意蝙蝠巡逻位置", "Watch bat patrol when pulling" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车 — 打法系怪", "Chain pull — focus caster" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车 — 打暮刃", "Chain pull — focus Twilight Blade" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车 — 打巫妖", "Chain pull — focus Lich" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "可以考虑打掉法系怪带精英", "Consider bringing Elite after caster dies" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Sx波次，注意路上不要被防御者打，掉血可以直接大红", "Heroism pull, avoid Defender hits on way, pot if low" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "过渡技能", "Transitional skills" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "先拉左边防御者，压力波次", "Pull left Defender first, high pressure" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车，先打掉节点专家", "Chain pull, kill Node Expert first" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "哨兵打T，主目标哨兵", "Sentinel hits tank, focus Sentinel" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "过渡波次", "Transitional pull" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "先拉右边司令官，等一次读条，最后聚怪点在右边司令官", "Pull right Commander first, wait for cast, stack on right Commander" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车，控制射手地板条", "Chain pull, CC archer floor cast" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "靠右走，注意法系怪AOE时控制掷斧者", "Keep right, CC Axe Thrower during caster AOE" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "推荐开嗜血", "Recommend Heroism" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车，全部法系怪死了可以带", "Chain pull, bring if all casters dead" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "注意聚怪点，开书获取急速buff", "Watch stack point, open book for haste buff" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "等110巡逻，不要add中间小怪，在机器人处聚怪", "Wait for patrol, don't pull middle, stack on robot" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Boss旁的浮龙，准备第二轮易伤再拉", "Mana Wyrm near boss, pull on 2nd damage taken phase" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "开火车，清掉浮龙+法系怪", "Chain pull, clear Mana Wyrms and casters" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "拉进去打", "Pull inside" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "如果嗜血好了可以考虑开火车", "Consider chain pull if Heroism is ready" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "主目标法系怪，开火车", "Focus caster, chain pull" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "AOE时候接控制，控撕裂者", "Chain CC during AOE, CC Maimer" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "酒仙可以扎针「虚空恐魔」减少打断压力，恐魔可以带boss", "Brewmaster can Clash Void Terror; Terror can be brought to boss" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "主目标召唤师", "Focus Summoner" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯·é€‰æ‹©...", "Select..." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Boss é… ç½®æ¨¡å —æœªåŠ è½½", "Boss configuration module not loaded" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ExBoss å®˜æ–¹é»˜è®¤è¯­éŸ³åŒ…", "Official EXBoss default voice pack" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¡¾è¡£è¡¿å°‘å¥³éŸ³ç‰ˆæœ¬ï¼Œä¿ç•™åŒä¸€å¥—æ ‡ç­¾ç»“æž„ï¼Œä¾¿äºŽç»Ÿä¸€åˆ‡æ¢ã€‚", "Guyijin girl-voice pack. Keeps the same label set for easy switching." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¡¾è¡£è¡¿å¾¡å§éŸ³ç‰ˆæœ¬ï¼Œä¿æŒæ ‡ç­¾å…¼å®¹ï¼Œé€‚é…çŽ°æœ‰å‰¯æœ¬æ–¹æ¡ˆã€‚", "Guyijin lady-voice pack. Keeps label compatibility with existing dungeon profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Kele è¯­éŸ³åŒ…ï¼Œæ ‡ç­¾å…¼å®¹é»˜è®¤æ–¹æ¡ˆï¼Œå¯ç›´æŽ¥ç”¨äºŽå‰¯æœ¬é…ç½®ã€‚", "Kele voice pack. Compatible with the default labels and ready for dungeon profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¤ä¸€å¯è¯­éŸ³åŒ…ï¼Œä¿æŒæ ‡å‡†æ ‡ç­¾å…¼å®¹ï¼Œå¯ç›´æŽ¥åˆ‡æ¢ä½¿ç”¨ã€‚", "Xiayike voice pack. Compatible with the standard label set and ready to use." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç„¶ç„¶è¯­éŸ³åŒ…ï¼ŒåŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Ranran voice pack with standard labels and countdown voice lines." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç³–ç³–é…±è¯­éŸ³åŒ…ï¼Œæ ‡ç­¾ç»“æž„ä¸Žé»˜è®¤åŒ…å…¼å®¹ã€‚", "Tangtangjiang voice pack. Compatible with the default label structure." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å°ç¾Š Yagi è¯­éŸ³åŒ…ï¼ŒåŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Yagi voice pack with standard labels and countdown voice lines." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½ å¥½ç‰›è¯­éŸ³åŒ…ï¼Œæ¥æºç›®å½•ä¸ºç‰›å¸ˆå‚…ï¼ŒåŒ…å«æ ‡å‡†æ ‡ç­¾ä¸Žå€’æ•°è¯­éŸ³ã€‚", "Niuniu voice pack with standard labels and countdown voice lines." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç»«é›¶è¯­éŸ³åŒ…ï¼Œä½¿ç”¨æ ‡å‡†æ ‡ç­¾ç»“æž„ï¼Œå…¼å®¹é»˜è®¤åŒ…é…ç½®ã€‚", "Ayarei voice pack using the standard label structure and default-profile compatibility." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "éœ²éœ²ç·¹å©­è¯­éŸ³åŒ…ï¼Œæ ‡ç­¾ç»“æž„ä¸Žé»˜è®¤åŒ…å…¼å®¹ã€‚", "Ruru Tia voice pack. Compatible with the default label structure." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æš‚æ— æè¿°", "No description available." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ ‡ç­¾ç›®å½•æœªåŠ è½½", "Label catalog not loaded" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ§½ä½æ¦‚è§ˆ", "Slot Overview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ­¤åŒºåŸŸåªå±•ç¤ºå½“å‰ 6 ä¸ªæ§½ä½å¯¹åº”çš„ä½œè€…æ–¹æ¡ˆã€‚", "This area only shows the author profiles currently assigned to the 6 slots." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ§½ä½ä¸ºå›ºå®šç»“æž„ï¼Œè¯·åœ¨è¯­éŸ³/é…ç½®é¡µåˆ‡æ¢ä½œè€…æ–¹æ¡ˆã€‚", "These slots are fixed. Change author profiles in Voice / Profiles." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ§½ä½ä¸ºå›ºå®šç»“æž„ï¼Œä¸æ”¯æŒåˆ é™¤ã€‚", "These slots are fixed and cannot be deleted." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é‡å‘½å", "Rename" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€šç”¨è®¾ç½®", "General Settings" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å…¨å±€æ˜¾ç¤ºæ¨¡å¼ä¸Žè¯­éŸ³è¾“å‡ºã€‚", "Global display mode and voice output." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "4ä¸ªå›ºå®šé¢œè‰²æ–¹æ¡ˆ + 1ä¸ªè‡ªå®šä¹‰æ–¹æ¡ˆ + æœ€å¤š3ä¸ªé¢å¤–æ–¹æ¡ˆã€‚BossæŠ€èƒ½é¡µå¯ç›´æŽ¥é€‰æ‹©æ–¹æ¡ˆæˆ–è‡ªå®šä¹‰é¢œè‰²ã€‚", "4 fixed color schemes + 1 custom scheme + up to 3 extra schemes. The Boss spell page can select a scheme directly or use custom colors." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è®¡æ—¶æ¡å¤–è§‚ã€æ–‡å­—ã€ä½ç½®ã€‚", "Timer bar appearance, text and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŸçŠ¶æ¡å¤–è§‚ã€è½¨é“ã€ä½ç½®ã€‚", "Bun bar appearance, track and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸­å¤®å€’æ•°æ–‡å­—ä¸Žå­—ä½“ã€ä½ç½®ã€‚", "Center countdown text, font and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸­å¤®æ–‡å­—å…¬å‘Šæ ·å¼ä¸Žä½ç½®ã€‚", "Center text style and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å±å¹•ä¸­å¤®åœ†çŽ¯è¿›åº¦æ ·å¼ã€å¤§å°ã€ä½ç½®ã€‚", "Center-screen ring style, size and position." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŸ¥çœ‹å½“å‰è¯­éŸ³æ³¨å†Œç»†èŠ‚ï¼ˆé»˜è®¤ä»…æ˜¾ç¤ºéžå›¢æœ¬ï¼‰ï¼šå‰¯æœ¬ > BOSSåç§°(æ•°é‡) + eventID(trigger0/1/2)ã€‚", "Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç›‘æŽ§çŽ©å®¶è‡ªèº«çš„3ä¸ªç§äººå…‰çŽ¯æ§½ä½ï¼Œæ”¯æŒå›¾æ ‡å¤§å°ã€ä½ç½®ã€å€’è®¡æ—¶ã€éŸ³æ•ˆç­‰é…ç½®ã€‚", "Monitors the player's 3 private aura slots, including icon size, position, countdown and sound settings." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æä¾›ä¸‰ç§é‡ç½®æ–¹å¼ï¼š\n1) ä»…é‡ç½®å¤–è§‚è®¾ç½®\n2) é‡ç½®æ‰€æœ‰é…ç½®ï¼ˆä¸åŒ…å«å¤–è§‚ï¼‰\n3) æ¸…é™¤å…¨éƒ¨è®¾ç½®ï¼ˆåŒ…å«å¤–è§‚ï¼‰", "Provides three reset modes:\n1) Reset appearance only\n2) Reset all settings (keep appearance)\n3) Wipe everything (including appearance)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä»…æŸçŠ¶æ¡", "Bun Bar Only" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸¤è€…éƒ½å¯ç”¨", "Both Enabled" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä»…è®¡æ—¶æ¡", "Timer Bar Only" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä¸¤è€…éƒ½éšè—", "Hide Both" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¦å…‹æ–¹æ¡ˆ", "Tank Scheme" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ²»ç–—æ–¹æ¡ˆ", "Healer Scheme" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å‡ä¼¤æ–¹æ¡ˆ", "Defensive Scheme" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœºåˆ¶æ–¹æ¡ˆ", "Mechanic Scheme" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¯­éŸ³å¼•æ“Žæœªå°±ç»ªï¼Œæ— æ³•è¯»å–æ³¨å†ŒçŠ¶æ€ã€‚", "The voice engine is not ready, so registration status cannot be read." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ³¨å†Œå¿«ç…§ä¸ºç©ºã€‚", "Registration snapshot is empty." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœ€è¿‘åˆ·æ–°: ", "Last Refresh: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œç”¨åŸŸ: ", "Scope: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æœ€è¿‘é”™è¯¯: ", "Last error: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "BossæŠ€èƒ½é¡µé¢å¯é€‰æ‹©ä¸‹åˆ—æ–¹æ¡ˆï¼›é€‰æ‹©â€œè‡ªå®šä¹‰é¢œè‰²â€æ—¶ä½¿ç”¨â€œè‡ªå®šä¹‰æ–¹æ¡ˆâ€ã€‚å‹¾é€‰å¯ç”¨çš„é¢å¤–æ–¹æ¡ˆä¼šå‡ºçŽ°åœ¨æŠ€èƒ½é¡µä¸‹æ‹‰ã€‚", "The Boss spell page can use the schemes below. Choosing \"Custom Colors\" uses the \"Custom Scheme\" row. Enabled extra schemes appear in spell-page dropdowns." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è‡ªå®šä¹‰æ–¹æ¡ˆ", "Custom Scheme" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è‡ªå®šä¹‰æ–¹æ¡ˆå", "Custom Scheme Name" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è‡ªå®šä¹‰æ–¹æ¡ˆé¢œè‰²", "Custom Scheme Color" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¢å¤–æ–¹æ¡ˆï¼ˆæœ€å¤š3ä¸ªï¼‰", "Extra Schemes (up to 3)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é¢å¤–æ–¹æ¡ˆ", "Extra Scheme" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŽ¨èå…ˆä½¿ç”¨â€œä»…é‡ç½®å¤–è§‚è®¾ç½®â€ï¼šåªé‡ç½®è®¡æ—¶æ¡/æŸçŠ¶æ¡/å€’è®¡æ—¶/æ–‡å­—å…¬å‘Šä¸Žé¢œè‰²æ–¹æ¡ˆã€‚\nâ€œé‡ç½®æ‰€æœ‰é…ç½®ï¼ˆä¸åŒ…å«å¤–è§‚ï¼‰â€ä¼šæ¸…ç©ºé€šç”¨è®¾ç½®ã€è¯­éŸ³é…ç½®ã€æŠ€èƒ½é…ç½®ä¸Žæ—¶é—´è½´è®¾ç½®ï¼Œä½†ä¿ç•™å¤–è§‚ã€‚\nâ€œæ¸…é™¤å…¨éƒ¨è®¾ç½®â€ä¼šæŠŠ EXBoss çš„å…¨éƒ¨é…ç½®éƒ½æ¢å¤åˆ°åˆå§‹çŠ¶æ€ã€‚", "Recommended: use Reset Appearance Only first. It resets Timer Bar / Bun Bar / Countdown / Flash Text styles and color schemes only.\nReset All Settings (Keep Appearance) clears general settings, voice config, spell config and timeline settings, while keeping appearance.\nWipe Everything resets all EXBoss settings back to their defaults." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä»…é‡ç½®å¤–è§‚è®¾ç½®", "Reset Appearance Only" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä»…é‡ç½®è®¡æ—¶æ¡/æŸçŠ¶æ¡/å€’è®¡æ—¶/æ–‡å­—å…¬å‘Šçš„å¤–è§‚æ ·å¼ï¼Œä¸åˆ é™¤æ³•æœ¯é…ç½®ã€‚æ˜¯å¦ç»§ç»­ï¼Ÿ", "This only resets Timer Bar / Bun Bar / Countdown / Flash Text styles and keeps spell configuration intact. Continue?" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é‡ç½®æ‰€æœ‰é…ç½®ï¼ˆä¸åŒ…å«å¤–è§‚ï¼‰", "Reset All Settings (Keep Appearance)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å°†æ¸…ç©º EXBoss çš„é€šç”¨è®¾ç½®ã€è¯­éŸ³é…ç½®ã€æŠ€èƒ½é…ç½®ä¸Žæ—¶é—´è½´è®¾ç½®ï¼Œä½†ä¿ç•™å¤–è§‚æ ·å¼ã€‚\nç¡®è®¤ç»§ç»­ï¼Ÿ", "This clears EXBoss general settings, voice config, spell config and timeline settings, while keeping appearance styles.\nContinue?" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç¡®å®šé‡ç½®", "Reset" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ¸…é™¤å…¨éƒ¨è®¾ç½®ï¼ˆåŒ…å«å¤–è§‚ï¼‰", "Wipe Everything (Including Appearance)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å±é™©ï¼šå°†æ¸…ç©º EXBoss çš„å…¨éƒ¨è®¾ç½®ï¼ˆåŒ…å«å¤–è§‚ï¼‰å¹¶é‡è½½ã€‚æ­¤æ“ä½œä¸å¯æ’¤é”€ã€‚\nç¡®è®¤ç»§ç»­ï¼Ÿ", "Warning: this wipes every EXBoss setting, including appearance, and reloads the UI. This cannot be undone.\nContinue?" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç¡®å®šæ¸…ç©º", "Wipe" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å€’è®¡æ—¶è®¾ç½®", "Countdown Settings" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŠ€èƒ½é¢„è­¦æ—¶åœ¨å±å¹•ä¸­å¤®æ˜¾ç¤º5ç§’å€’æ•°æ–‡å­—ã€‚\n|cff00ff00%s|r = æŠ€èƒ½åç§°  |cffffd100%t|r = å€’è®¡æ—¶æ•°å­—", "Shows a 5-second center-screen countdown when a spell alert triggers.\n|cff00ff00%s|r = spell name  |cffffd100%t|r = countdown number" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åŠŸèƒ½", "General" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ˜¾ç¤ºå›¾æ ‡", "Show Icon" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ˜¾ç¤ºå°æ•°ç‚¹", "Show Decimal" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¾æ ‡å¤§å°", "Icon Size" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æç¤ºæ–‡å­—æ¨¡æ¿", "Alert Text Template" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ¨¡æ¿ï¼ˆ|cff00ff00%s|r=æŠ€èƒ½å  |cffffd100%t|r=å€’è®¡æ—¶æ•°å­—ï¼‰", "Template (|cff00ff00%s|r = spell name  |cffffd100%t|r = countdown number)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æç¤ºæ–‡å­—å­—ä½“ï¼ˆ%sï¼‰", "Alert Text Font (%s)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æç¤ºæ–‡å­—", "Alert Text" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å€’è®¡æ—¶æ•°å­—å­—ä½“ï¼ˆ%tï¼‰", "Countdown Number Font (%t)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å€’è®¡æ—¶æ•°å­—", "Countdown Number" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½ç½®", "Position" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ°´å¹³ä½ç½® (X)", "Horizontal Position (X)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åž‚ç›´ä½ç½® (Y)", "Vertical Position (Y)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é‡ç½®ä½ç½®", "Reset Position" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åœºæ™¯é¢„è§ˆ", "Scene Preview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åˆ‡æ¢ç¼–è¾‘æ¨¡å¼é¢„è§ˆ", "Toggle Edit Mode Preview" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æµ‹è¯•å€’è®¡æ—¶", "Test Countdown" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¦å…‹å°–åˆº", "Tank Buster" }

for zhLabel, enLabel in pairs(LABEL_TRANSLATIONS) do
    TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { zhLabel, enLabel }
end

for zhName, enName in pairs(MAP_NAME_TRANSLATIONS) do
    TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { zhName, enName }
end

local SAFE_CHINESE_TEXT_REPLACEMENTS = {
    { "虚影尖塔", "The Voidspire" },
    { "梦境裂隙", "The Dreamrift" },
    { "进军奎尔丹纳斯", "March on Quel'Danas" },
    { "解放安德麦", "Liberation of Undermine" },
    { "尼鲁巴尔王宫", "Nerub-ar Palace" },
    { "永恒王宫", "The Eternal Palace" },
    { "团本坦克", "Raid Tank" },
    { "团本DPS", "Raid DPS" },
    { "团本治疗", "Raid Healer" },
    { "大米坦克", "Mythic+ Tank" },
    { "大米DPS", "Mythic+ DPS" },
    { "大米治疗", "Mythic+ Healer" },
    { "团本方案", "Raid Profiles" },
    { "大米方案", "Mythic+ Profiles" },
    { "团本配置：%s%s", "Raid Profiles: %s%s" },
    { "团本槽位已导入", "Raid slots imported" },
    { "团本首领：%d  |  大米副本：%d", "Raid Bosses: %d  |  Mythic+ Dungeons: %d" },
    { "团本首领战  |  encounterID:%s  |  法术数:%d", "Raid Boss Encounter  |  encounterID:%s  |  Spells: %d" },
    { "查看当前语音注册细节（默认仅显示非团本）：副本 > BOSS名称(数量) + eventID(trigger0/1/2)。", "Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." },
    { "非团本已注册BOSS: %d  |  非团本事件: %d / 全量: %d  |  触发器事件(0/1/2): %d/%d/%d%s", "Non-raid registered bosses: %d  |  Non-raid events: %d / Total: %d  |  Trigger events (0/1/2): %d/%d/%d%s" },
    { "暂无非团本已注册BOSS", "No non-raid registered bosses" },
    { "团本已过滤: %d", "Raid filtered: %d" },
    { "控制全局显示：仅计时条 / 仅束状条 / 两者都启用 / 两者都隐藏。\n可单独关闭大秘境或团本首领提示；关闭后将整体禁用该场景的 Boss 计时、中央文字、语音与颜色覆盖。\n可选：首领战中自动将战斗音频预警分类音量静音（0），脱战恢复原值。", "Controls the global display mode: Timer Bar only / Bun Bar only / both enabled / both hidden.\nYou can disable Mythic+ or Raid boss alerts separately; disabling one scene also disables its boss timers, center text, voice alerts, and color overlays.\nOptional: mute combat audio warning volume to 0 during boss fights and restore it after combat." },
    { "团本配置尚未完工，确认启用？", "Raid configuration is not finished yet. Enable it anyway?" },
    { "导出成功", "Export Successful" },
    { "Ctrl+C 复制并自动关闭，或点击 全选复制 按钮", "Press Ctrl+C to copy and auto-close, or click Select All." },
    { "已复制到剪贴板", "Copied to clipboard" },
    { "全选复制", "Select All" },
    { "关闭", "Close" },
    { "确认删除方案：%s ？", "Delete profile: %s ?" },
    { "删除", "Delete" },
    { "取消", "Cancel" },
    { "导入导出模块未加载", "Import / Export module is not loaded" },
    { "请至少勾选一项导出内容", "Select at least one export option" },
    { "请先粘贴导出字符串", "Paste an export string first" },
    { "解析失败：", "Parse failed: " },
    { "解析成功，选择要导入的内容后点击[执行导入]", "Parse successful. Choose what to import, then click [Run Import]." },
    { "请先点击[解析]按钮", "Click [Parse] first" },
    { "请至少勾选一项导入内容", "Select at least one import option" },
    { "导入成功：", "Import successful: " },
    { "导入失败：", "Import failed: " },
    { "读取摘要失败：", "Failed to read summary: " },
    { "配置名称", "Profile Name" },
    { "未命名配置", "Untitled Profile" },
    { "备注（可选）", "Notes (Optional)" },
    { "无", "None" },
    { "导出内容", "Export Contents" },
    { "导入内容", "Import Contents" },
    { "执行导入", "Run Import" },
    { "选择方案", "Select Profile" },
    { "槽位：%s    作者方案：%s", "Slot: %s   Profile: %s" },
    { "配置名：", "Profile Name: " },
    { "导出者：", "Exporter: " },
    { "时间：", "Time: " },
    { "备注：", "Notes: " },
    { "外观：", "Appearance: " },
    { "包含", "Included" },
    { "团本配置：", "Raid Profiles: " },
    { "大米配置：", "Mythic+ Profiles: " },
    { "条事件", "events" },
    { "官方默认语音包", "Official default voice pack" },
    { "中文配音语音包", "Chinese voice pack" },
    { "忘忧景久语音包，标签与默认包兼容，可直接替换全局语音。", "Wangyou Jingjiu voice pack. Compatible with the default labels and can replace the global voice pack directly." },
    { "顾衣衿少女音版本，保留同一套标签结构，便于统一切换。", "Guyijin girl-voice version using the same label layout for easy switching." },
    { "顾衣衿御姐音版本，保持标签兼容，适配现有副本方案。", "Guyijin lady-voice version with compatible labels for existing dungeon profiles." },
    { "Kele 语音包，标签兼容默认方案，可直接用于副本配置。", "Kele voice pack. Compatible with the default labels and ready for dungeon profiles." },
    { "夏一可语音包，保持标准标签兼容，可直接切换使用。", "Xiayike voice pack. Keeps standard label compatibility and is ready to use." },
    { "然然语音包，包含标准标签与倒数语音。", "Ranran voice pack with standard labels and countdown lines." },
    { "糖糖酱语音包，标签结构与默认包兼容。", "Tangtangjiang voice pack. Compatible with the default label structure." },
    { "小羊 Yagi 语音包，包含标准标签与倒数语音。", "Yagi voice pack with standard labels and countdown lines." },
    { "你好牛语音包，来源目录为牛师傅，包含标准标签与倒数语音。", "Niuniu voice pack sourced from Niushifu, with standard labels and countdown lines." },
    { "绫零语音包，使用标准标签结构，兼容默认包配置。", "Ayarei voice pack using the standard label structure and default profile compatibility." },
    { "露露緹婭语音包，标签结构与默认包兼容。", "Rurutia voice pack. Compatible with the default label structure." },
    { "请选择配置", "Please select a profile" },
    { "● 当前使用中", "● Active" },
    { "缺少语音", "Missing Labels" },
    { "缺少语音：?", "Missing Labels: ?" },
    { "缺少语音：0", "Missing Labels: 0" },
    { "已覆盖默认语音标签", "Covers all default voice labels" },
    { "配置方案", "Profile Slots" },
    { "Boss 配置模块未加载", "Boss config module is not loaded" },
    { "已切换 ", "Switched " },
    { "应用失败：", "Apply failed: " },
    { "通用设置", "General Settings" },
    { "通用颜色方案", "General Color Schemes" },
    { "束状条", "Bun Bar" },
    { "倒计时", "Countdown" },
    { "文字公告", "Center Text" },
    { "圆环进度", "Ring Progress" },
    { "语音注册监控", "Voice Registration Monitor" },
    { "私人光环监控", "Private Aura Monitor" },
    { "重置设置", "Reset Settings" },
    { "倒计时设置", "Countdown Settings" },
    { "计时条设置", "Timer Bar Settings" },
    { "计时条所有外观的设置", "All appearance settings for the timer bar." },
    { "计时条外观", "Timer Bar Appearance" },
    { "法术名称", "Spell Name" },
    { "时间文本", "Time Text" },
    { "技能预警时在屏幕中央显示5秒倒数文字。", "Shows a 5-second center-screen countdown when a spell alert triggers." },
    { "%s = 技能名称  %t = 倒计时数字", "%s = Spell Name  %t = Countdown Number" },
    { "%s = 技能名称 %t = 倒计时数字", "%s = Spell Name %t = Countdown Number" },
    { "显示图标", "Show Icon" },
    { "显示小数点", "Show Decimal" },
    { "图标大小", "Icon Size" },
    { "模板", "Template" },
    { "预览：", "Preview:" },
    { "预览", "Preview" },
    { "提示文字字体 (%s)", "Alert Text Font (%s)" },
    { "提示文字", "Alert Text" },
    { "倒计时数字字体 (%t)", "Countdown Number Font (%t)" },
    { "倒计时数字", "Countdown Number" },
    { "更新日志", "Changelog" },
    { "通用", "General" },
    { "显示名称", "Show Name" },
    { "显示时间", "Show Time" },
    { "条增长方式", "Bar Fill Mode" },
    { "左到右填充", "Left to Right Fill" },
    { "左到右消退", "Left to Right Fade" },
    { "右到左填充", "Right to Left Fill" },
    { "右到左消退", "Right to Left Fade" },
    { "间距", "Spacing" },
    { "最大显示数量", "Maximum Visible Bars" },
    { "增长方向", "Growth Direction" },
    { "水平位置 (X)", "Horizontal Position (X)" },
    { "垂直位置 (Y)", "Vertical Position (Y)" },
    { "重置位置", "Reset Position" },
    { "背景设置", "Background Settings" },
    { "背景材质", "Background Texture" },
    { "背景颜色", "Background Color" },
    { "边框材质", "Border Texture" },
    { "边框颜色", "Border Color" },
    { "边框粗细", "Border Width" },
    { "边框内距", "Border Inset" },
    { "显示背景", "Show Background" },
    { "显示边框", "Show Border" },
    { "显示冷却旋涡", "Show Cooldown Spiral" },
    { "显示数字倒计时", "Show Numeric Countdown" },
    { "名称位置", "Name Position" },
    { "图标左边", "Left of Icon" },
    { "图标右边", "Right of Icon" },
    { "图案倒数时间", "Pattern Countdown Time" },
    { "背景线粗细", "Background Line Width" },
    { "背景线颜色", "Background Line Color" },
    { "5秒线粗细", "5s Line Width" },
    { "5秒线颜色", "5s Line Color" },
    { "载入设置", "Load Settings" },
    { "这里统一管理 EXBoss 的全局显示模式与语音输出", "This page manages EXBoss global display mode and voice output." },
    { "全局显示模式与语音输出。", "Global display mode and voice output." },
    { "启用大秘境首领提示", "Enable Mythic+ Boss Alerts" },
    { "启用团本首领提示", "Enable Raid Boss Alerts" },
    { "关闭暴雪原生Timer Bar", "Disable Blizzard Encounter Timeline" },
    { "首领战时自动关闭战斗音频预警", "Mute Combat Audio Alerts During Boss Fights" },
    { "开启暴雪中央文字预警（注意：如果关闭会导致语音不工作）", "Enable Blizzard Center-Screen Warnings (required for voice alerts)" },
    { "音频输出选项", "Audio Output Options" },
    { "输出通道", "Audio Channel" },
    { "全局音量", "Global Volume" },
    { "4个固定Color方案 + 1个自定义方案 + 最多3个额外方案。BossSkill页可直接选择方案或自定义Color。", "4 fixed color schemes + 1 custom scheme + up to 3 extra schemes. The Boss Skill page can select a scheme directly or use a custom color." },
    { "BossSkill页可选择下列方案；选择“自定义Color”时使用“自定义方案”。勾选Enable的额外方案会出现在Skill页下拉。", "The Boss Skill page can use the schemes below. Choosing \"Custom Color\" uses the \"Custom Scheme\". Enabled extra schemes also appear in the Skill page dropdown." },
    { "坦克方案", "Tank Scheme" },
    { "治疗方案", "Healer Scheme" },
    { "特殊机制", "Special Mechanic" },
    { "自定义方案名", "Custom Scheme Name" },
    { "自定义方案", "Custom Scheme" },
    { "额外方案（最多3个）", "Extra Schemes (up to 3)" },
    { "额外方案1", "Extra Scheme 1" },
    { "额外方案2", "Extra Scheme 2" },
    { "额外方案3", "Extra Scheme 3" },
    { "导出内容", "Export Contents" },
    { "导入内容", "Import Contents" },
    { "粘贴导出字符串", "Paste Export String" },
    { "外观设置（计时条外观等）", "Appearance Settings (Timer Bar Style, etc.)" },
    { "导入外观设置（立即应用）", "Import Appearance Settings (apply immediately)" },
    { "导入作者名（留空则使用配置名）", "Imported Author Name (blank = profile name)" },
    { "固定时间轴总览", "Fixed Timeline Overview" },
    { "查看当前语音注册细节（Default仅显示非团本）：Dungeon > BOSS名称(数量) + eventID(trigger0/1/2)。", "Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." },
    { "当前语音注册状态", "Current Voice Registration State" },
    { "查看当前语音注册细节（Default仅显示非团本）：Dungeons > BOSS名称(数量) + eventID(trigger0/1/2)。", "Shows current voice registration details (default = non-raid only): Dungeons > Boss Name (count) + eventID(trigger0/1/2)." },
    { "非团本已注册BOSS: 0  |  非团本Event: 0 / 全量: 0  |  触发器Event(0/1/2): 0/0/0", "Non-raid registered bosses: 0  |  Non-raid events: 0 / Total: 0  |  Trigger events (0/1/2): 0/0/0" },
    { "暂无None非团本已注册BOSS", "No non-raid registered bosses" },
    { "当前职责: dps", "Current role: dps" },
    { "提示: 当前是什么职责，就自动使用并编辑对应的Raid/Mythic+ Profiles.", "Alert: the active role automatically selects and edits the matching Raid / Mythic+ Profiles." },
    { "最近刷新: -", "Last Refresh: -" },
    { "最近刷新:", "Last Refresh:" },
    { "最近错误:", "Last error:" },
    { "语音引擎未就绪，无法读取注册状态。", "The voice engine is not ready, so the registration state cannot be read." },
    { "注册快照为空。", "The registration snapshot is empty." },
    { "语音来源", "Voice Source" },
    { "语音标签", "Voice Label" },
    { "语音包标签", "Voice Pack Label" },
    { "语音 / 配置", "Voice / Profiles" },
    { "语音/配置", "Voice / Profiles" },
    { "左侧选择语音包，右侧按团本 / 大米配置作者方案。", "Choose a Voice Pack on the left, then configure Raid / Mythic+ author profiles on the right." },
    { "左侧选择Voice Pack，右侧按团本 / 大米配置 Author Profile。", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." },
    { "按 6 个职责槽位选择作者方案；副本页会按当前职责自动写入对应的团本 / 大米方案。", "Choose author profiles for the 6 role slots; the dungeon page writes the matching Raid / Mythic+ profile automatically for the current role." },
    { "按 6 个职责槽位选择Author Profile；Dungeons页会按当前职责自动写入对应的团本 / Mythic+ Profile。", "Choose author profiles for the 6 role slots; the Dungeons page writes the matching Raid / Mythic+ profile automatically for the current role." },
    { "当前职责进入团本时自动使用。", "Automatically used when entering raids with the current role." },
    { "当前职责进入大米时自动使用。", "Automatically used when entering Mythic+ with the current role." },
    { "6 槽位作者方案已接入，副本页会按当前职责自动写入对应方案。", "6 author profile slots are active. The dungeon page automatically writes the matching profile for your current role." },
    { "语音/配置页面依赖 ExwindTools.UI，当前未就绪。请确认 ExwindCore 已正确加载后重开面板。", "The Voice / Profiles page depends on ExwindTools.UI. Make sure ExwindCore loaded correctly, then reopen the panel." },
    { "语音包", "Voice Pack" },
    { "选择语音包", "Select Voice Pack" },
    { "当前语音包", "Current Voice Pack" },
    { "简介", "Description" },
    { "作者", "Author" },
    { "版本", "Version" },
    { "缺少语音", "Missing Labels" },
    { "官方EXBoss默认语音包", "Official EXBoss default voice pack" },
    { "ExBoss 官方默认语音包", "Official EXBoss default voice pack" },
    { "ExBoss 官方默认 Voice Pack", "Official EXBoss default voice pack" },
    { "覆盖常见Boss与Mythic+Voicelabels，标准参考实现。", "Covers common boss and Mythic+ voice labels with the standard reference implementation." },
    { "覆盖常见Boss与Mythic+Voicelabels, 标准参考实现。", "Covers common boss and Mythic+ voice labels with the standard reference implementation." },
    { "中文配音语音包", "Chinese voice pack" },
    { "标签与默认包兼容，可直接替换全局语音。", "Compatible with the default label set and can replace the global voice pack." },
    { "中央文本", "Center Text" },
    { "中央文本内容（可用 {name}）", "Center Text Content (supports {name})" },
    { "技能触发时在Screen Center显示Spell Name（淡入 → 停留 → 淡出）。", "Displays the Spell Name in the screen center when the skill triggers (fade in → hold → fade out)." },
    { "中心文本", "Center Text" },
    { "中央警告", "Center Warning" },
    { "施法开始", "Cast Start" },
    { "提前5秒", "Pre-Alert 5s" },
    { "提前(秒)", "Pre-Alert (sec)" },
    { "计时条改名", "Rename Timer Bar" },
    { "试听", "Preview" },
    { "延迟", "Delay" },
    { "模板（%s=技能名 %t=倒计时数字）", "Template (%s = spell name  %t = countdown number)" },
    { "提示文字字体（%s）", "Alert Text Font (%s)" },
    { "倒计时数字字体（%t）", "Countdown Number Font (%t)" },
    { "预览：", "Preview:" },
    { "坦克尖刺3.0", "Tank Buster 3.0" },
    { "坦克尖刺 3.0", "Tank Buster 3.0" },
    { "测试技能", "Test Skill" },
    { "测试施法", "Test Cast" },
    { "预览技能", "Preview Skill" },
    { "技能示例", "Skill Example" },
    { "场景预览", "Scene Preview" },
    { "切换编辑模式预览", "Toggle Edit-Mode Preview" },
    { "测试倒计时", "Test Countdown" },
    { "监控玩家自身的3个私人光环槽位，支持图标大小、位置、倒计时、音效等配置。", "Monitors the player's 3 private aura slots, including icon size, position, countdown and sound settings." },
    { "监控玩家自身的3个私人光环槽位。开启后进入编辑模式可拖动调整位置。", "Monitors the player's 3 private aura slots. Enable it and enter edit mode to drag the position." },
    { "启用私人光环监控", "Enable Private Aura Monitor" },
    { "当前对象没有私人光环法术。", "The current object has no private aura spells." },
    { "共%d个私人光环法术", "%d private aura spells total" },
    { "encounterID:%s  共%d个私人光环法术", "encounterID:%s  |  %d private aura spells" },
    { "ExwindGrid 不可用，无法渲染私人光环设置。", "ExwindGrid is unavailable; private aura settings cannot be rendered." },
    { "ExwindGrid 不可用，无法渲染设置区。", "ExwindGrid is unavailable; the settings pane cannot be rendered." },
    { "提供三种重置方式：\n1) 仅重置外观设置\n2) 重置所有配置（不包含外观）\n3) 清除全部Settings（包含外观）", "Provides three reset modes:\n1. Reset appearance only\n2. Reset all settings (keep appearance)\n3. Wipe everything (including appearance)" },
    { "推荐先使用“仅Reset外观Settings”。“仅Reset外观Settings”只ResetTimer Bar/Bun Bar/Countdown/Flash Text与ColorProfile。\n“Reset所有配置（不包含外观）”会清空General Settings、语音配置、Skill配置与TimelineSettings，但保留外观。\n“清除全部Settings（包含外观）”会把 EXBoss 的全部配置重置并恢复到初始状态。", "Recommended: start with \"Reset Appearance Only\". \"Reset Appearance Only\" resets only Timer Bar / Bun Bar / Countdown / Flash Text and Color Profile.\n\"Reset All Settings (Keep Appearance)\" clears General Settings, voice config, skill config and Timeline settings, while preserving appearance.\n\"Wipe Everything (Including Appearance)\" resets all EXBoss settings back to defaults." },
    { "仅Reset外观Settings", "Reset Appearance Only" },
    { "Reset所有配置（不包含外观）", "Reset All Settings (Keep Appearance)" },
    { "清除全部Settings（包含外观）", "Wipe Everything (Including Appearance)" },
    { "确认重置", "Confirm Reset" },
    { "确认清空", "Confirm Wipe" },
    { "仅重置计时条/束状条/倒计时/文字公告的外观样式，不删除法术配置。是否继续？", "Only resets the appearance of Timer Bar / Bun Bar / Countdown / Center Text and keeps spell configuration. Continue?" },
    { "将清空 EXBoss 的通用设置、语音设置、技能设置与时间轴设置，但保留外观样式。\n确认继续？", "This clears EXBoss general settings, voice settings, spell settings and timeline settings, while keeping appearance styles.\nContinue?" },
    { "危险：将清空 EXBoss 的全部设置（包含外观）并重载。此操作不可撤销。\n确认继续？", "Danger: this wipes every EXBoss setting, including appearance, and reloads the UI. This cannot be undone.\nContinue?" },
    { "快速切换聊天频道的工具栏，每个频道可自定义显示名称、颜色和指令", "A quick chat channel bar with customizable label, color, and command for each channel." },
    { "大秘境图标/分数/点击传送等增强。", "M+ icon, score, click-to-teleport enhancements." },
    { "法术信息查询与提示增强。", "Spell info lookup and tooltip enhancements." },
    { "进入模块设置页后可使用 Grid 面板调整样式、位置和功能开关。", "Inside a module settings page, use the Grid panel to adjust styles, position and feature toggles." },
    { "是否退出编辑模式？", "Exit Edit Mode?" },
    { "确定", "OK" },
    { "覆盖常见Boss与Mythic+Voicelabels, 标准参考实现.", "Covers common boss and Mythic+ voice labels with the standard reference implementation." },
    { "左侧Select Voice Pack, 右侧按Raid / Mythic+配置Author Profile.", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." },
    { "左侧Select Voice Pack，右侧按Raid / Mythic+配置Author Profile.", "Choose a Voice Pack on the left, then configure Raid / Mythic+ Author Profiles on the right." },
    { "按 6 个职责槽位选择Author Profile；Dungeons页会按当前职责自动写入对应的Raid / Mythic+ Profiles.", "Choose Author Profiles for the 6 role slots; the Dungeons page automatically writes the matching Raid / Mythic+ Profiles for your current role." },
    { "按 6 个职责槽位选择Author Profile；Dungeons页会按当前职责自动写入对应的Raid / Mythic+ Profile.", "Choose Author Profiles for the 6 role slots; the Dungeons page automatically writes the matching Raid / Mythic+ Profile for your current role." },
    { "当前职责进入Raid时自动使用.", "Automatically used when entering raids with the current role." },
    { "当前职责进入Mythic+时自动使用.", "Automatically used when entering Mythic+ with the current role." },
    { "6 槽位Author Profile已接入，Dungeons页会按当前职责自动写入对应Profile.", "6 Author Profile slots are active. The Dungeons page automatically writes the matching Profile for your current role." },
    { "6 槽位Author Profile已接入, Dungeons页会按当前职责自动写入对应Profile.", "6 Author Profile slots are active. The Dungeons page automatically writes the matching Profile for your current role." },
    { "Alert: 当前是什么职责，就自动使用并编辑对应的Raid/Mythic+ Profiles.", "Alert: the active role automatically selects and edits the matching Raid / Mythic+ Profiles." },
    { "当前职责: dps", "Current role: dps" },
    { "备注(可选)", "Notes (Optional)" },
    { "外观Settings(Timer Bar Appearance等)", "Appearance Settings (Timer Bar Appearance, etc.)" },
    { "Import外观Settings(立即应用)", "Import Appearance Settings (apply immediately)" },
    { "ImportAuthor名(留空则使用配置名)", "Imported Author Name (blank = profile name)" },
    { "此区域只展示当前 6 个槽位对应的Author Profile.", "This area only shows the Author Profiles currently assigned to the 6 slots." },
    { "槽位: Raid Tank  Author Profile: Default Preset", "Slot: Raid Tank   Profile: Default Preset" },
    { "开启暴雪中央Text预警（注意：如果Close会导致Voice不工作）", "Enable Blizzard center-screen text warnings (required for voice alerts)" },
    { "查看当前语音注册细节（Default仅显示非团本）：Dungeon > BOSS名称(数量) + eventID(trigger0/1/2)。", "Shows current voice registration details (Default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." },
    { "非团本已注册BOSS: 0  |  非团本Event: 0 / 全量: 0  |  触发器Event(0/1/2): 0/0/0", "Non-raid registered bosses: 0  |  Non-raid events: 0 / Total: 0  |  Trigger events (0/1/2): 0/0/0" },
    { "最近刷新:", "Last Refresh:" },
    { "最近错误:", "Last error:" },
    { "暂无None非团本已注册BOSS", "No non-raid registered bosses" },
    { "按首领查看固定轴Skill在前 3 分钟内的出现节点，便于快速校对Timeline节奏。", "Review when fixed-timeline Skills occur during the first 3 minutes of each boss fight to quickly verify Timeline pacing." },
    { "固定轴首领: %d  |  技能总数: %d  |  窗口: %s", "Fixed Bosses: %d  |  Total Skills: %d  |  Window: %s" },
    { "encounter:%d  |  技能:%d  |  节点:%d", "encounter:%d  |  Skills:%d  |  Markers:%d" },
    { "超出距离时图标变色（空=自动使用专精预设）", "Change the icon color when out of range (blank = automatically use the spec preset)." },
    { "显示条件", "Visibility Rules" },
    { "专精过滤（仅在勾选的专精下Enable）", "Spec Filter (only enabled for checked specs)" },
    { "我没有闪 (%t)", "No Blink (%t)" },
    { "我没有闪(%t)", "No Blink (%t)" },
    { "我没有闪", "No Blink" },
    { "测试技能 ", "Test Skill " },
    { "测试施法 ", "Test Cast " },
    { "预览技能 ", "Preview Skill " },
    { "技能示例 ", "Skill Example " },
    { "技能示例", "Skill Example" },
    { "技能名称示例", "Spell Name Example" },
    { "计时条", "Timer Bar" },
    { "æŒ‰BossæŸ¥çœ‹Fixed TimelineSkillåœ¨å‰ 3 åˆ†é’Ÿå†…çš„å‡ºçŽ°èŠ‚ç‚¹ï¼Œä¾¿äºŽå¿«é€Ÿæ ¡å¯¹TimelineèŠ‚å¥ã€‚", "Browse each boss's Fixed Timeline skill markers over the first 3 minutes to quickly verify the Timeline pacing." },
    -- ===== Screenshot 1: Voice/Profiles page =====
    { "72 标签", "72 Labels" },
    { "73 标签", "73 Labels" },
    { "暂None描述", "No description available." },
    { "Raid Tank 方案", "Raid Tank Profile" },
    { "Raid DPS 方案", "Raid DPS Profile" },
    { "Raid Healer 方案", "Raid Healer Profile" },
    { "Mythic+ Tank 方案", "Mythic+ Tank Profile" },
    { "Mythic+ DPS 方案", "Mythic+ DPS Profile" },
    { "Mythic+ Healer 方案", "Mythic+ Healer Profile" },
    { "当前职责：dps", "Current role: dps" },
    { "当前职责：tank", "Current role: tank" },
    { "当前职责：healer", "Current role: healer" },
    { "当前职责： dps", "Current role: dps" },
    { "当前职责： tank", "Current role: tank" },
    { "当前职责： healer", "Current role: healer" },
    -- ===== Screenshot 2: MDT Route Module =====
    { "当前进度：未获取", "Current progress: Not obtained" },
    { "当前进度： 未获取", "Current progress: Not obtained" },
    { "Route套装", "Route Preset" },
    { "导入MDT", "Import MDT" },
    -- ===== Screenshot 3: Import/Export =====
    { "导出", "Export" },
    { "导入", "Import" },
    { "解析", "Parse" },
    { "重命名", "Rename" },
    { "执行导入", "Run Import" },
    { "此区域只展示当前 6 个槽位对应的Author方案。", "This area only shows the Author Profiles currently assigned to the 6 slots." },
    { "槽位：Raid Tank Author方案：Default Preset", "Slot: Raid Tank  Author Profile: Default Preset" },
    { "槽位： Raid Tank  Author方案： Default Preset", "Slot: Raid Tank  Author Profile: Default Preset" },
    -- ===== Screenshot 4: Timeline =====
    { "Fixed TimelineBoss", "Fixed Timeline Boss" },
    { "Skill总数", "Total Skills" },
    { "窗口", "Window" },
    { "窗口:", "Window:" },
    { "窗口：", "Window:" },
    { "节点:", "Nodes:" },
    { "节点：", "Nodes:" },
    { "分钟节点:", "min Nodes:" },
    { "分钟节点：", "min Nodes:" },
    { "3分钟节点", "3min Nodes" },
    { "刷新", "Refresh" },
    { "次", "x" },
    { "按Boss查看Fixed TimelineSkill在前 3 分钟内的出现节点，便于快速校对Timeline节奏。", "Review each boss's Fixed Timeline skills over the first 3 minutes to quickly verify Timeline pacing." },
    { "按Boss查看Fixed TimelineSkill在前 3 分钟内的出现Nodes，便于快速校对Timeline节奏。", "Review each boss's Fixed Timeline skills over the first 3 minutes to quickly verify Timeline pacing." },
    { "按Boss查看Fixed TimelineSkill在前 3 分钟内的出现Nodes, 便于快速校对Timeline节奏。", "Review each boss's Fixed Timeline skills over the first 3 minutes to quickly verify Timeline pacing." },
    { "按Boss查看Fixed TimelineSkill在前3分钟内的出现Nodes，便于快速校对Timeline节奏。", "Review each boss's Fixed Timeline skills over the first 3 minutes to quickly verify Timeline pacing." },
    -- ===== Screenshot 5: Ring Progress Settings =====
    { "屏幕中央显示Ring Progress", "Displays Ring Progress in the screen center" },
    { "圆环样式", "Ring Style" },
    { "细环 1", "Thin Ring 1" },
    { "细环1", "Thin Ring 1" },
    { "细环 2", "Thin Ring 2" },
    { "细环2", "Thin Ring 2" },
    { "圆环尺寸", "Ring Size" },
    { "Test 圆环(3秒)", "Test Ring (3s)" },
    { "Test圆环(3秒)", "Test Ring (3s)" },
    { "Test 圆环（3秒）", "Test Ring (3s)" },
    { "Test圆环（3秒）", "Test Ring (3s)" },
    -- ===== Screenshot 6: Private Aura Monitor =====
    { "进入编辑模式", "Enter Edit Mode" },
    { "图标外观", "Icon Appearance" },
    { "图标Spacing", "Icon Spacing" },
    { "排列方向", "Growth Direction" },
    { "向右", "Right" },
    { "向左", "Left" },
    { "向上", "Up" },
    { "向下", "Down" },
    { "边框缩放", "Border Scale" },
    { "显示冷却圈", "Show Cooldown Spiral" },
    { "锚点", "Anchor Point" },
    { "屏幕中央", "Screen Center" },
    -- ===== Screenshot 7: Reset Settings =====
    { "提供三种Reset方式：\n1) Reset Appearance Only\n2) Reset所有配置（不Included外观）\n3) 清除全部Settings（Included外观）", "Provides three reset modes:\n1) Reset Appearance Only\n2) Reset All Settings (Keep Appearance)\n3) Wipe Everything (Including Appearance)" },
    { "推荐先使用\"Reset Appearance Only\"：只ResetTimer Bar/Bun Bar/Countdown/Center Text与Color方案。", "Recommended: start with \"Reset Appearance Only\". It only resets Timer Bar / Bun Bar / Countdown / Center Text and Color schemes." },
    { "\"Reset所有配置（不Included外观）\"会清空General Settings、Voice配置、Skill配置与TimelineSettings，但保留外观。", "\"Reset All Settings (Keep Appearance)\" clears General Settings, Voice config, Skill config and Timeline settings, while keeping appearance." },
    { "oss 的全部配置都Restoration到初始状态。", "All settings will be restored to their default state." },
    { "EXBoss的全部配置都Restoration到初始状态。", "All EXBoss settings will be restored to their default state." },
    { "Reset所有配置（不Included外观）", "Reset All Settings (Keep Appearance)" },
    { "清除全部Settings（Included外观）", "Wipe Everything (Including Appearance)" },
    -- ===== General UI tokens still showing Chinese =====
    { "启用", "Enable" },
    { "Color", "Color" },
}


-- Pairs rescued from TARGET_ADDONS (were misplaced as table entries)
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "73 æ ‡ç­¾", "73 Labels" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æš‚Noneæè¿°", "No description available." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å‡†å¤‡è·‘åœˆã€å‡†å¤‡è¿½äººã€å¬å”¤å°æ€ªã€å¦å…‹å‡»é€€ã€æ³¨æ„å‡»é£žã€é›†åˆæ”¾åœˆ", "Prepare Run Out, Prepare Chase, Summon Adds, Tank Knockback, Watch Knock-Up, Stack and Drop Circle" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Raid Tank æ–¹æ¡ˆ", "Raid Tank Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Raid DPS æ–¹æ¡ˆ", "Raid DPS Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Raid Healer æ–¹æ¡ˆ", "Raid Healer Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Mythic+ Tank æ–¹æ¡ˆ", "Mythic+ Tank Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Mythic+ DPS æ–¹æ¡ˆ", "Mythic+ DPS Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Mythic+ Healer æ–¹æ¡ˆ", "Mythic+ Healer Profile" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "4ä¸ªå›ºå®šColoræ–¹æ¡ˆ + 1ä¸ªCustom Scheme + æœ€å¤š 3 ä¸ªé¢å¤–æ–¹æ¡ˆã€‚BossSkillé¡µå¯ç›´æŽ¥Select Profileæˆ–è‡ªå®šä¹‰Colorã€‚", "4 fixed Color schemes + 1 Custom Scheme + up to 3 extra schemes. The Boss Skill page can select a profile directly or use a custom color." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "BossSkillé¡µé¢å¯é€‰æ‹©ä¸‹åˆ—æ–¹æ¡ˆï¼›é€‰æ‹©â€œè‡ªå®šä¹‰Colorâ€æ—¶ä½¿ç”¨â€œCustom Schemeâ€ã€‚å‹¾é€‰Enableçš„é¢å¤–æ–¹æ¡ˆä¼šå‡ºçŽ°åœ¨Skillé¡µä¸‹æ‹‰ã€‚", "The Boss Skill page can use the schemes below. Choosing \"Custom Color\" uses the \"Custom Scheme\". Enabled extra schemes appear in Skill-page dropdowns." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Template-(%s=Skillå %t=CountdownNumber)", "Template (%s = Spell Name  %t = Countdown Number)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å¦å…‹Buster3.0", "Tank Buster 3.0" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Skillè§¦å‘æ—¶åœ¨å±å¹•ä¸­å¤®æ˜¾ç¤ºSpell Nameï¼ˆæ·¡å…¥ â†’ åœç•™ â†’ æ·¡å‡ºï¼‰ã€‚", "Shows the Spell Name in the screen center when the skill triggers (fade in -> hold -> fade out)." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å±å¹•ä¸­å¤®æ˜¾ç¤ºRing Progress", "Displays Ring Progress in the screen center." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åœ†çŽ¯æ ·å¼", "Ring Style" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ç»†çŽ¯1", "Thin Ring 1" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é€æ˜Žåº¦", "Opacity" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "åœ†çŽ¯å°ºå¯¸", "Ring Size" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "Test åœ†çŽ¯(3ç§’)", "Test Ring (3s)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "éžRaidå·²æ³¨å†ŒBOSS: %d  |  éžRaidäº‹ä»¶: %d / Total: %d  |  è§¦å‘å™¨äº‹ä»¶(0/1/2): %d/%d/%d%s", "Non-Raid registered bosses: %d  |  Non-Raid events: %d / Total: %d  |  Trigger events (0/1/2): %d/%d/%d%s" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œç”¨åŸŸ:", "Scope:" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "ä½œç”¨åŸŸ: ", "Scope: " }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¿›å…¥ç¼–è¾‘æ¨¡å¼", "Enter Edit Mode" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¾æ ‡å¤–è§‚", "Icon Appearance" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å›¾æ ‡Spacing", "Icon Spacing" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŽ’åˆ—æ–¹å‘", "Growth Direction" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "è¾¹æ¡†ç¼©æ”¾", "Border Scale" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æ˜¾ç¤ºå†·å´åœˆ", "Show Cooldown Spiral" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "é”šç‚¹", "Anchor Point" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å±å¹•ä¸­å¤®", "Screen Center" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "å‘å³", "Right" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æä¾›ä¸‰ç§Resetæ–¹å¼ï¼š\n1) Reset Appearance Only\n2) Resetæ‰€æœ‰é…ç½®ï¼ˆä¸Includedå¤–è§‚ï¼‰\n3) æ¸…é™¤å…¨éƒ¨Settingsï¼ˆIncludedå¤–è§‚ï¼‰", "Provides three reset modes:\n1) Reset Appearance Only\n2) Reset All Settings (Keep Appearance)\n3) Wipe Everything (Including Appearance)" }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŽ¨èå…ˆä½¿ç”¨ â€œReset Appearance Onlyâ€ï¼›åªResetTimer Bar/Bun Bar/Countdown/Center Textä¸ŽColoræ–¹æ¡ˆã€‚", "Recommended: start with \"Reset Appearance Only\". It only resets Timer Bar / Bun Bar / Countdown / Center Text and Color schemes." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "â€œResetæ‰€æœ‰é…ç½®ï¼ˆä¸Includedå¤–è§‚ï¼‰â€ä¼šæ¸…ç©ºGeneral Settingsã€Voiceé…ç½®ã€Skillé…ç½®ä¸ŽTimelineSettingsï¼Œä½†ä¿ç•™å¤–è§‚ã€‚", "\"Reset All Settings (Keep Appearance)\" clears General Settings, Voice config, Skill config and Timeline settings, while keeping appearance." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "EXBossçš„å…¨éƒ¨é…ç½®éƒ½å°†Restorationåˆ°åˆå§‹çŠ¶æ€ã€‚", "All EXBoss settings will be restored to their default state." }
TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = { "æŒ‰BossæŸ¥çœ‹Fixed TimelineSkillåœ¨å‰ 3 åˆ†é’Ÿå†…çš„å‡ºçŽ°èŠ‚ç‚¹ï¼Œä¾¿äºŽå¿«é€Ÿæ ¡å¯¹TimelineèŠ‚å¥ã€‚", "Browse each boss's Fixed Timeline skill markers over the first 3 minutes to quickly verify the Timeline pacing." }

for i = 1, #SAFE_CHINESE_TEXT_REPLACEMENTS do
    TEXT_REPLACEMENTS[#TEXT_REPLACEMENTS + 1] = SAFE_CHINESE_TEXT_REPLACEMENTS[i]
end

-- Build SORTED_TEXT_REPLACEMENTS with deduplication for performance
local SORTED_TEXT_REPLACEMENTS = {}
do
    local seen = {}
    local function AddUnique(list)
        for i = 1, #list do
            local key = list[i][1]
            if key and not seen[key] then
                seen[key] = true
                SORTED_TEXT_REPLACEMENTS[#SORTED_TEXT_REPLACEMENTS + 1] = list[i]
            end
        end
    end
    AddUnique(TEXT_REPLACEMENTS)

    local EXTRA_TEXT_REPLACEMENTS = {
    { "æŸ¥çœ‹Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2).", "Shows current voice registration details (default = non-raid only): Dungeon > Boss Name (count) + eventID(trigger0/1/2)." },
    { "å…¨é‡: ", "Total: " },
    { "æœªåŒ¹é…BOSSäº‹ä»¶: ", "Unmatched boss events: " },
    { "å›¢æœ¬å·²è¿‡æ»¤: ", "Raid filtered: " },
    { "æ— æ•°æ®", "No data" },
    { "æœ€è¿‘é”™è¯¯: ", "Last error: " },
    { "ä½œç”¨åŸŸ: ", "Scope: " },
    { "ï¼ˆé¢„ä¼°ï¼‰", " (Estimated)" },
    { "ï¼ˆå®žæµ‹ï¼‰", " (Live)" },
    { "Ã¦Å“ÂªÃ§Å¸Â¥Ã¥â€°Â¯Ã¦Å“Â¬", "Unknown Dungeon" },
    { "Ã¦Å“ÂªÃ§Å¸Â¥Ã©Â¦â€“Ã©Â¢â€ ", "Unknown Boss" },
    { "Ã¦Å¡â€šÃ¦â€”Â Ã©ÂÅ¾Ã¥â€ºÂ¢Ã¦Å“Â¬Ã¥Â·Â²Ã¦Â³Â¨Ã¥â€ Å’BOSS", "No non-raid registered bosses" },
}
    AddUnique(EXTRA_TEXT_REPLACEMENTS)
end

table.sort(SORTED_TEXT_REPLACEMENTS, function(a, b)
    return #(a[1] or "") > #(b[1] or "")
end)

local TOKEN_REPLACEMENTS = {
    { "大秘境", "Mythic+" },
    { "大米", "Mythic+" },
    { "团本", "Raid" },
    { "副本", "Dungeon" },
    { "首领", "Boss" },
    { "语音包", "Voice Pack" },
    { "语音", "Voice" },
    { "设置", "Settings" },
    { "时间轴", "Timeline" },
    { "固定轴", "Fixed Timeline" },
    { "颜色", "Color" },
    { "位置", "Position" },
    { "更新日志", "Changelog" },
    { "载入", "Load" },
    { "重置", "Reset" },
    { "启用", "Enable" },
    { "禁用", "Disable" },
    { "全量", "Total" },
    { "最近错误", "Last error" },
    { "非团本", "Non-raid" },
    { "预估", "Estimated" },
    { "实测", "Live" },
    { "预设配置", "Default Preset" },
    { "未命名", "Untitled" },
    { "战士", "Warrior" },
    { "圣骑士", "Paladin" },
    { "潜行者", "Rogue" },
    { "牧师", "Priest" },
    { "术士", "Warlock" },
    { "武僧", "Monk" },
    { "恶魔猎手", "Demon Hunter" },
    { "唤魔师", "Evoker" },
    { "鲜血", "Blood" },
    { "冰霜", "Frost" },
    { "邪恶", "Unholy" },
    { "武器", "Arms" },
    { "防护", "Protection" },
    { "惩戒", "Retribution" },
    { "复仇", "Vengeance" },
    { "奇袭", "Assassination" },
    { "狂徒", "Outlaw" },
    { "敏锐", "Subtlety" },
    { "酒仙", "Brewmaster" },
    { "踏风", "Windwalker" },
    { "织雾", "Mistweaver" },
    { "野性", "Feral" },
    { "守护", "Guardian" },
    { "戒律", "Discipline" },
    { "暗影", "Shadow" },
    { "奥术", "Arcane" },
    { "火焰", "Fire" },
    { "元素", "Elemental" },
    { "增强", "Enhancement" },
    { "恢复", "Restoration" },
    { "射击", "Marksmanship" },
    { "野兽控制", "Beast Mastery" },
    { "生存", "Survival" },
    { "神圣", "Holy" },
    { "狂怒", "Fury" },
    { "浩劫", "Havoc" },
    { "痛苦", "Affliction" },
    { "恶魔学识", "Demonology" },
    { "毁灭", "Destruction" },
    { "湮灭", "Devastation" },
    { "恩护", "Preservation" },
    { "增辉", "Augmentation" },
    { "技能名称", "Spell Name" },
    { "技能示例", "Skill Example" },
    { "测试技能", "Test Skill" },
    { "预览技能", "Preview Skill" },
    { "测试施法", "Test Cast" },
    { "技能", "Skill" },
    { "法术", "Spell" },
    { "名称", "Name" },
    { "示例", "Example" },
    { "测试", "Test" },
    { "预览", "Preview" },
    { "提示", "Alert" },
    { "警告", "Warning" },
    { "未知", "Unknown" },
    { "私人光环", "Private Aura" },
    { "尖刺", "Buster" },
    { "倒计时", "Countdown" },
    { "文字", "Text" },
    { "就绪", "Ready" },
    { "正在施放", "Casting" },
    { "准备传送到", "preparing to teleport to" },
    { "开嗜血", "Heroism" },
    { "嗜血", "Heroism" },
    { "Sx波次", "Heroism " },
    { "主目标", "Focus " },
    { "合波", "Combine pull" },
    { "开火车", "Chain pull" },
    { "救人", "Save " },
    { "法系怪", "caster" },
    { "大怪", "big mob" },
    { "打掉", "kill " },
    { "注意", "Watch " },
    { "考虑", "Consider " },
    { "不要add", "don't pull extra" },
    { "波次", "pull" },
    { "打断", "interrupt" },
    { "减伤", "Defensives" },
    { "控制", "CC" },
    { "驱散", "dispel" },
    { "起手", "On pull" },
    { "走侧面", "flank" },
    { "吃buff", "get buff" },
    { "路线", "Route" },
    { "敌军", "Forces" },
    { "兵力", "Forces" },
    { "打T", "hits tank" },
    { "双打T", "double hits tank" },
    { "流血", "bleed " },
    { "层数", "stacks" },
    { "进度可平替", "count can be swapped" },
    { "大红", "Healthstone/Pot" },
    { "矮人", "Dwarf racial" },
    { "无敌", "Immunity" },
    { "å¤§ç§˜å¢ƒ", "Mythic+" },
    { "å¤§ç±³", "Mythic+" },
    { "打断", "interrupt" },
    { "减伤", "Defensives" },
    { "控制", "CC" },
    { "驱散", "dispel" },
    { "起手", "On pull" },
    { "走侧面", "flank" },
    { "吃buff", "get buff" },
    { "路线", "Route" },
    { "副本", "Dungeon" },
    { "敌军", "Forces" },
    { "部队", "Forces" },
    { "打T", "hits tank" },
    { "流血", "bleed " },
    { "层数", "stacks" },
    { "大红", "Healthstone/Pot" },
    { "矮人", "Dwarf racial" },
    { "无敌", "Immunity" },
    { "å¤§ç§˜å¢ƒ", "Mythic+" },
    { "å¤§ç±³", "Mythic+" },
    { "å›¢æœ¬", "Raid" },
    { "å‰¯æœ¬", "Dungeon" },
    { "é¦–é¢†", "Boss" },
    { "è¯­éŸ³åŒ…", "Voice Pack" },
    { "è¯­éŸ³", "Voice" },
    { "è®¾ç½®", "Settings" },
    { "æ—¶é—´è½´", "Timeline" },
    { "å›ºå®šè½´", "Fixed Timeline" },
    { "é¢œè‰²", "Color" },
    { "ä½ç½®", "Position" },
    { "æ›´æ–°æ—¥å¿—", "Changelog" },
    { "è½½å…¥", "Load" },
    { "é‡ç½®", "Reset" },
    { "å¯ç”¨", "Enable" },
    { "ç¦ç”¨", "Disable" },
    { "å…¨é‡", "Total" },
    { "æœ€è¿‘é”™è¯¯", "Last error" },
    { "éžå›¢æœ¬", "Non-raid" },
    { "é¢„ä¼°", "Estimated" },
    { "å®žæµ‹", "Live" },
    { "é¢„è®¾é…ç½®", "Default Preset" },
    { "æœªå‘½å", "Untitled" },
    { "æˆ˜å£«", "Warrior" },
    { "åœ£éª‘å£«", "Paladin" },
    { "æ½œè¡Œè€…", "Rogue" },
    { "ç‰§å¸ˆ", "Priest" },
    { "æœ¯å£«", "Warlock" },
    { "æ­¦åƒ§", "Monk" },
    { "æ¶é­”çŒŽæ‰‹", "Demon Hunter" },
    { "å”¤é­”å¸ˆ", "Evoker" },
    { "é²œè¡€", "Blood" },
    { "å†°éœœ", "Frost" },
    { "é‚ªæ¶", "Unholy" },
    { "æ­¦å™¨", "Arms" },
    { "é˜²æŠ¤", "Protection" },
    { "æƒ©æˆ’", "Retribution" },
    { "å¤ä»‡", "Vengeance" },
    { "å¥‡è¢­", "Assassination" },
    { "ç‹‚å¾’", "Outlaw" },
    { "æ•é”", "Subtlety" },
    { "é…’ä»™", "Brewmaster" },
    { "è¸é£Ž", "Windwalker" },
    { "ç»‡é›¾", "Mistweaver" },
    { "é‡Žæ€§", "Feral" },
    { "å®ˆæŠ¤", "Guardian" },
    { "æˆ’å¾‹", "Discipline" },
    { "æš—å½±", "Shadow" },
    { "å¥¥æœ¯", "Arcane" },
    { "ç«ç„°", "Fire" },
    { "å…ƒç´ ", "Elemental" },
    { "å¢žå¼º", "Enhancement" },
    { "æ¢å¤", "Restoration" },
    { "å°„å‡»", "Marksmanship" },
    { "å…½çŽ‹", "Beast Mastery" },
    { "ç”Ÿå­˜", "Survival" },
    { "ç¥žåœ£", "Holy" },
    { "ç‹‚æ€’", "Fury" },
    { "æµ©åŠ«", "Havoc" },
    { "ç—›è‹¦", "Affliction" },
    { "æ¶é­”å­¦è¯†", "Demonology" },
    { "æ¯ç­", "Destruction" },
    { "æ¹®ç­", "Devastation" },
    { "æ©æŠ¤", "Preservation" },
    { "å¢žè¾‰", "Augmentation" },
    { "æŠ€èƒ½åç§°", "Spell Name" },
    { "æ³•æœ¯åç§°", "Spell Name" },
    { "æŠ€èƒ½ç¤ºä¾‹", "Skill Example" },
    { "æµ‹è¯•æŠ€èƒ½", "Test Skill" },
    { "é¢„è§ˆæŠ€èƒ½", "Preview Skill" },
    { "æµ‹è¯•æ–½æ³•", "Test Cast" },
    { "æŠ€èƒ½", "Skill" },
    { "æ³•æœ¯", "Spell" },
    { "åç§°", "Name" },
    { "ç¤ºä¾‹", "Example" },
    { "æµ‹è¯•", "Test" },
    { "é¢„è§ˆ", "Preview" },
    { "æç¤º", "Alert" },
    { "è­¦å‘Š", "Warning" },
    { "æœªçŸ¥", "Unknown" },
    { "ç§äººå…‰çŽ¯", "Private Aura" },
    { "å°–åˆº", "Buster" },
    { "å€’è®¡æ—¶", "Countdown" },
    { "æ–‡å­—", "Text" },
    { "å°±ç»ª", "Ready" },
    { "æ­£åœ¨æ–½æ”¾", "Casting" },
    { "å‡†å¤‡ä¼ é€åˆ°", "preparing to teleport to" },
    { "å¹¿å‘Š", "spam" },
    -- Properly-encoded Chinese voice label fragments (visible in Screenshot 1)
    { "击退", "Knockback" },
    { "击飞", "Launch" },
    { "头前", "Frontal" },
    { "挡球", "Block Orb" },
    { "治疗", "Healing" },
    { "消球", "Clear Orb" },
    { "躲避", "Dodge" },
    { "准备dispel", "Prepare Dispel" },
    { "准备interrupt", "Prepare Interrupt" },
    { "坦克Buster", "Tank Buster" },
    { "强化Retribution骑", "Empower Ret Paladin" },
    { "快Save", "Rescue Now" },
    { "快interrupt", "Interrupt Now" },
    { "特殊Skill", "Special Mechanic" },
    { "转火big mob", "Switch Boss" },
    { "远离big mob", "Away Add" },
    -- Additional properly-encoded Chinese tokens
    { "方案", "Profile" },
    { "标签", "Labels" },
    { "描述", "Description" },
    { "职责", "Role" },
    { "进度", "Progress" },
    { "套装", "Preset" },
    { "总数", "Total" },
    { "节点", "Nodes" },
    { "刷新", "Refresh" },
    { "圆环", "Ring" },
    { "尺寸", "Size" },
    { "样式", "Style" },
    { "编辑模式", "Edit Mode" },
    { "外观", "Appearance" },
    { "排列", "Growth" },
    { "方向", "Direction" },
    { "缩放", "Scale" },
    { "冷却", "Cooldown" },
    { "重命名", "Rename" },
    { "槽位", "Slot" },
    { "窗口", "Window" },
    -- Chinese fragments from Timeline/Config description strings
    { "查看", "view" },
    { "便于", "for" },
    { "快速", "quickly" },
    { "校对", "verify" },
    { "节奏", "pacing" },
    { "出现", "appear" },
    { "分钟内的", "min " },
    { "在前", "over the first" },
    { "按", "by" },
}

-- Deduplicate TOKEN_REPLACEMENTS
do
    local seen, deduped = {}, {}
    for i = 1, #TOKEN_REPLACEMENTS do
        local key = TOKEN_REPLACEMENTS[i][1]
        if key and not seen[key] then
            seen[key] = true
            deduped[#deduped + 1] = TOKEN_REPLACEMENTS[i]
        end
    end
    TOKEN_REPLACEMENTS = deduped
end

local function EscapePattern(text)
    local value = SafeString(text) or ""
    local ok, escaped = pcall(function()
        return value:gsub("([%%%^%$%(%)%.%[%]%*%+%-%?])", "%%%1")
    end)
    return ok and escaped or ""
end

local function Trim(text)
    local value = SafeString(text) or ""
    local ok, trimmed = pcall(function()
        return value:gsub("^%s+", ""):gsub("%s+$", "")
    end)
    return ok and trimmed or ""
end

local function SanitizeTranslatedText(text)
    if type(text) ~= "string" or text == "" then
        return text
    end

    local out = text
    out = out:gsub("â–¡+", "")
    out = out:gsub("ï¿½+", "")
    out = out:gsub("ï¼ˆ", "("):gsub("ï¼‰", ")")
    out = out:gsub("ï¼š", ": "):gsub("ï¼Œ", ", "):gsub("ã€‚", ".")
    out = out:gsub("%s+\n", "\n"):gsub("\n%s+", "\n")
    out = out:gsub("[ \t][ \t]+", " ")
    out = out:gsub("%s+([,%.:%)])", "%1")
    out = out:gsub("%(%s+", "("):gsub("%s+%)", ")")
    out = out:gsub("\n\n\n+", "\n\n")
    out = out:gsub("VOICE%s*/%s*PROFILES+", "VOICE / PROFILES")
    out = out:gsub("Voice%s*/%s*Profiles+", "Voice / Profiles")
    out = out:gsub("Mythic%+ Profiles+", "Mythic+ Profiles")
    if (out:find("[%a%d]") or out:find("|c")) and utf8 and type(utf8.codes) == "function" and type(utf8.char) == "function" then
        local cleaned = {}
        local removedResidualCJK = false
        for _, codepoint in utf8.codes(out) do
            local isResidualCJK =
                (codepoint >= 0x3400 and codepoint <= 0x4DBF) or
                (codepoint >= 0x4E00 and codepoint <= 0x9FFF) or
                (codepoint >= 0x3000 and codepoint <= 0x303F) or
                (codepoint >= 0xFF00 and codepoint <= 0xFFEF)
            if isResidualCJK then
                removedResidualCJK = true
            else
                cleaned[#cleaned + 1] = utf8.char(codepoint)
            end
        end
        if removedResidualCJK then
            out = table.concat(cleaned)
            out = out:gsub("[ \t][ \t]+", " ")
            out = out:gsub("%s+([,%.:%)])", "%1")
            out = out:gsub("%(%s+", "("):gsub("%s+%)", ")")
            out = out:gsub("%[%s+", "["):gsub("%s+%]", "]")
            out = out:gsub("^%s+", ""):gsub("%s+$", "")
        end
    end
    return out
end

local TRANSLATION_CACHE = {}
local TRANSLATION_CACHE_SIZE = 0

local function ReplaceTokens(text)
    local plain = GetTranslatableString(text)
    if not plain or plain == "" then
        return text
    end

    local out = plain
    for i = 1, #TOKEN_REPLACEMENTS do
        local fromText, toText = TOKEN_REPLACEMENTS[i][1], TOKEN_REPLACEMENTS[i][2]
        local ok = pcall(function()
            if fromText and fromText ~= "" and toText and out:find(fromText, 1, true) then
                out = out:gsub(EscapePattern(fromText), toText)
            end
        end)
        if not ok then
            return plain
        end
    end
    return out
end

local function ReplaceTextUnsafe(text)
    local plain = GetTranslatableString(text)
    if not plain then
        return text
    end

    local exact = FAST_EXACT_REPLACEMENTS[plain]
    if exact then
        return exact
    end

    local cached = TRANSLATION_CACHE[plain]
    if cached ~= nil then
        return cached
    end

    local out = SanitizeTranslatedText(plain)
    for i = 1, #SORTED_TEXT_REPLACEMENTS do
        local fromText, toText = SORTED_TEXT_REPLACEMENTS[i][1], SORTED_TEXT_REPLACEMENTS[i][2]
        if fromText and fromText ~= "" and toText and out:find(fromText, 1, true) then
            if not (type(toText) == "string" and toText:find(fromText, 1, true) and out:find(toText, 1, true)) then
                out = out:gsub(EscapePattern(fromText), toText)
            end
        end
    end

    out = ReplaceTokens(out)
    out = SanitizeTranslatedText(out)
    out = FAST_EXACT_REPLACEMENTS[out] or out
    if TRANSLATION_CACHE_SIZE > 2048 then
        wipe(TRANSLATION_CACHE)
        TRANSLATION_CACHE_SIZE = 0
    end
    if TRANSLATION_CACHE[plain] == nil then
        TRANSLATION_CACHE_SIZE = TRANSLATION_CACHE_SIZE + 1
    end
    TRANSLATION_CACHE[plain] = out
    return out
end

local function ReplaceText(text)
    local plain = GetTranslatableString(text)
    if not plain then
        return text
    end

    local ok, translated = pcall(ReplaceTextUnsafe, plain)
    if ok then
        return translated
    end

    return plain
end

local function SafeReplaceText(text)
    return ReplaceText(text)
end

local function GetSpellName(spellID)
    local id = tonumber(spellID)
    if not id then
        return nil
    end

    if C_Spell and type(C_Spell.GetSpellName) == "function" then
        local ok, name = pcall(C_Spell.GetSpellName, id)
        if ok and type(name) == "string" and name ~= "" then
            return name
        end
    end

    if C_Spell and type(C_Spell.GetSpellInfo) == "function" then
        local ok, info = pcall(C_Spell.GetSpellInfo, id)
        if ok and type(info) == "table" and type(info.name) == "string" and info.name ~= "" then
            return info.name
        end
    end

    if type(GetSpellInfo) == "function" then
        local ok, name = pcall(GetSpellInfo, id)
        if ok and type(name) == "string" and name ~= "" then
            return name
        end
    end
end

local function GetEncounterName(journalEncounterID)
    local encounterID = tonumber(journalEncounterID)
    if not encounterID or encounterID <= 0 or type(EJ_GetEncounterInfo) ~= "function" then
        return nil
    end

    local ok, name = pcall(EJ_GetEncounterInfo, encounterID)
    if ok and type(name) == "string" and name ~= "" then
        return name
    end
end

local function ExtractParenthesizedEnglish(text)
    local raw = SafeString(text) or ""
    local ok, english = pcall(function()
        return raw:match("%(([^%(%)]+)%)")
    end)
    if not ok then
        return nil
    end
    english = Trim(english)
    return english ~= "" and english or nil
end

local function ForceLocales()
    if _G.ExBoss and _G.ExBoss.Locale then
        _G.ExBoss.Locale._currentLocale = "enUS"
        _G.ExBoss.Locale._defaultLocale = "enUS"
        _G.ExBoss.Locale._englishPatchForcedLocale = "enUS"
    end
    if _G.ExwindLocale then
        _G.ExwindLocale._currentLocale = "enUS"
        _G.ExwindLocale._defaultLocale = "enUS"
        _G.ExwindLocale._englishPatchForcedLocale = "enUS"
    end
end

local function PatchLocaleStore(store)
    if type(store) ~= "table" or store._englishPatchLocalePatched then
        return
    end

    for i = 1, #SORTED_TEXT_REPLACEMENTS do
        local fromText, toText = SORTED_TEXT_REPLACEMENTS[i][1], SORTED_TEXT_REPLACEMENTS[i][2]
        if fromText and fromText ~= "" and toText and toText ~= "" then
            store[fromText] = toText
        end
    end

    store._englishPatchLocalePatched = true
end

local function MirrorEnglishStore(targetStore, englishStore)
    if type(targetStore) ~= "table" or type(englishStore) ~= "table" then
        return
    end

    if targetStore._englishPatchMirrored and targetStore._englishPatchMirroredSource == englishStore then
        return
    end

    for key, value in next, englishStore do
        if type(key) == "string" and type(value) == "string" then
            local plain = GetTranslatableString(value)
            if plain and plain ~= "" then
                targetStore[key] = plain
            end
        end
    end

    targetStore._englishPatchMirrored = true
    targetStore._englishPatchMirroredSource = englishStore
end

local function PatchLocales()
    if _G.ExBoss and _G.ExBoss.Locale and type(_G.ExBoss.Locale._stores) == "table" then
        _G.ExBoss.Locale._stores.enUS = _G.ExBoss.Locale._stores.enUS or {}
        _G.ExBoss.Locale._stores.zhCN = _G.ExBoss.Locale._stores.zhCN or {}
        MirrorEnglishStore(_G.ExBoss.Locale._stores.zhCN, _G.ExBoss.Locale._stores.enUS)
        PatchLocaleStore(_G.ExBoss.Locale._stores.enUS)
        PatchLocaleStore(_G.ExBoss.Locale._stores.zhCN)
    end

    if _G.ExwindLocale and type(_G.ExwindLocale._stores) == "table" then
        _G.ExwindLocale._stores.enUS = _G.ExwindLocale._stores.enUS or {}
        _G.ExwindLocale._stores.zhCN = _G.ExwindLocale._stores.zhCN or {}
        MirrorEnglishStore(_G.ExwindLocale._stores.zhCN, _G.ExwindLocale._stores.enUS)
        PatchLocaleStore(_G.ExwindLocale._stores.enUS)
        PatchLocaleStore(_G.ExwindLocale._stores.zhCN)
    end
end

local function WrapLocaleProxy(proxy)
    if type(proxy) ~= "table" or proxy._englishPatchWrapped then
        return
    end

    local mt = getmetatable(proxy)
    if type(mt) ~= "table" or type(mt.__index) ~= "function" then
        return
    end

    local originalIndex = mt.__index
    mt.__index = function(tbl, key)
        local value = originalIndex(tbl, key)
        if type(value) == "string" then
            return SafeReplaceText(value)
        end
        return value
    end

    proxy._englishPatchWrapped = true
end

local function WrapLocaleRoot(localeRoot)
    if type(localeRoot) ~= "table" or localeRoot._englishPatchLocaleWrapped then
        return
    end

    localeRoot._currentLocale = "enUS"
    localeRoot._defaultLocale = "enUS"
    localeRoot._englishPatchForcedLocale = "enUS"

    if localeRoot._proxy then
        WrapLocaleProxy(localeRoot._proxy)
    end

    if type(localeRoot.GetLocale) == "function" then
        local original = localeRoot.GetLocale
        localeRoot.GetLocale = function(self, appName)
            self._currentLocale = "enUS"
            self._defaultLocale = "enUS"
            local proxy = original(self, appName)
            WrapLocaleProxy(proxy)
            return proxy
        end
    end

    if type(localeRoot.GetCurrentLocale) == "function" then
        localeRoot.GetCurrentLocale = function(self)
            return "enUS"
        end
    end

    if type(localeRoot.GetDefaultLocale) == "function" then
        localeRoot.GetDefaultLocale = function(self)
            return "enUS"
        end
    end

    localeRoot._englishPatchLocaleWrapped = true
end

local TRANSLATABLE_TABLE_KEYS = {
    title = true,
    subtitle = true,
    desc = true,
    description = true,
    content = true,
    label = true,
    text = true,
    note = true,
    notes = true,
    summary = true,
    status = true,
    message = true,
    placeholder = true,
    author = true,
    name = true,
    displayName = true,
    bossName = true,
    mapName = true,
    dungeon = true,
    boss = true,
    category = true,
    eventName = true,
    voiceLabel = true,
    header = true,
    caption = true,
    short = true,
}

local function ShouldTranslateTableString(key, value)
    local text = SafeNonEmptyString(value)
    if not text then
        return false
    end
    if TRANSLATABLE_TABLE_KEYS[key] then
        return true
    end
    local okFind, found = pcall(function()
        return text:find("[\128-\255]") ~= nil
    end)
    if not okFind then
        return false
    end
    return found
end

local function PatchDisplayStringTable(root, visited, depth)
    if type(root) ~= "table" then
        return
    end
    visited = visited or {}
    depth = depth or 0
    if visited[root] or depth > 10 or (root.GetObjectType and type(root.GetObjectType) == "function") then
        return
    end
    visited[root] = true

    for key, value in pairs(root) do
        if type(value) == "table" then
            PatchDisplayStringTable(value, visited, depth + 1)
        elseif ShouldTranslateTableString(key, value) then
            root[key] = SafeReplaceText(value)
        end
    end
end

local function PatchMetadataTables()
    local roots = {
        _G.ExBoss_MetaData,
        _G.ExwindTools_MetaData,
        _G.EXBOSS_ENCOUNTER_DATA,
        _G.EXBOSS_PRIVATE_AURA_DATA,
        _G.EXBOSS_AUTHOR_PRESETS,
    }

    for i = 1, #roots do
        PatchDisplayStringTable(roots[i])
    end
end

local function FindEncounterEventRow(eventID)
    local data = _G.EXBOSS_ENCOUNTER_DATA
    local maps = type(data) == "table" and (type(data.maps) == "table" and data.maps or data) or nil
    local id = tonumber(eventID)
    if not id or type(maps) ~= "table" then
        return nil
    end

    for _, mapRow in pairs(maps) do
        if type(mapRow) == "table" and type(mapRow.bosses) == "table" then
            for _, bossRow in pairs(mapRow.bosses) do
                if type(bossRow) == "table" and type(bossRow.events) == "table" then
                    for rawEventID, eventRow in pairs(bossRow.events) do
                        if tonumber(rawEventID) == id or (type(eventRow) == "table" and tonumber(eventRow.eventID) == id) then
                            return eventRow
                        end
                    end
                end
            end
        end
    end
end

local function PatchEncounterData()
    local data = _G.EXBOSS_ENCOUNTER_DATA
    local maps = type(data) == "table" and (type(data.maps) == "table" and data.maps or data) or nil
    if type(maps) ~= "table" then
        return
    end

    for _, mapRow in pairs(maps) do
        if type(mapRow) == "table" then
            local mapName = SafeNonEmptyString(mapRow.mapName) or SafeNonEmptyString(mapRow.name) or ""
            local translatedMapName = TranslateMapName(mapName)
            if translatedMapName ~= mapName and translatedMapName ~= "" then
                mapRow.mapName = translatedMapName
                if mapRow.name ~= nil then
                    mapRow.name = mapRow.mapName
                end
            end

            if mapRow.category == "åœ°ä¸‹åŸŽ" then
                mapRow.category = "Dungeon"
            elseif mapRow.category == "å›¢é˜Ÿ" then
                mapRow.category = "Raid"
            end

            if type(mapRow.bosses) == "table" then
                for _, bossRow in pairs(mapRow.bosses) do
                    if type(bossRow) == "table" then
                        local englishBoss = GetEncounterName(bossRow.journalEncounterID) or ExtractParenthesizedEnglish(bossRow.bossName)
                        if englishBoss then
                            bossRow.bossName = englishBoss
                            if bossRow.name ~= nil then
                                bossRow.name = englishBoss
                            end
                        end

                        if type(bossRow.events) == "table" then
                            for _, eventRow in pairs(bossRow.events) do
                                if type(eventRow) == "table" then
                                    local eventType = SafeNonEmptyString(eventRow.eventType)
                                    local voiceLabel = SafeNonEmptyString(eventRow.voiceLabel)
                                    eventRow.eventType = (eventType and EVENT_TYPE_TRANSLATIONS[eventType]) or eventRow.eventType
                                    eventRow.voiceLabel = (voiceLabel and LABEL_TRANSLATIONS[voiceLabel]) or eventRow.voiceLabel

                                    local spellName = GetSpellName(eventRow.spellID or eventRow.evenSpellID)
                                    if spellName then
                                        eventRow.eventName = spellName
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end

local function PatchPrivateAuraData()
    local root = _G.EXBOSS_PRIVATE_AURA_DATA
    if type(root) ~= "table" then
        return
    end

    for _, groupRow in pairs(root) do
        if type(groupRow) == "table" then
            for _, encounterRow in pairs(groupRow) do
                if type(encounterRow) == "table" then
                    encounterRow.dungeon = TranslateMapName(encounterRow.dungeon)

                    local englishBoss = ExtractParenthesizedEnglish(encounterRow.boss)
                    if englishBoss then
                        encounterRow.boss = englishBoss
                    end

                    if type(encounterRow.spells) == "table" then
                        for _, spellRow in pairs(encounterRow.spells) do
                            if type(spellRow) == "table" then
                                local spellName = GetSpellName(spellRow.spellID)
                                if spellName then
                                    spellRow.name = spellName
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end

local function PatchTimelineBosses()
    local bosses = _G.ExBoss and _G.ExBoss.Timeline and _G.ExBoss.Timeline._bosses
    if type(bosses) ~= "table" then
        return
    end

    for _, bossDef in pairs(bosses) do
        if type(bossDef) == "table" then
            local englishBoss = GetEncounterName(bossDef.journalEncounterID) or ExtractParenthesizedEnglish(bossDef.name)
            if englishBoss then
                bossDef.name = englishBoss
            end

            if type(bossDef.skills) == "table" then
                for i = 1, #bossDef.skills do
                    local skill = bossDef.skills[i]
                    if type(skill) == "table" then
                        local spellName = GetSpellName(skill.spellID or skill.eventSpellID or skill.evenSpellID)
                        if spellName then
                            skill.displayName = spellName
                        end
                        local voiceLabel = SafeNonEmptyString(skill.voiceLabel)
                        skill.voiceLabel = (voiceLabel and LABEL_TRANSLATIONS[voiceLabel]) or skill.voiceLabel
                    end
                end
            end
        end
    end
end

local function PatchAuthorPresets()
    local root = _G.EXBOSS_AUTHOR_PRESETS
    if type(root) ~= "table" then
        return
    end

    local visited = {}
    local function Walk(node)
        if type(node) ~= "table" or visited[node] then
            return
        end
        visited[node] = true

        for key, value in pairs(node) do
            if type(value) == "table" then
                Walk(value)
            elseif type(value) == "string" then
                if key == "name" or key == "author" or key == "label" or key == "title" then
                    node[key] = SafeReplaceText(value)
                end
            end
        end
    end

    Walk(root)
end

local function FixEventConfigRow(eventID, row)
    if type(row) ~= "table" then
        return row
    end

    if type(row.triggers) == "table" then
        for _, triggerRow in pairs(row.triggers) do
            if type(triggerRow) == "table" then
                local label = SafeNonEmptyString(triggerRow.label)
                local translated = label and LABEL_TRANSLATIONS[label]
                if translated then
                    triggerRow.label = translated
                end
                if label and (triggerRow.sourceType == nil or triggerRow.sourceType == "" or triggerRow.sourceType == "none") then
                    triggerRow.sourceType = "pack"
                end
            end
        end
    end

    local eventRow = FindEncounterEventRow(eventID or row.eventID)
    local eventType = type(eventRow) == "table" and SafeNonEmptyString(eventRow.eventType) or nil
    local scheme = EVENT_TYPE_SCHEMES[eventType or ""]
    if scheme and type(row.color) == "table" then
        row.color.scheme = scheme
    end

    return row
end

local function WrapExBossDataApi()
    local api = _G.EXBossData
    if type(api) ~= "table" or api._englishPatchWrapped then
        return
    end

    if type(api.GetFactoryEventDefaults) == "function" then
        local original = api.GetFactoryEventDefaults
        api.GetFactoryEventDefaults = function(eventID)
            local result = original(eventID)
            if tonumber(eventID) then
                return FixEventConfigRow(eventID, result)
            end
            if type(result) == "table" then
                for rawEventID, row in pairs(result) do
                    FixEventConfigRow(rawEventID, row)
                end
            end
            return result
        end
    end

    if type(api.GetResolvedEventConfig) == "function" then
        local original = api.GetResolvedEventConfig
        api.GetResolvedEventConfig = function(eventID)
            return FixEventConfigRow(eventID, original(eventID))
        end
    end

    if type(api.GetEventConfigRoot) == "function" then
        local original = api.GetEventConfigRoot
        api.GetEventConfigRoot = function()
            local result = original()
            if type(result) == "table" then
                for rawEventID, row in pairs(result) do
                    FixEventConfigRow(rawEventID, row)
                end
            end
            return result
        end
    end

    if type(api.GetEncounterDataRoot) == "function" then
        local original = api.GetEncounterDataRoot
        api.GetEncounterDataRoot = function()
            local result = original()
            if type(result) == "table" then
                PatchDisplayStringTable(result)
            end
            return result
        end
    end

    api._englishPatchWrapped = true
end

local function WrapAddOnMetadata()
    if _G._englishPatchMetadataWrapped then
        return
    end

    if type(GetAddOnMetadata) == "function" then
        local original = GetAddOnMetadata
        _G.GetAddOnMetadata = function(addonName, field)
            local value = original(addonName, field)
            local addonKey = SafeLower(addonName) or ""
            if TARGET_ADDONS[addonKey] and type(value) == "string" then
                return SafeReplaceText(value)
            end
            return value
        end
    end

    if _G.C_AddOns and type(_G.C_AddOns.GetAddOnMetadata) == "function" then
        local original = _G.C_AddOns.GetAddOnMetadata
        _G.C_AddOns.GetAddOnMetadata = function(addonName, field)
            local value = original(addonName, field)
            local addonKey = SafeLower(addonName) or ""
            if TARGET_ADDONS[addonKey] and type(value) == "string" then
                return SafeReplaceText(value)
            end
            return value
        end
    end

    _G._englishPatchMetadataWrapped = true
end

local function RegisterSoundAliases()
    local LSM = LibStub and LibStub("LibSharedMedia-3.0", true)
    if not LSM then
        return
    end

    local function RegisterPackSound(packName, label, soundFile)
        packName = SafeNonEmptyString(packName)
        label = SafeNonEmptyString(label)
        if not packName or not label then
            return
        end
        local resolvedFile = SafeNonEmptyString(soundFile) or "Check.ogg"
        local soundPath = CUSTOM_SOUND_BASE_PATH .. resolvedFile
        pcall(LSM.Register, LSM, "sound", "[" .. packName .. "]" .. label, soundPath)
    end

    local defaultPackNames = {
        "EXWIND (Default)",
        "EXWIND(默认)",
    }

    for i = 1, #SOUND_ALIASES do
        local zhLabel = SOUND_ALIASES[i][1]
        local enLabel = SOUND_ALIASES[i][2]
        local soundFile = CUSTOM_SOUND_BY_LABEL[enLabel]
        for packIndex = 1, #defaultPackNames do
            RegisterPackSound(defaultPackNames[packIndex], enLabel, soundFile)
            RegisterPackSound(defaultPackNames[packIndex], zhLabel, soundFile)
        end
        RegisterPackSound(CUSTOM_VOICE_PACK_NAME, enLabel, soundFile)
        RegisterPackSound(CUSTOM_VOICE_PACK_NAME, zhLabel, soundFile)
    end

    for packIndex = 1, #defaultPackNames do
        RegisterPackSound(defaultPackNames[packIndex], "54321", "5.ogg")
    end
    RegisterPackSound(CUSTOM_VOICE_PACK_NAME, "54321", "5.ogg")

    _G.EXBV_LABELS = ENGLISH_LABELS
    _G.EXBOSSEXWIND_LABELS = ENGLISH_LABELS

    ExBossDB = ExBossDB or {}
    ExBossDB.voice = ExBossDB.voice or {}
    ExBossDB.voice.global = ExBossDB.voice.global or {}
    local globalCfg = ExBossDB.voice.global
    local currentPack = SafeNonEmptyString(globalCfg.selectedVoicePack) or ""
    if not globalCfg._englishPatchVoicePackMigrated then
        local shouldMigrate = currentPack == ""
        if not shouldMigrate then
            local okFind, found = pcall(function()
                return currentPack:find("EXWIND", 1, true)
            end)
            shouldMigrate = okFind and found ~= nil
        end
        if shouldMigrate then
            globalCfg.selectedVoicePack = CUSTOM_VOICE_PACK_NAME
        end
        globalCfg._englishPatchVoicePackMigrated = true
    end

    local engine = _G.ExBoss and _G.ExBoss.Voice and _G.ExBoss.Voice.Engine
    if engine and type(engine.InvalidateLabelCache) == "function" then
        pcall(engine.InvalidateLabelCache, engine)
    end
end

RegisterSoundAliases = function()
    local LSM = LibStub and LibStub("LibSharedMedia-3.0", true)
    if not LSM then
        return
    end

    RefreshDynamicLabelTranslations()

    local function RegisterPackSound(packName, label, soundFile)
        packName = SafeNonEmptyString(packName)
        label = SafeNonEmptyString(label)
        if not packName or not label then
            return
        end
        local resolvedFile = SafeNonEmptyString(soundFile) or "Check.ogg"
        local soundPath = CUSTOM_SOUND_BASE_PATH .. resolvedFile
        pcall(LSM.Register, LSM, "sound", "[" .. packName .. "]" .. label, soundPath)
    end

    local registered = {}
    local function RegisterLabelVariant(sourceLabel, englishLabel, soundFile)
        local src = SafeNonEmptyString(sourceLabel)
        local en = SafeNonEmptyString(englishLabel)
        local file = SafeNonEmptyString(soundFile) or "Check.ogg"
        if not en then
            return
        end

        local key = (src or "") .. "\031" .. en .. "\031" .. file
        if registered[key] then
            return
        end
        registered[key] = true

        for packIndex = 1, #DEFAULT_VOICE_PACK_NAMES do
            local packName = DEFAULT_VOICE_PACK_NAMES[packIndex]
            RegisterPackSound(packName, en, file)
            if src and src ~= en then
                RegisterPackSound(packName, src, file)
            end
        end
    end

    for i = 1, #SOUND_ALIASES do
        local sourceLabel = SOUND_ALIASES[i][1]
        local englishLabel = SOUND_ALIASES[i][2]
        local soundFile = CUSTOM_SOUND_BY_LABEL[englishLabel]
        RegisterLabelVariant(sourceLabel, englishLabel, soundFile)
    end

    for sourceLabel, soundFile in pairs(SOUND_FILE_BY_LABEL) do
        local englishLabel = LABEL_TRANSLATIONS[sourceLabel] or sourceLabel
        RegisterLabelVariant(sourceLabel, englishLabel, soundFile)
    end

    for packIndex = 1, #DEFAULT_VOICE_PACK_NAMES do
        RegisterPackSound(DEFAULT_VOICE_PACK_NAMES[packIndex], "54321", "5.ogg")
    end

    ForceEnglishVoiceLabels()

    ExBossDB = ExBossDB or {}
    ExBossDB.voice = ExBossDB.voice or {}
    ExBossDB.voice.global = ExBossDB.voice.global or {}
    local globalCfg = ExBossDB.voice.global
    local currentPack = SafeNonEmptyString(globalCfg.selectedVoicePack) or ""
    if not globalCfg._englishPatchVoicePackMigrated then
        local shouldMigrate = currentPack == ""
        if not shouldMigrate then
            local okFind, found = pcall(function()
                return currentPack:find("EXWIND", 1, true)
            end)
            shouldMigrate = okFind and found ~= nil
        end
        if shouldMigrate then
            globalCfg.selectedVoicePack = CUSTOM_VOICE_PACK_NAME
        end
        globalCfg._englishPatchVoicePackMigrated = true
    end

    local engine = _G.ExBoss and _G.ExBoss.Voice and _G.ExBoss.Voice.Engine
    if engine and type(engine.InvalidateLabelCache) == "function" then
        pcall(engine.InvalidateLabelCache, engine)
    end
end
local function WrapLabelCatalog()
    local catalog = _G.ExBoss and _G.ExBoss.Voice and _G.ExBoss.Voice.LabelCatalog
    if type(catalog) ~= "table" or catalog._englishPatchWrapped then
        return
    end

    local function TranslateLabelList(list)
        if type(list) ~= "table" then
            return list
        end

        local out, seen = {}, {}
        for i = 1, #list do
            local label = SafeNonEmptyString(list[i])
            local translated = (label and LABEL_TRANSLATIONS[label]) or label
            if translated and translated ~= "" and not seen[translated] then
                seen[translated] = true
                out[#out + 1] = translated
            end
        end
        return out
    end

    if type(catalog.GetPackLabels) == "function" then
        local original = catalog.GetPackLabels
        catalog.GetPackLabels = function(packName)
            local name = SafeString(packName) or ""
            if name == "EXWIND (Default)" then
                name = "EXWIND(é»˜è®¤)"
            end
            return TranslateLabelList(original(name))
        end
    end

    if type(catalog.GetStandardLabels) == "function" then
        local original = catalog.GetStandardLabels
        catalog.GetStandardLabels = function()
            return TranslateLabelList(original())
        end
    end

    if type(catalog.GetDropdownItems) == "function" then
        local original = catalog.GetDropdownItems
        catalog.GetDropdownItems = function()
            local items = original()
            if type(items) ~= "table" then
                return items
            end
            for i = 1, #items do
                local row = items[i]
                if type(row) == "table" then
                    -- Voice labels kept in original language (Chinese) to distinguish from custom English audio
                end
            end
            return items
        end
    end

    catalog._englishPatchWrapped = true
end

WrapLabelCatalog = function()
    local catalog = _G.ExBoss and _G.ExBoss.Voice and _G.ExBoss.Voice.LabelCatalog
    if type(catalog) ~= "table" or catalog._englishPatchWrappedByEnglishVoice then
        return
    end

    local function GetEnglishLabelList()
        ForceEnglishVoiceLabels()
        return CopyStringArray(ENGLISH_LABELS)
    end

    if type(catalog.GetPackLabels) == "function" then
        local originalGetPackLabels = catalog.GetPackLabels
        catalog.GetPackLabels = function(packName)
            local name = SafeString(packName) or ""
            if name == "" or name == "EXWIND (Default)" or name == "EXWIND(é»˜è®¤)" or name == CUSTOM_VOICE_PACK_NAME then
                return GetEnglishLabelList()
            end

            local list = originalGetPackLabels(packName)
            if type(list) ~= "table" then
                return list
            end

            local out, seen = {}, {}
            for i = 1, #list do
                local label = SafeNonEmptyString(list[i])
                local translated = (label and LABEL_TRANSLATIONS[label]) or label
                if translated and translated ~= "" and not seen[translated] then
                    seen[translated] = true
                    out[#out + 1] = translated
                end
            end
            return out
        end
    end

    catalog.GetStandardLabels = function()
        return GetEnglishLabelList()
    end

    catalog.GetDropdownItems = function()
        local labels = GetEnglishLabelList()
        local items = {}
        for i = 1, #labels do
            local label = labels[i]
            items[#items + 1] = { label, label, text = label, label = label, value = label }
        end
        return items
    end

    catalog._englishPatchWrappedByEnglishVoice = true
end

ForceEnglishVoiceLabels = function()
    local base = {}
    if type(_G.EXBV_LABELS) == "table" then
        base = _G.EXBV_LABELS
    elseif type(_G.EXBOSSEXWIND_LABELS) == "table" then
        base = _G.EXBOSSEXWIND_LABELS
    end

    local out, seen = {}, {}
    local function AddFrom(list)
        if type(list) ~= "table" then
            return
        end
        for i = 1, #list do
            local label = SafeNonEmptyString(list[i])
            if label and not seen[label] then
                seen[label] = true
                out[#out + 1] = label
            end
        end
    end

    AddFrom(base)
    AddFrom(ENGLISH_LABELS)

    _G.EXBV_LABELS = CopyStringArray(out)
    _G.EXBOSSEXWIND_LABELS = CopyStringArray(out)
    return out
end

WrapLabelCatalog = function()
    local catalog = _G.ExBoss and _G.ExBoss.Voice and _G.ExBoss.Voice.LabelCatalog
    if type(catalog) ~= "table" or catalog._englishPatchMergedVoiceHook then
        return
    end

    local originalStandard = type(catalog.GetStandardLabels) == "function" and catalog.GetStandardLabels or nil
    local originalPackLabels = type(catalog.GetPackLabels) == "function" and catalog.GetPackLabels or nil

    local function MergeLabelLists(...)
        local out, seen = {}, {}
        local lists = { ... }
        for listIndex = 1, #lists do
            local list = lists[listIndex]
            if type(list) == "table" then
                for i = 1, #list do
                    local label = SafeNonEmptyString(list[i])
                    if label and not seen[label] then
                        seen[label] = true
                        out[#out + 1] = label
                    end
                end
            end
        end
        return out
    end

    local function GetMergedLabelList()
        local base = originalStandard and originalStandard() or _G.EXBV_LABELS
        local merged = MergeLabelLists(base, ENGLISH_LABELS)
        _G.EXBV_LABELS = CopyStringArray(merged)
        _G.EXBOSSEXWIND_LABELS = CopyStringArray(merged)
        return merged
    end

    catalog.GetStandardLabels = function()
        return GetMergedLabelList()
    end

    catalog.GetDropdownItems = function()
        local labels = GetMergedLabelList()
        local items = {}
        for i = 1, #labels do
            local label = labels[i]
            items[#items + 1] = { label, label, text = label, label = label, value = label }
        end
        return items
    end

    if originalPackLabels then
        catalog.GetPackLabels = function(packName)
            local name = SafeString(packName) or ""
            if name == CUSTOM_VOICE_PACK_NAME then
                return CopyStringArray(ENGLISH_LABELS)
            end
            if name == "" or name == "EXWIND (Default)" or name == "EXWIND(é»˜è®¤)" or name == "EXWIND(Ã©Â»ËœÃ¨Â®Â¤)" then
                return GetMergedLabelList()
            end
            return originalPackLabels(packName)
        end
    end

    catalog._englishPatchMergedVoiceHook = true
end

local function TranslateWidgetText(widget)
    if not widget or not widget.GetObjectType then
        return
    end

    local function SafeGetText(target)
        if type(target.GetText) ~= "function" then
            return nil
        end
        local ok, value = pcall(target.GetText, target)
        if not ok or type(value) ~= "string" then
            return nil
        end
        local comparable = pcall(function()
            return value == value
        end)
        if not comparable then
            return nil
        end
        return value
    end

    local function SafeTranslate(value)
        local ok, translated = pcall(ReplaceText, value)
        if not ok or type(translated) ~= "string" then
            return nil
        end
        local comparable = pcall(function()
            return translated == translated
        end)
        if not comparable then
            return nil
        end
        return translated
    end

    local function SafeStringsEqual(left, right)
        local ok, result = pcall(function()
            return left == right
        end)
        if not ok then
            return false
        end
        return result and true or false
    end

    local function SafeSetText(target, value)
        if type(target.SetText) ~= "function" then
            return
        end
        pcall(target.SetText, target, value)
    end

    local objectType = widget:GetObjectType()
    if objectType == "DropdownButton" and type(widget._items) == "table" then
        -- USER REQUEST: Do not translate dropdown contents (especially in Boss Dungeons Page)
        -- because these act as exact database lookup keys for audio files and configuration logic.
        return
    end

    if objectType == "FontString" then
        local parent = type(widget.GetParent) == "function" and widget:GetParent()
        local pType = parent and type(parent.GetObjectType) == "function" and parent:GetObjectType()
        if pType == "DropdownButton" then
            -- USER REQUEST: Bypass translating the text natively displayed on the button surface
            return
        end

        local current = SafeGetText(widget)
        if not current then
            return
        end
        local translated = SafeTranslate(current)
        if not translated then
            return
        end
        if SafeStringsEqual(widget._englishPatchLastSource, current) and SafeStringsEqual(widget._englishPatchLastTranslated, translated) then
            return
        end
        widget._englishPatchLastSource = current
        widget._englishPatchLastTranslated = translated
        if not SafeStringsEqual(translated, current) then
            SafeSetText(widget, translated)
        end
        return
    end

    if objectType == "Button" and type(widget.GetText) == "function" and type(widget.SetText) == "function" then
        local current = SafeGetText(widget)
        if not current then
            return
        end
        local translated = SafeTranslate(current)
        if not translated then
            return
        end
        if SafeStringsEqual(widget._englishPatchLastSource, current) and SafeStringsEqual(widget._englishPatchLastTranslated, translated) then
            return
        end
        widget._englishPatchLastSource = current
        widget._englishPatchLastTranslated = translated
        if not SafeStringsEqual(translated, current) then
            SafeSetText(widget, translated)
        end
        return
    end

    if objectType == "EditBox" and type(widget.GetText) == "function" and type(widget.SetText) == "function" and not widget:HasFocus() then
        local current = SafeGetText(widget)
        if not current then
            return
        end
        local translated = SafeTranslate(current)
        if not translated then
            return
        end
        if SafeStringsEqual(widget._englishPatchLastSource, current) and SafeStringsEqual(widget._englishPatchLastTranslated, translated) then
            return
        end
        widget._englishPatchLastSource = current
        widget._englishPatchLastTranslated = translated
        if not SafeStringsEqual(translated, current) then
            SafeSetText(widget, translated)
        end
    end
end

local trackedDropdowns = setmetatable({}, { __mode = "k" })

local function CanTranslateUiNow()
    return not (type(InCombatLockdown) == "function" and InCombatLockdown())
end

local function RegisterTrackedDropdown(dropdown)
    if type(dropdown) ~= "table" or type(dropdown.GetObjectType) ~= "function" then
        return
    end

    if dropdown:GetObjectType() ~= "DropdownButton" then
        return
    end

    trackedDropdowns[dropdown] = true

    if not dropdown._englishPatchMenuHideHook and type(dropdown.HookScript) == "function" then
        dropdown:HookScript("OnHide", function(self)
            if type(self.CloseMenu) == "function" then
                pcall(self.CloseMenu, self)
            end
        end)
        dropdown._englishPatchMenuHideHook = true
    end
end

local function CloseTrackedDropdownMenus()
    for dropdown in pairs(trackedDropdowns) do
        if type(dropdown) == "table" and type(dropdown.CloseMenu) == "function" then
            pcall(function()
                if type(dropdown.IsMenuOpen) ~= "function" or dropdown:IsMenuOpen() then
                    dropdown:CloseMenu()
                end
            end)
        end
    end
end

local function WrapExwindDropdownFactory(methodName)
    local ui = _G.ExwindTools and _G.ExwindTools.UI
    if not ui or ui["_englishPatchWrapped_" .. methodName] then
        return
    end

    local original = ui[methodName]
    if type(original) ~= "function" then
        return
    end

    ui[methodName] = function(self, ...)
        local dropdown = original(self, ...)
        RegisterTrackedDropdown(dropdown)
        return dropdown
    end

    ui["_englishPatchWrapped_" .. methodName] = true
end

local function InstallDropdownTracking()
    WrapExwindDropdownFactory("CreateDropdown")
    WrapExwindDropdownFactory("CreateLSMDropdown")
    WrapExwindDropdownFactory("CreateLSMTextureDropdown")
    WrapExwindDropdownFactory("CreateLSMSoundDropdown")
    WrapExwindDropdownFactory("CreateMultiSelectDropdown")
end

local function TranslateFrameTree(frame, context)
    if not frame or type(frame) ~= "table" then
        return
    end

    if type(frame.IsShown) == "function" and not frame:IsShown() then
        return
    end

    context = context or { visited = {}, count = 0, max = 15000 }
    local visited = context.visited
    if visited[frame] or context.count >= context.max then
        return
    end
    visited[frame] = true
    context.count = context.count + 1

    RegisterTrackedDropdown(frame)
    TranslateWidgetText(frame)

    if type(frame.GetRegions) == "function" then
        local regions = { frame:GetRegions() }
        for i = 1, #regions do
            if context.count >= context.max then
                break
            end
            TranslateWidgetText(regions[i])
            context.count = context.count + 1
        end
    end

    if type(frame.GetChildren) == "function" then
        local children = { frame:GetChildren() }
        for i = 1, #children do
            if context.count >= context.max then
                break
            end
            TranslateFrameTree(children[i], context)
        end
    end
end

local function TranslateKnownFrames()
    if not CanTranslateUiNow() then
        return
    end

    if _G.ExBoss_MainPanel and _G.ExBoss_MainPanel:IsShown() then
        TranslateFrameTree(_G.ExBoss_MainPanel)
    end
    if _G.ExwindToolsMainFrame and _G.ExwindToolsMainFrame:IsShown() then
        TranslateFrameTree(_G.ExwindToolsMainFrame)
    end
    if _G.ExBossChangelogFrame and _G.ExBossChangelogFrame:IsShown() then
        TranslateFrameTree(_G.ExBossChangelogFrame)
    end
    if _G.ExwindToolsChangelogFrame and _G.ExwindToolsChangelogFrame:IsShown() then
        TranslateFrameTree(_G.ExwindToolsChangelogFrame)
    end
    if _G.ExBoss_MDTOverlay and _G.ExBoss_MDTOverlay:IsShown() then
        TranslateFrameTree(_G.ExBoss_MDTOverlay)
    end
    if _G.ExwindDeathSoundFrame and _G.ExwindDeathSoundFrame:IsShown() then
        TranslateFrameTree(_G.ExwindDeathSoundFrame)
    end
    if _G.StaticPopup1 and _G.StaticPopup1:IsShown() then
        TranslateFrameTree(_G.StaticPopup1)
    end
    if _G.StaticPopup2 and _G.StaticPopup2:IsShown() then
        TranslateFrameTree(_G.StaticPopup2)
    end
    if _G.StaticPopup3 and _G.StaticPopup3:IsShown() then
        TranslateFrameTree(_G.StaticPopup3)
    end
    if _G.StaticPopup4 and _G.StaticPopup4:IsShown() then
        TranslateFrameTree(_G.StaticPopup4)
    end
end

local function ScheduleTranslateBurst(frame)
    if not CanTranslateUiNow() then
        return
    end

    if frame and type(frame) == "table" and type(frame.IsShown) == "function" and frame:IsShown() then
        TranslateFrameTree(frame)
    else
        TranslateKnownFrames()
    end
end

local translateTicker = nil
local hudTranslateTicker = nil

local function AreConfigPanelsVisible()
    if _G.ExBoss_MainPanel and _G.ExBoss_MainPanel:IsShown() then return true end
    if _G.ExwindToolsMainFrame and _G.ExwindToolsMainFrame:IsShown() then return true end
    return false
end

local function UpdateTranslateTicker()
    local canRun = CanTranslateUiNow()

    -- UI ticker: 0.5s for responsive translation when navigating Bosses/Skills
    local isConfigOpen = canRun and AreConfigPanelsVisible()
    if isConfigOpen and not translateTicker then
        translateTicker = C_Timer.NewTicker(0.5, function()
            if _G.ExBoss_MainPanel and _G.ExBoss_MainPanel:IsShown() then
                ScheduleTranslateBurst(_G.ExBoss_MainPanel)
            end
            if _G.ExwindToolsMainFrame and _G.ExwindToolsMainFrame:IsShown() then
                ScheduleTranslateBurst(_G.ExwindToolsMainFrame)
            end
        end)
    elseif not isConfigOpen and translateTicker then
        translateTicker:Cancel()
        translateTicker = nil
    end

    -- Slower HUD ticker: 2.5s for combat elements to save CPU
    local shouldRunHud = canRun and ((_G.ExBoss_MDTOverlay and _G.ExBoss_MDTOverlay:IsShown()) or (_G.ExwindDeathSoundFrame and _G.ExwindDeathSoundFrame:IsShown()))
    if shouldRunHud and not hudTranslateTicker then
        hudTranslateTicker = C_Timer.NewTicker(2.5, function()
            TranslateKnownFrames()
        end)
    elseif not shouldRunHud and hudTranslateTicker then
        hudTranslateTicker:Cancel()
        hudTranslateTicker = nil
    end
end

local function HookFrameOnShow(frame)
    if not frame or frame._englishPatchShowHook then
        return
    end
    frame:HookScript("OnShow", function()
        ScheduleTranslateBurst(frame)
        UpdateTranslateTicker()
    end)
    frame:HookScript("OnHide", function()
        UpdateTranslateTicker()
    end)
    frame._englishPatchShowHook = true
end

local function HookRenderMethod(target, methodName, frameArgIndex, idKey)
    if type(target) ~= "table" then
        return
    end

    local hookKey = idKey or ("_englishPatchHook_" .. tostring(methodName))
    if target[hookKey] or type(target[methodName]) ~= "function" then
        return
    end

    hooksecurefunc(target, methodName, function(_, ...)
        local frame = select(frameArgIndex or 1, ...)
        ScheduleTranslateBurst(frame)
    end)

    target[hookKey] = true
end

local function InstallUiHooks()
    if _G.ExBoss and _G.ExBoss.UI and _G.ExBoss.UI.Panel and type(_G.ExBoss.UI.Panel.Toggle) == "function" and not _G.ExBoss.UI.Panel._englishPatchToggleHook then
        hooksecurefunc(_G.ExBoss.UI.Panel, "Toggle", function()
            ScheduleTranslateBurst(_G.ExBoss_MainPanel)
            C_Timer.After(0, UpdateTranslateTicker)
        end)
        _G.ExBoss.UI.Panel._englishPatchToggleHook = true
    end

    if _G.ExwindTools and _G.ExwindTools.UI and type(_G.ExwindTools.UI.Toggle) == "function" and not _G.ExwindTools.UI._englishPatchToggleHook then
        hooksecurefunc(_G.ExwindTools.UI, "Toggle", function()
            ScheduleTranslateBurst(_G.ExwindToolsMainFrame)
            C_Timer.After(0, UpdateTranslateTicker)
        end)
        _G.ExwindTools.UI._englishPatchToggleHook = true
    end

    if _G.ExwindTools and _G.ExwindTools.UI and type(_G.ExwindTools.UI.RefreshContent) == "function" and not _G.ExwindTools.UI._englishPatchRefreshHook then
        hooksecurefunc(_G.ExwindTools.UI, "RefreshContent", function()
            ScheduleTranslateBurst(_G.ExwindToolsMainFrame)
        end)
        _G.ExwindTools.UI._englishPatchRefreshHook = true
    end

    local exBossPanel = _G.ExBoss and _G.ExBoss.UI and _G.ExBoss.UI.Panel
    if exBossPanel then
        HookRenderMethod(exBossPanel.VoicePackPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.OtherVoicePage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.ImportExportPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.FixedTimelinePage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.GlobalSettingsPage, "Render", 2, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.GeneralOverviewPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.GeneralColorPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.CountdownPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.PrivateAuraPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.PrivateAuraMonitorPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.BossPage, "Render", 2, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.TimerBarPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.BunBarPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.FlashTextPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.ConditionsPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.SpellPage, "Render", 1, "_englishPatchRenderHook")
        HookRenderMethod(exBossPanel.RingProgressPage, "Render", 1, "_englishPatchRenderHook")
    end

    HookFrameOnShow(_G.ExBoss_MainPanel)
    HookFrameOnShow(_G.ExwindToolsMainFrame)

    if _G.ExBoss_MDTOverlay then
        HookFrameOnShow(_G.ExBoss_MDTOverlay)
    end
    if _G.ExwindDeathSoundFrame then
        HookFrameOnShow(_G.ExwindDeathSoundFrame)
    end

    if _G.ExBoss and _G.ExBoss.MDT and _G.ExBoss.MDT.Overlay and type(_G.ExBoss.MDT.Overlay.Refresh) == "function" and not _G.ExBoss.MDT.Overlay._englishPatchRefreshHook then
        hooksecurefunc(_G.ExBoss.MDT.Overlay, "Refresh", function()
            ScheduleTranslateBurst(_G.ExBoss_MDTOverlay)
            C_Timer.After(0, UpdateTranslateTicker)
        end)
        _G.ExBoss.MDT.Overlay._englishPatchRefreshHook = true
    end

    if _G.UnitPopup_ShowMenu and not _G.EXBoss_EnglishPatch_UnitPopupHooked then
        hooksecurefunc("UnitPopup_ShowMenu", CloseTrackedDropdownMenus)
        _G.EXBoss_EnglishPatch_UnitPopupHooked = true
    end

    if _G.FriendsFrame_ShowDropdown and not _G.EXBoss_EnglishPatch_FriendsPopupHooked then
        hooksecurefunc("FriendsFrame_ShowDropdown", CloseTrackedDropdownMenus)
        _G.EXBoss_EnglishPatch_FriendsPopupHooked = true
    end
end

local function RefreshCaches()
    ForceEnglishVoiceLabels()

    if _G.EXBossData and type(_G.EXBossData.TouchEventConfig) == "function" then
        _G.EXBossData.TouchEventConfig()
    end
    if _G.EXBossData and type(_G.EXBossData.GetEventConfigRoot) == "function" then
        local root = _G.EXBossData.GetEventConfigRoot()
        if type(root) == "table" then
            for rawEventID, row in pairs(root) do
                FixEventConfigRow(rawEventID, row)
            end
        end
    end
    if _G.EXBossData and type(_G.EXBossData.RebuildTimelineBosses) == "function" then
        _G.EXBossData.RebuildTimelineBosses()
    end
    PatchTimelineBosses()

    local engine = _G.ExBoss and _G.ExBoss.Voice and _G.ExBoss.Voice.Engine
    if engine and type(engine.InvalidateLabelCache) == "function" then
        engine:InvalidateLabelCache()
    end
end

local applied = false
local function ApplyEnglishPatch(forceFull)
    ForceEnglishVoiceLabels()

    if forceFull or not applied then
        ForceLocales()
        PatchLocales()
        WrapLocaleRoot(_G.ExBoss and _G.ExBoss.Locale)
        WrapLocaleRoot(_G.ExwindLocale)
        WrapLocaleProxy(_G.ExBoss and _G.ExBoss.L)
        WrapLocaleProxy(_G.ExwindTools and _G.ExwindTools.L)
        
        -- Yield CPU to prevent 'script ran too long' timeouts during heavy UI/Audio setups
        C_Timer.After(0.1, function()
            PatchEncounterData()
            PatchPrivateAuraData()
            PatchAuthorPresets()
            PatchMetadataTables()
            WrapExBossDataApi()
            WrapAddOnMetadata()
            
            C_Timer.After(0.1, function()
                RegisterSoundAliases()
                WrapLabelCatalog()
                InstallDropdownTracking()
                
                C_Timer.After(0.1, function()
                    RefreshCaches()
                    InstallUiHooks()
                    applied = true
                    
                    RefreshDynamicLabelTranslations()
                    ForceEnglishVoiceLabels()
                    TranslateKnownFrames()
                    UpdateTranslateTicker()
                end)
            end)
        end)
    else
        RefreshDynamicLabelTranslations()
        ForceEnglishVoiceLabels()
        TranslateKnownFrames()
        UpdateTranslateTicker()
    end
end

local applyPatchQueued = false
local applyPatchNeedsFull = false
local function QueueApplyEnglishPatch(delay, forceFull)
    if forceFull then
        applyPatchNeedsFull = true
    end
    if applyPatchQueued then
        return
    end
    applyPatchQueued = true
    C_Timer.After(delay or 0, function()
        applyPatchQueued = false
        local runFull = applyPatchNeedsFull or not applied
        applyPatchNeedsFull = false
        ApplyEnglishPatch(runFull)
    end)
end

local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:RegisterEvent("PLAYER_LOGIN")
eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
eventFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
eventFrame:SetScript("OnEvent", function(_, event, arg1)
    if event == "ADDON_LOADED" then
        local addonName = SafeLower(arg1) or ""
        if TARGET_ADDONS[addonName] then
            QueueApplyEnglishPatch(0.05, true)
        end
        return
    end

    if event == "PLAYER_REGEN_DISABLED" then
        UpdateTranslateTicker()
        return
    end

    if event == "PLAYER_REGEN_ENABLED" then
        QueueApplyEnglishPatch(0, false)
        C_Timer.After(0.05, UpdateTranslateTicker)
        return
    end

    QueueApplyEnglishPatch(0.05, true)
end)

C_Timer.After(0, function()
    QueueApplyEnglishPatch(0, true)
end)