local addonName, MSUF = ...
MSUF = MSUF or _G.MSUF_NS or {}

local M = MSUF.MSUF2 or _G.MSUF2 or {}
MSUF.MSUF2 = M

local A = MSUF.Assistant or {}
MSUF.Assistant = A
M.Assistant = A

--- Shell/Menu2/Assistant/MSUF_AssistantParser.lua
---
--- High-level parse pipeline for assistant commands. The many P.* helpers are
--- loaded from registry/domain parser files; this module orders them from most
--- specific workflow/geometry matches to broader registry fallback.
---
--- New parser work should usually live in the owning domain file and be called
--- from one of the _ParsePipeline* functions below. Avoid applying settings here:
--- return a plan/action and let MSUF_Assistant.lua execute it.

local P = A.Parser or {}
A.Parser = P
P.RootPhrases = (((A.ParserData or {}).ROOT_PARSER or {}).PHRASES or {})
local Trim = P.Trim
local Normalize = P.Normalize
local ContainsAny = P.ContainsAny
local DetectBoolean = P.DetectBoolean
local FirstNumber = P.FirstNumber
local HasPhrase = P.HasPhrase
local DetectUnits = P.DetectUnits
local DetectGroups = P.DetectGroups
local ParseWorkflowLifecycle = P.ParseWorkflowLifecycle
local ParseProfileStagingState = P.ParseProfileStagingState
local ParseGroupCopyScopeState = P.ParseGroupCopyScopeState
local ParseUnitCopyScopeState = P.ParseUnitCopyScopeState
local ParseProfile = P.ParseProfile
local ParseGroupCopy = P.ParseGroupCopy
local ParseCopy = P.ParseCopy
local BuildContextReset = P.BuildContextReset
local ParseGroupSpellIndicatorAction = P.ParseGroupSpellIndicatorAction
local ParseGroupCornerIndicatorSetting = P.ParseGroupCornerIndicatorSetting
local ParseGroupCornerIndicatorReset = P.ParseGroupCornerIndicatorReset
local ParseGroupStatusIconReset = P.ParseGroupStatusIconReset
local ParseGroupStatusPreview = P.ParseGroupStatusPreview
local ParseUnitStatusIndicatorReset = P.ParseUnitStatusIndicatorReset
local ParseUnitStatusPreview = P.ParseUnitStatusPreview
local ParseUnitStatusIndicatorMove = P.ParseUnitStatusIndicatorMove
local ParseUnitStatusSymbolRegistryShortcut = P.ParseUnitStatusSymbolRegistryShortcut
local ParseStatusIconTestModeRegistryShortcut = P.ParseStatusIconTestModeRegistryShortcut
local ParseUnitLoadConditionShortcut = P.ParseUnitLoadConditionShortcut
local ParseCustomAnchorWorkflow = P.ParseCustomAnchorWorkflow
local ParseCustomAnchorSet = P.ParseCustomAnchorSet
local ParseCustomAnchorClear = P.ParseCustomAnchorClear
local ParseReset = P.ParseReset
local ParseOpen = P.ParseOpen
local ParseDashboardPanelAction = P.ParseDashboardPanelAction
local ParseNavRailAction = P.ParseNavRailAction
local ParseMenuWindowAction = P.ParseMenuWindowAction
local ParseScopedFontTextColorShortcut = P.ParseScopedFontTextColorShortcut
local ParseRegistryAlias = P.ParseRegistryAlias
local ParseScopedOnlyOverride = P.ParseScopedOnlyOverride
local ParseFontColorAction = P.ParseFontColorAction
local ParseColorAction = P.ParseColorAction
local ParseDiagnostic = P.ParseDiagnostic
local ParseScopedHelp = P.ParseScopedHelp
local ParseSupportWorkflow = P.ParseSupportWorkflow
local ParsePresetWorkflow = P.ParsePresetWorkflow
local ParseEditModeHUDControl = P.ParseEditModeHUDControl
local ParseScopedOverrideReset = P.ParseScopedOverrideReset
local ParseGameplayRootToggle = P.ParseGameplayRootToggle
local ParseGameplayAction = P.ParseGameplayAction
local ParseClassPowerRootToggle = P.ParseClassPowerRootToggle
local ParseClassPowerAction = P.ParseClassPowerAction
local ParseGlobalBarsAction = P.ParseGlobalBarsAction
local ParseDarkModeBrightnessShortcut = P.ParseDarkModeBrightnessShortcut
local ParseCastbarPreviewAction = P.ParseCastbarPreviewAction
local ParseCastbarGlobalDetail = P.ParseCastbarGlobalDetail
local ParseGuidedSetup = P.ParseGuidedSetup
local ParseGuidedSetupFollowup = P.ParseGuidedSetupFollowup
local ParseUnsupportedDetailShortcut = P.ParseUnsupportedDetailShortcut
local ParsePortraitDetailShortcut = P.ParsePortraitDetailShortcut

function A._DispelOverlayAlphaValue(normalized)
    local value = FirstNumber(normalized)
    if value ~= nil then
        if value > 1 then value = value / 100 end
        if value > 1 then value = 1 end
        if value < 0.05 then value = 0.05 end
        return value
    end
    if ContainsAny(normalized, { "max", "maximum", "full opacity", "full alpha", "strongest", "highest" }) then return 1 end
    if ContainsAny(normalized, { "min", "minimum", "lowest", "weakest" }) then return 0.05 end
    if ContainsAny(normalized, { "half", "50 percent", "50%" }) then return 0.5 end
    return nil
end

local function ParseDispelOverlayOpacityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[1]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[2]) then return nil end
    local value = A._DispelOverlayAlphaValue(normalized)
    if value == nil then return nil end

    local changes = {}
    local units = DetectUnits(normalized)
    local groups = DetectGroups(normalized)
    for i = 1, #units do
        local unit = tostring(units[i])
        local setting = A.Registry and A.Registry:GetSetting("barScope." .. unit .. ".unitDispelOverlayAlpha")
        if setting then changes[#changes + 1] = { setting = setting, value = value } end
    end
    for i = 1, #groups do
        local scope = groups[i] == "mythicraid" and "gf_mythicraid" or ("gf_" .. tostring(groups[i]))
        local setting = A.Registry and A.Registry:GetSetting(scope .. ".dispelOverlayAlpha")
        if setting then changes[#changes + 1] = { setting = setting, value = value } end
    end
    if #changes == 0 then
        local setting = A.Registry and A.Registry:GetSetting("general.unitDispelOverlayAlpha")
        if setting then changes[#changes + 1] = { setting = setting, value = value } end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Dispel Overlay Opacity") or "Dispel Overlay Opacity",
        bulkSafe = #changes > 1,
        summary = "Changes dispel overlay opacity for the requested scope.",
    }
end

local function CastbarWidthModeValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[3]) then return "manual" end
    if ContainsAny(normalized, P.RootPhrases[4]) then return "unitframe" end
    if ContainsAny(normalized, P.RootPhrases[5]) then return "essential" end
    if ContainsAny(normalized, P.RootPhrases[6]) then return "utility" end
    return nil
end

local function ParseCastbarWidthModeShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[7]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[8]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[9]) and not ContainsAny(normalized, P.RootPhrases[10]) then
        return nil
    end

    local value = CastbarWidthModeValue(normalized)
    if value == nil then return nil end

    local units = DetectUnits(normalized)
    if #units == 0 and ContainsAny(normalized, P.RootPhrases[11]) then
        units = { "player", "target", "focus", "boss" }
    end
    if #units == 0 then return nil end

    local keys = {
        player = "general.castbarPlayerMatchWidth",
        target = "general.castbarTargetMatchWidth",
        focus = "general.castbarFocusMatchWidth",
        boss = "general.bossCastbarMatchWidth",
    }
    local changes = {}
    local seen = {}
    for i = 1, #units do
        local key = keys[units[i]]
        if key and not seen[key] then
            seen[key] = true
            local setting = A.Registry and A.Registry:GetSetting(key)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Castbar Width Mode") or "Castbar Width Mode",
        bulkSafe = #changes > 1,
        summary = "Changes unit Cast Bar width mode.",
    }
end

local function ParseGroupAuraLaneOffsetShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[12]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[13]) then return nil end

    local lane
    if ContainsAny(normalized, P.RootPhrases[14]) then lane = "buff" end
    if ContainsAny(normalized, P.RootPhrases[15]) then
        if lane ~= nil then return nil end
        lane = "debuff"
    end
    if not lane then return nil end

    local axis
    if ContainsAny(normalized, P.RootPhrases[16]) then
        axis = "x"
    elseif ContainsAny(normalized, P.RootPhrases[17]) then
        axis = "y"
    end
    if not axis then return nil end

    local value = FirstNumber(normalized)
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[18]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".auras." .. lane .. "." .. axis)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Aura Offset") or "Group Aura Offsets",
        bulkSafe = #changes > 1,
        summary = "Changes group aura lane X/Y offset.",
    }
end

local function ParseGroupAuraLaneTextOffsetShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[19]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[20]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[21]) then return nil end

    local lane
    if ContainsAny(normalized, P.RootPhrases[22]) then lane = "buff" end
    if ContainsAny(normalized, P.RootPhrases[23]) then
        if lane ~= nil then return nil end
        lane = "debuff"
    end
    if not lane then return nil end

    local prefix
    if ContainsAny(normalized, P.RootPhrases[24]) then
        prefix = "cooldown"
    elseif ContainsAny(normalized, P.RootPhrases[25]) then
        prefix = "stack"
    end
    if not prefix then return nil end

    local axis
    if ContainsAny(normalized, P.RootPhrases[26]) then
        axis = "X"
    elseif ContainsAny(normalized, P.RootPhrases[27]) then
        axis = "Y"
    end
    if not axis then return nil end

    local value = FirstNumber(normalized)
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[28]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr = prefix .. axis
    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".auras." .. lane .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Aura Text Offset") or "Group Aura Text Offsets",
        bulkSafe = #changes > 1,
        summary = "Changes group aura cooldown/stack text X/Y offset.",
    }
end

local function ParseGroupAuraLaneTextSizeShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[29]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[30]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[31]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[32]) then return nil end

    local lane
    if ContainsAny(normalized, P.RootPhrases[33]) then lane = "buff" end
    if ContainsAny(normalized, P.RootPhrases[34]) then
        if lane ~= nil then return nil end
        lane = "debuff"
    end
    if not lane then return nil end

    local attr
    if ContainsAny(normalized, P.RootPhrases[35]) then
        attr = "cooldownSize"
    elseif ContainsAny(normalized, P.RootPhrases[36]) then
        attr = "stackSize"
    end
    if not attr then return nil end

    local value = FirstNumber(normalized)
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[37]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".auras." .. lane .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Aura Text Size") or "Group Aura Text Sizes",
        bulkSafe = #changes > 1,
        summary = "Changes group aura cooldown/stack text font size.",
    }
end

local function ParseGroupAuraLaneBooleanShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[38]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[39]) then return nil end

    local attr
    if ContainsAny(normalized, P.RootPhrases[40]) then
        attr = "showCooldown"
    elseif ContainsAny(normalized, P.RootPhrases[41]) then
        attr = "showStacks"
    elseif ContainsAny(normalized, P.RootPhrases[42]) then
        attr = "showCooldownSwipe"
    end
    if not attr then return nil end

    local lane
    if ContainsAny(normalized, P.RootPhrases[43]) then lane = "buff" end
    if ContainsAny(normalized, P.RootPhrases[44]) then
        if lane ~= nil then return nil end
        lane = "debuff"
    end
    if not lane then return nil end

    local value = DetectBoolean(normalized)
    if value == nil and ContainsAny(normalized, P.RootPhrases[45]) then value = true end
    if value == nil and ContainsAny(normalized, P.RootPhrases[46]) then value = false end
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[47]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".auras." .. lane .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Aura Toggle") or "Group Aura Toggles",
        bulkSafe = #changes > 1,
        summary = "Changes group aura cooldown/stack visibility.",
    }
end

local function ParseGroupAuraCooldownDarkenShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[48]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[49]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[50]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[51]) then return nil end

    local value = DetectBoolean(normalized)
    if value == nil and ContainsAny(normalized, P.RootPhrases[52]) then value = true end
    if value == nil and ContainsAny(normalized, P.RootPhrases[53]) then value = false end
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[54]) then
        groups = { "party", "raid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    local unsupportedMythic = false
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if scope == "party" or scope == "raid" then
            local key = "gf_" .. scope .. ".cooldownSwipeDarkenOnLoss"
            if not seen[key] then
                seen[key] = true
                local setting = A.Registry and A.Registry:GetSetting(key)
                if setting then changes[#changes + 1] = { setting = setting, value = value } end
            end
        elseif scope == "mythicraid" then
            unsupportedMythic = true
        end
    end
    if #changes == 0 and unsupportedMythic then
        return {
            kind = "answer",
            status = "info",
            text = "Aura Cooldown Darkens on Loss exists for Party and Raid group aura settings. Mythic Raid does not expose a separate toggle for that option, so I did not guess or change another setting.",
            summary = "Explains that Mythic Raid has no separate aura cooldown darken-on-loss toggle.",
        }
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Aura Cooldown Darkens on Loss") or "Aura Cooldown Darkens on Loss",
        bulkSafe = #changes > 1,
        summary = "Changes whether group aura cooldown swipes darken when an aura is missing or lost.",
    }
end

local function ParseExplicitUnitBarOpacityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[55]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[56]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[57]) then return nil end

    local units = DetectUnits(normalized)
    if #units == 0 then return nil end
    local value = FirstNumber(normalized)
    if value == nil then return nil end
    if value > 1 then value = value / 100 end

    local powerOpacity = ContainsAny(normalized, P.RootPhrases[58])
    local backgroundOpacity = ContainsAny(normalized, P.RootPhrases[59])
    local attr = powerOpacity and backgroundOpacity and "powerBarBgAlpha"
        or powerOpacity and "powerBarAlpha"
        or backgroundOpacity and "hpBgAlpha"
        or "hpBarAlpha"

    local changes = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        local setting = A.Registry and A.Registry:GetSetting(unit .. "." .. attr)
        if setting then changes[#changes + 1] = { setting = setting, value = value } end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = powerOpacity and backgroundOpacity and "Set unit resource background opacity"
            or powerOpacity and "Set unit power bar opacity"
            or backgroundOpacity and "Set unit background opacity"
            or "Set unit opacity",
        bulkSafe = #changes > 1,
        summary = powerOpacity and backgroundOpacity and "Sets the resource bar background opacity for the requested unit frame."
            or powerOpacity and "Sets the power bar opacity for the requested unit frame."
            or backgroundOpacity and "Sets the bar background opacity for the requested unit frame."
            or "Sets the HP bar opacity for the requested unit frame.",
    }
end

local function ParseGroupAvailabilityFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[60]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[61]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[62]) then
        return nil
    end

    local attr
    local hideSemantic = false
    if ContainsAny(normalized, P.RootPhrases[63]) then
        attr = "hideOfflineInCombat"
        hideSemantic = true
    elseif ContainsAny(normalized, P.RootPhrases[64]) then
        attr = "hideOfflineEnabled"
        hideSemantic = true
    elseif ContainsAny(normalized, P.RootPhrases[65]) then
        attr = "hideInClientScene"
        hideSemantic = true
    elseif ContainsAny(normalized, P.RootPhrases[66]) then
        attr = "hideInHousing"
        hideSemantic = true
    elseif ContainsAny(normalized, P.RootPhrases[67]) then
        attr = "showPlayer"
    elseif ContainsAny(normalized, P.RootPhrases[68]) then
        attr = "showSolo"
    elseif ContainsAny(normalized, P.RootPhrases[69]) then
        attr = "clickCastEnabled"
    elseif ContainsAny(normalized, P.RootPhrases[70]) then
        attr = "enabled"
    end
    if not attr then return nil end

    local fromToValue
    if ContainsAny(normalized, P.RootPhrases[71]) then
        fromToValue = true
    elseif ContainsAny(normalized, P.RootPhrases[72]) then
        fromToValue = false
    end

    local value
    if fromToValue ~= nil then
        value = fromToValue
    elseif hideSemantic then
        if ContainsAny(normalized, P.RootPhrases[73]) then
            value = false
        elseif ContainsAny(normalized, P.RootPhrases[74]) then
            value = true
        end
        if value == nil then value = true end
    else
        if ContainsAny(normalized, P.RootPhrases[75]) then
            value = false
        elseif ContainsAny(normalized, P.RootPhrases[76]) then
            value = true
        end
        if value == nil and DetectBoolean then value = DetectBoolean(normalized) end
    end
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[77]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group availability") or "Group availability",
        bulkSafe = #changes > 1,
        summary = "Changes group-frame visibility.",
    }
end

local function GroupBlizzardFallbackValue(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local function valueIn(text)
        if not text or text == "" then return nil end
        if ContainsAny(text, P.RootPhrases[78]) then
            return "AUTO"
        end
        if ContainsAny(text, P.RootPhrases[79]) then
            return "SHOW"
        end
        if ContainsAny(text, P.RootPhrases[80]) then
            return "NONE"
        end
        return nil
    end

    local value = valueIn(target)
    if value then return value end
    if ContainsAny(normalized, P.RootPhrases[81]) then
        return "SHOW"
    end
    if ContainsAny(normalized, P.RootPhrases[82]) then
        return "NONE"
    end
    return valueIn(normalized)
end

local function ParseGroupBlizzardFallbackFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[83]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[84]) then
        return nil
    end

    local value = GroupBlizzardFallbackValue(normalized)
    if not value then return nil end
    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[85]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".blizzardFallbackMode")
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Blizzard Fallback Mode") or "Blizzard Fallback Mode",
        bulkSafe = #changes > 1,
        summary = "Changes what Blizzard group frames do when MSUF group frames are disabled.",
    }
end

local function ParseGroupHideOfflineDelayFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[86]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[87]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[88]) then
        return nil
    end
    local value = FirstNumber(normalized)
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[89]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".hideOfflineDelay")
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Hide Offline Delay") or "Hide Offline Delay",
        bulkSafe = #changes > 1,
        summary = "Changes how long group frames wait before hiding offline members.",
    }
end

local function ParseGroupReverseFillFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[90]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[91]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[92]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local value
    local boolValue = DetectBoolean(normalized)
    if ContainsAny(normalized, P.RootPhrases[93]) then
        value = false
    elseif boolValue ~= nil then
        value = boolValue
    elseif ContainsAny(normalized, P.RootPhrases[94]) then
        value = true
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".reverseFill")
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Reverse Health Fill") or "Reverse Health Fill",
        bulkSafe = #changes > 1,
        summary = "Changes group-frame health bar fill direction.",
    }
end

local function ParseUnitReverseFillFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[95]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[96]) then
        return nil
    end

    local units = DetectUnits(normalized)
    if #units == 0 then return nil end

    local value
    local boolValue = DetectBoolean(normalized)
    if ContainsAny(normalized, P.RootPhrases[97]) then
        value = false
    elseif boolValue ~= nil then
        value = boolValue
    elseif ContainsAny(normalized, P.RootPhrases[98]) then
        value = true
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        if unit ~= "" and not seen[unit] then
            seen[unit] = true
            local setting = A.Registry and A.Registry:GetSetting(unit .. ".reverseFillBars")
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Reverse Fill Direction") or "Reverse Fill Direction",
        bulkSafe = #changes > 1,
        summary = "Changes unit-frame health bar reverse fill direction.",
    }
end

local function ParseUnitSimpleBooleanFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[99]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[100]) then
        return nil
    end

    local attr
    local label
    if ContainsAny(normalized, P.RootPhrases[101]) then
        attr = "powerSmoothFill"
        label = "Power Bar Smooth Fill"
    elseif ContainsAny(normalized, P.RootPhrases[102]) then
        attr = "smoothFill"
        label = "Smooth Health Fill"
    elseif ContainsAny(normalized, P.RootPhrases[103]) then
        attr = "showName"
        label = "Name"
    else
        return nil
    end

    local value = DetectBoolean(normalized)
    if value == nil then return nil end

    local units = DetectUnits(normalized)
    if #units == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        if unit ~= "" and not seen[unit] then
            seen[unit] = true
            local setting = A.Registry and A.Registry:GetSetting(unit .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes a simple unit-frame visibility/fill toggle.",
    }
end

local function ParseUnitStatusDetailFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[104]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[105]) then
        return nil
    end

    local wantsAnchor = ContainsAny(normalized, P.RootPhrases[106])
    local wantsX = ContainsAny(normalized, P.RootPhrases[107])
    local wantsY = ContainsAny(normalized, P.RootPhrases[108])
    local wantsSize = ContainsAny(normalized, P.RootPhrases[109])
    local wantsLayer = ContainsAny(normalized, P.RootPhrases[110])
    local wantsStyle = ContainsAny(normalized, P.RootPhrases[111])
    local wantsVisibility = ContainsAny(normalized, P.RootPhrases[112])
    if not (wantsAnchor or wantsX or wantsY or wantsSize or wantsLayer or wantsStyle or wantsVisibility) then return nil end

    local units = DetectUnits(normalized)
    if #units == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        if unit ~= "" and not seen[unit] then
            seen[unit] = true
            local spec = A.ResolveUnitStatusSpec and A.ResolveUnitStatusSpec(unit, normalized) or nil
            local attr
            if spec then
                if wantsX then
                    attr = spec.x
                elseif wantsY then
                    attr = spec.y
                elseif wantsAnchor then
                    attr = spec.anchor
                elseif wantsSize then
                    attr = spec.size
                elseif wantsLayer then
                    attr = spec.layer
                elseif wantsStyle then
                    attr = "raidGroupNameStyle"
                elseif wantsVisibility then
                    attr = spec.show
                end
            end
            local setting = attr and A.Registry and A.Registry:GetSetting(unit .. "." .. tostring(attr)) or nil
            if setting then
                local value
                local relativeDelta
                if wantsLayer then
                    local amount = FirstNumber(normalized) or 1
                    if ContainsAny(normalized, P.RootPhrases[113]) then
                        relativeDelta = -amount
                    elseif ContainsAny(normalized, P.RootPhrases[114]) then
                        relativeDelta = amount
                    end
                end
                if setting.type == "boolean" then
                    value = DetectBoolean(normalized)
                    if value == nil then value = true end
                elseif setting.type == "number" then
                    if relativeDelta == nil then
                        value = FirstNumber(normalized)
                    end
                elseif P.ValueForRegistrySetting then
                    value = P.ValueForRegistrySetting(setting, normalized, normalized)
                end
                if value ~= nil or relativeDelta ~= nil then
                    changes[#changes + 1] = { setting = setting, value = value, relativeDelta = relativeDelta }
                end
            end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Unit Frame Status Detail") or "Unit Frame Status Detail",
        bulkSafe = #changes > 1,
        summary = "Changes a unit-frame status indicator detail option.",
    }
end

local function ParseGroupSimpleBooleanFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[115]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[116]) then
        return nil
    end

    local attr
    local label
    if ContainsAny(normalized, P.RootPhrases[117]) then
        attr = "powerSmoothFill"
        label = "Power Smooth Fill"
    elseif ContainsAny(normalized, P.RootPhrases[118]) then
        attr = "smoothFill"
        label = "Smooth Health Fill"
    elseif ContainsAny(normalized, P.RootPhrases[119]) then
        attr = "ciEnabled"
        label = "Corner Indicators"
    elseif ContainsAny(normalized, P.RootPhrases[120]) then
        attr = "showGroupNumber"
        label = "Group Number"
    else
        return nil
    end

    local value = DetectBoolean(normalized)
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes a simple group-frame visibility/fill toggle.",
    }
end

local function GroupCornerCustomFilterValue(text)
    if ContainsAny(text, P.RootPhrases[121]) then return "HELPFUL|PLAYER" end
    if ContainsAny(text, P.RootPhrases[122]) then return "HARMFUL|PLAYER" end
    if ContainsAny(text, P.RootPhrases[123]) then return "HELPFUL" end
    if ContainsAny(text, P.RootPhrases[124]) then return "HARMFUL" end
    return nil
end

local function GroupCornerCustomValueAfterTo(raw, normalized)
    local source = tostring(raw or "")
    local value = source:match("%s+[Tt][Oo]%s+(.+)$")
        or source:match("%s+[Aa][Ss]%s+(.+)$")
        or tostring(normalized or ""):match("%s+to%s+(.+)$")
        or tostring(normalized or ""):match("%s+as%s+(.+)$")
    value = Trim(value or "")
    if value == "" then return nil end
    return value
end

local function ParseGroupCornerCustomFastShortcut(normalized, raw)
    if not ContainsAny(normalized, P.RootPhrases[125]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[126]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[127]) then return nil end

    local groups = DetectGroups(normalized)
    if #groups ~= 1 then return nil end

    local slot = A.ResolveGroupCornerSlot and A.ResolveGroupCornerSlot(normalized) or nil
    local slotKey = slot and slot.key
    if not slotKey or slotKey == "" then return nil end

    local attr
    local value
    if ContainsAny(normalized, P.RootPhrases[128]) then
        attr = "filter"
        value = GroupCornerCustomFilterValue(tostring(raw or ""):lower() .. " " .. normalized)
    elseif ContainsAny(normalized, P.RootPhrases[129]) then
        attr = "mode"
        if ContainsAny(normalized, P.RootPhrases[130]) then
            value = "missing"
        elseif ContainsAny(normalized, P.RootPhrases[131]) then
            value = "present"
        end
    elseif ContainsAny(normalized, P.RootPhrases[132]) then
        attr = "spells"
        value = GroupCornerCustomValueAfterTo(raw, normalized)
    end
    if not attr or value == nil then return nil end

    local setting = A.Registry and A.Registry:GetSetting("gf_" .. tostring(groups[1]) .. ".ciCustom" .. tostring(slotKey) .. "." .. attr)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Corner Custom " .. tostring(attr),
        summary = "Changes a group-frame corner custom spell indicator field.",
    }
end

local function ParseGroupTextureFastShortcut(normalized, raw)
    if not ContainsAny(normalized, P.RootPhrases[133]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[134]) then return nil end

    local groups = DetectGroups(normalized)
    if #groups ~= 1 then return nil end

    local key
    if ContainsAny(normalized, P.RootPhrases[135]) then
        key = "barScope.gf_" .. tostring(groups[1]) .. ".barBackgroundTexture"
    elseif ContainsAny(normalized, P.RootPhrases[136]) then
        key = "gf_" .. tostring(groups[1]) .. ".barBgTexture"
    elseif ContainsAny(normalized, P.RootPhrases[137]) then
        key = "gf_" .. tostring(groups[1]) .. ".barTexture"
    elseif ContainsAny(normalized, P.RootPhrases[138]) then
        key = "barScope.gf_" .. tostring(groups[1]) .. ".barTexture"
    else
        return nil
    end

    local value = GroupCornerCustomValueAfterTo(raw, normalized)
    if value == nil then return nil end
    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Group Texture",
        summary = "Changes a group-frame texture setting.",
    }
end

local function GroupNameClipSideValue(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local function valueIn(text)
        if not text or text == "" then return nil end
        if ContainsAny(text, P.RootPhrases[139]) then
            return "LEFT"
        end
        if ContainsAny(text, P.RootPhrases[140]) then
            return "RIGHT"
        end
        return nil
    end
    return valueIn(target) or valueIn(normalized)
end

local function ParseGroupNameTextFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[141]) then return nil end
    local hideNameDeadOffline = ContainsAny(normalized, P.RootPhrases[142])
    if ContainsAny(normalized, P.RootPhrases[143]) then
        return nil
    end

    local attr
    local value
    if hideNameDeadOffline then
        attr = "hideNameOnDeadOffline"
        if ContainsAny(normalized, P.RootPhrases[144]) then
            value = false
        elseif ContainsAny(normalized, P.RootPhrases[145]) then
            value = true
        end
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[146]) then
        attr = "nameMaxChars"
        value = FirstNumber(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[147]) then
        attr = "nameShortenEnabled"
        value = DetectBoolean(normalized)
        if value == nil then value = not ContainsAny(normalized, P.RootPhrases[148]) end
    elseif ContainsAny(normalized, P.RootPhrases[149]) then
        attr = "nameClipSide"
        value = GroupNameClipSideValue(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[150]) then
        attr = "nameNoEllipsis"
        if ContainsAny(normalized, P.RootPhrases[151]) then
            value = false
        elseif ContainsAny(normalized, P.RootPhrases[152]) then
            value = true
        end
        if value == nil then value = DetectBoolean(normalized) end
    end
    if not attr then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[153]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Name Text") or "Group Name Text",
        bulkSafe = #changes > 1,
        summary = "Changes group-frame name shortening settings.",
    }
end

local function ParseGroupPowerBarEnabledFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[154]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[155]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[156]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local value = DetectBoolean(normalized)
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. ".powerBarEnabled")
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Power Bar") or "Power Bars",
        bulkSafe = #changes > 1,
        summary = "Changes the group-frame power/resource bar master toggle.",
    }
end

local function ParseGroupRolePowerFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[157]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[158]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[159]) then
        return nil
    end

    local attr
    if ContainsAny(normalized, P.RootPhrases[160]) then
        attr = "powerShowTank"
    elseif ContainsAny(normalized, P.RootPhrases[161]) then
        attr = "powerShowHealer"
    elseif ContainsAny(normalized, P.RootPhrases[162]) then
        attr = "powerShowDamager"
    end
    if not attr then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[163]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local value = DetectBoolean(normalized)
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Role Power") or "Role Power",
        bulkSafe = #changes > 1,
        summary = "Changes which group member roles show power/resource bars.",
    }
end

local function ParseGroupLayoutNumberFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[164]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[165]) then
        return nil
    end

    local attr
    if ContainsAny(normalized, P.RootPhrases[166]) then
        attr = "unitsPerColumn"
    elseif ContainsAny(normalized, P.RootPhrases[167]) then
        attr = "maxColumns"
    elseif ContainsAny(normalized, P.RootPhrases[168]) then
        attr = "powerHeight"
    elseif ContainsAny(normalized, P.RootPhrases[169]) then
        attr = "spacing"
    elseif ContainsAny(normalized, P.RootPhrases[170]) then
        attr = "width"
    elseif ContainsAny(normalized, P.RootPhrases[171]) then
        attr = "height"
    end
    if not attr then return nil end

    local value = FirstNumber(normalized)
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[172]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Layout") or "Group Layout",
        bulkSafe = #changes > 1,
        summary = "Changes group-frame layout numeric settings.",
    }
end

local function GroupGrowthValue(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local function valueIn(text)
        if not text or text == "" then return nil end
        if ContainsAny(text, P.RootPhrases[173]) then return "DOWN" end
        if ContainsAny(text, P.RootPhrases[174]) then return "UP" end
        if ContainsAny(text, P.RootPhrases[175]) then return "RIGHT" end
        if ContainsAny(text, P.RootPhrases[176]) then return "LEFT" end
        return nil
    end
    return valueIn(target) or valueIn(normalized)
end

local function GroupSortModeValue(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local function valueIn(text)
        if not text or text == "" then return nil end
        if ContainsAny(text, P.RootPhrases[177]) then return "GROUP_ROLE" end
        if ContainsAny(text, P.RootPhrases[178]) then return "INDEX" end
        if ContainsAny(text, P.RootPhrases[179]) then return "ROLE" end
        if ContainsAny(text, P.RootPhrases[180]) then return "GROUP" end
        if ContainsAny(text, P.RootPhrases[181]) then return "NAME" end
        return nil
    end
    return valueIn(target) or valueIn(normalized)
end

local function GroupRoleOrderValue(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local function compactOrder(text)
        text = tostring(text or ""):lower()
        local out = {}
        for word in text:gmatch("%w+") do
            if word == "tank" or word == "tanks" then
                out[#out + 1] = "TANK"
            elseif word == "healer" or word == "healers" or word == "heal" then
                out[#out + 1] = "HEALER"
            elseif word == "dps" or word == "damager" or word == "damagers" or word == "damage" then
                out[#out + 1] = "DAMAGER"
            end
            if #out == 3 then break end
        end
        if #out ~= 3 then return nil end
        local seen = {}
        for i = 1, 3 do
            if seen[out[i]] then return nil end
            seen[out[i]] = true
        end
        return table.concat(out, ",")
    end
    return compactOrder(target) or compactOrder(normalized)
end

local function ParseGroupOrderingFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[182]) then return nil end

    local attr
    local value
    if ContainsAny(normalized, P.RootPhrases[183]) then
        attr = "roleOrder"
        value = GroupRoleOrderValue(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[184]) then
        attr = "growth"
        value = GroupGrowthValue(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[185]) then
        attr = "sortMode"
        value = GroupSortModeValue(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[186]) then
        attr = "sortByRole"
        value = DetectBoolean(normalized)
        if value == nil then value = not ContainsAny(normalized, P.RootPhrases[187]) end
    elseif ContainsAny(normalized, P.RootPhrases[188]) then
        attr = "playerFirstInRole"
        value = DetectBoolean(normalized)
        if value == nil then value = not ContainsAny(normalized, P.RootPhrases[189]) end
    elseif ContainsAny(normalized, P.RootPhrases[190]) then
        attr = "preserveRaidGroups"
        value = DetectBoolean(normalized)
        if value == nil then value = not ContainsAny(normalized, P.RootPhrases[191]) end
    end
    if not attr then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[192]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Ordering") or "Group Ordering",
        bulkSafe = #changes > 1,
        summary = "Changes group-frame ordering options.",
    }
end

local function GroupScaleModeValue(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local function valueIn(text)
        if not text or text == "" then return nil end
        if ContainsAny(text, P.RootPhrases[193]) then return "auto" end
        if ContainsAny(text, P.RootPhrases[194]) then return "manual" end
        if ContainsAny(text, P.RootPhrases[195]) then return "off" end
        if ContainsAny(text, P.RootPhrases[196]) then return "manual" end
        return nil
    end
    return valueIn(target) or valueIn(normalized)
end

local function NumberAfterLastConnector(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local value = target and FirstNumber(target) or nil
    if value ~= nil then return value end
    return FirstNumber(normalized)
end

local function ParseGroupScalingFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[197]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[198]) then
        return nil
    end

    local attr
    local value
    if ContainsAny(normalized, P.RootPhrases[199]) then
        attr = "frameScaleMode"
        value = GroupScaleModeValue(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[200]) and FirstNumber(normalized) == nil then
        attr = "frameScaleEnabled"
        value = DetectBoolean(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[201]) then
        attr = "scaleOver25"
        value = NumberAfterLastConnector(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[202]) then
        attr = "scaleAt25"
        value = NumberAfterLastConnector(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[203]) then
        attr = "scaleAt20"
        value = NumberAfterLastConnector(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[204]) then
        attr = "scaleAt10"
        value = NumberAfterLastConnector(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[205]) then
        attr = "frameScaleManual"
        value = NumberAfterLastConnector(normalized)
    end
    if not attr or value == nil then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[206]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Group Frame Scaling") or "Group Frame Scaling",
        bulkSafe = #changes > 1,
        summary = "Changes group-frame scaling settings.",
    }
end

local function ParseGlobalUiScaleFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[207]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[208]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[209]) then return nil end

    local key
    local value
    if ContainsAny(normalized, P.RootPhrases[210]) then
        key = "general.globalUiScaleEnabled"
        value = DetectBoolean(normalized)
        if value == nil then return nil end
    else
        key = "general.globalUiScale"
        value = NumberAfterLastConnector(normalized)
        if value == nil then return nil end
        if value > 1.5 then value = value / 100 end
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Global UI Scale",
        summary = key == "general.globalUiScaleEnabled" and "Changes the global UI scale override toggle." or "Changes the global UI scale value.",
    }
end

local function ParseDashboardScaleFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[211]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[212]) then return nil end

    local key
    local label
    if ContainsAny(normalized, P.RootPhrases[213]) then
        key = "general.slashMenuScale"
        label = "MSUF Menu Scale"
    elseif ContainsAny(normalized, P.RootPhrases[214]) then
        key = "general.msufUiScale"
        label = "MSUF Frame Scale"
    else
        return nil
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    local relativeDelta = P.RelativeNumberDeltaForText and P.RelativeNumberDeltaForText(setting, normalized, 5) or nil
    local value
    if relativeDelta == nil then
        value = FirstNumber(normalized)
        if value ~= nil and value > 1.5 then value = value / 100 end
    end
    if value == nil and relativeDelta == nil then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value, relativeDelta = relativeDelta } },
        label = label,
        summary = "Adjusts Dashboard scale.",
    }
end

local function ParseGlobalFontColorFastShortcut(normalized, raw)
    if not ContainsAny(normalized, P.RootPhrases[215]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[216]) then return nil end
    local setting = A.Registry and A.Registry:GetSetting("general.customFontColor")
    if not setting then return nil end
    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "Global Font Color",
        summary = "Changes the global custom font color.",
    }
end

local CLASS_COLOR_FAST_TOKENS = {
    { "death knight", "DEATHKNIGHT" },
    { "demon hunter", "DEMONHUNTER" },
    { "warrior", "WARRIOR" },
    { "paladin", "PALADIN" },
    { "hunter", "HUNTER" },
    { "rogue", "ROGUE" },
    { "priest", "PRIEST" },
    { "deathknight", "DEATHKNIGHT" },
    { "shaman", "SHAMAN" },
    { "mage", "MAGE" },
    { "warlock", "WARLOCK" },
    { "monk", "MONK" },
    { "druid", "DRUID" },
    { "demonhunter", "DEMONHUNTER" },
    { "evoker", "EVOKER" },
}

local function ParseClassColorFastShortcut(normalized, raw)
    local hasClassColorPhrase = ContainsAny(normalized, P.RootPhrases[217])
    local hasMutationVerb = ContainsAny(normalized, P.RootPhrases[218])
    local token
    for i = 1, #CLASS_COLOR_FAST_TOKENS do
        if HasPhrase(normalized, CLASS_COLOR_FAST_TOKENS[i][1]) then
            token = CLASS_COLOR_FAST_TOKENS[i][2]
            break
        end
    end
    if not token then return nil end
    if not hasClassColorPhrase and not hasMutationVerb then return nil end
    local setting = A.Registry and A.Registry:GetSetting("classColors." .. token)
    if not setting then return nil end
    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "Class Bar Color",
        summary = "Changes a class bar color override.",
    }
end

local function ParseGlobalBarBackgroundFastShortcut(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[220]) then
        if ContainsAny(normalized, P.RootPhrases[221]) then return nil end
        local setting = A.Registry and A.Registry:GetSetting("general.powerBarBgMatchBarColor")
        if not setting then return nil end
        local value = DetectBoolean(normalized)
        if value == nil then value = true end
        return {
            kind = "changes",
            changes = { { setting = setting, value = value } },
            label = setting.label or "Power Background Matches HP",
            summary = "Changes whether the power-bar background follows the HP bar color.",
        }
    end

    if ContainsAny(normalized, P.RootPhrases[222]) then return nil end

    local key
    local value
    if ContainsAny(normalized, P.RootPhrases[223]) then
        key = "general.classBarBgColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    elseif ContainsAny(normalized, P.RootPhrases[224]) then
        key = "general.barBgMatchHPColor"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[225]) then
        key = "general.barBgClassColor"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    else
        return nil
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Bar Background",
        summary = "Changes global bar background color behavior.",
    }
end

local function ParseDarkModeCustomColorFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[226]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[227]) then return nil end
    local value = DetectBoolean(normalized)
    if value == nil then return nil end
    local setting = A.Registry and A.Registry:GetSetting("general.darkBgCustomColor")
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Custom Color In Dark Mode",
        summary = "Changes the dark-mode custom background color toggle.",
    }
end

local GLOBAL_BAR_COLOR_SCOPE_BLOCKERS = {
    "player", "target", "focus", "pet", "boss", "targettarget", "target of target", "focustarget", "focus target",
    "party", "raid", "mythic raid", "mythicraid", "group frame", "group frames",
    "castbar", "cast bar", "class power", "class resource",
}

local function ParseGlobalUnitFrameColorFastShortcut(normalized, raw)
    if ContainsAny(normalized, GLOBAL_BAR_COLOR_SCOPE_BLOCKERS) then return nil end
    if ContainsAny(normalized, P.RootPhrases[228]) then return nil end

    local key
    local value
    if ContainsAny(normalized, P.RootPhrases[229]) then
        key = "general.unifiedBarColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    elseif ContainsAny(normalized, P.RootPhrases[230]) then
        key = "general.darkBarGray"
        value = FirstNumber(normalized)
        if value == nil then return nil end
        if value > 1 then value = value / 100 end
    elseif ContainsAny(normalized, P.RootPhrases[231]) then
        key = "general.powerBarBgColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    elseif ContainsAny(normalized, P.RootPhrases[232]) then
        key = "general.healAbsorbBarColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    elseif ContainsAny(normalized, P.RootPhrases[233]) then
        key = "general.absorbBarColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    elseif ContainsAny(normalized, P.RootPhrases[234]) then
        key = "general.aggroBorderColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    elseif ContainsAny(normalized, P.RootPhrases[235]) then
        key = "general.purgeBorderColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    elseif ContainsAny(normalized, P.RootPhrases[236]) then
        key = "general.barOutlineColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    else
        return nil
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Global Bar Color",
        summary = "Changes global unit-frame bar color behavior.",
    }
end

local function FollowupGradientDirection(normalized)
    if ContainsAny(normalized, P.RootPhrases[237]) then return "RIGHT" end
    if ContainsAny(normalized, P.RootPhrases[238]) then return "LEFT" end
    if ContainsAny(normalized, P.RootPhrases[239]) then return "UP" end
    if ContainsAny(normalized, P.RootPhrases[240]) then return "DOWN" end
    return nil
end

local function LastBarGradientIntent(ctx)
    local bundle = ctx and ctx.lastChangeBundle
    if type(bundle) ~= "table" then return nil end
    local healthValue
    local powerValue
    local direction
    for i = 1, #bundle do
        local item = bundle[i]
        local key = tostring(item and item.key or "")
        local value = item and item.value
        local attr = key:match("^barScope%.[^.]+%.([^.]+)$")
        if key == "general.enableGradient" or attr == "enableGradient" then
            healthValue = value and true or false
        elseif key == "general.enablePowerGradient" or attr == "enablePowerGradient" then
            powerValue = value and true or false
        elseif key == "general.gradientDirection" or attr == "gradientDirection" then
            if value ~= nil then direction = tostring(value) end
        end
    end
    if healthValue == nil and powerValue == nil and direction == nil then return nil end
    return healthValue, powerValue, direction
end

local function ParseLastBarGradientGroupFollowup(normalized, ctx)
    if not ContainsAny(normalized, P.RootPhrases[241]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[242]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[243]) then return nil end

    local healthValue, powerValue, direction = LastBarGradientIntent(ctx)
    if healthValue == nil and powerValue == nil and direction == nil then
        return {
            kind = "unknown",
            status = "ambiguous",
            text = "I can apply a bar-gradient change to group frames, but I need the previous gradient change first so I do not guess. Example: 'turn off bar gradient for all group frames' or 'turn on power bar gradient from right for all group frames'.",
            summary = "Asks for explicit group-frame gradient context.",
        }
    end

    local override = DetectBoolean(normalized)
    if override ~= nil then
        if healthValue ~= nil then healthValue = override end
        if powerValue ~= nil then powerValue = override end
    end
    local overrideDirection = FollowupGradientDirection(normalized)
    if overrideDirection then direction = overrideDirection end

    local scopes = {}
    local function addScope(scope)
        if scope and not scopes[scope] then scopes[scope] = true end
    end
    if ContainsAny(normalized, P.RootPhrases[244]) then addScope("gf_party") end
    if ContainsAny(normalized, P.RootPhrases[245]) then addScope("gf_raid") end
    if ContainsAny(normalized, P.RootPhrases[246]) then
        addScope("gf_party")
        addScope("gf_raid")
    end

    local changes = {}
    local function addChange(key, value)
        local setting = A.Registry and A.Registry:GetSetting(key)
        if setting then changes[#changes + 1] = { setting = setting, value = value } end
    end
    for scope in pairs(scopes) do
        if healthValue ~= nil then addChange("barScope." .. scope .. ".enableGradient", healthValue) end
        if powerValue ~= nil then addChange("barScope." .. scope .. ".enablePowerGradient", powerValue) end
        if direction ~= nil then addChange("barScope." .. scope .. ".gradientDirection", direction) end
    end
    if #changes == 0 then return nil end

    local label
    if healthValue ~= nil and powerValue ~= nil then
        label = "Group Bar Gradients"
    elseif powerValue ~= nil then
        label = "Group Power Bar Gradient"
    elseif healthValue ~= nil then
        label = "Group HP Bar Gradient"
    else
        label = "Group Bar Gradient Direction"
    end
    return {
        kind = "changes",
        changes = changes,
        label = label,
        bulkSafe = #changes > 1,
        summary = "Applies the previous bar-gradient change to group frames.",
    }
end

local function ParseHealthColorGradientFastShortcut(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[247]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[248]) then return nil end

    local key
    local value
    if ContainsAny(normalized, P.RootPhrases[249]) then
        key = "general.healthGradientLow"
    elseif ContainsAny(normalized, P.RootPhrases[250]) then
        key = "general.healthGradientMid"
    elseif ContainsAny(normalized, P.RootPhrases[251]) then
        key = "general.healthGradientHigh"
    else
        key = "general.enableHealthGradient"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end

    if value == nil then
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Health Color Gradient",
        summary = "Changes global health color gradient options.",
    }
end

local function ParseNPCReactionColorFastShortcut(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[252]) then return nil end
    local suffix
    if ContainsAny(normalized, P.RootPhrases[253]) then
        suffix = "friendly"
    elseif ContainsAny(normalized, P.RootPhrases[254]) then
        suffix = "neutral"
    elseif ContainsAny(normalized, P.RootPhrases[255]) then
        suffix = "enemy"
    elseif ContainsAny(normalized, P.RootPhrases[256]) then
        suffix = "dead"
    else
        return nil
    end

    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end
    local setting = A.Registry and A.Registry:GetSetting("npcColors." .. suffix)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "NPC Color",
        summary = "Changes global NPC reaction colors.",
    }
end

local function ParsePetFrameColorFastShortcut(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[257]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[258]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[259]) then return nil end

    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end
    local setting = A.Registry and A.Registry:GetSetting("general.petFrameColor")
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "Pet Frame Color",
        summary = "Changes the global pet frame color.",
    }
end

local function ParsePowerColorTokenFastShortcut(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[260]) then return nil end

    local specs = {
        { "MANA", { "mana power color", "mana color", "color of mana" } },
        { "RAGE", { "rage power color", "rage color", "color of rage" } },
        { "ENERGY", { "energy power color", "energy color", "color of energy", "color energy" } },
        { "FOCUS", { "focus power color", "hunter focus color", "color of focus power" } },
        { "RUNIC_POWER", { "runic power color", "color of runic power" } },
        { "INSANITY", { "insanity power color", "insanity color", "color of insanity" } },
        { "FURY", { "fury power color", "fury color", "color of fury" } },
        { "PAIN", { "pain power color", "pain color", "color of pain" } },
        { "ESSENCE", { "essence power color", "essence color", "color of essence" } },
        { "LUNAR_POWER", { "astral power color", "lunar power color", "color of astral power", "color of lunar power" } },
        { "MAELSTROM", { "maelstrom power color", "maelstrom color", "color of maelstrom" } },
    }
    local token
    for i = 1, #specs do
        if ContainsAny(normalized, specs[i][2]) then
            token = specs[i][1]
            break
        end
    end
    if not token then return nil end

    if ContainsAny(normalized, P.RootPhrases[261]) then
        local action = A.Registry and A.Registry:GetAction("reset_power_color_token")
        return action and {
            kind = "action",
            action = action,
            args = { token = token },
            label = "Reset power bar color",
            summary = "Resets a single Power Bar color.",
        } or nil
    end

    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end
    local setting = A.Registry and A.Registry:GetSetting("general.powerColorOverrides." .. token)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "Power Bar Color",
        summary = "Changes a global power-bar color token.",
    }
end

P.CastbarColorFastTerms = P.CastbarColorFastTerms or {
    blocked = { "what", "which", "where", "why", "help", "explain", "how", "current", "active", "reset", "restore", "default", "defaults" },
    aura = { "aura", "auras", "buff", "buffs", "debuff", "debuffs", "filter", "filters" },
    root = {
        "castbar", "cast bar", "cast color", "cast colour", "interruptible", "non interruptible", "noninterruptible",
        "uninterruptible", "unkickable", "interrupt unavailable", "unavailable fill", "interrupt feedback",
        "interrupted cast", "kick ready", "kick not ready", "spell name color", "spell text color",
    },
    kickNotReady = { "not ready", "notready", "kick cooldown", "interrupt cooldown" },
    kick = { "kick", "interrupt" },
    kickReady = { "kick ready", "interrupt ready" },
    interruptUnavailable = { "interrupt unavailable fill color", "interrupt unavailable fill", "unavailable cast fill color", "unavailable cast fill", "unavailable fill color", "kick unavailable fill color", "castbar unavailable fill color", "cast bar unavailable fill color" },
    interruptFeedback = { "interrupt feedback color", "castbar interrupt feedback color", "cast bar interrupt feedback color", "interrupted cast color", "interrupted castbar color", "interrupted cast bar color", "after interrupt cast color" },
    nonInterruptible = { "non interruptible", "noninterruptible", "not interruptible", "uninterruptible", "unkickable", "not kickable", "cannot interrupt", "cant interrupt" },
    playerOverride = { "player castbar override color", "player cast bar override color", "player castbar custom color", "player cast custom color", "custom player castbar color" },
    text = { "castbar text color", "castbar font color", "cast bar text color", "cast bar font color", "castbar spell name color", "castbar spell text color", "spell name color", "spell text color" },
    border = { "castbar border color", "cast bar border color", "castbar outline color", "cast bar outline color" },
    background = { "castbar background color", "cast bar background color", "castbar bg color", "cast bar bg color" },
    interruptible = { "interruptible cast color", "interruptible castbar color", "interruptible cast bar color", "castbar interruptible color", "cast bar interruptible color", "interrupt castbar color", "interrupt cast bar color", "kickable cast color", "kickable castbar color" },
}

local function ParseCastbarColorFastShortcut(normalized, raw)
    local terms = P.CastbarColorFastTerms
    if ContainsAny(normalized, terms.blocked) then return nil end
    if ContainsAny(normalized, terms.aura) then return nil end
    if not ContainsAny(normalized, terms.root) then return nil end

    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end

    local key
    if ContainsAny(normalized, terms.kickNotReady)
        and ContainsAny(normalized, terms.kick) then
        key = "general.kickNotReadyColor"
    elseif ContainsAny(normalized, terms.kickReady) then
        key = "general.kickReadyColor"
    elseif ContainsAny(normalized, terms.interruptUnavailable) then
        key = "general.castbarInterruptUnavailableColor"
    elseif ContainsAny(normalized, terms.interruptFeedback) then
        key = "general.castbarInterruptFeedbackColor"
    elseif ContainsAny(normalized, terms.nonInterruptible) then
        key = "general.castbarNonInterruptibleColor"
    elseif ContainsAny(normalized, terms.playerOverride) then
        key = "general.playerCastbarOverrideColor"
    elseif ContainsAny(normalized, terms.text) then
        key = "general.castbarFontColor"
    elseif ContainsAny(normalized, terms.border) then
        key = "general.castbarBorderColor"
    elseif ContainsAny(normalized, terms.background) then
        key = "general.castbarBackgroundColor"
    elseif ContainsAny(normalized, terms.interruptible) then
        key = "general.castbarInterruptibleColor"
    end

    local setting = key and A.Registry and A.Registry:GetSetting(key) or nil
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "Castbar Color",
        summary = "Changes a Castbar color option.",
    }
end

local function ParseCastbarOverrideModeFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[270]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[271]) then return nil end

    local value
    if ContainsAny(normalized, P.RootPhrases[272]) then
        value = "CLASS"
    elseif ContainsAny(normalized, P.RootPhrases[273]) then
        value = "CUSTOM"
    end
    if value == nil then return nil end

    local setting = A.Registry and A.Registry:GetSetting("general.playerCastbarOverrideMode")
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Player Castbar Override Mode",
        summary = "Changes whether the player castbar override uses class color or a custom color.",
    }
end

A._ParseMouseoverHighlightFastShortcut = A._ParseMouseoverHighlightFastShortcut or function(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[274]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[275]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[276]) then return nil end

    local key
    local value
    if ContainsAny(normalized, P.RootPhrases[277]) then
        key = "general.highlightColor"
        local extract = P.ExtractColor
        if type(extract) ~= "function" then return nil end
        local r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
        value = { r = r, g = g, b = b, label = label }
    else
        key = "general.highlightEnabled"
        value = DetectBoolean(normalized)
        if value == nil then return nil end
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Mouseover Highlight",
        summary = "Changes the global unit-frame mouseover highlight.",
    }
end

P.GlobalHighlightColorFastSpecs = P.GlobalHighlightColorFastSpecs or {
    { key = "general.bossTargetHighlightColor", label = "Boss Target Highlight Color", terms = { "boss target highlight color", "boss target color", "boss target border highlight color" } },
    { key = "gameplay.combatTimerColor", label = "Combat Timer Text Color", terms = { "combat timer text color", "combat timer color" } },
    { key = "gameplay.combatStateEnterColor", label = "Combat Enter Text Color", terms = { "combat enter text color", "combat enter color", "combat state enter color" } },
    { key = "gameplay.combatStateLeaveColor", label = "Combat Leave Text Color", terms = { "combat leave text color", "combat leave color", "combat state leave color" } },
    { key = "gameplay.crosshairInRangeColor", label = "Crosshair In-Range Color", terms = { "crosshair in range color", "combat crosshair in range color", "melee range in color" } },
    { key = "gameplay.crosshairOutRangeColor", label = "Crosshair Out-of-Range Color", terms = { "crosshair out of range color", "crosshair out-of-range color", "combat crosshair out range color", "melee range out color" } },
    { key = "general.aurasOwnBuffHighlightColor", label = "Own Buff Highlight Color", terms = { "own buff highlight color", "my buff highlight color", "aura own buff color", "own buff aura highlight color", "buff aura highlight color" } },
    { key = "general.aurasOwnDebuffHighlightColor", label = "Own Debuff Highlight Color", terms = { "own debuff highlight color", "my debuff highlight color", "aura own debuff color", "own debuff aura highlight color", "debuff aura highlight color" } },
}

A._ParseGlobalHighlightColorFastShortcut = A._ParseGlobalHighlightColorFastShortcut or function(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[278]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[279]) then return nil end

    local specs = P.GlobalHighlightColorFastSpecs
    local matched
    for i = 1, #(specs or {}) do
        local spec = specs[i]
        if ContainsAny(normalized, spec.terms) then
            matched = spec
            break
        end
    end
    if not matched then return nil end

    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end
    local setting = A.Registry and A.Registry:GetSetting(matched.key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or matched.label,
        summary = "Changes a global MSUF highlight color.",
    }
end

P._EnsureExactColorSettingIndex = P._EnsureExactColorSettingIndex or function(settings)
    settings = settings or {}
    if P._exactColorSettingIndexSettings == settings
        and P._exactColorSettingIndexCount == #settings
        and type(P._exactColorSettingIndex) == "table" then
        return P._exactColorSettingIndex
    end

    local index = { byLength = {}, maxTokens = 0 }
    local function addPhrase(setting, phrase)
        phrase = Normalize(phrase)
        if phrase == "" then return end
        local tokens = {}
        for token in phrase:gmatch("%S+") do tokens[#tokens + 1] = token end
        if #tokens == 0 or #tokens > 12 then return end
        index.byLength[#tokens] = index.byLength[#tokens] or {}
        index.byLength[#tokens][phrase] = index.byLength[#tokens][phrase] or {}
        index.byLength[#tokens][phrase][#index.byLength[#tokens][phrase] + 1] = setting
        if #tokens > index.maxTokens then index.maxTokens = #tokens end
    end

    for i = 1, #settings do
        if i % 64 == 0 and A and type(A.MaybeYield) == "function" then A.MaybeYield() end
        local setting = settings[i]
        if type(setting) == "table" and setting.type == "color" then
            if setting.matchLabel ~= false then addPhrase(setting, setting.label) end
            for j = 1, #(setting.aliases or {}) do addPhrase(setting, setting.aliases[j]) end
            for j = 1, #(setting.exactAliases or {}) do addPhrase(setting, setting.exactAliases[j]) end
        end
    end

    P._exactColorSettingIndexSettings = settings
    P._exactColorSettingIndexCount = #settings
    P._exactColorSettingIndex = index
    return index
end

A._ParseExactColorSettingFastShortcut = A._ParseExactColorSettingFastShortcut or function(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[280]) then return nil end
    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label
    if not ContainsAny(normalized, P.RootPhrases[281]) then
        r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
    end

    if ContainsAny(normalized, P.RootPhrases[282])
        and not ContainsAny(normalized, P.RootPhrases[283])
    then
        local fontAction = ParseFontColorAction and ParseFontColorAction(normalized, raw)
        if fontAction then return fontAction end
    end

    if not ContainsAny(normalized, P.RootPhrases[284]) then
        local powerParsed = A._ParsePowerColorTokenFastShortcut and A._ParsePowerColorTokenFastShortcut(normalized, raw)
        if powerParsed then return powerParsed end
    end

    if not r then
        r, g, b, label = extract(raw or normalized, normalized)
        if not r then return nil end
    end

    local registry = A.Registry
    local settings = registry and type(registry.AllSettings) == "function" and registry:AllSettings() or nil
    if type(settings) ~= "table" or #settings == 0 then return nil end
    local index = P._EnsureExactColorSettingIndex and P._EnsureExactColorSettingIndex(settings) or nil
    if type(index) ~= "table" or (tonumber(index.maxTokens) or 0) <= 0 then return nil end

    local matchText = Normalize(normalized)
    while true do
        local first, rest = matchText:match("^(%S+)%s+(.+)$")
        local second = rest and rest:match("^(%S+)")
        if first and second and first == second and (first == "set" or first == "change" or first == "make") then
            matchText = rest
        else
            break
        end
    end

    local tokens = {}
    for token in matchText:gmatch("%S+") do tokens[#tokens + 1] = token end
    local bestLen = 0
    local best = {}
    local seen = {}
    local maxLen = math.min(tonumber(index.maxTokens) or 0, #tokens)
    for len = maxLen, 1, -1 do
        local bucket = index.byLength and index.byLength[len]
        if bucket then
            for startIndex = 1, (#tokens - len + 1) do
                local phrase = table.concat(tokens, " ", startIndex, startIndex + len - 1)
                local matches = bucket[phrase]
                if matches then
                    for i = 1, #matches do
                        local setting = matches[i]
                        local key = tostring(setting and setting.key or "")
                        local allowed = key ~= ""
                        if allowed and type(P.RegistrySettingMayMatchExactAlias) == "function" then
                            allowed = P.RegistrySettingMayMatchExactAlias(setting, matchText) == true
                        end
                        if allowed and not seen[key] then
                            seen[key] = true
                            best[#best + 1] = setting
                            bestLen = len
                        end
                    end
                end
            end
        end
        if bestLen > 0 then break end
    end
    if #best ~= 1 then return nil end

    local setting = best[1]
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "Color",
        summary = "Changes the exact matched MSUF color setting.",
    }
end

local function ParseScopedBarOutlineColorFastShortcut(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[285]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[286]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[287]) then return nil end

    local units = DetectUnits(normalized)
    local groups = DetectGroups(normalized)
    if (#units + #groups) ~= 1 then return nil end

    local scope
    if #units == 1 then
        scope = tostring(units[1])
    else
        local group = tostring(groups[1])
        scope = group == "party" and "gf_party" or "gf_raid"
    end

    local extract = P.ExtractColor
    if type(extract) ~= "function" then return nil end
    local r, g, b, label = extract(raw or normalized, normalized)
    if not r then return nil end
    local setting = A.Registry and A.Registry:GetSetting("barScope." .. scope .. ".barOutlineColor")
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
        label = setting.label or "Bar Outline Color",
        summary = "Changes a target-specific bar outline color.",
    }
end

local function ParseNPCTypeColorFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[288]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[289]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[290]) then return nil end

    local colorKey
    if ContainsAny(normalized, P.RootPhrases[291]) then
        colorKey = "npcBoss"
    elseif ContainsAny(normalized, P.RootPhrases[292]) then
        colorKey = "npcMiniboss"
    elseif ContainsAny(normalized, P.RootPhrases[293]) then
        colorKey = "npcCaster"
    elseif ContainsAny(normalized, P.RootPhrases[294]) then
        colorKey = "npcMelee"
    elseif ContainsAny(normalized, P.RootPhrases[295]) then
        colorKey = "npcRegular"
    end
    if colorKey then
        local extract = P.ExtractColor
        if type(extract) == "function" then
            local r, g, b, label = extract(normalized, normalized)
            if r then
                local setting = A.Registry and A.Registry:GetSetting("npcColors." .. colorKey)
                if setting then
                    return {
                        kind = "changes",
                        changes = { { setting = setting, value = { r = r, g = g, b = b, label = label } } },
                        label = setting.label or "NPC Type Color",
                        summary = "Changes NPC type colors.",
                    }
                end
            end
        end
    end

    local key
    if ContainsAny(normalized, P.RootPhrases[296]) then
        key = "general.npcTypeToT"
    elseif ContainsAny(normalized, P.RootPhrases[297]) then
        key = "general.npcTypeTarget"
    elseif ContainsAny(normalized, P.RootPhrases[298]) then
        key = "general.npcTypeFocus"
    elseif ContainsAny(normalized, P.RootPhrases[299]) then
        key = "general.npcTypeBoss"
    elseif ContainsAny(normalized, P.RootPhrases[300]) then
        key = "general.npcTypeColorBar"
    elseif ContainsAny(normalized, P.RootPhrases[301]) then
        key = "general.npcTypeColorText"
    else
        key = "general.npcColorMode"
    end

    local value = DetectBoolean(normalized)
    if value == nil then value = true end
    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "NPC Type Colors",
        summary = "Changes NPC type color options.",
    }
end

local function ParseClassResourceHPBarFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[302]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[303]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[304]) then return nil end

    local value = DetectBoolean(normalized)
    if value == nil then value = true end
    local setting = A.Registry and A.Registry:GetSetting("bars.playerHPBarEnabled")
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Class Resources Player HP Bar",
        summary = "Changes the class-resource Player HP bar visibility.",
    }
end

local function ParseGlobalColorModeBooleanFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[305]) then return nil end
    local key
    local value
    if ContainsAny(normalized, P.RootPhrases[309]) then
        if ContainsAny(normalized, P.RootPhrases[310]) then return nil end
        key = "general.playerCastbarOverrideEnabled"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    else
        return nil
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Color Setting",
        summary = "Changes global color mode options.",
    }
end

local function ParseRaidMarkerNumberFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[311]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[312]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[313]) then return nil end

    local attr
    if ContainsAny(normalized, P.RootPhrases[314]) then
        attr = "x"
    elseif ContainsAny(normalized, P.RootPhrases[315]) then
        attr = "y"
    elseif ContainsAny(normalized, P.RootPhrases[316]) then
        attr = "size"
    elseif ContainsAny(normalized, P.RootPhrases[317]) then
        attr = "layer"
    else
        return nil
    end

    local value = NumberAfterLastConnector(normalized)
    if value == nil then return nil end
    local groups = DetectGroups(normalized)
    local units = {}
    if #groups == 0 then units = DetectUnits(normalized) end
    if (#groups + #units) ~= 1 then return nil end

    local key
    if #groups == 1 then
        local groupAttr = attr == "x" and "raidMarkerX"
            or attr == "y" and "raidMarkerY"
            or attr == "size" and "raidMarkerSize"
            or "raidMarkerLayer"
        key = "gf_" .. tostring(groups[1]) .. "." .. groupAttr
    else
        local unitAttr = attr == "x" and "raidMarkerOffsetX"
            or attr == "y" and "raidMarkerOffsetY"
            or attr == "size" and "raidMarkerSize"
            or "raidMarkerLayer"
        key = tostring(units[1]) .. "." .. unitAttr
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Raid Marker",
        summary = "Changes raid-marker numeric settings for the requested frame.",
    }
end

local function ParseExactTextSlotOffsetFastShortcut(normalized)
    if P.LooksLikeExactKeyLookup and P.LooksLikeExactKeyLookup(normalized) then return nil end
    if ContainsAny(normalized, P.RootPhrases[318]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[319]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[320]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[321]) then return nil end

    local tab
    if ContainsAny(normalized, P.RootPhrases[322]) then
        tab = "hp"
    elseif ContainsAny(normalized, P.RootPhrases[323]) then
        tab = "power"
    else
        return nil
    end

    local slot
    if ContainsAny(normalized, P.RootPhrases[324])
        or HasPhrase(normalized, tab .. " left slot")
        or HasPhrase(normalized, "left " .. tab .. " slot")
    then
        slot = "Left"
    elseif ContainsAny(normalized, P.RootPhrases[325])
        or HasPhrase(normalized, tab .. " center slot")
        or HasPhrase(normalized, tab .. " centre slot")
        or HasPhrase(normalized, tab .. " middle slot")
    then
        slot = "Center"
    elseif ContainsAny(normalized, P.RootPhrases[326])
        or HasPhrase(normalized, tab .. " right slot")
        or HasPhrase(normalized, "right " .. tab .. " slot")
    then
        slot = "Right"
    else
        return nil
    end

    local axis
    if ContainsAny(normalized, P.RootPhrases[327]) then axis = "X" end
    if ContainsAny(normalized, P.RootPhrases[328]) then
        if axis then return nil end
        axis = "Y"
    end
    if not axis then return nil end

    local value = NumberAfterLastConnector(normalized)
    if value == nil then return nil end

    local groups = DetectGroups(normalized)
    local units = {}
    if #groups == 0 then units = DetectUnits(normalized) end
    if (#groups + #units) ~= 1 then return nil end

    local attr = (tab == "hp" and "hpText" or "powerText") .. slot .. "Offset" .. axis
    local key = #groups == 1 and ("gf_" .. tostring(groups[1]) .. "." .. attr) or (tostring(units[1]) .. "." .. attr)
    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = "Set text slot offset",
        summary = "Changes the HP/Power left/center/right text-slot offset for the selected unit or group.",
    }
end

local function SpellIndicatorSpecValue(normalized)
    local data = A.GroupFramesRegistry and A.GroupFramesRegistry.SpellIndicatorData
    local aliases = data and data.SPEC_ALIASES or nil
    local values = data and data.SPEC_VALUES or nil
    local displays = data and data.SPEC_DISPLAY_LABELS or nil
    local compact = tostring(normalized or ""):lower():gsub("[^%w]+", "")
    local bestValue
    local bestScore = 0
    if type(aliases) == "table" then
        for alias, value in pairs(aliases) do
            local aliasKey = tostring(alias or ""):lower():gsub("[^%w]+", "")
            if aliasKey ~= "" and compact:find(aliasKey, 1, true) then
                local score = #aliasKey
                if compact == aliasKey then score = score + 10000 end
                if score > bestScore then
                    bestValue = value
                    bestScore = score
                end
            end
        end
    end
    if bestValue then return bestValue end
    if type(values) == "table" then
        for i = 1, #values do
            local value = tostring(values[i] or "")
            local valueKey = value:lower():gsub("[^%w]+", "")
            local displayKey = tostring(displays and displays[value] or ""):lower():gsub("[^%w]+", "")
            if valueKey ~= "" and compact:find(valueKey, 1, true) then return value end
            if displayKey ~= "" and compact:find(displayKey, 1, true) then return value end
        end
    end
    return nil
end

local function ParseGroupSpellIndicatorsEnabledFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[329]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[330]) then
        return nil
    end
    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[331]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[332]) then
        attr = "spellIndicators.layer"
        label = "Spell Indicator Layer"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[333]) then
        attr = "spellIndicators.spec"
        label = "Spell Indicator Spec"
        value = SpellIndicatorSpecValue(normalized)
    else
        attr = "spellIndicators.enabled"
        label = "Spell Indicators"
        value = DetectBoolean(normalized)
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = attr == "spellIndicators.enabled" and "Changes the group-frame Spell Indicators master toggle."
            or "Changes the group-frame Spell Indicators " .. tostring(label) .. " option.",
    }
end

local function ParseGroupFrameColorFastShortcut(normalized, raw)
    if not P.ParseGroupFrameColorShortcut then return nil end
    if P.HasGroupFrameColorIntent and not P.HasGroupFrameColorIntent(normalized) then return nil end
    if ContainsAny(normalized, P.RootPhrases[334]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[335]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[336])
        and not ContainsAny(normalized, P.RootPhrases[337])
    then
        return nil
    end
    if P.GroupColorTargetForText and not P.GroupColorTargetForText(normalized) then return nil end

    return P.ParseGroupFrameColorShortcut(normalized, raw)
end

local function ParseGroupDeadBackgroundFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[338]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[339]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[340]) then
        return nil
    end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[341]) then
        attr = "deadBgOffline"
        label = "Tint Offline Members"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[342]) then
        attr = "deadBgA"
        label = "Dead Background Opacity"
        if ContainsAny(normalized, P.RootPhrases[343]) then return nil end
        value = FirstNumber(normalized)
        if value == nil then return nil end
        if value > 1 then value = value / 100 end
    else
        attr = "deadBgEnabled"
        label = "Dead Background"
        value = DetectBoolean(normalized)
        if value == nil then return nil end
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[344]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = attr == "deadBgA" and "Changes group-frame dead background opacity."
            or attr == "deadBgOffline" and "Changes whether offline group members also get the dead background tint."
            or "Changes the group-frame dead background tint toggle.",
    }
end

local function GroupFrameAnchorTargetValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[345]) then return "FREE" end
    if ContainsAny(normalized, P.RootPhrases[346]) then return "targettarget" end
    if ContainsAny(normalized, P.RootPhrases[347]) then return "focustarget" end
    if ContainsAny(normalized, P.RootPhrases[348]) then return "player" end
    if ContainsAny(normalized, P.RootPhrases[349]) then return "target" end
    if ContainsAny(normalized, P.RootPhrases[350]) then return "focus" end
    return nil
end

local function GroupFrameAnchorPointValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[351]) then return "TOPLEFT" end
    if ContainsAny(normalized, P.RootPhrases[352]) then return "TOPRIGHT" end
    if ContainsAny(normalized, P.RootPhrases[353]) then return "BOTTOMLEFT" end
    if ContainsAny(normalized, P.RootPhrases[354]) then return "BOTTOMRIGHT" end
    if ContainsAny(normalized, P.RootPhrases[355]) then return "TOP" end
    if ContainsAny(normalized, P.RootPhrases[356]) then return "BOTTOM" end
    if ContainsAny(normalized, P.RootPhrases[357]) then return "LEFT" end
    if ContainsAny(normalized, P.RootPhrases[358]) then return "RIGHT" end
    if ContainsAny(normalized, P.RootPhrases[359]) then return "CENTER" end
    return nil
end

local TARGETED_SPELL_TERMS = {
    "targeted spell", "targeted spells", "targeted spell indicator",
    "targeted spell indicators", "targeted spell tracker",
    "targeted spells tracker", "enemy targeted spell",
    "enemy targeted spells", "enemy nameplate cast tracker",
}

local function TargetedSpellPartyScope(normalized)
    if not ContainsAny(normalized, TARGETED_SPELL_TERMS) then return false, false end
    local groups = DetectGroups(normalized)
    local hasParty = false
    local hasOther = false
    for i = 1, #groups do
        if groups[i] == "party" then
            hasParty = true
        elseif groups[i] == "raid" or groups[i] == "mythicraid" then
            hasOther = true
        end
    end
    return hasParty, hasOther
end

local function TargetedSpellModeValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[360]) then return "whenHealing" end
    if ContainsAny(normalized, P.RootPhrases[361]) then return "always" end
    return nil
end

local function TargetedSpellGrowValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[362]) then return "CENTER" end
    if ContainsAny(normalized, P.RootPhrases[363]) then return "RIGHT" end
    if ContainsAny(normalized, P.RootPhrases[364]) then return "LEFT" end
    if ContainsAny(normalized, P.RootPhrases[365]) then return "UP" end
    if ContainsAny(normalized, P.RootPhrases[366]) then return "DOWN" end
    return nil
end

local function ParsePartyTargetedSpellFastShortcut(normalized, raw)
    local hasParty, hasOther = TargetedSpellPartyScope(normalized)
    if hasOther then
        return {
            kind = "answer",
            status = "clarify",
            text = "Targeted Spell Indicators are a Party-only MSUF option. I can change party targeted spell settings, but I should not apply that to Raid or Mythic Raid because those frames do not own this setting.",
            summary = "Explains targeted spell indicator scope.",
        }
    end
    if not hasParty then return nil end

    local attr
    local label
    local value
    local valueLabel
    if ContainsAny(normalized, P.RootPhrases[378]) then
        attr = "targetedSpellsIconSize"
        label = "Targeted Spell Icon Size"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[379]) then
        attr = "targetedSpellsMaxIcons"
        label = "Targeted Spell Max Icons"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[380]) then
        attr = "targetedSpellsLayer"
        label = "Targeted Spell Layer"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[381]) then
        attr = "targetedSpellsAnchor"
        label = "Targeted Spell Anchor"
        value = GroupFrameAnchorPointValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[382]) then
        attr = "targetedSpellsGrow"
        label = "Targeted Spell Growth"
        value = TargetedSpellGrowValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[383]) then
        attr = "targetedSpellsX"
        label = "Targeted Spell X Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[384]) then
        attr = "targetedSpellsY"
        label = "Targeted Spell Y Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[385]) then
        attr = "targetedSpellsMode"
        label = "Targeted Spell Mode"
        value = TargetedSpellModeValue(normalized)
    else
        attr = "targetedSpellsEnabled"
        label = "Targeted Spell Indicators"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end
    if value == nil then return nil end

    local setting = A.Registry and A.Registry:GetSetting("gf_party." .. attr)
    if not setting then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value, valueLabel = valueLabel } },
        label = setting.label or label,
        summary = "Changes Party Targeted Spell Indicator settings.",
    }
end
A._ParsePartyTargetedSpellFastShortcut = ParsePartyTargetedSpellFastShortcut

local function ParseGroupFrameAnchorFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[386]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[387]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[388]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[389]) then
        attr = "anchorPoint"
        label = "Anchor Point"
        value = GroupFrameAnchorPointValue(normalized)
    else
        attr = "anchorToFrame"
        label = "Anchor To"
        value = GroupFrameAnchorTargetValue(normalized)
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = attr == "anchorPoint" and "Changes the group-frame Anchor Point dropdown."
            or "Changes the group-frame Anchor To dropdown.",
    }
end

local function GroupBarColorModeValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[390]) then return "GLOBAL" end
    if ContainsAny(normalized, P.RootPhrases[391]) then return "dark" end
    if ContainsAny(normalized, P.RootPhrases[392]) then return "unified" end
    if ContainsAny(normalized, P.RootPhrases[393]) then return "GRADIENT" end
    if ContainsAny(normalized, P.RootPhrases[394]) then return "CUSTOM" end
    if ContainsAny(normalized, P.RootPhrases[395]) then return "CLASS" end
    return nil
end

local function ParseGroupBarColorModeFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[396]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[397]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[398]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    if ContainsAny(normalized, P.RootPhrases[399]) then
        attr = "healthColorMode"
        label = "Health Color Mode"
    else
        attr = "gfBarMode"
        label = "Bar Color Mode"
    end
    local value = GroupBarColorModeValue(normalized)
    if value == nil then return nil end
    if attr == "healthColorMode" and (value == "GLOBAL" or value == "dark" or value == "unified") then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = attr == "healthColorMode" and "Changes the group health color mode dropdown."
            or "Changes the group bar color mode dropdown.",
    }
end

local function GroupTextDelimiterValue(normalized)
    local target = P.TargetAfterLastConnector and P.TargetAfterLastConnector(normalized) or nil
    local text = target or normalized
    if ContainsAny(text, P.RootPhrases[400]) then return "  " end
    if ContainsAny(text, P.RootPhrases[401]) then return " " end
    if ContainsAny(text, P.RootPhrases[402]) then return " / " end
    if ContainsAny(text, P.RootPhrases[403]) then return " - " end
    if ContainsAny(text, P.RootPhrases[404]) then return " : " end
    if ContainsAny(text, P.RootPhrases[405]) then return " | " end
    if text:find("/", 1, true) then return " / " end
    if text:find("-", 1, true) then return " - " end
    if text:find(":", 1, true) then return " : " end
    if text:find("|", 1, true) then return " | " end
    if normalized:match("%s+to$") or normalized:match("%s+as$") or normalized:match("%s+is$") then return false end
    return nil
end

A._ParseGroupTextDirectFastShortcut = function(normalized)
    if ContainsAny(normalized, P.RootPhrases[406]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[407]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[408]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local numeric = false
    if ContainsAny(normalized, P.RootPhrases[409]) then
        attr = "hpFontSize"
        label = "HP Font Size"
        numeric = true
    elseif ContainsAny(normalized, P.RootPhrases[410]) then
        attr = "powerFontSize"
        label = "Power Font Size"
        numeric = true
    elseif ContainsAny(normalized, P.RootPhrases[411]) then
        attr = "powerTextLeft"
        label = "Left Power Text"
    elseif ContainsAny(normalized, P.RootPhrases[412]) then
        attr = "powerTextCenter"
        label = "Center Power Text"
    elseif ContainsAny(normalized, P.RootPhrases[413]) then
        attr = "powerTextRight"
        label = "Right Power Text"
    elseif ContainsAny(normalized, P.RootPhrases[414]) then
        attr = "textLeft"
        label = "Left HP Text"
    elseif ContainsAny(normalized, P.RootPhrases[415]) then
        attr = "textCenter"
        label = "Center HP Text"
    elseif ContainsAny(normalized, P.RootPhrases[416]) then
        attr = "textRight"
        label = "Right HP Text"
    elseif ContainsAny(normalized, P.RootPhrases[417]) then
        attr = "showPowerText"
        label = "Power Text"
        numeric = false
    elseif ContainsAny(normalized, P.RootPhrases[418]) then
        attr = "showHPText"
        label = "HP Text"
        numeric = false
    end
    if not attr then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            local value
            if setting then
                if numeric then
                    value = FirstNumber(normalized)
                elseif setting.type == "boolean" then
                    value = DetectBoolean(normalized)
                elseif P.ValueForRegistrySetting then
                    value = P.ValueForRegistrySetting(setting, normalized, normalized)
                end
            end
            if setting and value ~= nil then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes group-frame HP/Power text controls.",
    }
end

local function ParseGroupTextFormatFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[419]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[420]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[421]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[422]) then
        attr = "powerTextDelimiter"
        label = "Power Text Delimiter"
        value = GroupTextDelimiterValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[423]) then
        attr = "textDelimiter"
        label = "HP Text Delimiter"
        value = GroupTextDelimiterValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[424]) then
        attr = "powerOffsetX"
        label = "Power Text X Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[425]) then
        attr = "powerOffsetY"
        label = "Power Text Y Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[426]) then
        attr = "powerTextLayer"
        label = "Power Text Layer"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[427]) then
        attr = "hpOffsetX"
        label = "HP Text X Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[428]) then
        attr = "hpOffsetY"
        label = "HP Text Y Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[429]) then
        attr = "textLayer"
        label = "HP Text Layer"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[430]) then
        attr = "hpTextReverse"
        label = "Reverse HP Text"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[431]) then
        attr = "healthTextDecimals"
        label = "Health Text Decimals"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end
    if not attr or value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes group-frame HP/Power text formatting.",
    }
end

local function GroupDispelOverlayTriggerValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[432]) then return "BY_ME" end
    if ContainsAny(normalized, P.RootPhrases[433]) then return "DISPEL_TYPE" end
    if ContainsAny(normalized, P.RootPhrases[434]) then return "ANY_DEBUFF" end
    if ContainsAny(normalized, P.RootPhrases[435]) then return "BORDER" end
    return nil
end

local function GroupDispelOverlayStyleValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[436]) then return "FULL" end
    if ContainsAny(normalized, P.RootPhrases[437]) then return "BOTTOM" end
    if ContainsAny(normalized, P.RootPhrases[438]) then return "TOP" end
    if ContainsAny(normalized, P.RootPhrases[439]) then return "LEFT" end
    if ContainsAny(normalized, P.RootPhrases[440]) then return "RIGHT" end
    return nil
end

function A._HasDispelOverlayAlphaIntent(normalized)
    return ContainsAny(normalized, { "opacity", "alpha", "max", "maximum", "min", "minimum", "half", "50 percent", "50%" })
        and not ContainsAny(normalized, { "style", "detects", "trigger", "detection", "current health", "on health" })
end

function A._HasDispelOverlayImplicitTriggerIntent(normalized)
    return ContainsAny(normalized, { "by me", "byme", "dispellable by me", "any debuff", "all debuffs", "dispel type", "dispeltype" })
        and not ContainsAny(normalized, { "turn on", "enable", "enabled", "on", "turn off", "disable", "disabled", "off" })
end

local function ParseGroupDispelOverlayFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[441]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[442]) then return nil end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[443]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if A._HasDispelOverlayAlphaIntent(normalized) then
        attr = "dispelOverlayAlpha"
        label = "Dispel Overlay Opacity"
        value = A._DispelOverlayAlphaValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[444]) then
        attr = "dispelOverlayOnHealth"
        label = "Dispel Overlay on Current Health"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[445]) then
        attr = "dispelOverlayTrigger"
        label = "Dispel Overlay Detects"
        value = GroupDispelOverlayTriggerValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[446]) then
        attr = "dispelOverlayStyle"
        label = "Dispel Overlay Style"
        value = GroupDispelOverlayStyleValue(normalized)
    elseif GroupDispelOverlayStyleValue(normalized) and DetectBoolean(normalized) == nil then
        attr = "dispelOverlayStyle"
        label = "Dispel Overlay Style"
        value = GroupDispelOverlayStyleValue(normalized)
    elseif A._HasDispelOverlayImplicitTriggerIntent(normalized) then
        attr = "dispelOverlayTrigger"
        label = "Dispel Overlay Detects"
        value = GroupDispelOverlayTriggerValue(normalized)
    else
        attr = "dispelOverlayEnabled"
        label = "Dispel Overlay"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes group-frame dispel overlay options.",
    }
end

local function GroupRangeFadeLayerValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[447]) then return "health" end
    if ContainsAny(normalized, P.RootPhrases[448]) then return "frame" end
    return nil
end

local function ParseGroupRangeFadeFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[449]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[450]) then return nil end
    if not ContainsAny(normalized, P.RootPhrases[451]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[452]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[453]) then
        attr = "offlineAlpha"
        label = "Offline Opacity"
        value = FirstNumber(normalized)
        if value == nil then return nil end
        if value > 1 then value = value / 100 end
    elseif ContainsAny(normalized, P.RootPhrases[454]) then
        if ContainsAny(normalized, P.RootPhrases[455]) then
            attr = "healthFadeThreshold"
            label = "Health Fade Threshold"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[456]) then
            attr = "healthFadeAlpha"
            label = "Health Fade Opacity"
            value = FirstNumber(normalized)
            if value and value > 1 then value = value / 100 end
        else
            attr = "healthFadeEnabled"
            label = "Health Fade"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        end
    elseif ContainsAny(normalized, P.RootPhrases[457]) then
        attr = "rangeFadeLayerMode"
        label = "Range Fade Affects"
        value = GroupRangeFadeLayerValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[458]) or FirstNumber(normalized) ~= nil then
        attr = "rangeFadeAlpha"
        label = "Range Fade Alpha"
        value = FirstNumber(normalized)
        if value == nil then return nil end
        if value > 1 then value = value / 100 end
    else
        attr = "rangeFadeEnabled"
        label = "Range Fade"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes group-frame range, offline, or health fade options.",
    }
end

local function GroupCornerAnchorValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[459]) then return "TOPLEFT" end
    if ContainsAny(normalized, P.RootPhrases[460]) then return "TOPRIGHT" end
    if ContainsAny(normalized, P.RootPhrases[461]) then return "BOTTOMLEFT" end
    if ContainsAny(normalized, P.RootPhrases[462]) then return "BOTTOMRIGHT" end
    if ContainsAny(normalized, P.RootPhrases[463]) then return "TOPLEFT" end
    if ContainsAny(normalized, P.RootPhrases[464]) then return "BOTTOMRIGHT" end
    return nil
end

local function ParseGroupNumberFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[465]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[466]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[467]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[468]) then
        attr = "groupNumberAnchor"
        label = "Group Number Anchor"
        value = GroupCornerAnchorValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[469]) then
        attr = "groupNumberX"
        label = "Group Number X Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[470]) then
        attr = "groupNumberY"
        label = "Group Number Y Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[471]) then
        attr = "groupNumberSize"
        label = "Group Number Size"
        value = FirstNumber(normalized)
    else
        attr = "showGroupNumber"
        label = "Group Number"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes group-frame group-number display settings.",
    }
end

local function GroupAggroModeValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[472]) then return "NON_TANK" end
    if ContainsAny(normalized, P.RootPhrases[473]) then return "HEALER" end
    if ContainsAny(normalized, P.RootPhrases[474]) then return "TANK" end
    if ContainsAny(normalized, P.RootPhrases[475]) then return "ALL" end
    return nil
end

local function ParseGroupHighlightFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[476]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[477]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[478]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[479]) then
        attr = "hlHoverSize"
        label = "Hover Highlight Thickness"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[480]) then
        attr = "aggroMode"
        label = "Aggro Shows For"
        value = GroupAggroModeValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[481]) then
        attr = "aggroEnabled"
        label = "Aggro Border"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[482]) then
        attr = "dispelEnabled"
        label = "Dispel Border"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[483]) then
        attr = "targetIndicator"
        label = "Target Highlight"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[484]) then
        attr = "hlFocusSize"
        label = "Focus Highlight Thickness"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[485]) then
        attr = "hlFocusOffset"
        label = "Focus Highlight Offset"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[486]) then
        attr = "hlFocusEnabled"
        label = "Focus Highlight"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end
    if not attr or value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes group-frame highlight and fallback border settings.",
    }
end

local function ParseFullGroupBorderFastShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[487]) then
        return nil
    end
    if ContainsAny(normalized, P.RootPhrases[488]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[489]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[490]) then
        attr = "groupBorderPadding"
        label = "Group Border Padding"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[491]) then
        attr = "groupBorderA"
        label = "Group Border Opacity"
        value = FirstNumber(normalized)
        if value and value > 1 then value = value / 100 end
    elseif ContainsAny(normalized, P.RootPhrases[492]) then
        attr = "groupBorderSize"
        label = "Group Border Thickness"
        value = FirstNumber(normalized)
    else
        attr = "groupBorderEnabled"
        label = "Group Border"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes the optional border around the whole group-frame block.",
    }
end

local function GroupStatusIconStyleValue(normalized)
    if ContainsAny(normalized, P.RootPhrases[493]) then return "MIDNIGHT" end
    if ContainsAny(normalized, P.RootPhrases[494]) then return "CLASSIC" end
    if ContainsAny(normalized, P.RootPhrases[495]) then return "BLIZZARD" end
    return nil
end

local function ParseGroupStatusIconStyleFastShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[496]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[497]) then
        return nil
    end

    local groups = DetectGroups(normalized)
    if #groups == 0 and ContainsAny(normalized, P.RootPhrases[498]) then
        groups = { "party", "raid", "mythicraid" }
    end
    if #groups == 0 then return nil end

    local attr
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[499])
        and not ContainsAny(normalized, P.RootPhrases[500])
    then
        attr = "useMidnightIcons"
        label = "Use Midnight Status Icons"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    else
        attr = "iconStyle"
        label = "Default Role Icon Style"
        value = GroupStatusIconStyleValue(normalized)
    end
    if value == nil then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #groups do
        local scope = tostring(groups[i])
        if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. attr)
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label) or label,
        bulkSafe = #changes > 1,
        summary = "Changes group-frame status icon style options.",
    }
end
local ParseUnitDetailMove = P.ParseUnitDetailMove
local ParseGroupDetailMove = P.ParseGroupDetailMove
local ParseAmbiguousGroupOutlineBorderShortcut = P.ParseAmbiguousGroupOutlineBorderShortcut
local ParseBorderThicknessShortcut = P.ParseBorderThicknessShortcut
local ParseBarOutlineHighlightShortcut = P.ParseBarOutlineHighlightShortcut
local ParseAbsorbBarShortcut = P.ParseAbsorbBarShortcut
local ParseBarBorderEnumShortcut = P.ParseBarBorderEnumShortcut
local ParseUnitDetailOffsetShortcut = P.ParseUnitDetailOffsetShortcut
local ParseCastbarTextMoveShortcut = P.ParseCastbarTextMoveShortcut
local ParseUnitOpacityShortcut = P.ParseUnitOpacityShortcut
local ParseMenuSelectorState = P.ParseMenuSelectorState
local BuildFollowup = P.BuildFollowup
local BuildBooleanCorrection = P.BuildBooleanCorrection
local ParseSetting = P.ParseSetting

local function LooksLikeAbsorbBarCommand(text)
    text = tostring(text or "")
    return text:find("absorb", 1, true)
        or text:find("heal prediction", 1, true)
        or text:find("incoming heal", 1, true)
end

local function LooksLikeBarBorderEnumCommand(text)
    text = tostring(text or "")
    return text:find("aggro", 1, true)
        or text:find("threat", 1, true)
        or text:find("dispel", 1, true)
        or text:find("dispellable", 1, true)
        or text:find("purge", 1, true)
        or text:find("purgeable", 1, true)
        or text:find("boss target", 1, true)
end

local function LooksLikeBarOutlineHighlightCommand(text)
    text = tostring(text or "")
    return text:find("outline", 1, true)
        or text:find("border", 1, true)
        or text:find("highlight", 1, true)
        or text:find("prio", 1, true)
        or text:find("priority", 1, true)
end

local function LooksLikeAlphaExcludeTextPortraitCommand(text)
    text = tostring(text or "")
    return text:find("keep text", 1, true)
        or text:find("keep portrait", 1, true)
        or text:find("exclude text", 1, true)
        or text:find("exclude portrait", 1, true)
        or text:find("names visible", 1, true)
        or text:find("name visible", 1, true)
        or text:find("text visible", 1, true)
end

local function ParseCastbarInterruptVisibilityShortcut(text)
    if not ContainsAny(text, P.RootPhrases[501]) then return nil end
    if ContainsAny(text, P.RootPhrases[502]) then return nil end
    local value = DetectBoolean(text)
    if value == nil then return nil end
    local units = DetectUnits(text)
    if #units == 0 then return nil end

    local changes = {}
    local Registry = A.Registry
    for i = 1, #units do
        local setting = Registry and Registry:GetSetting(tostring(units[i]) .. ".showInterrupt")
        if setting then changes[#changes + 1] = { setting = setting, value = value } end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = "Cast Bar interrupt visibility",
        bulkSafe = #changes > 1,
        summary = "Changes per-unit Show Cast Bar Interrupt options.",
    }
end

if not P.InitUnsupportedAuraCommand then
    function P.InitUnsupportedAuraCommand()
        if not P.AURA_OUT_OF_SCOPE_TERMS then
            P.AURA_OUT_OF_SCOPE_TERMS = {
                "aura", "auras", "auren",
                "group aura", "group auras", "gruppen aura", "gruppenauren",
            }
        end
        if not P.AURA_BUFF_TERMS then
            P.AURA_BUFF_TERMS = { "buff", "buffs", "debuff", "debuffs" }
        end
        if not P.AURA_BUFF_CONTEXT_TERMS then
            P.AURA_BUFF_CONTEXT_TERMS = {
                "filter", "filters", "blacklist", "whitelist", "preset", "quick setup", "setup",
                "hidden", "hide", "show", "open", "help", "why", "where", "settings",
                "turn", "turn on", "turn off", "on", "off", "enable", "disable", "enabled", "disabled",
                "set", "change", "make", "size", "count", "max", "maximum", "cap", "caps", "limit", "limits",
                "icon", "icons", "per row", "growth", "spacing", "gap", "x offset", "y offset", "layer", "z layer", "frame level",
                "copy", "use", "kopieren", "kopiere", "uebernehme", "uebernehmen",
                "own", "mine", "only mine", "only player", "raid filter", "player filter",
                "stack", "cooldown", "duration", "duration bar", "timer bar", "pandemic",
            }
        end
        if not P.AURA_COPY_COMMAND_TERMS then
            P.AURA_COPY_COMMAND_TERMS = {
                "copy", "use", "kopieren", "kopiere", "uebernehme", "uebernehmen",
                "look like", "looks like", "same as", "the same as", "match", "mirror", "clone",
            }
        end
        if not P.AURA_COPY_EXCLUDE_TERMS then
            P.AURA_COPY_EXCLUDE_TERMS = {
                "not aura", "not auras", "no aura", "no auras",
                "without aura", "without auras", "except aura", "except auras",
                "excluding aura", "excluding auras", "exclude aura", "exclude auras",
                "but not aura", "but not auras", "aber keine aura", "aber keine auren",
                "ohne aura", "ohne auras", "ohne auren",
            }
        end
        if not P.AURA_DEBUFF_STRIPE_TERMS then
            P.AURA_DEBUFF_STRIPE_TERMS = { "debuff stripe", "debuff stripes" }
        end
        if not P.AURA_DISPEL_OVERLAY_TERMS then
            P.AURA_DISPEL_OVERLAY_TERMS = {
                "dispel overlay", "unitframe dispel overlay", "unit frame dispel overlay",
                "debuff overlay", "dispellable overlay", "dispellable debuff overlay",
                "dispel health overlay", "dispellable health overlay",
            }
        end
        if not P.AURA_GROUP_BLACKLIST_SCOPE_TERMS then
            P.AURA_GROUP_BLACKLIST_SCOPE_TERMS = {
                "group aura", "group auras", "group frame aura", "group frame auras",
                "party aura", "party auras", "party buff", "party buffs", "party debuff", "party debuffs",
                "raid aura", "raid auras", "raid buff", "raid buffs", "raid debuff", "raid debuffs",
                "mythic raid aura", "mythic raid auras", "mythic raid buff", "mythic raid buffs", "mythic raid debuff", "mythic raid debuffs",
            }
        end
        if not P.AURA_GROUP_BLACKLIST_TERMS then
            P.AURA_GROUP_BLACKLIST_TERMS = {
                "blacklist", "blacklisted", "whitelist", "whitelisted",
                "block", "blocked", "ignore", "ignored", "exclude", "excluded",
                "hide", "hidden", "allow", "unblacklist", "unblock", "unhide",
            }
        end
        if not P.AURA_GROUP_BLACKLIST_DETAIL_TERMS then
            P.AURA_GROUP_BLACKLIST_DETAIL_TERMS = {
                "spell", "spells", "spell id", "spellid", "spell link",
                "category", "categories", "public category", "public categories",
                "preset", "presets", "exact", "specific",
            }
        end
        if not P.AURA_UNIT_BLACKLIST_SCOPE_TERMS then
            P.AURA_UNIT_BLACKLIST_SCOPE_TERMS = {
                "aura blacklist", "blacklist aura", "blacklist spell", "hidden aura", "hidden auras",
                "player aura", "player auras", "target aura", "target auras",
                "focus aura", "focus auras", "boss aura", "boss auras",
                "shared aura", "shared auras", "unit aura", "unit auras",
            }
        end

        if not P.CopyCommandExcludesAuras then
            function P.CopyCommandExcludesAuras(text)
                if not ContainsAny(text, P.AURA_COPY_COMMAND_TERMS) then return false end
                return ContainsAny(text, P.AURA_COPY_EXCLUDE_TERMS)
            end
        end

        if not P.ParseUnsupportedAuraCommand then
            function P.ParseUnsupportedAuraCommand(text)
                if P.CopyCommandExcludesAuras and P.CopyCommandExcludesAuras(text) then return nil end
                if ContainsAny(text, P.AURA_DEBUFF_STRIPE_TERMS) then return nil end
                if ContainsAny(text, P.AURA_DISPEL_OVERLAY_TERMS) then return nil end
                local groupBlacklistScope = ContainsAny(text, P.AURA_GROUP_BLACKLIST_SCOPE_TERMS)
                local groupBlacklistIntent = ContainsAny(text, P.AURA_GROUP_BLACKLIST_TERMS)
                local groupBlacklistDetail = ContainsAny(text, P.AURA_GROUP_BLACKLIST_DETAIL_TERMS) or text:match("#?%d%d%d+") ~= nil
                if groupBlacklistScope and groupBlacklistIntent and (groupBlacklistDetail or text:find("blacklist", 1, true)) then
                    return {
                        kind = "unsupported",
                        status = "info",
                        summary = "Explains native group aura blacklist limitation.",
                        text = "Group aura exact spell/category blacklist data is legacy read-only in the native 12.1 backend, so I will not edit it as if it could affect live aura display. I can change live group aura filter tokens instead, such as All, Raid, or Dispellable, plus icon size, count, spacing, growth, layer, cooldown text, stack text, duration bars, and private aura options.",
                    }
                end
                local unitBlacklistScope = ContainsAny(text, P.AURA_UNIT_BLACKLIST_SCOPE_TERMS)
                if unitBlacklistScope and groupBlacklistIntent and (groupBlacklistDetail or text:find("blacklist", 1, true)) then
                    return {
                        kind = "unsupported",
                        status = "info",
                        summary = "Explains native unit aura blacklist limitation.",
                        text = "Exact aura blacklist edits are legacy read-only while the native 12.1 backend is active, so I will not edit them as if they could affect live aura display. I can change live Aura Filter options instead, such as player-only, raid, dispellable, crowd-control, exclusive filters, icon size, count, spacing, growth, cooldown text, stack text, and duration bars.",
                    }
                end
                if ContainsAny(text, P.RootPhrases[503])
                    and ContainsAny(text, P.RootPhrases[504])
                then
                    return {
                        kind = "unsupported",
                        status = "info",
                        summary = "Explains dependent target aura limitation.",
                        text = "Target of Target and Focus Target do not expose Auras3 settings in MSUF, so I did not change anything. Their unit pages can still change frame visibility, size, health/text, cast bar, range fade, colors, and position. For aura changes, use Player, Target, Focus, Boss, or group aura scopes, such as 'hide target buffs' or 'show only dispellable raid debuffs'.",
                    }
                end
                if not ContainsAny(text, P.AURA_OUT_OF_SCOPE_TERMS)
                    and not (ContainsAny(text, P.AURA_BUFF_TERMS) and ContainsAny(text, P.AURA_BUFF_CONTEXT_TERMS))
                then
                    return nil
                end
                return {
                    kind = "unsupported",
                    status = "info",
                    summary = "Aura option fallback.",
                    text = "I don't see an MSUF aura option for that request yet. I can change aura icon size, caps/count, X/Y offsets, spacing, growth, layer, cooldown text, stack text, duration bars, live filter tokens, quick presets, private aura options, and group aura copy when those options exist in MSUF. Saved exact SpellID blacklist data can be listed, but it is read-only while the native 12.1 backend is active. Aura areas I can't match will stay as they are.",
                }
            end
        end
    end
end
P.InitUnsupportedAuraCommand()

local function EarlyAuraShortcut(normalized, raw)
    return (P.ParseAuraFilterGuidanceShortcut and P.ParseAuraFilterGuidanceShortcut(normalized))
        or (A.RouterTryAuraFilterStatusShortcut and A.RouterTryAuraFilterStatusShortcut(normalized))
        or (P.ParseAuraScopeOverrideShortcut and P.ParseAuraScopeOverrideShortcut(normalized))
        or (P.ParseAuraDirectSettingShortcut and P.ParseAuraDirectSettingShortcut(normalized, raw))
        or (P.ParseUnitAuraFilterBooleanShortcut and P.ParseUnitAuraFilterBooleanShortcut(normalized))
        or (P.ParseGroupAuraLiveFilterShortcut and P.ParseGroupAuraLiveFilterShortcut(normalized))
        or (P.ParseUnitAuraLiveFilterShortcut and P.ParseUnitAuraLiveFilterShortcut(normalized))
        or (P.ParseAuraCooldownSwipeDirectionShortcut and P.ParseAuraCooldownSwipeDirectionShortcut(normalized))
        or (P.ParseAuraDurationBarShortcut and P.ParseAuraDurationBarShortcut(normalized))
        or (P.ParseAuraDebuffBorderModeShortcut and P.ParseAuraDebuffBorderModeShortcut(normalized))
        or (P.AuraGeometryShortcut and P.AuraGeometryShortcut(normalized))
        or (P.ParseGroupAuraRootSettingShortcut and P.ParseGroupAuraRootSettingShortcut(normalized))
        or (P.ParseGroupAuraVisibilityShortcut and P.ParseGroupAuraVisibilityShortcut(normalized))
end

local function CopyRequest(normalized)
    return ParseGroupCopy(normalized)
        or (P.ParseUnsupportedMixedCopy and P.ParseUnsupportedMixedCopy(normalized))
        or ParseCopy(normalized)
end

local function ExactTextDetailShortcut(normalized)
    return (A._ParseTextLayerShortcut and A._ParseTextLayerShortcut(normalized))
        or (A._ParseTextSlotDropdownShortcut and A._ParseTextSlotDropdownShortcut(normalized))
        or (A._ParseTextDetailExactOffset and A._ParseTextDetailExactOffset(normalized))
end

local GLOBAL_STATUS_TEXT_STATES = {
    {
        key = "showGhost",
        label = "Dead Text Shows Ghost Units",
        terms = { "dead text ghost units", "status text ghost units", "show ghost text", "ghost text", "ghost status text" },
    },
    {
        key = "showAFK",
        label = "Dead Text Shows AFK Units",
        terms = { "dead text afk", "status text afk", "show afk text", "afk text", "afk status text", "away text" },
    },
    {
        key = "showDND",
        label = "Dead Text Shows DND Units",
        terms = { "dead text dnd", "status text dnd", "show dnd text", "dnd text", "dnd status text" },
    },
    {
        key = "showDead",
        label = "Dead Text Shows Dead/Offline Units",
        terms = {
            "dead text dead units", "status text dead units", "show dead text for dead",
            "offline text", "offline status text", "disconnected text", "connection text",
        },
    },
}

local function ParseGlobalStatusTextStateShortcut(text)
    if ContainsAny(text, P.RootPhrases[505]) then return nil end
    local value = DetectBoolean and DetectBoolean(text) or nil
    if value == nil then return nil end
    for i = 1, #GLOBAL_STATUS_TEXT_STATES do
        local spec = GLOBAL_STATUS_TEXT_STATES[i]
        if ContainsAny(text, spec.terms) then
            local Registry = A.Registry
            local setting = Registry and Registry.GetSetting and Registry:GetSetting("general.statusIndicators." .. spec.key)
            return setting and {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = spec.label,
                summary = value and "Enables a global Dead Text runtime state." or "Disables a global Dead Text runtime state.",
            } or nil
        end
    end
    return nil
end

A._ParseGlobalStatusIconsStyleFastShortcut = function(text)
    if not ContainsAny(text, P.RootPhrases[506]) then
        return nil
    end
    if ContainsAny(text, P.RootPhrases[507]) then return nil end
    local setting = A.Registry and A.Registry:GetSetting("general.statusIconsUseMidnightStyle")
    if not setting then return nil end
    local value = DetectBoolean and DetectBoolean(text) or nil
    if value == nil then value = not ContainsAny(text, P.RootPhrases[508]) end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Status Icons Midnight Style",
        summary = "Changes the global unit-frame status icon Midnight style.",
    }
end

A._ParseUnitAnchorPointFastShortcut = function(text)
    if not ContainsAny(text, P.RootPhrases[509]) then return nil end
    if ContainsAny(text, P.RootPhrases[510]) then
        return nil
    end
    local units = DetectUnits and DetectUnits(text) or {}
    if #units == 0 then return nil end
    local changes = {}
    local seen = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        if unit ~= "" and not seen[unit] then
            seen[unit] = true
            local setting = A.Registry and A.Registry:GetSetting(unit .. ".point")
            local value = setting and P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, text, text) or nil
            if setting and value ~= nil then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Anchor Point") or "Anchor Point",
        bulkSafe = #changes > 1,
        summary = "Changes unit-frame anchor point.",
    }
end

A._ParseBossTargetHighlightFastShortcut = function(text)
    if not ContainsAny(text, P.RootPhrases[511]) then return nil end
    if ContainsAny(text, P.RootPhrases[512]) then return nil end
    local setting = A.Registry and A.Registry:GetSetting("general.bossTargetHighlightEnabled")
    if not setting then return nil end
    local value = DetectBoolean and DetectBoolean(text) or nil
    if value == nil then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Boss Target Highlight",
        summary = "Changes Boss Target Highlight visibility.",
    }
end

A._ParseHumanIndicatorMoveFastShortcut = function(text)
    if not ContainsAny(text, P.RootPhrases[513]) then return nil end
    if ContainsAny(text, P.RootPhrases[514]) then return nil end
    local direction
    if ContainsAny(text, P.RootPhrases[515]) then
        direction = "right"
    elseif ContainsAny(text, P.RootPhrases[516]) then
        direction = "left"
    elseif ContainsAny(text, P.RootPhrases[517]) then
        direction = "up"
    elseif ContainsAny(text, P.RootPhrases[518]) then
        direction = "down"
    end
    if not direction then return nil end

    local axis = (direction == "left" or direction == "right") and "x" or "y"
    local amount = FirstNumber(text) or 10
    if direction == "left" or direction == "down" then amount = -amount end

    local unitSpecs = {
        { terms = { "raid group name", "raid group indicator", "raid group", "group number in name", "group number indicator", "subgroup indicator" }, x = "raidGroupNameOffsetX", y = "raidGroupNameOffsetY", label = "Raid Group Name" },
        { terms = { "raid marker", "raid marker icon", "raid marker indicator", "target marker", "target marker icon", "target marker indicator" }, x = "raidMarkerOffsetX", y = "raidMarkerOffsetY", label = "Raid Marker" },
        { terms = { "leader icon", "leader indicator", "assist icon", "assist indicator", "leader assist icon", "leader assist indicator" }, x = "leaderIconOffsetX", y = "leaderIconOffsetY", label = "Leader/Assist Icon" },
        { terms = { "level", "level indicator", "level text" }, x = "levelIndicatorOffsetX", y = "levelIndicatorOffsetY", label = "Level Indicator" },
        { terms = { "elite icon", "rare icon", "elite indicator", "rare indicator", "elite rare icon" }, x = "eliteIconOffsetX", y = "eliteIconOffsetY", label = "Elite / Rare Icon" },
        { terms = { "dead text", "status text", "offline text", "dead indicator", "offline indicator" }, x = "statusTextOffsetX", y = "statusTextOffsetY", label = "Dead Text" },
        { terms = { "combat indicator", "combat state indicator", "combat status indicator", "combat icon" }, x = "combatStateIndicatorOffsetX", y = "combatStateIndicatorOffsetY", label = "Combat Indicator" },
        { terms = { "rested indicator", "resting indicator", "rested icon", "resting icon" }, x = "restedStateIndicatorOffsetX", y = "restedStateIndicatorOffsetY", label = "Rested Indicator" },
        { terms = { "incoming rez", "incoming rez indicator", "incoming resurrection", "incoming resurrection indicator", "resurrection indicator", "resurrection icon", "rez indicator" }, x = "incomingResIndicatorOffsetX", y = "incomingResIndicatorOffsetY", label = "Incoming Rez Indicator" },
        { terms = { "pvp flag", "pvp indicator", "pvp icon", "war mode indicator", "flagged indicator" }, x = "pvpIndicatorOffsetX", y = "pvpIndicatorOffsetY", label = "PvP Flag Indicator" },
    }
    local groupSpecs = {
        { terms = { "ready check", "ready check icon", "ready check indicator", "ready icon", "ready indicator" }, x = "readyCheckX", y = "readyCheckY", label = "Ready Check" },
        { terms = { "role icon", "role indicator", "role symbol", "tank icon", "healer icon", "dps icon" }, x = "roleIconX", y = "roleIconY", label = "Role Icon" },
        { terms = { "leader icon", "leader indicator", "leader symbol" }, x = "leaderIconX", y = "leaderIconY", label = "Leader Icon" },
        { terms = { "assist icon", "assistant icon", "assist indicator", "assistant indicator" }, x = "assistIconX", y = "assistIconY", label = "Assist Icon" },
        { terms = { "raid marker", "raid marker icon", "raid marker indicator", "target marker", "target marker icon", "target marker indicator" }, x = "raidMarkerX", y = "raidMarkerY", label = "Raid Marker" },
        { terms = { "summon icon", "summon indicator", "summon symbol" }, x = "summonX", y = "summonY", label = "Summon Icon" },
        { terms = { "resurrect icon", "resurrect indicator", "resurrection icon", "resurrection indicator", "incoming resurrection", "incoming rez", "rez icon", "rez indicator" }, x = "resurrectX", y = "resurrectY", label = "Resurrection Icon" },
        { terms = { "phase icon", "phasing icon", "phase indicator", "phasing indicator" }, x = "phaseX", y = "phaseY", label = "Phase Icon" },
        { terms = { "pvp flag", "pvp icon", "pvp indicator", "war mode indicator", "flagged indicator" }, x = "pvpIconX", y = "pvpIconY", label = "PvP Icon" },
        { terms = { "dead text", "status text", "offline text", "offline indicator" }, x = "statusOffsetX", y = "statusOffsetY", label = "Status Text" },
        { terms = { "ghost text", "ghost indicator", "ghost status" }, x = "statusGhostOffsetX", y = "statusGhostOffsetY", label = "Ghost Text" },
        { terms = { "afk text", "dnd text", "afk indicator", "dnd indicator", "away text" }, x = "statusAFKOffsetX", y = "statusAFKOffsetY", label = "AFK/DND Text" },
    }
    local function matchSpec(specs)
        for i = 1, #specs do
            if ContainsAny(text, specs[i].terms) then return specs[i] end
        end
        return nil
    end

    local units = DetectUnits(text)
    local groups = DetectGroups(text)
    local unitSpec = matchSpec(unitSpecs)
    local groupSpec = matchSpec(groupSpecs)
    local changes = {}
    local label
    if #units > 0 and unitSpec
        and (#groups == 0 or ContainsAny(text, P.RootPhrases[519]))
    then
        local spec = unitSpec
        if not spec then return nil end
        local key = axis == "x" and spec.x or spec.y
        local seen = {}
        for i = 1, #units do
            local unit = tostring(units[i])
            if unit ~= "" and not seen[unit] then
                seen[unit] = true
                local setting = A.Registry and A.Registry:GetSetting(unit .. "." .. key)
                if setting then changes[#changes + 1] = { setting = setting, relativeDelta = amount, direction = direction } end
            end
        end
        label = spec.label
    elseif #groups > 0 and groupSpec and #units == 0 then
        local spec = groupSpec
        if not spec then return nil end
        local key = axis == "x" and spec.x or spec.y
        local seen = {}
        for i = 1, #groups do
            local scope = tostring(groups[i])
            if (scope == "party" or scope == "raid" or scope == "mythicraid") and not seen[scope] then
                seen[scope] = true
                local setting = A.Registry and A.Registry:GetSetting("gf_" .. scope .. "." .. key)
                if setting then changes[#changes + 1] = { setting = setting, relativeDelta = amount, direction = direction } end
            end
        end
        label = spec.label
    else
        return nil
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or label or "Indicator Position") or (label or "Indicator Position"),
        bulkSafe = #changes > 1,
        summary = "Moves the requested unit/group-frame indicator with its X/Y offset.",
    }
end

local function ParseClassResourceFillFastShortcut(text)
    if not ContainsAny(text, P.RootPhrases[520]) then return nil end
    if ContainsAny(text, P.RootPhrases[521]) and not ContainsAny(text, P.RootPhrases[522]) then
        local direction = DetectDirection and DetectDirection(text, {}) or nil
        local key
        local fallback = 10
        if ContainsAny(text, P.RootPhrases[523]) then
            key = "bars.classPowerFrameLevelOffset"
            fallback = 1
        elseif direction == "left" or direction == "right" or ContainsAny(text, P.RootPhrases[524]) then
            key = "bars.classPowerOffsetX"
        elseif direction == "up" or direction == "down" or ContainsAny(text, P.RootPhrases[525]) then
            key = "bars.classPowerOffsetY"
        end
        local setting = key and A.Registry and A.Registry:GetSetting(key) or nil
        if setting then
            local relativeDelta = P.RelativeNumberDeltaForText and P.RelativeNumberDeltaForText(setting, text, fallback) or nil
            local value
            if relativeDelta == nil then value = FirstNumber and FirstNumber(text) or nil end
            if value ~= nil or relativeDelta ~= nil then
                return {
                    kind = "changes",
                    changes = { { setting = setting, value = value, relativeDelta = relativeDelta } },
                    label = setting.label or "Class Resource Position",
                    summary = "Moves or layers the Class Resource frame.",
                }
            end
        end
    end
    if ContainsAny(text, P.RootPhrases[526]) then
        return nil
    end
    if not ContainsAny(text, P.RootPhrases[527]) then return nil end

    local value
    local boolValue = DetectBoolean and DetectBoolean(text) or nil
    if ContainsAny(text, P.RootPhrases[528]) then
        value = false
    elseif ContainsAny(text, P.RootPhrases[529]) then
        value = true
    elseif ContainsAny(text, P.RootPhrases[530]) then
        value = boolValue
        if value == nil and ContainsAny(text, P.RootPhrases[531]) then value = true end
        if value == nil and ContainsAny(text, P.RootPhrases[532]) then value = false end
    end
    if value == nil then return nil end

    local setting = A.Registry and A.Registry:GetSetting("bars.classPowerFillReverse")
    return setting and {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Class Resource Reverse Fill",
        summary = "Changes the Class Resource fill direction.",
    } or nil
end

local function ParseAuraBlacklistPresetFastShortcut(text)
    if not ContainsAny(text, P.RootPhrases[533]) then return nil end
    if ContainsAny(text, P.RootPhrases[534]) then return nil end
    if not ContainsAny(text, P.RootPhrases[535]) then return nil end
    local setting = A.Registry and A.Registry:GetSetting("menu.auraBlacklistPreset")
    if not setting then return nil end
    local value = P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, text, text) or nil
    if value == nil then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Aura Blacklist Preset",
        summary = "Changes the aura blacklist preset selector.",
    }
end

local function ParseDispelBorderTriggerFastShortcut(text)
    if not ContainsAny(text, P.RootPhrases[536]) then return nil end
    if ContainsAny(text, P.RootPhrases[537]) then return nil end
    if #(DetectUnits and DetectUnits(text) or {}) > 0 or #(DetectGroups and DetectGroups(text) or {}) > 0 then return nil end
    local setting = A.Registry and A.Registry:GetSetting("general.dispelBorderTrigger")
    if not setting then return nil end
    local value = P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, text, text) or nil
    if value == nil then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Dispel Border Detects",
        summary = "Changes which dispellable auras can trigger the global dispel border.",
    }
end

function A._DispelBorderTriggerValue(setting, text)
    local value = GroupDispelOverlayTriggerValue(text)
    if value == "BORDER" then value = nil end
    if value == nil and setting and P.EnumValueForText then value = P.EnumValueForText(setting, text) end
    if value == nil and setting and P.ValueForRegistrySetting then value = P.ValueForRegistrySetting(setting, text, text) end
    return value
end

function A._ParseScopedDispelBorderTriggerFastShortcut(text)
    if not ContainsAny(text, P.RootPhrases[536]) then return nil end
    if ContainsAny(text, P.RootPhrases[537]) then return nil end
    local units = DetectUnits and DetectUnits(text) or {}
    if #units == 0 then return nil end

    local changes = {}
    local seen = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        if unit ~= "" and not seen[unit] then
            seen[unit] = true
            local setting = A.Registry and A.Registry:GetSetting("barScope." .. unit .. ".dispelBorderTrigger")
            local value = setting and A._DispelBorderTriggerValue(setting, text) or nil
            if setting and value ~= nil then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Dispel Border Detects") or "Dispel Border Detects",
        bulkSafe = #changes > 1,
        summary = "Changes which dispellable auras can trigger scoped unit-frame dispel borders.",
    }
end

local function ParseUnitPortraitShapeFastShortcut(text)
    if not ContainsAny(text, P.RootPhrases[538]) then return nil end
    if ContainsAny(text, P.RootPhrases[539]) then return nil end
    local units = DetectUnits and DetectUnits(text) or {}
    if #units == 0 then return nil end
    local changes = {}
    local seen = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        if unit ~= "" and not seen[unit] then
            seen[unit] = true
            local setting = A.Registry and A.Registry:GetSetting(unit .. ".portraitShape")
            local value = setting and P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, text, text) or nil
            if setting and value ~= nil then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = #changes == 1 and (changes[1].setting.label or "Portrait Shape") or "Portrait Shape",
        bulkSafe = #changes > 1,
        summary = "Changes unit-frame portrait shape.",
    }
end

local function ParseClassPowerTextOffsetShortcut(text)
    if not ContainsAny(text, P.RootPhrases[540]) then return nil end
    if ContainsAny(text, P.RootPhrases[541]) then return nil end
    if not ContainsAny(text, P.RootPhrases[542]) then return nil end
    local axis
    if ContainsAny(text, P.RootPhrases[543]) or HasPhrase and HasPhrase(text, "x") then
        axis = "X"
    elseif ContainsAny(text, P.RootPhrases[544]) or HasPhrase and HasPhrase(text, "y") then
        axis = "Y"
    end
    if not axis then return nil end

    local Registry = A.Registry
    local setting = Registry and Registry.GetSetting and Registry:GetSetting("bars.classPowerTextOffset" .. axis)
    if not setting then return nil end
    local relativeDelta = P.RelativeNumberDeltaForText and P.RelativeNumberDeltaForText(setting, text, 1) or nil
    local value
    if relativeDelta == nil then
        value = FirstNumber and FirstNumber(text) or nil
        if value == nil then return nil end
    end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value, relativeDelta = relativeDelta } },
        label = setting.label or ("Class Resource Text Offset " .. axis),
        summary = "Changes the Class Resource text X/Y offset.",
    }
end

local UNIT_ROOT_FRAME_DETAIL_BLOCKERS = {
    "name", "names", "text", "hp", "health", "power", "mana", "castbar", "cast bar",
    "buff", "buffs", "debuff", "debuffs", "aura", "auras", "icon", "icons",
    "indicator", "indicators", "portrait", "range fade", "alpha", "opacity",
    "width", "height", "size", "anchor", "position", "move", "offset",
    "gradient", "gradients", "bar gradient", "bar gradients", "gradient direction",
    "load condition", "load conditions", "visibility condition", "when", "while",
    "in group", "grouped", "solo", "mounted", "vehicle", "instance", "combat",
    "resting", "stealth", "housing",
}

local function UnitRootVisibilityValue(text)
    if ContainsAny(text, P.RootPhrases[545]) then return false end
    if ContainsAny(text, P.RootPhrases[546]) then return true end
    return DetectBoolean and DetectBoolean(text) or nil
end

local function UnitRootLabel(unit)
    if A and type(A.DisplayUnitLabel) == "function" then return A.DisplayUnitLabel(unit) end
    if unit == "targettarget" then return "Target of Target" end
    if unit == "focustarget" then return "Focus Target" end
    return tostring(unit or "Unit"):gsub("^%l", string.upper)
end

local function ParseUnitRootVisibilityShortcut(text)
    if not ContainsAny(text, P.RootPhrases[547]) then return nil end
    if ContainsAny(text, UNIT_ROOT_FRAME_DETAIL_BLOCKERS) then return nil end
    local value = UnitRootVisibilityValue(text)
    if value == nil then return nil end
    local units = DetectUnits and DetectUnits(text) or {}
    if #units == 0 then return nil end
    local Registry = A.Registry
    local changes = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        local setting = Registry and Registry.GetSetting and Registry:GetSetting(unit .. ".enabled")
        if setting then changes[#changes + 1] = { setting = setting, value = value } end
    end
    if #changes == 0 then return nil end
    local label = #changes == 1 and (UnitRootLabel(units[1]) .. " Frame Enabled") or "Unit Frames Enabled"
    return {
        kind = "changes",
        changes = changes,
        label = label,
        bulkSafe = #changes > 1,
        summary = "Changes root Unit Frame visibility.",
    }
end

local function ParseGroupDebuffStripeShortcut(text, raw)
    if not ContainsAny(text, P.RootPhrases[548]) then return nil end
    if ContainsAny(text, P.RootPhrases[549]) then return nil end

    local groups = DetectGroups and DetectGroups(text) or {}
    if #groups == 0 then return nil end

    local attr
    local title = "Group Debuff Stripe"
    if ContainsAny(text, P.RootPhrases[550]) then
        attr = "debuffStripeEdge"
        title = "Debuff Stripe Edge"
    elseif ContainsAny(text, P.RootPhrases[551]) then
        attr = "debuffStripeAlpha"
        title = "Debuff Stripe Opacity"
    elseif ContainsAny(text, P.RootPhrases[552]) then
        attr = "debuffStripeHeight"
        title = "Debuff Stripe Height"
    else
        attr = "debuffStripeEnabled"
    end

    local changes = {}
    local Registry = A.Registry
    for i = 1, #groups do
        local setting = Registry and Registry:GetSetting("gf_" .. tostring(groups[i]) .. "." .. attr)
        if setting then
            local value
            if setting.type == "boolean" then
                value = DetectBoolean(text)
            elseif setting.type == "enum" then
                value = P.EnumValueForText and P.EnumValueForText(setting, text) or nil
            elseif setting.type == "number" then
                value = A._NumberValueForText and A._NumberValueForText(setting, text) or FirstNumber(text)
                if setting.percent == true and value and value > 1 then value = value / 100 end
            end
            if value ~= nil then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end

    if #changes == 0 then return nil end
    local concrete = true
    if P.GroupShortcutScopes then
        local scopes, scopedConcrete = P.GroupShortcutScopes(text)
        concrete = scopedConcrete
        if type(scopes) ~= "table" or #scopes == 0 then concrete = true end
    end
    if P.GroupShortcutResponse then
        return P.GroupShortcutResponse(text, changes, concrete, title, "Changes Group Frame Debuff Stripe settings.")
    end
    return {
        kind = "changes",
        changes = changes,
        label = title,
        bulkSafe = #changes > 1,
        summary = "Changes Group Frame Debuff Stripe settings.",
    }
end

--- Pipeline order matters. Specific workflows and follow-up answers must win
--- before broad registry matching, otherwise "yes", copy/profile flows, and
--- exact assistant keys can be swallowed by generic setting aliases.
function A._ParsePipelineWorkflow(normalized, raw, ctx)
    local result = ParseGuidedSetupFollowup(normalized, ctx); if result then return result end
    result = A._ParseFollowupAnswer(normalized, ctx); if result then return result end
    result = BuildFollowup(normalized, ctx); if result then return result end
    result = P.BuildContinuationFollowup and P.BuildContinuationFollowup(normalized, ctx); if result then return result end
    result = BuildBooleanCorrection(normalized, ctx); if result then return result end
    result = P.ParseFrameRecovery and P.ParseFrameRecovery(normalized); if result then return result end
    result = P.ParseBroadHumanAnchorTargetAnswer and P.ParseBroadHumanAnchorTargetAnswer(normalized, raw); if result then return result end
    result = ParseWorkflowLifecycle(normalized); if result then return result end
    result = P.ParseProfileRepairShortcut and P.ParseProfileRepairShortcut(normalized); if result then return result end
    result = ParseGroupCornerIndicatorReset and ParseGroupCornerIndicatorReset(normalized); if result then return result end
    result = ParseGroupCornerIndicatorSetting and ParseGroupCornerIndicatorSetting(normalized, raw); if result then return result end
    result = ParseDiagnostic(normalized); if result then return result end
    result = CopyRequest(normalized); if result then return result end
    result = ParseProfileStagingState(normalized, raw); if result then return result end
    result = ParseProfile(normalized, raw); if result then return result end
    result = P.ParseBossFramePreviewShortcut and P.ParseBossFramePreviewShortcut(normalized); if result then return result end
    result = P.ParseGroupStatusIconDetail and P.ParseGroupStatusIconDetail(normalized); if result then return result end
    result = P.ParseExactRegistryKeyShortcut and P.ParseExactRegistryKeyShortcut(normalized, raw); if result then return result end
    result = P.ParseExactActionKeyShortcut and P.ParseExactActionKeyShortcut(normalized, raw); if result then return result end
    result = P.ParseRegistryActionAliasShortcut and P.ParseRegistryActionAliasShortcut(normalized, raw); if result then return result end
    result = P.ParseRegistryPriorityShortcut and P.ParseRegistryPriorityShortcut(normalized, raw); if result then return result end
    result = P.ParseRegistryExactAliasShortcut and P.ParseRegistryExactAliasShortcut(normalized, raw); if result then return result end
    result = A._ParseClassPowerDetachedPlayerPowerShortcut and A._ParseClassPowerDetachedPlayerPowerShortcut(normalized, raw); if result then return result end
    result = ParseClassPowerRootToggle and ParseClassPowerRootToggle(normalized); if result then return result end
    result = A._ParseClassPowerWidthModeShortcut and A._ParseClassPowerWidthModeShortcut(normalized); if result then return result end
    result = A._ParseClassPowerVisibilityShortcut and A._ParseClassPowerVisibilityShortcut(normalized); if result then return result end
    result = A._ParseClassPowerAnchorShortcut and A._ParseClassPowerAnchorShortcut(normalized); if result then return result end
    result = A._ParseClassPowerPlacementShortcut and A._ParseClassPowerPlacementShortcut(normalized); if result then return result end
    result = A._ParseClassPowerDisplayStyleShortcut and A._ParseClassPowerDisplayStyleShortcut(normalized); if result then return result end
    result = A._ParseClassPowerShapeShortcut and A._ParseClassPowerShapeShortcut(normalized); if result then return result end
    result = A._ParseClassPowerFillDirectionShortcut and A._ParseClassPowerFillDirectionShortcut(normalized); if result then return result end
    result = P.ParseGroupFrameFillDirectionShortcut and P.ParseGroupFrameFillDirectionShortcut(normalized); if result then return result end
    result = A._ParseClassPowerTextSizeShortcut and A._ParseClassPowerTextSizeShortcut(normalized); if result then return result end
    result = A._ParseClassPowerSizeShortcut and A._ParseClassPowerSizeShortcut(normalized); if result then return result end
    result = A._ParseClassPowerSeparatorShortcut and A._ParseClassPowerSeparatorShortcut(normalized); if result then return result end
    result = A._ParseClassPowerGapShortcut and A._ParseClassPowerGapShortcut(normalized); if result then return result end
    result = A._ParseClassPowerBackgroundShortcut and A._ParseClassPowerBackgroundShortcut(normalized); if result then return result end
    result = A._ParseClassPowerMoveShortcut and A._ParseClassPowerMoveShortcut(normalized); if result then return result end
    result = ParseGameplayRootToggle(normalized); if result then return result end
    result = A._ParseGameplayBooleanShortcut(normalized); if result then return result end
    result = A._ParseGameplayAnchorShortcut(normalized); if result then return result end
    result = A._ParseGameplayNumberShortcut(normalized); if result then return result end
    result = A._ParseGameplayPositionPreset(normalized); if result then return result end
    result = A._ParseGameplayMoveShortcut(normalized); if result then return result end
    result = ParsePresetWorkflow(normalized); if result then return result end
    result = P.ParseNameShorteningShortcut and P.ParseNameShorteningShortcut(normalized, ctx); if result then return result end
    result = ParseGuidedSetup(normalized); if result then return result end
    result = ParseScopedHelp(normalized); if result then return result end
    result = P.ParseGroupPowerBarSizeShortcut and P.ParseGroupPowerBarSizeShortcut(normalized); if result then return result end
    result = P.ParsePowerBarSizeShortcut and P.ParsePowerBarSizeShortcut(normalized); if result then return result end
    result = P.ParseMiscRegistryShortcut(normalized, raw); if result then return result end
    result = ParseSupportWorkflow(normalized); if result then return result end
    result = ParseDashboardPanelAction(normalized); if result then return result end
    result = ParseNavRailAction(normalized); if result then return result end
    result = ParseMenuWindowAction(normalized); if result then return result end
    result = ParseScopedFontTextColorShortcut(normalized); if result then return result end
    result = ParseUnitCopyScopeState(normalized); if result then return result end
    return P.ParseDashboardScaleShortcut and P.ParseDashboardScaleShortcut(normalized)
end

--- Geometry commands often share words with visual feature commands ("move",
--- "size", "left", "right"). Keep exact/positional parsers before fallback
--- setting lookup so directional phrases stay actionable.
function A._ParsePipelineGeometry(normalized, raw)
    local result = P.ParseTextVisibilityShortcut and P.ParseTextVisibilityShortcut(normalized); if result then return result end
    result = A._ParseNameTextAnchorShortcut(normalized); if result then return result end
    result = A._ParseNameTextVerticalPlacementShortcut(normalized); if result then return result end
    result = A._ParseTextSlotDropdownValueShortcut(normalized); if result then return result end
    result = A._ParseHPTextOptionShortcut(normalized); if result then return result end
    result = A._ParsePowerTextOptionShortcut(normalized); if result then return result end
    result = A._ParseTextAreaOffsetShortcut(normalized); if result then return result end
    result = A._ParseTextSlotValueMoveShortcut(normalized); if result then return result end
    result = A._ParseTextSlotOffsetShortcut(normalized); if result then return result end
    result = P.ParseHumanAnchorTarget and P.ParseHumanAnchorTarget(normalized, raw); if result then return result end
    result = P.ParseGroupScaleBreakpointShortcut and P.ParseGroupScaleBreakpointShortcut(normalized); if result then return result end
    result = P.ParseCastbarTextSizeShortcut and P.ParseCastbarTextSizeShortcut(normalized); if result then return result end
    result = P.ParseCastbarSizeShortcut and P.ParseCastbarSizeShortcut(normalized); if result then return result end
    result = P.ParseCastbarPlacementShortcut and P.ParseCastbarPlacementShortcut(normalized); if result then return result end
    result = P.ParseGroupAuraLiveFilterShortcut and P.ParseGroupAuraLiveFilterShortcut(normalized); if result then return result end
    result = P.ParseUnitAuraLiveFilterShortcut and P.ParseUnitAuraLiveFilterShortcut(normalized); if result then return result end
    result = P.ParseAuraCooldownSwipeDirectionShortcut and P.ParseAuraCooldownSwipeDirectionShortcut(normalized); if result then return result end
    result = P.ParseAuraDurationBarShortcut and P.ParseAuraDurationBarShortcut(normalized); if result then return result end
    result = P.ParseAuraDebuffBorderModeShortcut and P.ParseAuraDebuffBorderModeShortcut(normalized); if result then return result end
    result = P.AuraGeometryShortcut and P.AuraGeometryShortcut(normalized); if result then return result end
    result = P.ParseGroupPowerBarSizeShortcut and P.ParseGroupPowerBarSizeShortcut(normalized); if result then return result end
    result = P.ParsePowerBarSizeShortcut and P.ParsePowerBarSizeShortcut(normalized); if result then return result end
    result = A._ParseTextFontSizeShortcut(normalized); if result then return result end
    result = ParseUnitStatusSymbolRegistryShortcut and ParseUnitStatusSymbolRegistryShortcut(normalized); if result then return result end
    result = ParseStatusIconTestModeRegistryShortcut and ParseStatusIconTestModeRegistryShortcut(normalized); if result then return result end
    result = P.ParseGroupStatusIconDetail and P.ParseGroupStatusIconDetail(normalized); if result then return result end
    result = P.ParseUnitStatusIndicatorDetail and P.ParseUnitStatusIndicatorDetail(normalized); if result then return result end
    result = P.ParseUnitStatusIndicatorMove and P.ParseUnitStatusIndicatorMove(normalized); if result then return result end
    result = P.ParseFrameResizeShortcut and P.ParseFrameResizeShortcut(normalized); if result then return result end
    result = P.ParseUnitSizeMatchShortcut(normalized); if result then return result end
    result = P.ParseDetachedPowerBarMoveShortcut and P.ParseDetachedPowerBarMoveShortcut(normalized); if result then return result end
    result = P.ParseBossFrameSpacingShortcut and P.ParseBossFrameSpacingShortcut(normalized); if result then return result end
    result = P.ParsePairwiseFrameSpacingShortcut and P.ParsePairwiseFrameSpacingShortcut(normalized); if result then return result end
    result = P.ParseGroupFrameSpacingShortcut and P.ParseGroupFrameSpacingShortcut(normalized); if result then return result end
    result = ParseUnitDetailMove(normalized); if result then return result end
    result = ParseGroupDetailMove(normalized); if result then return result end
    result = P.ParseGroupFrameRootMove and P.ParseGroupFrameRootMove(normalized); if result then return result end
    result = P.ParseUnitFrameRootMove and P.ParseUnitFrameRootMove(normalized); if result then return result end
    result = P.ParseGenericOffsetMove(normalized); if result then return result end
    result = ParseUnsupportedDetailShortcut(normalized); if result then return result end
    result = ParseScopedOnlyOverride(normalized, raw); if result then return result end
    result = A._ParseTextLayerShortcut(normalized); if result then return result end
    result = A._ParseTextSlotDropdownShortcut(normalized); if result then return result end
    result = ParseMenuSelectorState(normalized); if result then return result end
    result = ParsePortraitDetailShortcut(normalized); if result then return result end
    if LooksLikeAbsorbBarCommand(normalized) then
        result = ParseAbsorbBarShortcut and ParseAbsorbBarShortcut(normalized); if result then return result end
    end
    if LooksLikeBarBorderEnumCommand(normalized) then
        result = ParseBarBorderEnumShortcut and ParseBarBorderEnumShortcut(normalized); if result then return result end
    end
    result = ParseAmbiguousGroupOutlineBorderShortcut and ParseAmbiguousGroupOutlineBorderShortcut(normalized); if result then return result end
    if LooksLikeBarOutlineHighlightCommand(normalized) then
        result = ParseBarOutlineHighlightShortcut and ParseBarOutlineHighlightShortcut(normalized); if result then return result end
    end
    result = ParseBorderThicknessShortcut(normalized); if result then return result end
    result = A._ParseTextDetailExactOffset(normalized); if result then return result end
    result = ParseUnitDetailOffsetShortcut(normalized); if result then return result end
    result = ParseCastbarTextMoveShortcut(normalized); if result then return result end
    result = A._ParseGroupRangeFadeShortcut(normalized); if result then return result end
    result = A._ParseGroupOpacityShortcut(normalized); if result then return result end
    return ParseUnitOpacityShortcut(normalized)
end

--- Feature pipeline handles domain toggles and richer actions that are not
--- pure geometry. It runs after workflow/geometry in A.Parse, then falls back
--- to generic setting parsing if no domain-specific action matched.
function A._ParsePipelineFeature(normalized, raw, ctx)
    local result = ParseGameplayAction(normalized, raw); if result then return result end
    result = ParseClassPowerAction and ParseClassPowerAction(normalized); if result then return result end
    result = A._ParseClassPowerColorShortcut and A._ParseClassPowerColorShortcut(normalized, raw); if result then return result end
    result = A._ParsePowerColorShortcut and A._ParsePowerColorShortcut(normalized, raw); if result then return result end
    result = ParseDarkModeBrightnessShortcut(normalized); if result then return result end
    result = ParseGlobalBarsAction(normalized); if result then return result end
    result = P.ParseNameShorteningShortcut and P.ParseNameShorteningShortcut(normalized, ctx); if result then return result end
    result = EarlyAuraShortcut(normalized, raw); if result then return result end
    result = ParseCastbarGlobalDetail(normalized); if result then return result end
    result = P.ParseCastbarDirectionClarification and P.ParseCastbarDirectionClarification(normalized); if result then return result end
    result = ParseCastbarPreviewAction(normalized); if result then return result end
    result = ParseScopedOverrideReset(normalized); if result then return result end
    result = ParseGroupCopyScopeState(normalized); if result then return result end
    result = CopyRequest(normalized); if result then return result end
    result = BuildContextReset(normalized, ctx); if result then return result end
    result = ParseColorAction(normalized); if result then return result end
    result = ParseGroupSpellIndicatorAction(normalized, raw); if result then return result end
    result = ParseGroupCornerIndicatorReset(normalized); if result then return result end
    result = ParseGroupCornerIndicatorSetting and ParseGroupCornerIndicatorSetting(normalized, raw); if result then return result end
    result = ParseGroupStatusPreview(normalized); if result then return result end
    result = P.ParseGroupStatusIconDetail and P.ParseGroupStatusIconDetail(normalized); if result then return result end
    result = ParseUnitStatusPreview(normalized, ctx); if result then return result end
    result = P.ParseUnitStatusIconStyle and P.ParseUnitStatusIconStyle(normalized); if result then return result end
    result = ParseGroupStatusIconReset(normalized); if result then return result end
    result = ParseUnitStatusIndicatorReset(normalized, ctx); if result then return result end
    result = P.ParseUnitStatusIndicatorDetail and P.ParseUnitStatusIndicatorDetail(normalized); if result then return result end
    return ParseUnitStatusIndicatorMove(normalized)
end

function A._ParsePipelineFallback(normalized, raw, ctx)
    return A._ParseGroupAnchorTargetShortcut(normalized)
        or ParseCustomAnchorSet(normalized, raw)
        or ParseCustomAnchorWorkflow(normalized)
        or ParseCustomAnchorClear(normalized)
        or ParseReset(normalized)
        or ParseOpen(normalized, raw)
        or ParseFontColorAction(normalized, raw)
        or (P.ParseExactActionPhraseShortcut and P.ParseExactActionPhraseShortcut(normalized, raw))
        or ParseRegistryAlias(normalized, raw)
        or ParseSetting(normalized, ctx)
end

local function ParseBarGradientPriorityShortcut(normalized)
    return (P.ParseBarGradientRegistryShortcut and P.ParseBarGradientRegistryShortcut(normalized))
        or (P.ParsePowerBarGradientRegistryShortcut and P.ParsePowerBarGradientRegistryShortcut(normalized))
end
A._ParseBarGradientPriorityShortcut = ParseBarGradientPriorityShortcut

local function ParseGlobalBarModePriorityShortcut(normalized)
    if ContainsAny(normalized, P.RootPhrases[553]) then
        return nil
    end
    if not ContainsAny(normalized, P.RootPhrases[554]) then
        return nil
    end
    local setting = A.Registry and A.Registry:GetSetting("general.barMode")
    local value = setting and P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
    if value == nil then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = "Global Bar Mode",
        summary = "Changes the global Unit Frame bar color mode.",
    }
end
A._ParseGlobalBarModePriorityShortcut = ParseGlobalBarModePriorityShortcut

local function ParseGlobalBarTexturePriorityShortcut(normalized, raw)
    if not ContainsAny(normalized, P.RootPhrases[555]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[556]) then
        return nil
    end

    local key
    if ContainsAny(normalized, P.RootPhrases[557]) then
        key = "general.barBackgroundTexture"
    else
        key = "general.barTexture"
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    local value = P.RawAfterLastConnector and P.RawAfterLastConnector(raw or normalized, { " to ", " as ", " = " }) or nil
    if value == nil or value == "" then
        value = P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, normalized, raw or normalized) or nil
    end
    if value == nil or value == "" then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Global Bar Texture",
        summary = "Changes the shared MSUF bar texture.",
    }
end
A._ParseGlobalBarTexturePriorityShortcut = ParseGlobalBarTexturePriorityShortcut

local function ParseGlobalGradientStrengthPriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[558]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[559]) then
        return nil
    end
    local setting = A.Registry and A.Registry:GetSetting("general.gradientStrength")
    if not setting then return nil end
    local value = FirstNumber(normalized)
    if value == nil then return nil end
    if value > 1 and tostring(normalized):find("%%") then
        value = value / 100
    end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Bar Gradient Strength",
        summary = "Changes the shared MSUF bar gradient strength.",
    }
end
A._ParseGlobalGradientStrengthPriorityShortcut = ParseGlobalGradientStrengthPriorityShortcut

local function ParseGlobalRoundedBarsPriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[560]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[561]) then
        return nil
    end

    local key
    if ContainsAny(normalized, P.RootPhrases[562]) then
        key = "bars.roundedMouseover"
    elseif ContainsAny(normalized, P.RootPhrases[563]) then
        key = "bars.roundedPowerBars"
    elseif ContainsAny(normalized, P.RootPhrases[564]) then
        key = "bars.roundedGroupFrames"
    elseif ContainsAny(normalized, P.RootPhrases[565]) then
        key = "bars.roundedUnitFrames"
    else
        key = "bars.roundedFramesEnabled"
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    local value = DetectBoolean(normalized)
    if value == nil then value = true end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Rounded Frame Texture",
        summary = "Changes MSUF rounded bar/frame texture options.",
    }
end
A._ParseGlobalRoundedBarsPriorityShortcut = ParseGlobalRoundedBarsPriorityShortcut

local function ParseGlobalUnitDispelOverlayPriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[566]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[567]) then
        return nil
    end

    local key
    local value
    if A._HasDispelOverlayAlphaIntent(normalized) then
        key = "general.unitDispelOverlayAlpha"
        value = A._DispelOverlayAlphaValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[568]) or A._HasDispelOverlayImplicitTriggerIntent(normalized) then
        key = "general.unitDispelOverlayTrigger"
    elseif ContainsAny(normalized, P.RootPhrases[569]) then
        key = "general.unitDispelOverlayStyle"
    elseif GroupDispelOverlayStyleValue(normalized) and DetectBoolean(normalized) == nil then
        key = "general.unitDispelOverlayStyle"
    elseif ContainsAny(normalized, P.RootPhrases[570]) then
        key = "general.unitDispelOverlayOnHealth"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[571]) then
        key = "general.unitDispelOverlayAlpha"
        value = A._DispelOverlayAlphaValue(normalized)
        if value == nil then return nil end
    else
        key = "general.unitDispelOverlayEnabled"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    if value == nil then
        if setting.type == "enum" then
            value = P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
        else
            value = P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, normalized, normalized) or nil
        end
    end
    if value == nil then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "UnitFrame Dispel Overlay",
        summary = "Changes the global unit-frame dispel overlay option.",
    }
end
A._ParseGlobalUnitDispelOverlayPriorityShortcut = ParseGlobalUnitDispelOverlayPriorityShortcut

local function ParseScopedUnitDispelOverlayPriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[572]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[573]) then
        return nil
    end

    local units = DetectUnits and DetectUnits(normalized) or {}
    if #units == 0 then return nil end

    local suffix
    local value
    if A._HasDispelOverlayAlphaIntent(normalized) then
        suffix = "unitDispelOverlayAlpha"
        value = A._DispelOverlayAlphaValue(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[574]) or A._HasDispelOverlayImplicitTriggerIntent(normalized) then
        suffix = "unitDispelOverlayTrigger"
    elseif ContainsAny(normalized, P.RootPhrases[575]) then
        suffix = "unitDispelOverlayStyle"
    elseif GroupDispelOverlayStyleValue(normalized) and DetectBoolean(normalized) == nil then
        suffix = "unitDispelOverlayStyle"
    elseif ContainsAny(normalized, P.RootPhrases[576]) then
        suffix = "unitDispelOverlayOnHealth"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    elseif ContainsAny(normalized, P.RootPhrases[577]) then
        suffix = "unitDispelOverlayAlpha"
        value = A._DispelOverlayAlphaValue(normalized)
        if value == nil then return nil end
    else
        suffix = "unitDispelOverlayEnabled"
        value = DetectBoolean(normalized)
        if value == nil then value = true end
    end

    local changes = {}
    local seen = {}
    for i = 1, #units do
        local unit = tostring(units[i])
        if not seen[unit] then
            seen[unit] = true
            local setting = A.Registry and A.Registry:GetSetting("barScope." .. unit .. "." .. suffix)
            if setting then
                local settingValue = value
                if settingValue == nil then
                    if setting.type == "enum" then
                        settingValue = P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
                    else
                        settingValue = P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, normalized, normalized) or nil
                    end
                end
                if settingValue ~= nil then changes[#changes + 1] = { setting = setting, value = settingValue } end
            end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = "UnitFrame Dispel Overlay",
        bulkSafe = #changes > 1,
        summary = "Changes scoped unit-frame dispel overlay options.",
    }
end
A._ParseScopedUnitDispelOverlayPriorityShortcut = ParseScopedUnitDispelOverlayPriorityShortcut

local function ParseGlobalPowerBarDetailPriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[578]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[579]) then
        return nil
    end

    local key = ContainsAny(normalized, P.RootPhrases[580])
        and "bars.realtimePowerText"
        or "bars.smoothPowerBar"
    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    local value = DetectBoolean(normalized)
    if value == nil then value = true end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = setting.label or "Power Bar",
        summary = "Changes the shared MSUF power bar detail option.",
    }
end
A._ParseGlobalPowerBarDetailPriorityShortcut = ParseGlobalPowerBarDetailPriorityShortcut

local function ParseScopedBarOverridePriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[581]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[582]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[583]) then
        return nil
    end

    local scopes = {}
    local units = DetectUnits and DetectUnits(normalized) or {}
    for i = 1, #units do scopes[#scopes + 1] = tostring(units[i]) end
    local groups = DetectGroups and DetectGroups(normalized) or {}
    for i = 1, #groups do scopes[#scopes + 1] = "gf_" .. tostring(groups[i]) end
    if #scopes == 0 then return nil end

    local value = DetectBoolean(normalized)
    if value == nil then value = true end
    local changes = {}
    local seen = {}
    for i = 1, #scopes do
        local scope = tostring(scopes[i])
        if not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("barScope." .. scope .. ".override")
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = "Bars Override",
        bulkSafe = #changes > 1,
        summary = "Changes scoped Global Bars override toggles.",
    }
end
A._ParseScopedBarOverridePriorityShortcut = ParseScopedBarOverridePriorityShortcut

local function ParseScopedGradientStrengthPriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[584]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[585]) then
        return nil
    end

    local scopes = {}
    local units = DetectUnits and DetectUnits(normalized) or {}
    for i = 1, #units do scopes[#scopes + 1] = tostring(units[i]) end
    local groups = DetectGroups and DetectGroups(normalized) or {}
    for i = 1, #groups do scopes[#scopes + 1] = "gf_" .. tostring(groups[i]) end
    if #scopes == 0 then return nil end

    local value = FirstNumber(normalized)
    if value == nil then return nil end
    if value > 1 and tostring(normalized):find("%%") then
        value = value / 100
    end

    local changes = {}
    local seen = {}
    for i = 1, #scopes do
        local scope = tostring(scopes[i])
        if not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("barScope." .. scope .. ".gradientStrength")
            if setting then changes[#changes + 1] = { setting = setting, value = value } end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = "Bar Gradient Strength",
        bulkSafe = #changes > 1,
        summary = "Changes scoped MSUF bar gradient strength.",
    }
end
A._ParseScopedGradientStrengthPriorityShortcut = ParseScopedGradientStrengthPriorityShortcut

local function ParseGlobalFontPriorityShortcut(normalized, raw)
    if ContainsAny(normalized, P.RootPhrases[586]) then
        return nil
    end

    local key
    local label
    local value
    if ContainsAny(normalized, P.RootPhrases[587]) then
        key = "general.fontSize"
        label = "Global Font Size"
        value = FirstNumber(normalized)
    elseif ContainsAny(normalized, P.RootPhrases[588]) then
        if ContainsAny(normalized, P.RootPhrases[589]) then return nil end
        key = "general.fontColor"
        label = "Global Font Palette Color"
    elseif ContainsAny(normalized, P.RootPhrases[590]) then
        key = "general.fontKey"
        label = "Global Font"
    else
        return nil
    end

    local setting = A.Registry and A.Registry:GetSetting(key)
    if not setting then return nil end
    if value == nil then
        if key == "general.fontKey" and A.MediaResolver and type(A.MediaResolver.Find) == "function" then
            local query = P.RawAfterLastConnector and P.RawAfterLastConnector(raw or normalized) or nil
            if query and query ~= "" then
                local media = A.MediaResolver.Find("font", query, { limit = 8 })
                if media and media.status == "exact" and media.value ~= nil then
                    value = media.value
                elseif media and media.status == "none" then
                    local textOut = A.MediaResolver.NoMatchMessage and A.MediaResolver.NoMatchMessage(media.mediaType, media.query) or "That font is not in the current MSUF media list."
                    return { kind = "unknown", text = textOut, status = "failed" }
                elseif media and media.status == "choices" and type(media.choices) == "table" then
                    local choices = {}
                    for i = 1, #media.choices do
                        local item = media.choices[i]
                        choices[#choices + 1] = {
                            setting = setting,
                            value = item.value,
                            valueLabel = item.label or item.value,
                            label = type(A.DisplaySettingValueLabel) == "function" and A.DisplaySettingValueLabel(setting, item.label or item.value, "Option") or (tostring(setting.label or "Option") .. ": " .. tostring(item.label or item.value)),
                            mediaType = "font",
                            mediaChoice = true,
                        }
                    end
                    if #choices > 0 then
                        return { kind = "ambiguous", choices = choices, label = "Which font?", summary = "Asks which matching font should be used." }
                    end
                end
            end
        end
        if value == nil then value = P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, normalized, raw or normalized) or nil end
    end
    if value == nil then return nil end
    return {
        kind = "changes",
        changes = { { setting = setting, value = value } },
        label = label,
        summary = "Changes a global font option.",
    }
end
A._ParseGlobalFontPriorityShortcut = ParseGlobalFontPriorityShortcut

local function ParseFontScopePriorityShortcut(normalized)
    if not ContainsAny(normalized, P.RootPhrases[591]) then return nil end
    if ContainsAny(normalized, P.RootPhrases[592]) then
        return nil
    end

    local scopes = {}
    local units = DetectUnits and DetectUnits(normalized) or {}
    for i = 1, #units do scopes[#scopes + 1] = tostring(units[i]) end
    local groups = DetectGroups and DetectGroups(normalized) or {}
    for i = 1, #groups do scopes[#scopes + 1] = "gf_" .. tostring(groups[i]) end
    if #scopes == 0 and ContainsAny(normalized, P.RootPhrases[593]) then
        scopes[#scopes + 1] = "shared"
    end
    if #scopes == 0 and ContainsAny(normalized, P.RootPhrases[594]) then
        scopes[#scopes + 1] = "shared"
    end
    if #scopes == 0 and ContainsAny(normalized, P.RootPhrases[595]) then
        scopes[#scopes + 1] = "shared"
    end
    if #scopes == 0 then return nil end

    local suffix
    local value
    if ContainsAny(normalized, P.RootPhrases[596]) then
        suffix = "override"
    elseif ContainsAny(normalized, P.RootPhrases[597]) then
        suffix = "fontSize"
        value = FirstNumber(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[598]) then
        suffix = "outline"
    elseif ContainsAny(normalized, P.RootPhrases[599]) then
        suffix = "fontMonochrome"
    elseif ContainsAny(normalized, P.RootPhrases[600]) then
        suffix = "fontTextAlpha"
    elseif ContainsAny(normalized, P.RootPhrases[601]) then
        suffix = "fontBaselineOffset"
    elseif ContainsAny(normalized, P.RootPhrases[602]) then
        suffix = "textBackdrop"
    elseif ContainsAny(normalized, P.RootPhrases[603]) then
        suffix = "fontShadowStrength"
    elseif ContainsAny(normalized, P.RootPhrases[604]) then
        suffix = "shortenNames"
    elseif ContainsAny(normalized, P.RootPhrases[605]) then
        suffix = "shortenNameClipSide"
    elseif ContainsAny(normalized, P.RootPhrases[606]) then
        suffix = "shortenNameMaxChars"
        value = FirstNumber(normalized)
        if value == nil then return nil end
    elseif ContainsAny(normalized, P.RootPhrases[607]) then
        suffix = "shortenNameNoEllipsis"
        if ContainsAny(normalized, P.RootPhrases[608]) then
            value = false
        elseif ContainsAny(normalized, P.RootPhrases[609]) then
            value = true
        end
    else
        return nil
    end

    local changes = {}
    local seen = {}
    for i = 1, #scopes do
        local scope = tostring(scopes[i])
        if not seen[scope] then
            seen[scope] = true
            local setting = A.Registry and A.Registry:GetSetting("fontScope." .. scope .. "." .. suffix)
            if setting then
                local settingValue = value
                if settingValue == nil then
                    settingValue = P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, normalized, normalized) or nil
                end
                if settingValue ~= nil then changes[#changes + 1] = { setting = setting, value = settingValue } end
            end
        end
    end
    if #changes == 0 then return nil end
    return {
        kind = "changes",
        changes = changes,
        label = suffix == "override" and "Font Override" or "Font Rendering",
        bulkSafe = #changes > 1,
        summary = "Changes scoped MSUF font options.",
    }
end
A._ParseFontScopePriorityShortcut = ParseFontScopePriorityShortcut

local function ParseGlobalUIShellPriorityShortcut(normalized)
    local specs = {
        { key = "general.slashMenuSnapEnabled", label = "Menu Edge Snap", terms = { "menu edge snap", "edge snap", "snap menu", "menu snapping" } },
        { key = "general.hideAdvancedMenu", label = "Advanced Menu", terms = { "advanced menu", "hide advanced menu", "show advanced menu" } },
        { key = "general.reduceMotion", label = "Reduce Motion", terms = { "reduce motion", "reduced motion", "less motion" } },
        { key = "general.showNavigationIcons", label = "Navigation Icons", terms = { "navigation icons", "nav icons" } },
        { key = "general.navHoverScale", label = "Navigation Hover Size", terms = { "navigation hover size", "nav hover size", "navigation hover scale", "nav hover scale" } },
        { key = "general.showWelcomeMessage", label = "Welcome Message", terms = { "welcome message", "startup message" } },
        { key = "general.versionCheckEnabled", label = "Version Check", terms = { "version check", "version checker" } },
        { key = "general.showMinimapIcon", label = "Minimap Icon", terms = { "minimap icon", "minimap button" } },
        { key = "general.playTargetSelectLostSounds", label = "Target Sounds", terms = { "target sounds", "target select sound", "target lost sound" } },
        { key = "general.disableBlizzardUnitFrames", label = "Blizzard Unitframes", terms = { "blizzard unitframes", "blizzard unit frames" } },
        { key = "general.hardKillBlizzardPlayerFrame", label = "Fully Hide Blizzard Playerframe", terms = { "fully hide blizzard playerframe", "hard hide blizzard playerframe", "hard kill blizzard playerframe" } },
        { key = "general.menuLocale", label = "Menu Language", terms = { "menu language", "menu locale" } },
        { key = "general.unitTooltipProvider", label = "Tooltip Source", terms = { "tooltip source", "tooltip provider" } },
        { key = "general.unitTooltipAnchor", label = "Tooltip Anchor", terms = { "tooltip anchor" } },
        { key = "general.unitTooltipMode", label = "Show Unitframe Tooltips", terms = { "show unitframe tooltips", "unitframe tooltips", "unit frame tooltips" } },
        { key = "general.unitTooltipModifier", label = "Tooltip Modifier", terms = { "tooltip modifier" } },
        { key = "general.styleEnabled", label = "MSUF Style", terms = { "msuf style" } },
        { key = "general.dropdownStyleMode", label = "Dropdown Style", terms = { "dropdown style", "dropdown mode" } },
    }
    for i = 1, #specs do
        local spec = specs[i]
        if ContainsAny(normalized, spec.terms) then
            local setting = A.Registry and A.Registry:GetSetting(spec.key)
            local value = setting and P.ValueForRegistrySetting and P.ValueForRegistrySetting(setting, normalized, normalized) or nil
            if value ~= nil then
                return {
                    kind = "changes",
                    changes = { { setting = setting, value = value } },
                    label = spec.label,
                    summary = "Changes a global MSUF menu/UI option.",
                }
            end
        end
    end
    return nil
end
A._ParseGlobalUIShellPriorityShortcut = ParseGlobalUIShellPriorityShortcut

local function ParseClassPowerPriorityShortcut(normalized, raw)
    return (ParseClassPowerRootToggle and ParseClassPowerRootToggle(normalized))
        or (A._ParseClassPowerPreviewResourceShortcut and A._ParseClassPowerPreviewResourceShortcut(normalized))
        or (A._ParseClassPowerWidthModeShortcut and A._ParseClassPowerWidthModeShortcut(normalized))
        or (A._ParseClassPowerVisibilityShortcut and A._ParseClassPowerVisibilityShortcut(normalized))
        or (A._ParseClassPowerDisplayStyleShortcut and A._ParseClassPowerDisplayStyleShortcut(normalized))
        or (A._ParseClassPowerFillDirectionShortcut and A._ParseClassPowerFillDirectionShortcut(normalized))
        or (A._ParseClassPowerEmpoweredComboShortcut and A._ParseClassPowerEmpoweredComboShortcut(normalized))
        or (A._ParseClassPowerRuneTimeShortcut and A._ParseClassPowerRuneTimeShortcut(normalized))
        or (A._ParseClassPowerDisplayBooleanShortcut and A._ParseClassPowerDisplayBooleanShortcut(normalized))
        or (A._ParseClassPowerColorModeShortcut and A._ParseClassPowerColorModeShortcut(normalized))
        or (A._ParseClassPowerDetachedPowerBarDetailShortcut and A._ParseClassPowerDetachedPowerBarDetailShortcut(normalized, raw))
        or (A._ParseClassPowerAltManaShortcut and A._ParseClassPowerAltManaShortcut(normalized, raw))
        or (A._ParseClassPowerPlayerHPDetailShortcut and A._ParseClassPowerPlayerHPDetailShortcut(normalized, raw))
        or (A._ParseClassPowerAnchorShortcut and A._ParseClassPowerAnchorShortcut(normalized))
        or (A._ParseClassPowerPlacementShortcut and A._ParseClassPowerPlacementShortcut(normalized))
        or (A._ParseClassPowerShapeShortcut and A._ParseClassPowerShapeShortcut(normalized))
        or (A._ParseClassPowerTextSizeShortcut and A._ParseClassPowerTextSizeShortcut(normalized))
        or (A._ParseClassPowerSizeShortcut and A._ParseClassPowerSizeShortcut(normalized))
        or (A._ParseClassPowerFrameLevelShortcut and A._ParseClassPowerFrameLevelShortcut(normalized))
        or (A._ParseClassPowerSeparatorShortcut and A._ParseClassPowerSeparatorShortcut(normalized))
        or (A._ParseClassPowerGapShortcut and A._ParseClassPowerGapShortcut(normalized))
        or (A._ParseClassPowerBackgroundShortcut and A._ParseClassPowerBackgroundShortcut(normalized))
        or (A._ParseClassPowerOutlineOpacityShortcut and A._ParseClassPowerOutlineOpacityShortcut(normalized))
        or (A._ParseClassPowerTextureShortcut and A._ParseClassPowerTextureShortcut(normalized, raw))
        or (A._ParseClassPowerMoveShortcut and A._ParseClassPowerMoveShortcut(normalized))
end
A._ParseClassPowerPriorityShortcut = ParseClassPowerPriorityShortcut

local function ParseGameplayPriorityShortcut(normalized, raw)
    return (ParseGameplayRootToggle and ParseGameplayRootToggle(normalized))
        or (A._ParseGameplayTextValueShortcut and A._ParseGameplayTextValueShortcut(normalized, raw))
        or (A._ParseGameplayBooleanShortcut and A._ParseGameplayBooleanShortcut(normalized))
        or (A._ParseGameplayAnchorShortcut and A._ParseGameplayAnchorShortcut(normalized))
        or (A._ParseGameplaySpellIDShortcut and A._ParseGameplaySpellIDShortcut(normalized))
        or (A._ParseGameplayNumberShortcut and A._ParseGameplayNumberShortcut(normalized))
        or (A._ParseGameplayPositionPreset and A._ParseGameplayPositionPreset(normalized))
        or (A._ParseGameplayMoveShortcut and A._ParseGameplayMoveShortcut(normalized))
end
A._ParseGameplayPriorityShortcut = ParseGameplayPriorityShortcut

A._ParseCastbarWidthModeShortcut = ParseCastbarWidthModeShortcut
A._ParseGroupSpellIndicatorsFastShortcut = ParseGroupSpellIndicatorsEnabledFastShortcut
A._ParseGroupBlizzardFallbackFastShortcut = ParseGroupBlizzardFallbackFastShortcut
A._ParseGroupHideOfflineDelayFastShortcut = ParseGroupHideOfflineDelayFastShortcut
A._ParseGroupReverseFillFastShortcut = ParseGroupReverseFillFastShortcut
A._ParseUnitReverseFillFastShortcut = ParseUnitReverseFillFastShortcut
A._ParseUnitSimpleBooleanFastShortcut = ParseUnitSimpleBooleanFastShortcut
A._ParseUnitStatusDetailFastShortcut = ParseUnitStatusDetailFastShortcut
A._ParseGroupSimpleBooleanFastShortcut = ParseGroupSimpleBooleanFastShortcut
A._ParseGroupCornerCustomFastShortcut = ParseGroupCornerCustomFastShortcut
A._ParseGroupTextureFastShortcut = ParseGroupTextureFastShortcut
A._ParseGroupNameTextFastShortcut = ParseGroupNameTextFastShortcut
A._ParseGroupRolePowerFastShortcut = ParseGroupRolePowerFastShortcut
A._ParseGroupPowerBarEnabledFastShortcut = ParseGroupPowerBarEnabledFastShortcut
A._ParseGroupOrderingFastShortcut = ParseGroupOrderingFastShortcut
A._ParseGlobalUiScaleFastShortcut = ParseGlobalUiScaleFastShortcut
A._ParseDashboardScaleFastShortcut = ParseDashboardScaleFastShortcut
A._ParseGlobalFontColorFastShortcut = ParseGlobalFontColorFastShortcut
A._ParseClassColorFastShortcut = ParseClassColorFastShortcut
A._ParseGlobalBarBackgroundFastShortcut = ParseGlobalBarBackgroundFastShortcut
A._ParseDarkModeCustomColorFastShortcut = ParseDarkModeCustomColorFastShortcut
A._ParseGlobalUnitFrameColorFastShortcut = ParseGlobalUnitFrameColorFastShortcut
A._ParseLastBarGradientGroupFollowup = ParseLastBarGradientGroupFollowup
A._ParseHealthColorGradientFastShortcut = ParseHealthColorGradientFastShortcut
A._ParseNPCReactionColorFastShortcut = ParseNPCReactionColorFastShortcut
A._ParsePetFrameColorFastShortcut = ParsePetFrameColorFastShortcut
A._ParsePowerColorTokenFastShortcut = ParsePowerColorTokenFastShortcut
A._ParseCastbarColorFastShortcut = ParseCastbarColorFastShortcut
A._ParseCastbarOverrideModeFastShortcut = ParseCastbarOverrideModeFastShortcut
A._ParseScopedBarOutlineColorFastShortcut = ParseScopedBarOutlineColorFastShortcut
A._ParseNPCTypeColorFastShortcut = ParseNPCTypeColorFastShortcut
A._ParseClassResourceHPBarFastShortcut = ParseClassResourceHPBarFastShortcut
A._ParseGlobalColorModeBooleanFastShortcut = ParseGlobalColorModeBooleanFastShortcut
A._ParseRaidMarkerNumberFastShortcut = ParseRaidMarkerNumberFastShortcut
A._ParseExactTextSlotOffsetFastShortcut = ParseExactTextSlotOffsetFastShortcut
A._ParseGroupScalingFastShortcut = ParseGroupScalingFastShortcut
A._ParseGroupFrameAnchorFastShortcut = ParseGroupFrameAnchorFastShortcut
A._ParseGroupLayoutNumberFastShortcut = ParseGroupLayoutNumberFastShortcut
A._ParseGroupTextFormatFastShortcut = ParseGroupTextFormatFastShortcut
A._ParseGroupDispelOverlayFastShortcut = ParseGroupDispelOverlayFastShortcut
A._ParseGroupRangeFadeFastShortcut = ParseGroupRangeFadeFastShortcut
A._ParseGroupNumberFastShortcut = ParseGroupNumberFastShortcut
A._ParseGroupHighlightFastShortcut = ParseGroupHighlightFastShortcut
A._ParseFullGroupBorderFastShortcut = ParseFullGroupBorderFastShortcut
A._ParseGroupStatusIconStyleFastShortcut = ParseGroupStatusIconStyleFastShortcut
A._ParseGroupBarColorModeFastShortcut = ParseGroupBarColorModeFastShortcut
A._ParseGroupFrameColorFastShortcut = ParseGroupFrameColorFastShortcut
A._ParseGroupDeadBackgroundFastShortcut = ParseGroupDeadBackgroundFastShortcut
A._ParseGroupAvailabilityFastShortcut = ParseGroupAvailabilityFastShortcut
A._ParseGroupAuraCooldownDarkenShortcut = ParseGroupAuraCooldownDarkenShortcut
A._ParseGroupAuraLaneBooleanShortcut = ParseGroupAuraLaneBooleanShortcut
A._ParseGroupAuraLaneTextSizeShortcut = ParseGroupAuraLaneTextSizeShortcut
A._ParseGroupAuraLaneTextOffsetShortcut = ParseGroupAuraLaneTextOffsetShortcut
A._ParseGroupAuraLaneOffsetShortcut = ParseGroupAuraLaneOffsetShortcut
A._ParseDispelOverlayOpacityShortcut = ParseDispelOverlayOpacityShortcut
A._ParseExplicitUnitBarOpacityShortcut = ParseExplicitUnitBarOpacityShortcut
A._ParseEditModeHUDControl = ParseEditModeHUDControl
A._ParseGlobalStatusTextStateShortcut = ParseGlobalStatusTextStateShortcut
A._ParseClassPowerTextOffsetShortcut = ParseClassPowerTextOffsetShortcut
A._ParseUnitRootVisibilityShortcut = ParseUnitRootVisibilityShortcut

local function ParseHumanSafetyGuidanceShortcut(normalized)
    if FirstNumber(normalized) ~= nil then return nil end
    if ContainsAny(normalized, P.RootPhrases[610]) then return nil end

    local broadIntent = ContainsAny(normalized, P.RootPhrases[611])
    if not broadIntent then return nil end
    if not ContainsAny(normalized, P.RootPhrases[612]) then return nil end

    local area = "that area"
    local examples = "open player; open bars; set target health bar height to 24; set target buff icon count to 8"
    if ContainsAny(normalized, P.RootPhrases[613]) then
        area = "raid frames"
        examples = "open raid frames; set raid debuff filter to RAID_IN_COMBAT; set raid name max chars to 12; set raid frame scale to 90"
    elseif ContainsAny(normalized, P.RootPhrases[614]) then
        area = "party frames"
        examples = "open party frames; set party buff count to 4; set party frame spacing to 8; turn on party range fade"
    elseif ContainsAny(normalized, P.RootPhrases[615]) then
        area = "auras"
        examples = "open aura filters; set target buff icon count to 8; set target debuff filter to RAID; set party buff icon size to 24"
    elseif ContainsAny(normalized, P.RootPhrases[616]) then
        area = "bars"
        examples = "open bars; turn on gradient from right for all unitframes; set gradient strength to 0.45; set bar texture to Minimalist"
    end

    return {
        kind = "answer",
        status = "ambiguous",
        result = "ambiguous",
        text = "I did not change " .. area .. " from that broad request. Tell me which exact setting to adjust, or start by opening the relevant page.\nSafe examples: " .. examples .. ".",
        summary = "Gives safe MSUF guidance for a broad visual request instead of guessing settings.",
    }
end
A._ParseHumanSafetyGuidanceShortcut = ParseHumanSafetyGuidanceShortcut

function A.ParseSimpleChange(text, ctxOverride)
    local raw = Trim(text)
    local normalized = Normalize(raw)
    local ctx = type(ctxOverride) == "table" and ctxOverride or (A.GetContext and A.GetContext() or {})
    if normalized == "" then return nil end
    local parsed = (A._ParseHumanSafetyGuidanceShortcut and A._ParseHumanSafetyGuidanceShortcut(normalized))
        or (A._ParseDispelOverlayOpacityShortcut and A._ParseDispelOverlayOpacityShortcut(normalized))
        or (A._ParseScopedDispelBorderTriggerFastShortcut and A._ParseScopedDispelBorderTriggerFastShortcut(normalized))
        or (A._ParsePowerColorTokenFastShortcut and A._ParsePowerColorTokenFastShortcut(normalized, raw))
        or (A._ParseExactColorSettingFastShortcut and A._ParseExactColorSettingFastShortcut(normalized, raw))
        or (P.ParseAmbiguousFontTextColorShortcut and P.ParseAmbiguousFontTextColorShortcut(normalized))
        or (P.ParseAmbiguousColorShortcut and P.ParseAmbiguousColorShortcut(normalized, raw))
        or (P.ParseScopedFontTextColorShortcut and P.ParseScopedFontTextColorShortcut(normalized, raw))
        or (A._ParseGroupDispelOverlayFastShortcut and A._ParseGroupDispelOverlayFastShortcut(normalized))
        or (A._ParseGlobalBarModePriorityShortcut and A._ParseGlobalBarModePriorityShortcut(normalized))
        or (A._ParseGlobalBarTexturePriorityShortcut and A._ParseGlobalBarTexturePriorityShortcut(normalized, raw))
        or (A._ParseGlobalGradientStrengthPriorityShortcut and A._ParseGlobalGradientStrengthPriorityShortcut(normalized))
        or (A._ParseGlobalRoundedBarsPriorityShortcut and A._ParseGlobalRoundedBarsPriorityShortcut(normalized))
        or (A._ParseGlobalUnitDispelOverlayPriorityShortcut and A._ParseGlobalUnitDispelOverlayPriorityShortcut(normalized))
        or (A._ParseScopedUnitDispelOverlayPriorityShortcut and A._ParseScopedUnitDispelOverlayPriorityShortcut(normalized))
        or (A._ParseGlobalPowerBarDetailPriorityShortcut and A._ParseGlobalPowerBarDetailPriorityShortcut(normalized))
        or (A._ParseScopedBarOverridePriorityShortcut and A._ParseScopedBarOverridePriorityShortcut(normalized))
        or (A._ParseScopedGradientStrengthPriorityShortcut and A._ParseScopedGradientStrengthPriorityShortcut(normalized))
        or (A._ParseGlobalFontPriorityShortcut and A._ParseGlobalFontPriorityShortcut(normalized, raw))
        or (A._ParseFontScopePriorityShortcut and A._ParseFontScopePriorityShortcut(normalized))
        or (A._ParseGlobalUIShellPriorityShortcut and A._ParseGlobalUIShellPriorityShortcut(normalized))
        or (A._ParseBarGradientPriorityShortcut and A._ParseBarGradientPriorityShortcut(normalized))
        or (A._ParseClassPowerPriorityShortcut and A._ParseClassPowerPriorityShortcut(normalized, raw))
        or (A._ParseGameplayPriorityShortcut and A._ParseGameplayPriorityShortcut(normalized, raw))
        or EarlyAuraShortcut(normalized, raw)
        or (P.ParseTextVisibilityShortcut and P.ParseTextVisibilityShortcut(normalized))
        or (A._ParseNameTextAnchorShortcut and A._ParseNameTextAnchorShortcut(normalized))
        or (A._ParseNameTextOffsetShortcut and A._ParseNameTextOffsetShortcut(normalized))
        or (A._ParseNameTextVerticalPlacementShortcut and A._ParseNameTextVerticalPlacementShortcut(normalized))
        or (A._ParseTextSlotDropdownValueShortcut and A._ParseTextSlotDropdownValueShortcut(normalized))
        or (A._ParseHPTextOptionShortcut and A._ParseHPTextOptionShortcut(normalized))
        or (A._ParsePowerTextOptionShortcut and A._ParsePowerTextOptionShortcut(normalized))
        or (A._ParseTextAreaOffsetShortcut and A._ParseTextAreaOffsetShortcut(normalized))
        or (A._ParseTextSlotValueMoveShortcut and A._ParseTextSlotValueMoveShortcut(normalized))
        or (A._ParseTextSlotOffsetShortcut and A._ParseTextSlotOffsetShortcut(normalized))
        or (A._ParseTextFontSizeShortcut and A._ParseTextFontSizeShortcut(normalized))
        or ParseCustomAnchorSet(normalized, raw)
        or ParsePortraitDetailShortcut(normalized)
        or (LooksLikeAbsorbBarCommand(normalized) and ParseAbsorbBarShortcut and ParseAbsorbBarShortcut(normalized, raw))
        or (LooksLikeBarBorderEnumCommand(normalized) and ParseBarBorderEnumShortcut and ParseBarBorderEnumShortcut(normalized))
        or (ParseAmbiguousGroupOutlineBorderShortcut and ParseAmbiguousGroupOutlineBorderShortcut(normalized))
        or (LooksLikeBarOutlineHighlightCommand(normalized) and ParseBarOutlineHighlightShortcut and ParseBarOutlineHighlightShortcut(normalized))
        or (P.ParsePowerBarSizeShortcut and P.ParsePowerBarSizeShortcut(normalized))
        or (P.ParseUnitPowerBarBorderThicknessShortcut and P.ParseUnitPowerBarBorderThicknessShortcut(normalized))
        or (P.ParseUnitPowerBarBooleanShortcut and P.ParseUnitPowerBarBooleanShortcut(normalized))
        or (P.ParsePlayerPowerBarShapeShortcut and P.ParsePlayerPowerBarShapeShortcut(normalized))
        or (P.ParsePlayerPowerOrbSizeShortcut and P.ParsePlayerPowerOrbSizeShortcut(normalized))
        or (A._ParseClassPowerDetachedPlayerPowerShortcut and A._ParseClassPowerDetachedPlayerPowerShortcut(normalized, raw))
        or (P.ParseDetachedPowerBarRegistryShortcut and P.ParseDetachedPowerBarRegistryShortcut(normalized, raw))
        or (ParseUnitStatusSymbolRegistryShortcut and ParseUnitStatusSymbolRegistryShortcut(normalized))
        or (ParseStatusIconTestModeRegistryShortcut and ParseStatusIconTestModeRegistryShortcut(normalized))
        or (P.ParseUnitStatusIndicatorDetail and P.ParseUnitStatusIndicatorDetail(normalized))
        or (ParseUnitLoadConditionShortcut and ParseUnitLoadConditionShortcut(normalized))
        or (A._ParseTextLayerShortcut and A._ParseTextLayerShortcut(normalized))
        or (P.ParseFrameSizeExactShortcut and P.ParseFrameSizeExactShortcut(normalized))
        or (P.ParseUnitFrameRootMove and P.ParseUnitFrameRootMove(normalized))
        or (P.ParseGroupFrameRootMove and P.ParseGroupFrameRootMove(normalized))
        or (P.ParseUnitRangeFadeShortcut and P.ParseUnitRangeFadeShortcut(normalized))
        or (A._ParseGroupRangeFadeShortcut and A._ParseGroupRangeFadeShortcut(normalized))
        or (P.ParseUnitHealthColorSchemeShortcut and P.ParseUnitHealthColorSchemeShortcut(normalized))
        or (LooksLikeAlphaExcludeTextPortraitCommand(normalized) and P.ParseAlphaExcludeTextPortraitShortcut and P.ParseAlphaExcludeTextPortraitShortcut(normalized))
        or ParseCastbarInterruptVisibilityShortcut(normalized)
        or ParseGroupDebuffStripeShortcut(normalized, raw)
        or (P.ParseUnitAnchorTargetShortcut and P.ParseUnitAnchorTargetShortcut(normalized))
        or (P.ParseUnitAnchorPointShortcut and P.ParseUnitAnchorPointShortcut(normalized))
        or (P.ParseExactRegistryKeyShortcut and P.ParseExactRegistryKeyShortcut(normalized, raw))
        or (P.ParseRegistryPriorityShortcut and P.ParseRegistryPriorityShortcut(normalized, raw))
        or (P.ParseRegistryExactAliasShortcut and P.ParseRegistryExactAliasShortcut(normalized, raw))
        or ExactTextDetailShortcut(normalized)
        or (A._ParseGroupOpacityShortcut and A._ParseGroupOpacityShortcut(normalized))
        or (ParseUnitOpacityShortcut and ParseUnitOpacityShortcut(normalized))
        or ParseScopedFontTextColorShortcut(normalized, raw)
        or ParseFontColorAction(normalized, raw)
        or ParseColorAction(normalized)
        or ParseRegistryAlias(normalized, raw)
        or ParseSetting(normalized, ctx)
    if parsed then
        parsed.raw = raw
        parsed.normalized = normalized
    end
    return parsed
end

function A.Parse(text, ctxOverride)
    local raw = Trim(text)
    local normalized = Normalize(raw)
    local ctx = type(ctxOverride) == "table" and ctxOverride or (A.GetContext and A.GetContext() or {})
    if normalized == "" then return { kind = "empty" } end
    local humanSafetyParsed = A._ParseHumanSafetyGuidanceShortcut and A._ParseHumanSafetyGuidanceShortcut(normalized)
    if humanSafetyParsed then
        humanSafetyParsed.raw = raw
        humanSafetyParsed.normalized = normalized
        return humanSafetyParsed
    end
    local continuationPriorityParsed = P.BuildContinuationFollowup and P.BuildContinuationFollowup(normalized, ctx)
    if continuationPriorityParsed then
        continuationPriorityParsed.raw = raw
        continuationPriorityParsed.normalized = normalized
        return continuationPriorityParsed
    end
    local earlyDispelOverlayOpacityParsed = A._ParseDispelOverlayOpacityShortcut and A._ParseDispelOverlayOpacityShortcut(normalized)
    if earlyDispelOverlayOpacityParsed then
        earlyDispelOverlayOpacityParsed.raw = raw
        earlyDispelOverlayOpacityParsed.normalized = normalized
        return earlyDispelOverlayOpacityParsed
    end
    local earlyScopedDispelBorderTriggerParsed = A._ParseScopedDispelBorderTriggerFastShortcut and A._ParseScopedDispelBorderTriggerFastShortcut(normalized)
    if earlyScopedDispelBorderTriggerParsed then
        earlyScopedDispelBorderTriggerParsed.raw = raw
        earlyScopedDispelBorderTriggerParsed.normalized = normalized
        return earlyScopedDispelBorderTriggerParsed
    end
    if LooksLikeAbsorbBarCommand(normalized) then
        local earlyAbsorbBarParsed = ParseAbsorbBarShortcut and ParseAbsorbBarShortcut(normalized, raw)
        if earlyAbsorbBarParsed then
            earlyAbsorbBarParsed.raw = raw
            earlyAbsorbBarParsed.normalized = normalized
            return earlyAbsorbBarParsed
        end
    end
    local earlyPowerColorTokenParsed = A._ParsePowerColorTokenFastShortcut and A._ParsePowerColorTokenFastShortcut(normalized, raw)
    if earlyPowerColorTokenParsed then
        earlyPowerColorTokenParsed.raw = raw
        earlyPowerColorTokenParsed.normalized = normalized
        return earlyPowerColorTokenParsed
    end
    -- Long exact-alias phrases are the most specific statement of intent a
    -- sentence can carry; resolve them before any topical fast path so a
    -- broad shortcut (opacity, portrait, combat state, ...) cannot swallow a
    -- precisely named option. Full-phrase mode: the whole command minus verb
    -- and value must equal exactly one alias; everything else falls through.
    local exactAliasPriorityParsed = P.ParseRegistryExactAliasShortcut and P.ParseRegistryExactAliasShortcut(normalized, raw, { minTokens = 3, fullPhrase = true })
    if exactAliasPriorityParsed then
        exactAliasPriorityParsed.raw = raw
        exactAliasPriorityParsed.normalized = normalized
        return exactAliasPriorityParsed
    end
    local humanIndicatorMovePriorityParsed = A._ParseHumanIndicatorMoveFastShortcut and A._ParseHumanIndicatorMoveFastShortcut(normalized)
    if humanIndicatorMovePriorityParsed then
        humanIndicatorMovePriorityParsed.raw = raw
        humanIndicatorMovePriorityParsed.normalized = normalized
        return humanIndicatorMovePriorityParsed
    end
    local globalStatusTextPriorityParsed = ParseGlobalStatusTextStateShortcut(normalized)
    if globalStatusTextPriorityParsed then
        globalStatusTextPriorityParsed.raw = raw
        globalStatusTextPriorityParsed.normalized = normalized
        return globalStatusTextPriorityParsed
    end
    local classResourceFillPriorityParsed = ParseClassResourceFillFastShortcut(normalized)
    if classResourceFillPriorityParsed then
        classResourceFillPriorityParsed.raw = raw
        classResourceFillPriorityParsed.normalized = normalized
        return classResourceFillPriorityParsed
    end
    local auraBlacklistPresetPriorityParsed = ParseAuraBlacklistPresetFastShortcut(normalized)
    if auraBlacklistPresetPriorityParsed then
        auraBlacklistPresetPriorityParsed.raw = raw
        auraBlacklistPresetPriorityParsed.normalized = normalized
        return auraBlacklistPresetPriorityParsed
    end
    local dispelBorderTriggerPriorityParsed = ParseDispelBorderTriggerFastShortcut(normalized)
    if dispelBorderTriggerPriorityParsed then
        dispelBorderTriggerPriorityParsed.raw = raw
        dispelBorderTriggerPriorityParsed.normalized = normalized
        return dispelBorderTriggerPriorityParsed
    end
    local unitPortraitShapePriorityParsed = ParseUnitPortraitShapeFastShortcut(normalized)
    if unitPortraitShapePriorityParsed then
        unitPortraitShapePriorityParsed.raw = raw
        unitPortraitShapePriorityParsed.normalized = normalized
        return unitPortraitShapePriorityParsed
    end
    local directSettingPriorityParsed = (A._ParseGlobalStatusIconsStyleFastShortcut and A._ParseGlobalStatusIconsStyleFastShortcut(normalized))
        or (A._ParseUnitAnchorPointFastShortcut and A._ParseUnitAnchorPointFastShortcut(normalized))
        or (A._ParseBossTargetHighlightFastShortcut and A._ParseBossTargetHighlightFastShortcut(normalized))
    if directSettingPriorityParsed then
        directSettingPriorityParsed.raw = raw
        directSettingPriorityParsed.normalized = normalized
        return directSettingPriorityParsed
    end
    local globalFontColorPriorityParsed = A._ParseGlobalFontColorFastShortcut and A._ParseGlobalFontColorFastShortcut(normalized, raw)
    if globalFontColorPriorityParsed then
        globalFontColorPriorityParsed.raw = raw
        globalFontColorPriorityParsed.normalized = normalized
        return globalFontColorPriorityParsed
    end
    local classColorPriorityParsed = A._ParseClassColorFastShortcut and A._ParseClassColorFastShortcut(normalized, raw)
    if classColorPriorityParsed then
        classColorPriorityParsed.raw = raw
        classColorPriorityParsed.normalized = normalized
        return classColorPriorityParsed
    end
    local globalBarBackgroundPriorityParsed = A._ParseGlobalBarBackgroundFastShortcut and A._ParseGlobalBarBackgroundFastShortcut(normalized, raw)
    if globalBarBackgroundPriorityParsed then
        globalBarBackgroundPriorityParsed.raw = raw
        globalBarBackgroundPriorityParsed.normalized = normalized
        return globalBarBackgroundPriorityParsed
    end
    local darkModeCustomColorPriorityParsed = A._ParseDarkModeCustomColorFastShortcut and A._ParseDarkModeCustomColorFastShortcut(normalized)
    if darkModeCustomColorPriorityParsed then
        darkModeCustomColorPriorityParsed.raw = raw
        darkModeCustomColorPriorityParsed.normalized = normalized
        return darkModeCustomColorPriorityParsed
    end
    local globalUnitFrameColorPriorityParsed = A._ParseGlobalUnitFrameColorFastShortcut and A._ParseGlobalUnitFrameColorFastShortcut(normalized, raw)
    if globalUnitFrameColorPriorityParsed then
        globalUnitFrameColorPriorityParsed.raw = raw
        globalUnitFrameColorPriorityParsed.normalized = normalized
        return globalUnitFrameColorPriorityParsed
    end
    local exactColorSettingPriorityParsed = A._ParseExactColorSettingFastShortcut and A._ParseExactColorSettingFastShortcut(normalized, raw)
    if exactColorSettingPriorityParsed then
        exactColorSettingPriorityParsed.raw = raw
        exactColorSettingPriorityParsed.normalized = normalized
        return exactColorSettingPriorityParsed
    end
    local lastBarGradientGroupFollowupParsed = A._ParseLastBarGradientGroupFollowup and A._ParseLastBarGradientGroupFollowup(normalized, ctx)
    if lastBarGradientGroupFollowupParsed then
        lastBarGradientGroupFollowupParsed.raw = raw
        lastBarGradientGroupFollowupParsed.normalized = normalized
        return lastBarGradientGroupFollowupParsed
    end
    local healthColorGradientPriorityParsed = A._ParseHealthColorGradientFastShortcut and A._ParseHealthColorGradientFastShortcut(normalized, raw)
    if healthColorGradientPriorityParsed then
        healthColorGradientPriorityParsed.raw = raw
        healthColorGradientPriorityParsed.normalized = normalized
        return healthColorGradientPriorityParsed
    end
    local npcReactionColorPriorityParsed = A._ParseNPCReactionColorFastShortcut and A._ParseNPCReactionColorFastShortcut(normalized, raw)
    if npcReactionColorPriorityParsed then
        npcReactionColorPriorityParsed.raw = raw
        npcReactionColorPriorityParsed.normalized = normalized
        return npcReactionColorPriorityParsed
    end
    local petFrameColorPriorityParsed = A._ParsePetFrameColorFastShortcut and A._ParsePetFrameColorFastShortcut(normalized, raw)
    if petFrameColorPriorityParsed then
        petFrameColorPriorityParsed.raw = raw
        petFrameColorPriorityParsed.normalized = normalized
        return petFrameColorPriorityParsed
    end
    local powerColorTokenPriorityParsed = A._ParsePowerColorTokenFastShortcut and A._ParsePowerColorTokenFastShortcut(normalized, raw)
    if powerColorTokenPriorityParsed then
        powerColorTokenPriorityParsed.raw = raw
        powerColorTokenPriorityParsed.normalized = normalized
        return powerColorTokenPriorityParsed
    end
    local castbarColorPriorityParsed = A._ParseCastbarColorFastShortcut and A._ParseCastbarColorFastShortcut(normalized, raw)
    if castbarColorPriorityParsed then
        castbarColorPriorityParsed.raw = raw
        castbarColorPriorityParsed.normalized = normalized
        return castbarColorPriorityParsed
    end
    local castbarOverrideModePriorityParsed = A._ParseCastbarOverrideModeFastShortcut and A._ParseCastbarOverrideModeFastShortcut(normalized)
    if castbarOverrideModePriorityParsed then
        castbarOverrideModePriorityParsed.raw = raw
        castbarOverrideModePriorityParsed.normalized = normalized
        return castbarOverrideModePriorityParsed
    end
    local globalHighlightColorPriorityParsed = A._ParseGlobalHighlightColorFastShortcut and A._ParseGlobalHighlightColorFastShortcut(normalized, raw)
    if globalHighlightColorPriorityParsed then
        globalHighlightColorPriorityParsed.raw = raw
        globalHighlightColorPriorityParsed.normalized = normalized
        return globalHighlightColorPriorityParsed
    end
    local mouseoverHighlightPriorityParsed = A._ParseMouseoverHighlightFastShortcut and A._ParseMouseoverHighlightFastShortcut(normalized, raw)
    if mouseoverHighlightPriorityParsed then
        mouseoverHighlightPriorityParsed.raw = raw
        mouseoverHighlightPriorityParsed.normalized = normalized
        return mouseoverHighlightPriorityParsed
    end
    local scopedBarOutlineColorPriorityParsed = A._ParseScopedBarOutlineColorFastShortcut and A._ParseScopedBarOutlineColorFastShortcut(normalized, raw)
    if scopedBarOutlineColorPriorityParsed then
        scopedBarOutlineColorPriorityParsed.raw = raw
        scopedBarOutlineColorPriorityParsed.normalized = normalized
        return scopedBarOutlineColorPriorityParsed
    end
    local npcTypeColorPriorityParsed = A._ParseNPCTypeColorFastShortcut and A._ParseNPCTypeColorFastShortcut(normalized)
    if npcTypeColorPriorityParsed then
        npcTypeColorPriorityParsed.raw = raw
        npcTypeColorPriorityParsed.normalized = normalized
        return npcTypeColorPriorityParsed
    end
    local classResourceHPBarPriorityParsed = A._ParseClassResourceHPBarFastShortcut and A._ParseClassResourceHPBarFastShortcut(normalized)
    if classResourceHPBarPriorityParsed then
        classResourceHPBarPriorityParsed.raw = raw
        classResourceHPBarPriorityParsed.normalized = normalized
        return classResourceHPBarPriorityParsed
    end
    local globalColorModeBooleanPriorityParsed = A._ParseGlobalColorModeBooleanFastShortcut and A._ParseGlobalColorModeBooleanFastShortcut(normalized)
    if globalColorModeBooleanPriorityParsed then
        globalColorModeBooleanPriorityParsed.raw = raw
        globalColorModeBooleanPriorityParsed.normalized = normalized
        return globalColorModeBooleanPriorityParsed
    end
    local raidMarkerNumberPriorityParsed = A._ParseRaidMarkerNumberFastShortcut and A._ParseRaidMarkerNumberFastShortcut(normalized)
    if raidMarkerNumberPriorityParsed then
        raidMarkerNumberPriorityParsed.raw = raw
        raidMarkerNumberPriorityParsed.normalized = normalized
        return raidMarkerNumberPriorityParsed
    end
    local exactTextSlotOffsetPriorityParsed = A._ParseExactTextSlotOffsetFastShortcut and A._ParseExactTextSlotOffsetFastShortcut(normalized)
    if exactTextSlotOffsetPriorityParsed then
        exactTextSlotOffsetPriorityParsed.raw = raw
        exactTextSlotOffsetPriorityParsed.normalized = normalized
        return exactTextSlotOffsetPriorityParsed
    end
    local ambiguousFontTextColorParsed = P.ParseAmbiguousFontTextColorShortcut and P.ParseAmbiguousFontTextColorShortcut(normalized)
    if ambiguousFontTextColorParsed then
        ambiguousFontTextColorParsed.raw = raw
        ambiguousFontTextColorParsed.normalized = normalized
        return ambiguousFontTextColorParsed
    end
    local ambiguousColorParsed = P.ParseAmbiguousColorShortcut and P.ParseAmbiguousColorShortcut(normalized, raw)
    if ambiguousColorParsed then
        ambiguousColorParsed.raw = raw
        ambiguousColorParsed.normalized = normalized
        return ambiguousColorParsed
    end
    local fontTextColorParsed = P.ParseScopedFontTextColorShortcut and P.ParseScopedFontTextColorShortcut(normalized, raw)
    if fontTextColorParsed then
        fontTextColorParsed.raw = raw
        fontTextColorParsed.normalized = normalized
        return fontTextColorParsed
    end
    local globalBarModePriorityParsed = A._ParseGlobalBarModePriorityShortcut and A._ParseGlobalBarModePriorityShortcut(normalized)
    if globalBarModePriorityParsed then
        globalBarModePriorityParsed.raw = raw
        globalBarModePriorityParsed.normalized = normalized
        return globalBarModePriorityParsed
    end
    local globalBarTexturePriorityParsed = A._ParseGlobalBarTexturePriorityShortcut and A._ParseGlobalBarTexturePriorityShortcut(normalized, raw)
    if globalBarTexturePriorityParsed then
        globalBarTexturePriorityParsed.raw = raw
        globalBarTexturePriorityParsed.normalized = normalized
        return globalBarTexturePriorityParsed
    end
    local globalGradientStrengthPriorityParsed = A._ParseGlobalGradientStrengthPriorityShortcut and A._ParseGlobalGradientStrengthPriorityShortcut(normalized)
    if globalGradientStrengthPriorityParsed then
        globalGradientStrengthPriorityParsed.raw = raw
        globalGradientStrengthPriorityParsed.normalized = normalized
        return globalGradientStrengthPriorityParsed
    end
    local globalRoundedBarsPriorityParsed = A._ParseGlobalRoundedBarsPriorityShortcut and A._ParseGlobalRoundedBarsPriorityShortcut(normalized)
    if globalRoundedBarsPriorityParsed then
        globalRoundedBarsPriorityParsed.raw = raw
        globalRoundedBarsPriorityParsed.normalized = normalized
        return globalRoundedBarsPriorityParsed
    end
    local groupDispelOverlayPriorityParsed = A._ParseGroupDispelOverlayFastShortcut and A._ParseGroupDispelOverlayFastShortcut(normalized)
    if groupDispelOverlayPriorityParsed then
        groupDispelOverlayPriorityParsed.raw = raw
        groupDispelOverlayPriorityParsed.normalized = normalized
        return groupDispelOverlayPriorityParsed
    end
    local globalUnitDispelOverlayPriorityParsed = A._ParseGlobalUnitDispelOverlayPriorityShortcut and A._ParseGlobalUnitDispelOverlayPriorityShortcut(normalized)
    if globalUnitDispelOverlayPriorityParsed then
        globalUnitDispelOverlayPriorityParsed.raw = raw
        globalUnitDispelOverlayPriorityParsed.normalized = normalized
        return globalUnitDispelOverlayPriorityParsed
    end
    local scopedUnitDispelOverlayPriorityParsed = A._ParseScopedUnitDispelOverlayPriorityShortcut and A._ParseScopedUnitDispelOverlayPriorityShortcut(normalized)
    if scopedUnitDispelOverlayPriorityParsed then
        scopedUnitDispelOverlayPriorityParsed.raw = raw
        scopedUnitDispelOverlayPriorityParsed.normalized = normalized
        return scopedUnitDispelOverlayPriorityParsed
    end
    local globalPowerBarDetailPriorityParsed = A._ParseGlobalPowerBarDetailPriorityShortcut and A._ParseGlobalPowerBarDetailPriorityShortcut(normalized)
    if globalPowerBarDetailPriorityParsed then
        globalPowerBarDetailPriorityParsed.raw = raw
        globalPowerBarDetailPriorityParsed.normalized = normalized
        return globalPowerBarDetailPriorityParsed
    end
    local scopedBarOverridePriorityParsed = A._ParseScopedBarOverridePriorityShortcut and A._ParseScopedBarOverridePriorityShortcut(normalized)
    if scopedBarOverridePriorityParsed then
        scopedBarOverridePriorityParsed.raw = raw
        scopedBarOverridePriorityParsed.normalized = normalized
        return scopedBarOverridePriorityParsed
    end
    local scopedGradientStrengthPriorityParsed = A._ParseScopedGradientStrengthPriorityShortcut and A._ParseScopedGradientStrengthPriorityShortcut(normalized)
    if scopedGradientStrengthPriorityParsed then
        scopedGradientStrengthPriorityParsed.raw = raw
        scopedGradientStrengthPriorityParsed.normalized = normalized
        return scopedGradientStrengthPriorityParsed
    end
    local globalFontPriorityParsed = A._ParseGlobalFontPriorityShortcut and A._ParseGlobalFontPriorityShortcut(normalized, raw)
    if globalFontPriorityParsed then
        globalFontPriorityParsed.raw = raw
        globalFontPriorityParsed.normalized = normalized
        return globalFontPriorityParsed
    end
    local fontScopePriorityParsed = A._ParseFontScopePriorityShortcut and A._ParseFontScopePriorityShortcut(normalized)
    if fontScopePriorityParsed then
        fontScopePriorityParsed.raw = raw
        fontScopePriorityParsed.normalized = normalized
        return fontScopePriorityParsed
    end
    local globalUIShellPriorityParsed = A._ParseGlobalUIShellPriorityShortcut and A._ParseGlobalUIShellPriorityShortcut(normalized)
    if globalUIShellPriorityParsed then
        globalUIShellPriorityParsed.raw = raw
        globalUIShellPriorityParsed.normalized = normalized
        return globalUIShellPriorityParsed
    end
    local dashboardScalePriorityParsed = A._ParseDashboardScaleFastShortcut and A._ParseDashboardScaleFastShortcut(normalized)
    if dashboardScalePriorityParsed then
        dashboardScalePriorityParsed.raw = raw
        dashboardScalePriorityParsed.normalized = normalized
        return dashboardScalePriorityParsed
    end
    local barGradientPriorityParsed = A._ParseBarGradientPriorityShortcut and A._ParseBarGradientPriorityShortcut(normalized)
    if barGradientPriorityParsed then
        barGradientPriorityParsed.raw = raw
        barGradientPriorityParsed.normalized = normalized
        return barGradientPriorityParsed
    end
    local classPowerPriorityParsed = A._ParseClassPowerPriorityShortcut and A._ParseClassPowerPriorityShortcut(normalized, raw)
    if classPowerPriorityParsed then
        classPowerPriorityParsed.raw = raw
        classPowerPriorityParsed.normalized = normalized
        return classPowerPriorityParsed
    end
    local gameplayPriorityParsed = A._ParseGameplayPriorityShortcut and A._ParseGameplayPriorityShortcut(normalized, raw)
    if gameplayPriorityParsed then
        gameplayPriorityParsed.raw = raw
        gameplayPriorityParsed.normalized = normalized
        return gameplayPriorityParsed
    end
    local partyTargetedSpellParsed = A._ParsePartyTargetedSpellFastShortcut and A._ParsePartyTargetedSpellFastShortcut(normalized, raw)
    if partyTargetedSpellParsed then
        partyTargetedSpellParsed.raw = raw
        partyTargetedSpellParsed.normalized = normalized
        return partyTargetedSpellParsed
    end
    local castbarWidthModeParsed = A._ParseCastbarWidthModeShortcut and A._ParseCastbarWidthModeShortcut(normalized)
    if castbarWidthModeParsed then
        castbarWidthModeParsed.raw = raw
        castbarWidthModeParsed.normalized = normalized
        return castbarWidthModeParsed
    end
    local groupSpellIndicatorsParsed = A._ParseGroupSpellIndicatorsFastShortcut and A._ParseGroupSpellIndicatorsFastShortcut(normalized)
    if groupSpellIndicatorsParsed then
        groupSpellIndicatorsParsed.raw = raw
        groupSpellIndicatorsParsed.normalized = normalized
        return groupSpellIndicatorsParsed
    end
    local groupBlizzardFallbackParsed = A._ParseGroupBlizzardFallbackFastShortcut and A._ParseGroupBlizzardFallbackFastShortcut(normalized)
    if groupBlizzardFallbackParsed then
        groupBlizzardFallbackParsed.raw = raw
        groupBlizzardFallbackParsed.normalized = normalized
        return groupBlizzardFallbackParsed
    end
    local groupHideOfflineDelayParsed = A._ParseGroupHideOfflineDelayFastShortcut and A._ParseGroupHideOfflineDelayFastShortcut(normalized)
    if groupHideOfflineDelayParsed then
        groupHideOfflineDelayParsed.raw = raw
        groupHideOfflineDelayParsed.normalized = normalized
        return groupHideOfflineDelayParsed
    end
    local groupReverseFillParsed = A._ParseGroupReverseFillFastShortcut and A._ParseGroupReverseFillFastShortcut(normalized)
    if groupReverseFillParsed then
        groupReverseFillParsed.raw = raw
        groupReverseFillParsed.normalized = normalized
        return groupReverseFillParsed
    end
    local unitReverseFillParsed = A._ParseUnitReverseFillFastShortcut and A._ParseUnitReverseFillFastShortcut(normalized)
    if unitReverseFillParsed then
        unitReverseFillParsed.raw = raw
        unitReverseFillParsed.normalized = normalized
        return unitReverseFillParsed
    end
    local unitSimpleBooleanParsed = A._ParseUnitSimpleBooleanFastShortcut and A._ParseUnitSimpleBooleanFastShortcut(normalized)
    if unitSimpleBooleanParsed then
        unitSimpleBooleanParsed.raw = raw
        unitSimpleBooleanParsed.normalized = normalized
        return unitSimpleBooleanParsed
    end
    local unitStatusDetailParsed = A._ParseUnitStatusDetailFastShortcut and A._ParseUnitStatusDetailFastShortcut(normalized)
    if unitStatusDetailParsed then
        unitStatusDetailParsed.raw = raw
        unitStatusDetailParsed.normalized = normalized
        return unitStatusDetailParsed
    end
    local groupSimpleBooleanParsed = A._ParseGroupSimpleBooleanFastShortcut and A._ParseGroupSimpleBooleanFastShortcut(normalized)
    if groupSimpleBooleanParsed then
        groupSimpleBooleanParsed.raw = raw
        groupSimpleBooleanParsed.normalized = normalized
        return groupSimpleBooleanParsed
    end
    local groupCornerCustomParsed = A._ParseGroupCornerCustomFastShortcut and A._ParseGroupCornerCustomFastShortcut(normalized, raw)
    if groupCornerCustomParsed then
        groupCornerCustomParsed.raw = raw
        groupCornerCustomParsed.normalized = normalized
        return groupCornerCustomParsed
    end
    local groupTextureParsed = A._ParseGroupTextureFastShortcut and A._ParseGroupTextureFastShortcut(normalized, raw)
    if groupTextureParsed then
        groupTextureParsed.raw = raw
        groupTextureParsed.normalized = normalized
        return groupTextureParsed
    end
    local groupNameTextParsed = A._ParseGroupNameTextFastShortcut and A._ParseGroupNameTextFastShortcut(normalized)
    if groupNameTextParsed then
        groupNameTextParsed.raw = raw
        groupNameTextParsed.normalized = normalized
        return groupNameTextParsed
    end
    local groupRolePowerParsed = A._ParseGroupRolePowerFastShortcut and A._ParseGroupRolePowerFastShortcut(normalized)
    if groupRolePowerParsed then
        groupRolePowerParsed.raw = raw
        groupRolePowerParsed.normalized = normalized
        return groupRolePowerParsed
    end
    local groupPowerBarParsed = A._ParseGroupPowerBarEnabledFastShortcut and A._ParseGroupPowerBarEnabledFastShortcut(normalized)
    if groupPowerBarParsed then
        groupPowerBarParsed.raw = raw
        groupPowerBarParsed.normalized = normalized
        return groupPowerBarParsed
    end
    local groupOrderingParsed = A._ParseGroupOrderingFastShortcut and A._ParseGroupOrderingFastShortcut(normalized)
    if groupOrderingParsed then
        groupOrderingParsed.raw = raw
        groupOrderingParsed.normalized = normalized
        return groupOrderingParsed
    end
    local globalUiScaleParsed = A._ParseGlobalUiScaleFastShortcut and A._ParseGlobalUiScaleFastShortcut(normalized)
    if globalUiScaleParsed then
        globalUiScaleParsed.raw = raw
        globalUiScaleParsed.normalized = normalized
        return globalUiScaleParsed
    end
    local groupScalingParsed = A._ParseGroupScalingFastShortcut and A._ParseGroupScalingFastShortcut(normalized)
    if groupScalingParsed then
        groupScalingParsed.raw = raw
        groupScalingParsed.normalized = normalized
        return groupScalingParsed
    end
    local groupFrameAnchorParsed = A._ParseGroupFrameAnchorFastShortcut and A._ParseGroupFrameAnchorFastShortcut(normalized)
    if groupFrameAnchorParsed then
        groupFrameAnchorParsed.raw = raw
        groupFrameAnchorParsed.normalized = normalized
        return groupFrameAnchorParsed
    end
    local groupLayoutNumberParsed = A._ParseGroupLayoutNumberFastShortcut and A._ParseGroupLayoutNumberFastShortcut(normalized)
    if groupLayoutNumberParsed then
        groupLayoutNumberParsed.raw = raw
        groupLayoutNumberParsed.normalized = normalized
        return groupLayoutNumberParsed
    end
    local groupTextDirectParsed = A._ParseGroupTextDirectFastShortcut and A._ParseGroupTextDirectFastShortcut(normalized)
    if groupTextDirectParsed then
        groupTextDirectParsed.raw = raw
        groupTextDirectParsed.normalized = normalized
        return groupTextDirectParsed
    end
    local groupTextFormatParsed = A._ParseGroupTextFormatFastShortcut and A._ParseGroupTextFormatFastShortcut(normalized)
    if groupTextFormatParsed then
        groupTextFormatParsed.raw = raw
        groupTextFormatParsed.normalized = normalized
        return groupTextFormatParsed
    end
    local groupDispelOverlayParsed = A._ParseGroupDispelOverlayFastShortcut and A._ParseGroupDispelOverlayFastShortcut(normalized)
    if groupDispelOverlayParsed then
        groupDispelOverlayParsed.raw = raw
        groupDispelOverlayParsed.normalized = normalized
        return groupDispelOverlayParsed
    end
    local groupRangeFadeParsed = A._ParseGroupRangeFadeFastShortcut and A._ParseGroupRangeFadeFastShortcut(normalized)
    if groupRangeFadeParsed then
        groupRangeFadeParsed.raw = raw
        groupRangeFadeParsed.normalized = normalized
        return groupRangeFadeParsed
    end
    local groupNumberParsed = A._ParseGroupNumberFastShortcut and A._ParseGroupNumberFastShortcut(normalized)
    if groupNumberParsed then
        groupNumberParsed.raw = raw
        groupNumberParsed.normalized = normalized
        return groupNumberParsed
    end
    local groupHighlightParsed = A._ParseGroupHighlightFastShortcut and A._ParseGroupHighlightFastShortcut(normalized)
    if groupHighlightParsed then
        groupHighlightParsed.raw = raw
        groupHighlightParsed.normalized = normalized
        return groupHighlightParsed
    end
    local fullGroupBorderParsed = A._ParseFullGroupBorderFastShortcut and A._ParseFullGroupBorderFastShortcut(normalized)
    if fullGroupBorderParsed then
        fullGroupBorderParsed.raw = raw
        fullGroupBorderParsed.normalized = normalized
        return fullGroupBorderParsed
    end
    local groupStatusIconStyleParsed = A._ParseGroupStatusIconStyleFastShortcut and A._ParseGroupStatusIconStyleFastShortcut(normalized)
    if groupStatusIconStyleParsed then
        groupStatusIconStyleParsed.raw = raw
        groupStatusIconStyleParsed.normalized = normalized
        return groupStatusIconStyleParsed
    end
    local groupBarColorModeParsed = A._ParseGroupBarColorModeFastShortcut and A._ParseGroupBarColorModeFastShortcut(normalized)
    if groupBarColorModeParsed then
        groupBarColorModeParsed.raw = raw
        groupBarColorModeParsed.normalized = normalized
        return groupBarColorModeParsed
    end
    local groupFrameColorParsed = A._ParseGroupFrameColorFastShortcut and A._ParseGroupFrameColorFastShortcut(normalized, raw)
    if groupFrameColorParsed then
        groupFrameColorParsed.raw = raw
        groupFrameColorParsed.normalized = normalized
        return groupFrameColorParsed
    end
    local groupDeadBackgroundParsed = A._ParseGroupDeadBackgroundFastShortcut and A._ParseGroupDeadBackgroundFastShortcut(normalized)
    if groupDeadBackgroundParsed then
        groupDeadBackgroundParsed.raw = raw
        groupDeadBackgroundParsed.normalized = normalized
        return groupDeadBackgroundParsed
    end
    local groupAvailabilityParsed = A._ParseGroupAvailabilityFastShortcut and A._ParseGroupAvailabilityFastShortcut(normalized)
    if groupAvailabilityParsed then
        groupAvailabilityParsed.raw = raw
        groupAvailabilityParsed.normalized = normalized
        return groupAvailabilityParsed
    end
    local groupAuraCooldownDarkenParsed = A._ParseGroupAuraCooldownDarkenShortcut and A._ParseGroupAuraCooldownDarkenShortcut(normalized)
    if groupAuraCooldownDarkenParsed then
        groupAuraCooldownDarkenParsed.raw = raw
        groupAuraCooldownDarkenParsed.normalized = normalized
        return groupAuraCooldownDarkenParsed
    end
    local groupAuraLaneOffsetParsed = (A._ParseGroupAuraLaneBooleanShortcut and A._ParseGroupAuraLaneBooleanShortcut(normalized))
        or (A._ParseGroupAuraLaneTextSizeShortcut and A._ParseGroupAuraLaneTextSizeShortcut(normalized))
        or (A._ParseGroupAuraLaneTextOffsetShortcut and A._ParseGroupAuraLaneTextOffsetShortcut(normalized))
        or (A._ParseGroupAuraLaneOffsetShortcut and A._ParseGroupAuraLaneOffsetShortcut(normalized))
    if groupAuraLaneOffsetParsed then
        groupAuraLaneOffsetParsed.raw = raw
        groupAuraLaneOffsetParsed.normalized = normalized
        return groupAuraLaneOffsetParsed
    end
    local fontRenderingParsed = P.ParseFontRenderingShortcut and P.ParseFontRenderingShortcut(normalized)
    if fontRenderingParsed then
        fontRenderingParsed.raw = raw
        fontRenderingParsed.normalized = normalized
        return fontRenderingParsed
    end
    local fontTextOpacityParsed = P.ParseFontTextOpacityShortcut and P.ParseFontTextOpacityShortcut(normalized)
    if fontTextOpacityParsed then
        fontTextOpacityParsed.raw = raw
        fontTextOpacityParsed.normalized = normalized
        return fontTextOpacityParsed
    end
    local globalFontFamilyParsed = P.ParseGlobalFontFamilyShortcut and P.ParseGlobalFontFamilyShortcut(normalized, raw)
    if globalFontFamilyParsed then
        globalFontFamilyParsed.raw = raw
        globalFontFamilyParsed.normalized = normalized
        return globalFontFamilyParsed
    end
    local dispelOverlayOpacityParsed = A._ParseDispelOverlayOpacityShortcut and A._ParseDispelOverlayOpacityShortcut(normalized)
    if dispelOverlayOpacityParsed then
        dispelOverlayOpacityParsed.raw = raw
        dispelOverlayOpacityParsed.normalized = normalized
        return dispelOverlayOpacityParsed
    end
    if ContainsAny(normalized, P.RootPhrases[617]) then
        local opacityUnits = DetectUnits(normalized)
        local opacityGroups = DetectGroups(normalized)
        local scopedOpacityParsed
        if #opacityUnits > 0 then
            scopedOpacityParsed = A._ParseExplicitUnitBarOpacityShortcut and A._ParseExplicitUnitBarOpacityShortcut(normalized)
                or (P.ParseUnitOpacityShortcut and P.ParseUnitOpacityShortcut(normalized))
        elseif #opacityGroups > 0 then
            scopedOpacityParsed = A._ParseGroupOpacityShortcut and A._ParseGroupOpacityShortcut(normalized)
        end
        if scopedOpacityParsed then
            scopedOpacityParsed.raw = raw
            scopedOpacityParsed.normalized = normalized
            return scopedOpacityParsed
        end
    end
    local actionExplainParsed = P.ParseRegistryActionExplainShortcut and P.ParseRegistryActionExplainShortcut(normalized, raw)
    if actionExplainParsed then
        actionExplainParsed.raw = raw
        actionExplainParsed.normalized = normalized
        return actionExplainParsed
    end
    local editModeControlParsed = A._ParseEditModeHUDControl and A._ParseEditModeHUDControl(normalized)
    if editModeControlParsed then
        editModeControlParsed.raw = raw
        editModeControlParsed.normalized = normalized
        return editModeControlParsed
    end
    local customAnchorActionParsed
    if ContainsAny(normalized, P.RootPhrases[618])
        or (ContainsAny(normalized, P.RootPhrases[619])
            and ContainsAny(normalized, P.RootPhrases[620]))
    then
        customAnchorActionParsed = ParseCustomAnchorWorkflow(normalized) or ParseCustomAnchorClear(normalized)
        if customAnchorActionParsed then
            customAnchorActionParsed.raw = raw
            customAnchorActionParsed.normalized = normalized
            return customAnchorActionParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[621]) then
        local setting
        local value
        if ContainsAny(normalized, P.RootPhrases[622]) then
            setting = A.Registry and A.Registry:GetSetting("targettarget.totInlineColorMode")
            value = setting and P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
        elseif ContainsAny(normalized, P.RootPhrases[623]) then
            setting = A.Registry and A.Registry:GetSetting("targettarget.totInlineCustomSeparator")
            value = P.RawAfterLastConnector and P.RawAfterLastConnector(raw, { " to ", " as ", " value ", " separator " }) or nil
            value = value or tostring(raw or ""):match("[Tt][Oo]%s+(.+)$")
        elseif ContainsAny(normalized, P.RootPhrases[624]) then
            setting = A.Registry and A.Registry:GetSetting("targettarget.totInlineSeparator")
            value = setting and P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
            value = value or (P.RawAfterLastConnector and P.RawAfterLastConnector(raw, { " to ", " as ", " value " }) or nil)
        else
            setting = A.Registry and A.Registry:GetSetting("targettarget.showToTInTargetName")
            value = DetectBoolean(normalized)
            if value == nil and ContainsAny(normalized, P.RootPhrases[625]) then value = true end
            if value == nil and ContainsAny(normalized, P.RootPhrases[626]) then value = false end
        end
        if setting and value ~= nil then
            return {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = setting.label or "Target Target Inline Text",
                summary = "Changes Target of Target inline text settings.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[627])
        and ContainsAny(normalized, P.RootPhrases[628])
        and not ContainsAny(normalized, P.RootPhrases[629])
    then
        local setting
        local value
        if ContainsAny(normalized, P.RootPhrases[630]) then
            setting = A.Registry and A.Registry:GetSetting("boss.bossLayoutMode")
            value = setting and P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
        else
            setting = A.Registry and A.Registry:GetSetting("boss.spacing")
            value = FirstNumber(normalized)
        end
        if setting and value ~= nil then
            return {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = setting.label or "Boss Layout",
                summary = "Changes Boss frame layout settings.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[631])
        and ContainsAny(normalized, P.RootPhrases[632])
        and ContainsAny(normalized, P.RootPhrases[633])
    then
        local castbarUnits = DetectUnits(normalized)
        local castbarOffsetKeys = {
            player = { x = "general.castbarPlayerOffsetX", y = "general.castbarPlayerOffsetY" },
            target = { x = "general.castbarTargetOffsetX", y = "general.castbarTargetOffsetY" },
            focus = { x = "general.castbarFocusOffsetX", y = "general.castbarFocusOffsetY" },
        }
        local unit
        for i = 1, #castbarUnits do
            if castbarOffsetKeys[castbarUnits[i]] then
                unit = castbarUnits[i]
                break
            end
        end
        local direction
        if normalized:find("to left", 1, true) or normalized:find("to the left", 1, true) or normalized:find("nach links", 1, true) then
            direction = "left"
        elseif normalized:find("to right", 1, true) or normalized:find("to the right", 1, true) or normalized:find("nach rechts", 1, true) then
            direction = "right"
        elseif normalized:find("up", 1, true) or normalized:find("oben", 1, true) then
            direction = "up"
        elseif normalized:find("down", 1, true) or normalized:find("unten", 1, true) then
            direction = "down"
        elseif normalized:find("left", 1, true) or normalized:find("links", 1, true) then
            direction = "left"
        elseif normalized:find("right", 1, true) or normalized:find("rechts", 1, true) then
            direction = "right"
        end
        local axis = (direction == "left" or direction == "right") and "x" or ((direction == "up" or direction == "down") and "y" or nil)
        local key = unit and axis and castbarOffsetKeys[unit] and castbarOffsetKeys[unit][axis]
        local setting = key and A.Registry and A.Registry:GetSetting(key)
        if setting then
            local amount = FirstNumber(normalized) or 10
            if direction == "left" or direction == "down" then amount = -amount end
            return {
                kind = "changes",
                changes = { { setting = setting, relativeDelta = amount, direction = direction } },
                label = "Move position offset",
                summary = "Moves the matching Cast Bar X/Y offset option.",
                raw = raw,
                normalized = normalized,
            }
        end
        local earlyCastbarMoveParsed = P.ParseGenericOffsetMove and P.ParseGenericOffsetMove(normalized)
        if earlyCastbarMoveParsed then
            earlyCastbarMoveParsed.raw = raw
            earlyCastbarMoveParsed.normalized = normalized
            return earlyCastbarMoveParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[634])
        and ContainsAny(normalized, P.RootPhrases[635])
    then
        local setting = A.Registry and A.Registry:GetSetting("general.castbarPlayerBackend")
        local value = setting and P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
        if setting and value ~= nil then
            return {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = setting.label or "Player Cast Bar Provider",
                summary = "Changes the Player Cast Bar provider.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[636])
        and ContainsAny(normalized, P.RootPhrases[637])
        and not ContainsAny(normalized, P.RootPhrases[638])
    then
        local key
        local value
        if ContainsAny(normalized, P.RootPhrases[639]) then
            key = "runtime.focusKickPreview"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[640]) then
            key = "general.focusKickIconWidth"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[641]) then
            key = "general.focusKickIconHeight"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[642]) then
            key = "general.focusKickTextSize"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[643]) then
            key = "general.focusKickIconOffsetX"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[644]) then
            key = "general.focusKickIconOffsetY"
            value = FirstNumber(normalized)
        else
            key = "general.enableFocusKickIcon"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        end
        local setting = key and A.Registry and A.Registry:GetSetting(key)
        if setting and value ~= nil then
            return {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = setting.label or "Focus Kick Tracker",
                summary = "Changes Focus Kick Tracker visibility, preview, size, or offset.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[645])
        and not ContainsAny(normalized, P.RootPhrases[646])
    then
        local key
        local value
        if ContainsAny(normalized, P.RootPhrases[647]) then
            key = "general.kickReadyAutoSize"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[648]) then
            key = "general.kickReadyStyle"
        elseif ContainsAny(normalized, P.RootPhrases[649]) then
            key = "general.kickReadyAnchor"
        elseif ContainsAny(normalized, P.RootPhrases[650]) then
            key = "general.kickReadyOffsetX"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[651]) then
            key = "general.kickReadyOffsetY"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[652]) then
            key = "general.kickReadySize"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[653]) then
            key = "general.kickReadyShowTarget"
        elseif ContainsAny(normalized, P.RootPhrases[654]) then
            key = "general.kickReadyShowFocus"
        elseif ContainsAny(normalized, P.RootPhrases[655]) then
            key = "general.kickReadyShowBoss"
        end
        local setting = key and A.Registry and A.Registry:GetSetting(key)
        if setting and value == nil then
            if setting.type == "enum" then
                value = P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
            elseif setting.type == "boolean" then
                value = DetectBoolean(normalized)
                if value == nil then value = true end
            end
        end
        if setting and value ~= nil then
            return {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = setting.label or "Interrupt Ready",
                summary = "Changes Cast Bar Interrupt Ready visibility or indicator details.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[656])
        and ContainsAny(normalized, P.RootPhrases[657])
        and not ContainsAny(normalized, P.RootPhrases[658])
        and not (ContainsAny(normalized, P.RootPhrases[659])
            and ContainsAny(normalized, P.RootPhrases[660]))
    then
        local key
        local value
        if ContainsAny(normalized, P.RootPhrases[661]) then
            key = "general.castbarShakeStrength"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[662]) then
            key = "general.castbarInterruptShake"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[663]) then
            key = "general.castbarUnifiedDirection"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[664]) then
            key = "general.castbarOpositeDirectionTarget"
            value = DetectBoolean(normalized)
            if value == nil then
                value = not ContainsAny(normalized, P.RootPhrases[665])
            end
        elseif ContainsAny(normalized, P.RootPhrases[666]) then
            key = "general.castbarFillDirection"
            local setting = A.Registry and A.Registry:GetSetting(key)
            value = setting and P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
        elseif ContainsAny(normalized, P.RootPhrases[667]) then
            key = "general.castbarShowChannelTicks"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[668]) then
            key = "general.castbarBackgroundTexture"
            value = P.RawAfterLastConnector and P.RawAfterLastConnector(raw, { " to ", " as ", " = " }) or nil
        elseif ContainsAny(normalized, P.RootPhrases[669]) then
            key = "general.castbarTexture"
            value = P.RawAfterLastConnector and P.RawAfterLastConnector(raw, { " to ", " as ", " = " }) or nil
        elseif ContainsAny(normalized, P.RootPhrases[670]) then
            key = "general.castbarOutlineThickness"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[671]) then
            key = "general.castbarShowGlow"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[672]) then
            key = "general.castbarShowLatency"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[673]) then
            key = "general.castbarSparkOverflow"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[674]) then
            key = "general.castbarShowSpark"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[675]) then
            key = "general.empowerStageBlinkTime"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[676]) then
            key = "general.empowerColorStages"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[677]) then
            key = "general.empowerStageBlink"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[678]) then
            key = "general.castbarSpellNameShortening"
            value = DetectBoolean(normalized)
            if value == nil then value = true end
        elseif ContainsAny(normalized, P.RootPhrases[679]) then
            key = "general.castbarSpellNameMaxLen"
            value = FirstNumber(normalized)
        elseif ContainsAny(normalized, P.RootPhrases[680]) then
            key = "general.castbarSpellNameReservedSpace"
            value = FirstNumber(normalized)
        end
        local setting = key and A.Registry and A.Registry:GetSetting(key)
        if setting and value ~= nil then
            return {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = setting.label or "Cast Bar Behavior",
                summary = "Changes a global Cast Bar behavior option.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[681])
        and ContainsAny(normalized, P.RootPhrases[682])
        and not DetectUnits(normalized)[1]
        and not ContainsAny(normalized, P.RootPhrases[683])
    then
        local key
        if ContainsAny(normalized, P.RootPhrases[684]) then
            key = "general.castbarSpellNameFontSize"
        elseif ContainsAny(normalized, P.RootPhrases[685]) then
            key = "general.castbarTimeFontSize"
        elseif ContainsAny(normalized, P.RootPhrases[686]) then
            key = "general.castbarIconSize"
        elseif ContainsAny(normalized, P.RootPhrases[687]) then
            key = "general.castbarIconOffsetX"
        elseif ContainsAny(normalized, P.RootPhrases[688]) then
            key = "general.castbarIconOffsetY"
        end
        local setting = key and A.Registry and A.Registry:GetSetting(key)
        local value = setting and FirstNumber(normalized) or nil
        if setting and value ~= nil then
            return {
                kind = "changes",
                changes = { { setting = setting, value = value } },
                label = setting.label or "Castbar Detail",
                summary = "Changes a global Cast Bar detail size or offset.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[689])
        and ContainsAny(normalized, P.RootPhrases[690])
        and not ContainsAny(normalized, P.RootPhrases[691])
    then
        local attr
        if ContainsAny(normalized, P.RootPhrases[692]) then
            attr = "border"
        elseif ContainsAny(normalized, P.RootPhrases[693]) then
            attr = "spacing"
        elseif ContainsAny(normalized, P.RootPhrases[694]) then
            attr = "position"
        elseif ContainsAny(normalized, P.RootPhrases[695]) then
            attr = "x"
        elseif ContainsAny(normalized, P.RootPhrases[696]) then
            attr = "y"
        elseif ContainsAny(normalized, P.RootPhrases[697]) then
            attr = "size"
        end

        local keyMap = {
            player = {
                size = "general.castbarPlayerIconSize",
                position = "general.castbarPlayerIconPosition",
                x = "general.castbarPlayerIconOffsetX",
                y = "general.castbarPlayerIconOffsetY",
                spacing = "general.castbarPlayerIconSpacing",
                border = "general.castbarPlayerIconBorderStyle",
            },
            target = {
                size = "general.castbarTargetIconSize",
                position = "general.castbarTargetIconPosition",
                x = "general.castbarTargetIconOffsetX",
                y = "general.castbarTargetIconOffsetY",
                spacing = "general.castbarTargetIconSpacing",
                border = "general.castbarTargetIconBorderStyle",
            },
            focus = {
                size = "general.castbarFocusIconSize",
                position = "general.castbarFocusIconPosition",
                x = "general.castbarFocusIconOffsetX",
                y = "general.castbarFocusIconOffsetY",
                spacing = "general.castbarFocusIconSpacing",
                border = "general.castbarFocusIconBorderStyle",
            },
            boss = {
                size = "general.bossCastIconSize",
                position = "general.bossCastIconPosition",
                x = "general.bossCastIconOffsetX",
                y = "general.bossCastIconOffsetY",
                spacing = "general.bossCastIconSpacing",
                border = "general.bossCastIconBorderStyle",
            },
        }

        local units = DetectUnits(normalized)
        local changes = {}
        if attr then
            for i = 1, #units do
                local key = keyMap[units[i]] and keyMap[units[i]][attr]
                local setting = key and A.Registry and A.Registry:GetSetting(key)
                if setting then
                    local value
                    if setting.type == "enum" then
                        value = P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
                    else
                        value = FirstNumber(normalized)
                    end
                    if value ~= nil then changes[#changes + 1] = { setting = setting, value = value } end
                end
            end
        end
        if #changes > 0 then
            return {
                kind = "changes",
                changes = changes,
                label = #changes == 1 and (changes[1].setting.label or "Castbar Icon Detail") or "Castbar Icon Details",
                bulkSafe = #changes > 1,
                summary = "Changes unit Cast Bar icon size, position, spacing, or border options.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[698])
        and ContainsAny(normalized, P.RootPhrases[699])
        and not ContainsAny(normalized, P.RootPhrases[700])
    then
        local attr
        if ContainsAny(normalized, P.RootPhrases[701]) then
            attr = "timeFormat"
        elseif ContainsAny(normalized, P.RootPhrases[702]) then
            attr = "timePosition"
        elseif ContainsAny(normalized, P.RootPhrases[703]) then
            attr = "timeX"
        elseif ContainsAny(normalized, P.RootPhrases[704]) then
            attr = "timeY"
        elseif ContainsAny(normalized, P.RootPhrases[705]) then
            attr = "timeFontSize"
        elseif ContainsAny(normalized, P.RootPhrases[706]) then
            attr = "spellTruncate"
        elseif ContainsAny(normalized, P.RootPhrases[707]) then
            attr = "spellMaxWidth"
        elseif ContainsAny(normalized, P.RootPhrases[708]) then
            attr = "spellFontSize"
        elseif ContainsAny(normalized, P.RootPhrases[709]) then
            attr = "spellAlign"
        elseif ContainsAny(normalized, P.RootPhrases[710]) then
            attr = "spellPosition"
        elseif ContainsAny(normalized, P.RootPhrases[711]) then
            attr = "textX"
        elseif ContainsAny(normalized, P.RootPhrases[712]) then
            attr = "textY"
        end

        local keyMap = {
            player = {
                spellPosition = "general.castbarPlayerSpellNamePosition",
                textX = "general.castbarPlayerTextOffsetX",
                textY = "general.castbarPlayerTextOffsetY",
                spellAlign = "general.castbarPlayerSpellNameAlign",
                spellFontSize = "general.castbarPlayerSpellNameFontSize",
                spellMaxWidth = "general.castbarPlayerSpellNameMaxWidth",
                spellTruncate = "general.castbarPlayerSpellNameTruncate",
                timeFormat = "general.castbarPlayerTimeFormat",
                timePosition = "general.castbarPlayerTimePosition",
                timeX = "general.castbarPlayerTimeOffsetX",
                timeY = "general.castbarPlayerTimeOffsetY",
                timeFontSize = "general.castbarPlayerTimeFontSize",
            },
            target = {
                spellPosition = "general.castbarTargetSpellNamePosition",
                textX = "general.castbarTargetTextOffsetX",
                textY = "general.castbarTargetTextOffsetY",
                spellAlign = "general.castbarTargetSpellNameAlign",
                spellFontSize = "general.castbarTargetSpellNameFontSize",
                spellMaxWidth = "general.castbarTargetSpellNameMaxWidth",
                spellTruncate = "general.castbarTargetSpellNameTruncate",
                timeFormat = "general.castbarTargetTimeFormat",
                timePosition = "general.castbarTargetTimePosition",
                timeX = "general.castbarTargetTimeOffsetX",
                timeY = "general.castbarTargetTimeOffsetY",
                timeFontSize = "general.castbarTargetTimeFontSize",
            },
            focus = {
                spellPosition = "general.castbarFocusSpellNamePosition",
                textX = "general.castbarFocusTextOffsetX",
                textY = "general.castbarFocusTextOffsetY",
                spellAlign = "general.castbarFocusSpellNameAlign",
                spellFontSize = "general.castbarFocusSpellNameFontSize",
                spellMaxWidth = "general.castbarFocusSpellNameMaxWidth",
                spellTruncate = "general.castbarFocusSpellNameTruncate",
                timeFormat = "general.castbarFocusTimeFormat",
                timePosition = "general.castbarFocusTimePosition",
                timeX = "general.castbarFocusTimeOffsetX",
                timeY = "general.castbarFocusTimeOffsetY",
                timeFontSize = "general.castbarFocusTimeFontSize",
            },
            boss = {
                spellPosition = "general.bossCastSpellNamePosition",
                textX = "general.bossCastTextOffsetX",
                textY = "general.bossCastTextOffsetY",
                spellAlign = "general.bossCastSpellNameAlign",
                spellFontSize = "general.bossCastSpellNameFontSize",
                spellMaxWidth = "general.bossCastSpellNameMaxWidth",
                spellTruncate = "general.bossCastSpellNameTruncate",
                timeFormat = "general.bossCastTimeFormat",
                timePosition = "general.bossCastTimePosition",
                timeX = "general.bossCastTimeOffsetX",
                timeY = "general.bossCastTimeOffsetY",
                timeFontSize = "general.bossCastTimeFontSize",
            },
        }

        local units = DetectUnits(normalized)
        local changes = {}
        if attr then
            for i = 1, #units do
                local key = keyMap[units[i]] and keyMap[units[i]][attr]
                local setting = key and A.Registry and A.Registry:GetSetting(key)
                if setting then
                    local value
                    if setting.type == "enum" then
                        value = P.EnumValueForText and P.EnumValueForText(setting, normalized) or nil
                    else
                        value = FirstNumber(normalized)
                    end
                    if value ~= nil then changes[#changes + 1] = { setting = setting, value = value } end
                end
            end
        end
        if #changes > 0 then
            return {
                kind = "changes",
                changes = changes,
                label = #changes == 1 and (changes[1].setting.label or "Castbar Text Detail") or "Castbar Text Details",
                bulkSafe = #changes > 1,
                summary = "Changes unit Cast Bar spell text or time text detail options.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[713])
        and ContainsAny(normalized, P.RootPhrases[714])
        and not ContainsAny(normalized, P.RootPhrases[715])
    then
        local attr
        if ContainsAny(normalized, P.RootPhrases[716]) then
            attr = "time"
        elseif ContainsAny(normalized, P.RootPhrases[717]) then
            attr = "icon"
        elseif ContainsAny(normalized, P.RootPhrases[718]) then
            attr = "text"
        end
        local value = DetectBoolean(normalized)
        local units = DetectUnits(normalized)
        local keys = {
            player = { time = "general.showPlayerCastTime", icon = "general.castbarPlayerShowIcon", text = "general.castbarPlayerShowSpellName" },
            target = { time = "general.showTargetCastTime", icon = "general.castbarTargetShowIcon", text = "general.castbarTargetShowSpellName" },
            focus = { time = "general.showFocusCastTime", icon = "general.castbarFocusShowIcon", text = "general.castbarFocusShowSpellName" },
            boss = { time = "general.showBossCastTime", icon = "general.showBossCastIcon", text = "general.showBossCastName" },
        }
        local changes = {}
        if attr and value ~= nil then
            for i = 1, #units do
                local key = keys[units[i]] and keys[units[i]][attr]
                local setting = key and A.Registry and A.Registry:GetSetting(key)
                if setting then changes[#changes + 1] = { setting = setting, value = value } end
            end
        end
        if #changes > 0 then
            return {
                kind = "changes",
                changes = changes,
                label = #changes == 1 and (changes[1].setting.label or "Cast Bar Detail") or "Cast Bar Details",
                bulkSafe = #changes > 1,
                summary = "Changes Cast Bar time, icon, or spell text visibility.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[719])
        and ContainsAny(normalized, P.RootPhrases[720])
        and not ContainsAny(normalized, P.RootPhrases[721])
    then
        local axis
        if ContainsAny(normalized, P.RootPhrases[722]) then
            axis = "w"
        elseif ContainsAny(normalized, P.RootPhrases[723]) then
            axis = "h"
        end
        local value = FirstNumber(normalized)
        local units = DetectUnits(normalized)
        local keys = {
            player = { w = "general.castbarPlayerBarWidth", h = "general.castbarPlayerBarHeight" },
            target = { w = "general.castbarTargetBarWidth", h = "general.castbarTargetBarHeight" },
            focus = { w = "general.castbarFocusBarWidth", h = "general.castbarFocusBarHeight" },
            boss = { w = "general.bossCastbarWidth", h = "general.bossCastbarHeight" },
        }
        local changes = {}
        if axis and value ~= nil then
            for i = 1, #units do
                local key = keys[units[i]] and keys[units[i]][axis]
                local setting = key and A.Registry and A.Registry:GetSetting(key)
                if setting then changes[#changes + 1] = { setting = setting, value = value } end
            end
        end
        if #changes > 0 then
            return {
                kind = "changes",
                changes = changes,
                label = #changes == 1 and (changes[1].setting.label or "Cast Bar Size") or "Cast Bar Size",
                bulkSafe = #changes > 1,
                summary = "Changes unit Cast Bar width or height.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[724])
        and ContainsAny(normalized, P.RootPhrases[725])
        and not ContainsAny(normalized, P.RootPhrases[726])
    then
        local axis
        if ContainsAny(normalized, P.RootPhrases[727]) then
            axis = "x"
        elseif ContainsAny(normalized, P.RootPhrases[728]) then
            axis = "y"
        end
        local value = FirstNumber(normalized)
        local units = DetectUnits(normalized)
        local keys = {
            player = { x = "general.castbarPlayerOffsetX", y = "general.castbarPlayerOffsetY" },
            target = { x = "general.castbarTargetOffsetX", y = "general.castbarTargetOffsetY" },
            focus = { x = "general.castbarFocusOffsetX", y = "general.castbarFocusOffsetY" },
            boss = { x = "general.bossCastbarOffsetX", y = "general.bossCastbarOffsetY" },
        }
        local changes = {}
        if axis and value ~= nil then
            for i = 1, #units do
                local key = keys[units[i]] and keys[units[i]][axis]
                local setting = key and A.Registry and A.Registry:GetSetting(key)
                if setting then changes[#changes + 1] = { setting = setting, value = value } end
            end
        end
        if #changes > 0 then
            return {
                kind = "changes",
                changes = changes,
                label = #changes == 1 and (changes[1].setting.label or "Cast Bar Offset") or "Cast Bar Offset",
                bulkSafe = #changes > 1,
                summary = "Changes unit Cast Bar X/Y offset.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[729])
        and not ContainsAny(normalized, P.RootPhrases[730])
    then
        local value = DetectBoolean(normalized)
        if value ~= nil then
            local units = DetectUnits(normalized)
            local keys = {
                player = "general.enablePlayerCastbar",
                target = "general.enableTargetCastbar",
                focus = "general.enableFocusCastbar",
                boss = "general.enableBossCastbar",
            }
            local changes = {}
            for i = 1, #units do
                local key = keys[units[i]]
                local setting = key and A.Registry and A.Registry:GetSetting(key)
                if setting then changes[#changes + 1] = { setting = setting, value = value } end
            end
            if #changes > 0 then
                return {
                    kind = "changes",
                    changes = changes,
                    label = #changes == 1 and (changes[1].setting.label or "Cast Bar") or "Cast Bars",
                    bulkSafe = #changes > 1,
                    summary = "Changes unit Cast Bar visibility.",
                    raw = raw,
                    normalized = normalized,
                }
            end
        end
    end
    if ContainsAny(normalized, P.RootPhrases[731]) and not ContainsAny(normalized, P.RootPhrases[732]) then
        local actionKey
        local args = {}
        local label
        local summary
        local confirmRequired = false
        if ContainsAny(normalized, P.RootPhrases[733]) then
            local clear = ContainsAny(normalized, P.RootPhrases[734])
            actionKey = "confirm_wago_backup"
            args.confirmed = not clear
            label = clear and "Clear Wago backup confirmation" or "Confirm Wago backup"
            summary = "Marks the Wago backup checklist for the active profile."
        elseif ContainsAny(normalized, P.RootPhrases[735]) then
            actionKey = "open_recovery_tools"
            label = "Open recovery tools"
            summary = "Opens the Dashboard recovery area."
        elseif ContainsAny(normalized, P.RootPhrases[736]) then
            actionKey = "set_dashboard_panel"
            if ContainsAny(normalized, P.RootPhrases[737]) then
                args.open = false
            elseif ContainsAny(normalized, P.RootPhrases[738]) then
                args.open = nil
            else
                args.open = true
            end
            label = "Set Dashboard panel"
            summary = "Asks which Dashboard panel to open, such as recovery tools, scaling tools, or changelog."
        elseif ContainsAny(normalized, P.RootPhrases[739]) then
            actionKey = "set_nav_search_intro"
            if ContainsAny(normalized, P.RootPhrases[740]) then
                args.command = "seen"
            elseif ContainsAny(normalized, P.RootPhrases[741]) then
                args.command = "reset"
            else
                args.command = "show"
            end
            label = "Set search intro"
            summary = "Shows or hides the menu search intro."
        elseif ContainsAny(normalized, P.RootPhrases[742]) then
            actionKey = "set_nav_section"
            if ContainsAny(normalized, P.RootPhrases[743]) then
                args.section = "groupframes"
                label = "Group Frames"
            elseif ContainsAny(normalized, P.RootPhrases[744]) then
                args.section = "unitframes"
                label = "Frames"
            elseif ContainsAny(normalized, P.RootPhrases[745]) then
                args.section = "globalstyle"
                label = "Appearance"
            elseif ContainsAny(normalized, P.RootPhrases[746]) then
                args.section = "modules"
                label = "Advanced"
            elseif ContainsAny(normalized, P.RootPhrases[747]) then
                args.section = "auras"
                label = "Auras"
            end
            if ContainsAny(normalized, P.RootPhrases[748]) then
                args.open = false
            elseif ContainsAny(normalized, P.RootPhrases[749]) then
                args.open = nil
            else
                args.open = true
            end
            if label then
                label = (args.open == false and "Close " or (args.open == nil and "Toggle " or "Open ")) .. label .. " navigation section"
            else
                label = "Set navigation section"
            end
            summary = "Expands or collapses a menu section."
        elseif ContainsAny(normalized, P.RootPhrases[750]) then
            actionKey = "open_dashboard_panel"
            args.panel = "scaling"
            label = "Open scaling tools"
            summary = "Opens the Dashboard scaling area."
        elseif ContainsAny(normalized, P.RootPhrases[751]) then
            actionKey = "open_dashboard_panel"
            args.panel = "changelog"
            label = "Open changelog"
            summary = "Opens the Dashboard changelog."
        elseif ContainsAny(normalized, P.RootPhrases[752]) then
            if ContainsAny(normalized, P.RootPhrases[753]) then
                actionKey = "assistant.diagnostic.editMode.status"
                if ContainsAny(normalized, P.RootPhrases[754]) then args.reason = "why_exit" end
                label = "Show MSUF Edit Mode status"
            elseif ContainsAny(normalized, P.RootPhrases[755]) then
                actionKey = "assistant.action.editMode.cancel"
                confirmRequired = true
                label = "Cancel MSUF Edit Mode"
            elseif ContainsAny(normalized, P.RootPhrases[756]) then
                actionKey = "assistant.action.editMode.toggle"
                label = "Toggle MSUF Edit Mode"
            elseif ContainsAny(normalized, P.RootPhrases[757]) then
                actionKey = "assistant.action.editMode.exit"
                label = "Exit MSUF Edit Mode"
            elseif ContainsAny(normalized, P.RootPhrases[758]) then
                actionKey = "assistant.action.editMode.enter"
                label = "Enter MSUF Edit Mode"
            end
            summary = "Starts, stops, or checks MSUF Edit Mode."
        end
        local action = actionKey and A.Registry and A.Registry:GetAction(actionKey)
        if action then
            return {
                kind = "action",
                action = action,
                args = args,
                confirmRequired = confirmRequired,
                label = label or (action.label or "Assistant shortcut"),
                summary = summary or "Runs the matched Assistant shortcut.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[759]) then
        local earlyMenuSelectorParsed = (ParseGroupCopyScopeState and ParseGroupCopyScopeState(normalized))
            or (ParseUnitCopyScopeState and ParseUnitCopyScopeState(normalized))
            or (ParseMenuSelectorState and ParseMenuSelectorState(normalized))
        if earlyMenuSelectorParsed then
            earlyMenuSelectorParsed.raw = raw
            earlyMenuSelectorParsed.normalized = normalized
            return earlyMenuSelectorParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[760])
        and ContainsAny(normalized, P.RootPhrases[761])
        and not ContainsAny(normalized, P.RootPhrases[762])
    then
        local earlyCopyParsed = CopyRequest(normalized)
        if earlyCopyParsed then
            earlyCopyParsed.raw = raw
            earlyCopyParsed.normalized = normalized
            return earlyCopyParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[763]) then
        local earlyMenuWindowParsed = ParseMenuWindowAction and ParseMenuWindowAction(normalized)
        if earlyMenuWindowParsed then
            earlyMenuWindowParsed.raw = raw
            earlyMenuWindowParsed.normalized = normalized
            return earlyMenuWindowParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[764]) and not ContainsAny(normalized, P.RootPhrases[765]) then
        local earlyOpenParsed = ParseOpen and ParseOpen(normalized, raw)
        if earlyOpenParsed then
            earlyOpenParsed.raw = raw
            earlyOpenParsed.normalized = normalized
            return earlyOpenParsed
        end
    end
    if normalized == "help" or normalized == "hilfe" or ContainsAny(normalized, P.RootPhrases[766]) then
        local action = A.Registry and A.Registry:GetAction("assistant_help")
        if action then
            return {
                kind = "action",
                action = action,
                args = {},
                label = "Show Assistant help",
                summary = "Shows Assistant examples handled locally by MSUF.",
                raw = raw,
                normalized = normalized,
            }
        end
    end
    if ContainsAny(normalized, P.RootPhrases[767]) then
        local earlyScopedHelpParsed = ParseScopedHelp and ParseScopedHelp(normalized)
        if earlyScopedHelpParsed then
            earlyScopedHelpParsed.raw = raw
            earlyScopedHelpParsed.normalized = normalized
            return earlyScopedHelpParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[768]) then
        local earlySupportParsed = ParseSupportWorkflow and ParseSupportWorkflow(normalized)
        if earlySupportParsed then
            earlySupportParsed.raw = raw
            earlySupportParsed.normalized = normalized
            return earlySupportParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[769]) then
        local earlyGuidedSetupParsed = (ParseGuidedSetupFollowup and ParseGuidedSetupFollowup(normalized, ctx))
            or (ParseGuidedSetup and ParseGuidedSetup(normalized))
        if earlyGuidedSetupParsed then
            earlyGuidedSetupParsed.raw = raw
            earlyGuidedSetupParsed.normalized = normalized
            return earlyGuidedSetupParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[770]) then
        local actionKey
        local args = {}
        local label
        local summary
        local confirmRequired = false
        if ContainsAny(normalized, P.RootPhrases[771]) then
            actionKey = "assistant_nomatch_clear"
            label = "Clear Assistant learning phrases"
            summary = "Clears stored Assistant learning/no-match phrases."
            confirmRequired = true
        elseif ContainsAny(normalized, P.RootPhrases[772]) then
            actionKey = "assistant_nomatch_worklist"
            if ContainsAny(normalized, P.RootPhrases[773]) then args.owner = "action-parser" end
            label = "Show Assistant learning list"
            summary = "Shows phrases that still need better Assistant answers."
        elseif ContainsAny(normalized, P.RootPhrases[774]) then
            actionKey = "assistant_nomatch_telemetry"
            label = "Show Assistant phrases to improve"
            summary = "Shows stored phrases that still need better Assistant answers."
        elseif ContainsAny(normalized, P.RootPhrases[775]) then
            actionKey = "assistant_status"
            label = "Show MSUF status"
            summary = "Shows read-only MSUF and Assistant details."
        end
        local action = actionKey and A.Registry and A.Registry:GetAction(actionKey)
        local earlyDiagnosticParsed = action and {
            kind = "action",
            action = action,
            args = args,
            confirmRequired = confirmRequired,
            label = label or action.label or "Assistant diagnostic",
            summary = summary or "Runs an Assistant diagnostic.",
        } or (ParseDiagnostic and ParseDiagnostic(normalized))
        if earlyDiagnosticParsed then
            earlyDiagnosticParsed.raw = raw
            earlyDiagnosticParsed.normalized = normalized
            return earlyDiagnosticParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[776]) then
        local auraActionParsed = P.ParseRegistryActionAliasShortcut and P.ParseRegistryActionAliasShortcut(normalized, raw)
        if auraActionParsed then
            auraActionParsed.raw = raw
            auraActionParsed.normalized = normalized
            return auraActionParsed
        end
    end
    local actionFirstParsed
    if ContainsAny(normalized, P.RootPhrases[777]) then
        actionFirstParsed = ParseGameplayAction(normalized, raw)
    end
    actionFirstParsed = actionFirstParsed or ParsePresetWorkflow(normalized) or ParseGlobalBarsAction(normalized)
    if not actionFirstParsed and ContainsAny(normalized, P.RootPhrases[778]) then
        actionFirstParsed = ParseFontColorAction(normalized, raw)
    end
    if not actionFirstParsed
        and ContainsAny(normalized, P.RootPhrases[779])
        and ContainsAny(normalized, P.RootPhrases[780])
    then
        actionFirstParsed = ParseColorAction(normalized)
    end
    actionFirstParsed = actionFirstParsed
        or ParseScopedOverrideReset(normalized)
        or (not ContainsAny(normalized, P.RootPhrases[781]) and ParseCastbarPreviewAction(normalized))
        or ParseGroupSpellIndicatorAction(normalized, raw)
        or ParseGroupCornerIndicatorReset(normalized)
        or ParseGroupStatusPreview(normalized)
        or ParseUnitStatusPreview(normalized, ctx)
        or (P.ParseGroupStatusIconDetail and P.ParseGroupStatusIconDetail(normalized))
        or (P.ParseBarGradientRegistryShortcut and P.ParseBarGradientRegistryShortcut(normalized))
        or (P.ParsePowerBarGradientRegistryShortcut and P.ParsePowerBarGradientRegistryShortcut(normalized))
        or (P.ParseDetachedPowerBarMoveShortcut and P.ParseDetachedPowerBarMoveShortcut(normalized))
    if not actionFirstParsed
        and ContainsAny(normalized, P.RootPhrases[782])
        and not ContainsAny(normalized, P.RootPhrases[783])
    then
        actionFirstParsed = ParseGroupStatusIconReset(normalized)
            or ParseUnitStatusIndicatorReset(normalized, ctx)
    end
    if not actionFirstParsed
        and ContainsAny(normalized, P.RootPhrases[784])
        and ContainsAny(normalized, P.RootPhrases[785])
    then
        actionFirstParsed = ParseReset(normalized)
    end
    if not actionFirstParsed
        and ContainsAny(normalized, P.RootPhrases[786])
        and ContainsAny(normalized, P.RootPhrases[787])
        and not ContainsAny(normalized, P.RootPhrases[788])
    then
        actionFirstParsed = ParseReset(normalized)
    end
    if actionFirstParsed then
        actionFirstParsed.raw = raw
        actionFirstParsed.normalized = normalized
        return actionFirstParsed
    end
    local earlyAuraParsed = EarlyAuraShortcut(normalized, raw)
    if earlyAuraParsed then
        earlyAuraParsed.raw = raw
        earlyAuraParsed.normalized = normalized
        return earlyAuraParsed
    end
    local earlyTextVisibilityParsed = P.ParseTextVisibilityShortcut and P.ParseTextVisibilityShortcut(normalized)
    if earlyTextVisibilityParsed then
        earlyTextVisibilityParsed.raw = raw
        earlyTextVisibilityParsed.normalized = normalized
        return earlyTextVisibilityParsed
    end
    local earlyTextDetailParsed = (A._ParseNameTextAnchorShortcut and A._ParseNameTextAnchorShortcut(normalized))
        or (A._ParseNameTextOffsetShortcut and A._ParseNameTextOffsetShortcut(normalized))
        or (A._ParseNameTextVerticalPlacementShortcut and A._ParseNameTextVerticalPlacementShortcut(normalized))
        or (A._ParseTextSlotDropdownValueShortcut and A._ParseTextSlotDropdownValueShortcut(normalized))
        or (A._ParseHPTextOptionShortcut and A._ParseHPTextOptionShortcut(normalized))
        or (A._ParsePowerTextOptionShortcut and A._ParsePowerTextOptionShortcut(normalized))
        or (A._ParseTextAreaOffsetShortcut and A._ParseTextAreaOffsetShortcut(normalized))
        or (A._ParseTextSlotValueMoveShortcut and A._ParseTextSlotValueMoveShortcut(normalized))
        or (A._ParseTextSlotOffsetShortcut and A._ParseTextSlotOffsetShortcut(normalized))
        or (A._ParseTextFontSizeShortcut and A._ParseTextFontSizeShortcut(normalized))
    if earlyTextDetailParsed then
        earlyTextDetailParsed.raw = raw
        earlyTextDetailParsed.normalized = normalized
        return earlyTextDetailParsed
    end
    local earlyCustomAnchorSetParsed = ParseCustomAnchorSet(normalized, raw)
    if earlyCustomAnchorSetParsed then
        earlyCustomAnchorSetParsed.raw = raw
        earlyCustomAnchorSetParsed.normalized = normalized
        return earlyCustomAnchorSetParsed
    end
    local earlyPortraitDetailParsed = ParsePortraitDetailShortcut(normalized)
    if earlyPortraitDetailParsed then
        earlyPortraitDetailParsed.raw = raw
        earlyPortraitDetailParsed.normalized = normalized
        return earlyPortraitDetailParsed
    end
    local earlyPowerBarDetailParsed = (P.ParsePowerBarSizeShortcut and P.ParsePowerBarSizeShortcut(normalized))
        or (P.ParseUnitPowerBarBorderThicknessShortcut and P.ParseUnitPowerBarBorderThicknessShortcut(normalized))
        or (P.ParseUnitPowerBarBooleanShortcut and P.ParseUnitPowerBarBooleanShortcut(normalized))
        or (P.ParsePlayerPowerBarShapeShortcut and P.ParsePlayerPowerBarShapeShortcut(normalized))
        or (P.ParsePlayerPowerOrbSizeShortcut and P.ParsePlayerPowerOrbSizeShortcut(normalized))
        or (A._ParseClassPowerDetachedPlayerPowerShortcut and A._ParseClassPowerDetachedPlayerPowerShortcut(normalized, raw))
        or (P.ParseDetachedPowerBarRegistryShortcut and P.ParseDetachedPowerBarRegistryShortcut(normalized, raw))
    if earlyPowerBarDetailParsed then
        earlyPowerBarDetailParsed.raw = raw
        earlyPowerBarDetailParsed.normalized = normalized
        return earlyPowerBarDetailParsed
    end
    local earlyUnitStatusDetailParsed = (ParseUnitStatusSymbolRegistryShortcut and ParseUnitStatusSymbolRegistryShortcut(normalized))
        or (ParseStatusIconTestModeRegistryShortcut and ParseStatusIconTestModeRegistryShortcut(normalized))
        or (P.ParseUnitStatusIndicatorDetail and P.ParseUnitStatusIndicatorDetail(normalized))
    if earlyUnitStatusDetailParsed then
        earlyUnitStatusDetailParsed.raw = raw
        earlyUnitStatusDetailParsed.normalized = normalized
        return earlyUnitStatusDetailParsed
    end
    local earlyUnitLoadConditionParsed = ParseUnitLoadConditionShortcut and ParseUnitLoadConditionShortcut(normalized)
    if earlyUnitLoadConditionParsed then
        earlyUnitLoadConditionParsed.raw = raw
        earlyUnitLoadConditionParsed.normalized = normalized
        return earlyUnitLoadConditionParsed
    end
    local earlyTextLayerParsed = A._ParseTextLayerShortcut and A._ParseTextLayerShortcut(normalized)
    if earlyTextLayerParsed then
        earlyTextLayerParsed.raw = raw
        earlyTextLayerParsed.normalized = normalized
        return earlyTextLayerParsed
    end
    local earlyFrameSizeParsed = P.ParseFrameSizeExactShortcut and P.ParseFrameSizeExactShortcut(normalized)
    if earlyFrameSizeParsed then
        earlyFrameSizeParsed.raw = raw
        earlyFrameSizeParsed.normalized = normalized
        return earlyFrameSizeParsed
    end
    local earlyRootMoveParsed = (P.ParseUnitFrameRootMove and P.ParseUnitFrameRootMove(normalized))
        or (P.ParseGroupFrameRootMove and P.ParseGroupFrameRootMove(normalized))
    if earlyRootMoveParsed then
        earlyRootMoveParsed.raw = raw
        earlyRootMoveParsed.normalized = normalized
        return earlyRootMoveParsed
    end
    local earlyRangeFadeParsed = (P.ParseUnitRangeFadeShortcut and P.ParseUnitRangeFadeShortcut(normalized))
        or (A._ParseGroupRangeFadeShortcut and A._ParseGroupRangeFadeShortcut(normalized))
    if earlyRangeFadeParsed then
        earlyRangeFadeParsed.raw = raw
        earlyRangeFadeParsed.normalized = normalized
        return earlyRangeFadeParsed
    end
    if LooksLikeAlphaExcludeTextPortraitCommand(normalized) then
        local earlyAlphaExcludeParsed = P.ParseAlphaExcludeTextPortraitShortcut and P.ParseAlphaExcludeTextPortraitShortcut(normalized)
        if earlyAlphaExcludeParsed then
            earlyAlphaExcludeParsed.raw = raw
            earlyAlphaExcludeParsed.normalized = normalized
            return earlyAlphaExcludeParsed
        end
    end
    local earlyCastbarInterruptVisibilityParsed = ParseCastbarInterruptVisibilityShortcut(normalized)
    if earlyCastbarInterruptVisibilityParsed then
        earlyCastbarInterruptVisibilityParsed.raw = raw
        earlyCastbarInterruptVisibilityParsed.normalized = normalized
        return earlyCastbarInterruptVisibilityParsed
    end
    local earlyOpacityParsed = (A._ParseGroupOpacityShortcut and A._ParseGroupOpacityShortcut(normalized))
        or (ParseUnitOpacityShortcut and ParseUnitOpacityShortcut(normalized))
    if earlyOpacityParsed then
        earlyOpacityParsed.raw = raw
        earlyOpacityParsed.normalized = normalized
        return earlyOpacityParsed
    end
    if LooksLikeAbsorbBarCommand(normalized) then
        local earlyAbsorbBarParsed = ParseAbsorbBarShortcut and ParseAbsorbBarShortcut(normalized, raw)
        if earlyAbsorbBarParsed then
            earlyAbsorbBarParsed.raw = raw
            earlyAbsorbBarParsed.normalized = normalized
            return earlyAbsorbBarParsed
        end
    end
    if LooksLikeBarBorderEnumCommand(normalized) then
        local earlyBarBorderEnumParsed = ParseBarBorderEnumShortcut and ParseBarBorderEnumShortcut(normalized)
        if earlyBarBorderEnumParsed then
            earlyBarBorderEnumParsed.raw = raw
            earlyBarBorderEnumParsed.normalized = normalized
            return earlyBarBorderEnumParsed
        end
    end
    local earlyAmbiguousGroupOutlineParsed = ParseAmbiguousGroupOutlineBorderShortcut and ParseAmbiguousGroupOutlineBorderShortcut(normalized)
    if earlyAmbiguousGroupOutlineParsed then
        earlyAmbiguousGroupOutlineParsed.raw = raw
        earlyAmbiguousGroupOutlineParsed.normalized = normalized
        return earlyAmbiguousGroupOutlineParsed
    end
    if LooksLikeBarOutlineHighlightCommand(normalized) then
        local earlyBarOutlineHighlightParsed = ParseBarOutlineHighlightShortcut and ParseBarOutlineHighlightShortcut(normalized)
        if earlyBarOutlineHighlightParsed then
            earlyBarOutlineHighlightParsed.raw = raw
            earlyBarOutlineHighlightParsed.normalized = normalized
            return earlyBarOutlineHighlightParsed
        end
    end
    local earlyHealthColorParsed = P.ParseUnitHealthColorSchemeShortcut and P.ParseUnitHealthColorSchemeShortcut(normalized)
    if earlyHealthColorParsed then
        earlyHealthColorParsed.raw = raw
        earlyHealthColorParsed.normalized = normalized
        return earlyHealthColorParsed
    end
    local earlyUnitAnchorParsed = P.ParseUnitAnchorTargetShortcut and P.ParseUnitAnchorTargetShortcut(normalized)
        or (P.ParseUnitAnchorPointShortcut and P.ParseUnitAnchorPointShortcut(normalized))
    if earlyUnitAnchorParsed then
        earlyUnitAnchorParsed.raw = raw
        earlyUnitAnchorParsed.normalized = normalized
        return earlyUnitAnchorParsed
    end
    if ContainsAny(normalized, P.RootPhrases[789]) then
        local directColorParsed
        if ContainsAny(normalized, P.RootPhrases[790]) then
            directColorParsed = ParseScopedFontTextColorShortcut(normalized)
        end
        if ContainsAny(normalized, P.RootPhrases[791]) then
            directColorParsed = A._ParseClassPowerColorShortcut and A._ParseClassPowerColorShortcut(normalized, raw)
        end
        if not directColorParsed and ContainsAny(normalized, P.RootPhrases[792]) then
            directColorParsed = A._ParsePowerColorShortcut and A._ParsePowerColorShortcut(normalized, raw)
        end
        if directColorParsed then
            directColorParsed.raw = raw
            directColorParsed.normalized = normalized
            return directColorParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[793])
        and ContainsAny(normalized, P.RootPhrases[794])
    then
        local detachedPowerDetail = P.ParseDetachedPowerBarRegistryShortcut
            and P.ParseDetachedPowerBarRegistryShortcut(normalized, raw)
        if detachedPowerDetail then
            detachedPowerDetail.raw = raw
            detachedPowerDetail.normalized = normalized
            return detachedPowerDetail
        end
    end
    if ContainsAny(normalized, P.RootPhrases[795]) then
        local groupNumberParsed = P.ParseGroupNumberRegistryShortcut and P.ParseGroupNumberRegistryShortcut(normalized)
        if groupNumberParsed then
            groupNumberParsed.raw = raw
            groupNumberParsed.normalized = normalized
            return groupNumberParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[796]) and ContainsAny(normalized, P.RootPhrases[797]) then
        local castbarColorParsed = P.ParseCastbarColorShortcut and P.ParseCastbarColorShortcut(normalized, raw)
        if castbarColorParsed then
            castbarColorParsed.raw = raw
            castbarColorParsed.normalized = normalized
            return castbarColorParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[798])
        and ContainsAny(normalized, P.RootPhrases[799])
        and ContainsAny(normalized, P.RootPhrases[800])
    then
        local castbarMoveParsed = P.ParseGenericOffsetMove and P.ParseGenericOffsetMove(normalized)
        if castbarMoveParsed then
            castbarMoveParsed.raw = raw
            castbarMoveParsed.normalized = normalized
            return castbarMoveParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[801]) and not ContainsAny(normalized, P.RootPhrases[802]) then
        local statusTextParsed = A._ParseGlobalStatusTextStateShortcut and A._ParseGlobalStatusTextStateShortcut(normalized)
            or (P.ParseUnitStatusIconStyle and P.ParseUnitStatusIconStyle(normalized))
            or (P.ParseUnitStatusIndicatorDetail and P.ParseUnitStatusIndicatorDetail(normalized))
        if statusTextParsed then
            statusTextParsed.raw = raw
            statusTextParsed.normalized = normalized
            return statusTextParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[803])
        and ContainsAny(normalized, P.RootPhrases[804])
    then
        local classPowerTextOffsetParsed = A._ParseClassPowerTextOffsetShortcut and A._ParseClassPowerTextOffsetShortcut(normalized)
        if classPowerTextOffsetParsed then
            classPowerTextOffsetParsed.raw = raw
            classPowerTextOffsetParsed.normalized = normalized
            return classPowerTextOffsetParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[805]) and ContainsAny(normalized, P.RootPhrases[806]) then
        local groupRootMoveParsed = P.ParseGroupFrameRootMove and P.ParseGroupFrameRootMove(normalized)
        if groupRootMoveParsed then
            groupRootMoveParsed.raw = raw
            groupRootMoveParsed.normalized = normalized
            return groupRootMoveParsed
        end
    end
    local groupDebuffStripeParsed = ParseGroupDebuffStripeShortcut(normalized, raw)
    if groupDebuffStripeParsed then
        groupDebuffStripeParsed.raw = raw
        groupDebuffStripeParsed.normalized = normalized
        return groupDebuffStripeParsed
    end
    if ContainsAny(normalized, P.RootPhrases[807]) then
        local groupFrameParsed = P.ParseGroupPreserveRaidGroupsShortcut
            and P.ParseGroupPreserveRaidGroupsShortcut(normalized)
        if not groupFrameParsed and ContainsAny(normalized, P.RootPhrases[808]) then
            groupFrameParsed = P.ParseGroupAvailabilityIntent and P.ParseGroupAvailabilityIntent(normalized)
        end
        if groupFrameParsed then
            groupFrameParsed.raw = raw
            groupFrameParsed.normalized = normalized
            return groupFrameParsed
        end
    end
    if ContainsAny(normalized, P.RootPhrases[809]) then
        local unitRootParsed = A._ParseUnitRootVisibilityShortcut and A._ParseUnitRootVisibilityShortcut(normalized)
        if unitRootParsed then
            unitRootParsed.raw = raw
            unitRootParsed.normalized = normalized
            return unitRootParsed
        end
    end
    local exactKeyParsed = (P.ParseExactRegistryKeyShortcut and P.ParseExactRegistryKeyShortcut(normalized, raw))
        or (P.ParseExactActionKeyShortcut and P.ParseExactActionKeyShortcut(normalized, raw))
        or (P.ParseRegistryActionAliasShortcut and P.ParseRegistryActionAliasShortcut(normalized, raw))
    if exactKeyParsed then
        exactKeyParsed.raw = raw
        exactKeyParsed.normalized = normalized
        return exactKeyParsed
    end
    local priorityRegistryParsed = P.ParseRegistryPriorityShortcut and P.ParseRegistryPriorityShortcut(normalized, raw)
    if priorityRegistryParsed then
        priorityRegistryParsed.raw = raw
        priorityRegistryParsed.normalized = normalized
        return priorityRegistryParsed
    end
    local broadHumanAnchor = P.ParseBroadHumanAnchorTargetAnswer and P.ParseBroadHumanAnchorTargetAnswer(normalized, raw)
    if broadHumanAnchor then
        broadHumanAnchor.raw = raw
        broadHumanAnchor.normalized = normalized
        return broadHumanAnchor
    end
    local historyAction = A._ParseMenuHistoryAction(normalized)
    if historyAction then
        historyAction.raw = raw
        historyAction.normalized = normalized
        return historyAction
    end
    local hasEditModeContext = ContainsAny(normalized, P.RootPhrases[810])
    if not hasEditModeContext and ContainsAny(normalized, P.RootPhrases[811]) then
        return { kind = "undo" }
    end
    if not hasEditModeContext and ContainsAny(normalized, P.RootPhrases[812]) then
        return { kind = "redo" }
    end
    local guidedSetupFollowup = ParseGuidedSetupFollowup(normalized, ctx)
    if guidedSetupFollowup then
        guidedSetupFollowup.raw = raw
        guidedSetupFollowup.normalized = normalized
        return guidedSetupFollowup
    end
    local directFollowupAnswer = A._ParseFollowupAnswer and A._ParseFollowupAnswer(normalized, ctx)
    if directFollowupAnswer then
        directFollowupAnswer.raw = raw
        directFollowupAnswer.normalized = normalized
        return directFollowupAnswer
    end
    local lookupQuestion = P.ParseLookupQuestion and P.ParseLookupQuestion(normalized, raw)
    if lookupQuestion then
        lookupQuestion.raw = raw
        lookupQuestion.normalized = normalized
        return lookupQuestion
    end
    local parsed = A._ParsePipelineWorkflow(normalized, raw, ctx)
    if A and type(A.MaybeYield) == "function" then A.MaybeYield() end
    if not parsed then parsed = A._ParsePipelineGeometry(normalized, raw) end
    if A and type(A.MaybeYield) == "function" then A.MaybeYield() end
    if not parsed then parsed = A._ParsePipelineFeature(normalized, raw, ctx) end
    if A and type(A.MaybeYield) == "function" then A.MaybeYield() end
    local parsedByEarlyCompound = false
    if not parsed and P.ParseCompound then
        parsed = P.ParseCompound(normalized, raw, nil)
        parsedByEarlyCompound = parsed ~= nil
    end
    if A and type(A.MaybeYield) == "function" then A.MaybeYield() end
    if not parsed then parsed = A._ParsePipelineFallback(normalized, raw, ctx) end
    if A and type(A.MaybeYield) == "function" then A.MaybeYield() end
    if not parsedByEarlyCompound and not (parsed and parsed.compoundComplete == true) then
        local compound = P.ParseCompound and P.ParseCompound(normalized, raw, parsed)
        if compound then parsed = compound end
    end
    if parsed then
        parsed.raw = raw
        parsed.normalized = normalized
        return parsed
    end
    if P.ParseUnsupportedAuraCommand then
        local auraUnsupported = P.ParseUnsupportedAuraCommand(normalized)
        if auraUnsupported then
            auraUnsupported.raw = raw
            auraUnsupported.normalized = normalized
            return auraUnsupported
        end
    end
    return {
        kind = "unknown",
        raw = raw,
        normalized = normalized,
        text = "Which page and option do you want me to use? Example: 'set target cast bar height to 20'.",
        status = "failed",
    }
end

local function ParserContext(ctxOverride)
    if type(ctxOverride) == "table" then return ctxOverride end
    return A.GetContext and A.GetContext() or {}
end
A.ParserContext = ParserContext

A.ParsePlan = A.Parse
A.ParseForTest = A.Parse
MSUF.Public = MSUF.Public or {}
MSUF.Public.Assistant = MSUF.Public.Assistant or {}
MSUF.Public.Assistant.Parse = A.Parse
MSUF.Public.Assistant.ParseSimpleChange = A.ParseSimpleChange
