-- read namespace from global env
local AddonName, _ = ...
local _G = _G
local Grichelde = _G.Grichelde

local L = LibStub('AceLocale-3.0'):NewLocale(AddonName, 'enUS', true)
if not L then return end

local cYellow    = Grichelde.F.cYellow
local cGray      = Grichelde.F.cGray
local cHyperlink = Grichelde.F.cHyperlink
local cPrefix    = Grichelde.F.cPrefix

-- system messages
L.AddonName = "Grichelde"
L.AddonNamePlusVersion = "%s v%s"
L.AddonLoaded = "%s happily assists you with your spelling disabilities now."
L.AddonUnloaded = "%s patiently awaits to support you again."
L.Upgrade_ToVersion = "Upgrade database to version %s."
L.Upgrade_Successful = "Upgrade successful."
L.Upgrade_Error = "Upgrade failed!"
L.Downgrade_Detected = "Downgrade detected, %s might not work correctly!"

-- debug
L.Debug_Options = "Options"
L.Debug_Mappings = "Mappings"
L.Debug_Mappings_Hint = "The content of this input box is used for debugging purposes only and can be copied. No input from this box will be read or processed."
L.Debug_Mappings_Found = "%d mappings found"
L.Debug_Profile = "Profile"

-- errors
L.Error_InvalidCommand = "Invalid command"
L.Error_InvalidChannel = "Invalid channel"
L.Error_InvalidWhisperTarget = "Invalid whisper target"
L.Error_UnsupportedChannel = "Unsupported channel"

-- profiles
L.Profiles_Available = "Available profiles:"
L.Profiles_Created = "New profile %s created."
L.Profiles_Loaded = "Profile %s is loaded."
L.Profiles_Activated = "Profile %s activated."
L.Profiles_Deactivated = "Profile %s deactivated."
L.Profiles_Refreshed = "Profile %s refreshed."
L.Profiles_Deleted = "Profile %s deleted."
L.Profiles_Copied = "Settings applied from profile %s."
L.Profiles_Reset = "Profile %s reset."
L.Profiles_Invalid = "Invalid profile %s!"
L.Profiles_DeleteError = "The active profile cannot be deleted!"
L.Profiles_AlreadyExistsError = "The profile %s already exists!"

-- minimap
L.Minimap_Tooltip_Enabled = "%s"
L.Minimap_Tooltip_Disabled = "%s " .. cGray("(inactive)")
L.Minimap_Tooltip_Options_Left = "Left-Click"
L.Minimap_Tooltip_Options_Right = "Opens or closes the options UI."
L.Minimap_Tooltip_Mappings_Left = "Right-Click"
L.Minimap_Tooltip_Mappings_Right = "Enables or disables any replacements."

-- options
L.Options_Title = "%s Options"
L.Options_Enabled_Name = "Enabled"
L.Options_Enabled_Desc = "Enables %s"
L.Options_Minimap_Button_Name = "Show minimap button"
L.Options_Minimap_Button_Desc = "Shows or hides the button on the minimap."

L.Options_Channels_Group_Name = "Channels"
L.Options_Channels_Group_Desc = "%s is active in the following channels."
L.Options_Channels_Header = "Text replacement will only be done for marked channels below:"

L.Options_Channel_Say_Name = "Say"
L.Options_Channel_Say_Desc = "Activates %s in channel \"Say\"."
L.Options_Channel_Emote_Name = "Emote"
L.Options_Channel_Emote_Desc = "Activates %s in channel \"Emote\"."
L.Options_Channel_Yell_Name = "Yell"
L.Options_Channel_Yell_Desc = "Activates %s in channel \"Yell\"."
L.Options_Channel_Party_Name = "Party"
L.Options_Channel_Party_Desc = "Activates %s in channel \"Party\"."
L.Options_Channel_PartyLeader_Name = "Party Leader"
L.Options_Channel_PartyLeader_Desc = "Activates %s in channel \"Party Leader\"."
L.Options_Channel_Guild_Name = "Guild"
L.Options_Channel_Guild_Desc = "Activates %s in channel \"Guild\"."
L.Options_Channel_Officer_Name = "Officers"
L.Options_Channel_Officer_Desc = "Activates %s in channel \"Officers\"."
L.Options_Channel_Raid_Name = "Raid"
L.Options_Channel_Raid_Desc = "Activates %s in channel \"Raid\"."
L.Options_Channel_RaidLeader_Name = "Raid Leader"
L.Options_Channel_RaidLeader_Desc = "Activates %s in channel \"Raid Leader\"."
L.Options_Channel_RaidWarning_Name = "Raid Warning"
L.Options_Channel_RaidWarning_Desc = "Activates %s in channel \"Raid Warning\"."
L.Options_Channel_Instance_Name = "Instance"
L.Options_Channel_Instance_Desc = "Activates %s in channel \"Instance\"."
L.Options_Channel_Battleground_Name = "Battleground"
L.Options_Channel_Battleground_Desc = "Activates %s in channel \"Battleground\"."
L.Options_Channel_Whisper_Name = "Whisper"
L.Options_Channel_Whisper_Desc = "Activates %s in channel \"Whisper\"."

L.Options_Replacements_Group_Name = "Replacements"
L.Options_Replacements_Group_Desc = "These lookups will be replaced in activated channels."
L.Options_Replacements_Add_Name = "Add"
L.Options_Replacements_Add_Desc = "Adds a new replacement mapping."
L.Options_Replacements_DeleteAll_Name = "Delete All"
L.Options_Replacements_DeleteAll_Desc = "Deletes all replacement mappings."
L.Options_Replacements_DeleteAll_ConfirmText = "Do you really want to delete ALL replacement mappings?"
L.Options_Replacements_Header = "All matches on the lefthand side of the arrow \"=>\" will be replaced in activated channels by the text on the righthand side. "

L.Options_Mapping_Group_Name = "%s => %s"
L.Options_Mapping_Group_Desc = "This lookup will be replaced in activated channels."
L.Options_Mapping_EmptyMapping = "(none)"
L.Options_Mapping_MoveUp_Name = "^"
L.Options_Mapping_MoveUp_Desc = "move up"
L.Options_Mapping_MoveDown_Name = "v"
L.Options_Mapping_MoveDown_Desc = "move down"
L.Options_Mapping_MatchWhen_Name = "when:"
L.Options_Mapping_MatchWhen_Desc = "Replacement is only done if the search text matches either |nanywhere (<always>), |nif the search text mantches <as a whole word>, |nolny at the <start of each word>, |nor at the <end of each word>, |nor <only at the start or end of each word> but not in between, |nor only in the middle of each word, but <never at start or end of any word>."
L.Options_Mapping_MatchWhen_Select1 = "never (disabled)"
L.Options_Mapping_MatchWhen_Select2 = "always"
L.Options_Mapping_MatchWhen_Select3 = "as a whole word"
L.Options_Mapping_MatchWhen_Select4 = "start of each word"
L.Options_Mapping_MatchWhen_Select5 = "end of each word"
L.Options_Mapping_MatchWhen_Select6 = "only at start and end of each word"
L.Options_Mapping_MatchWhen_Select7 = "never at start or end of any word"
L.Options_Mapping_SearchText_Name = "Search for:"
L.Options_Mapping_SearchText_Desc = "This text is looked up in your chat input box."
L.Options_Mapping_ReplaceText_Name = "Replacement:"
L.Options_Mapping_ReplaceText_Desc = "Any match will be replaced with this text."
L.Options_Mapping_ExactCase_Name = "exact case"
L.Options_Mapping_ExactCase_Desc = "When set, matches must be case-sensitive. Otherwise the case for each letter of the matching text is taken over when replaced."
L.Options_Mapping_Consolidate_Name = "consolidate consecutive matches"
L.Options_Mapping_Consolidate_Desc = "If after the replacement a text sequence is repeated|ndirectly after another, treat them as one occurrence."
L.Options_Mapping_StopOnMatch_Name = "stop on match"
L.Options_Mapping_StopOnMatch_Desc = "Stops looking for any following replacements, when this one matched."
L.Options_Mapping_Delete_Name = "Delete"
L.Options_Mapping_Delete_Desc = "Deletes this replacement mapping."
L.Options_Mapping_Delete_ConfirmText = "Delete this replacement mapping?"

L.Options_Help_Group_Name = "Help"
L.Options_Help_Group_Desc = "Guideance to search patterns and replacement logic."
L.Options_Help_Disclaimer = cYellow("Disclaimer of warranty:") .. " The addon is provided \"AS IS\" and comes without warranty of any kind of function or correctness (for more details, consult the GPL 3 license). "
                            .."Also the author is not held responsible for any risk or damage the addon or its use might cause, especially lost of progress or data due to crashes of the WoW client."

L.Options_Help_Tab_Info_Name = "Info"
L.Options_Help_Tab_Info_Desc = "About this addon."
L.Options_Help_Tab_Basics_Name = "Basics"
L.Options_Help_Tab_Basics_Desc = "Some explanatory notes the the basic behaviour."
L.Options_Help_Tab_Expert_Name = "Expert"
L.Options_Help_Tab_Expert_Desc = "More details on special search options."
L.Options_Help_Tab_Examples_Name = "Examples"
L.Options_Help_Tab_Examples_Desc = "Templates for particular scenarios."

L.Options_Help_Info = cYellow("About this addon")
                        .. "|n%s replaces any characters or words you typed in a chatbox according to your replacement rules and text. The replacement is done before the text is send to other players/in the target channel. "
                        .. "It does not change text other players have written in the chat, but the text they will see from you. Its purpose is to simulate a speaking disability of your toon and to strengthen immersion in roleplay."
                        .. "|n|nOf course it can be used for many other things, too (trollifier, abbreviations, nick names, etc.). A extensive description of all options, the general replacement workflow and a lot of examples can be found on the next tabs."
                        .. "|n|n" .. cYellow("Contact")
                        .. "|nPlease report errors and your experiences directly as a comment on the project website at " .. cPrefix("CurseForge") .. " (" .. cHyperlink("https://www.curseforge.com/wow/addons/grichelde") .. "). "
                        .. "You are encouraged to attach screenshots of error messages and your mappings. An overview of all your mappings is shnown by using the command " .. cPrefix("\"/gri mappings\"") .. " and copy it out. "
                        .. "|nI'm looking forward for your feedback and reports."
                        .. "|n|n" .. cYellow("Thanks")
                        .. "|Many thanks to my beta testers " .. cPrefix("Chamera") .. ", " .. cPrefix("Tabenoca") .. " and " .. cPrefix("Nordraka") .. ", and very special thanks to " .. cPrefix("Shinue") .. " for the inspiration and hilarious moments."
L.Options_Help_Basics = cYellow("Ordering")
                        .. "|nYou can have an unlimited number of replacements. All mappings will be processed in same order as defined, from top down. "
                        .. "Replacements are also transitive, so consecutive mappings do not work on the original input but the resulting text from the previous replacements. "
                        .. "|nBoth mappings " .. cPrefix("\"a\" => \"b\"") .. " and " .. cPrefix("\"b\" => \"c\"") .. " applied, result in the final text " .. cPrefix("\"a\" => \"c\"") .. "."
                        .. "|n|n" .. cYellow("exact case")
                        .. "|nIf \"exact case\" is checked, lower and upper case must match exactly to be replaced, otherwise the mapping is skipped. "
                        .. "If case sensivity is ignored, the case for each letter of the matching text is taken over when replaced. "
                        .. "|nWith mapping " .. cPrefix("\"aBcDeF\" => \"uvWXYz\"") .. " text results in " .. cPrefix("\"abcdef\" => \"uvwxyz\"") .. ", "
                        .. "also " .. cPrefix("\"ABCDEF\" => \"UVWXYZ\"") .. " and " .. cPrefix("\"AbCdEf\" => \"UvWxYz\"") .. "."
                        .. "|n|n" .. cYellow("consolidate consecutive matches")
                        .. "|nConsolidation of consecutive matches prevent unaesthetic repetitions of letters introduced during replacements. "
                        .. "Consolidation takes place after all replacements were done, meaning it's applied to the completely replaced text. "
                        .. "|nWith mapping " .. cPrefix("\"s\" => \"sh\"") .. " text becomes " .. cPrefix("\"tossing\" => \"toshing\"") .. " instead of " .. cPrefix("\"toshshing\"") .. ", yet still " .. cPrefix("\"paths\" => \"pathsh\"") .. ". "
                        .. "Such edge cases can usually be mitigated with an additional mapping at the end: " .. cPrefix("\"thsh\" => \"thz\"") .. "."
                        .. "|n|n" .. cYellow("stop on match")
                        .. "|nAll other consecutive replacements are skipped, when the current mapping matched. When the current mapping does not match, the remaining mappings are processed as usual."
L.Options_Help_Expert = cYellow("shortening/lengthening replacements")
                        .. "|nIf the replacement is shorter than the actual match, all remaining characters will be skipped. If the replacement is longer, all remaining characters will be appended. "
                        .. "The case of the replaced character is considered as well as the case of the next character in the original text. That way capital case abbreviations and expressions will not be distorted. "
                        .. "|nWith mapping " .. cPrefix("\"Body\" => \"Corpse\"") .. " the input becomes " .. cPrefix("\"BODY\" => \"CORPSE\"") .. " instead of " .. cPrefix("\"CORPse\"") .. " "
                        .. "but still keeps intended exceptions like " .. cPrefix("\"BodYGuard\" => \"CorPSEGuard\"") .. " instead of " .. cPrefix("\"CorpseGuard\"") .. ". "
                        .. "|n|n" .. cYellow("On-Demand")
                        .. "|nFor convenience input text in a chatbox can be forcefully replaced, even if the addon or the channel was disabled. "
                        .. "In the chatbox put " .. cPrefix("/gri") .. " or " .. cPrefix("/grichelde") .. " in front of your typed text, you can also include the target channel, "
                        .. "i.e. " .. cPrefix("\"/gri /guild hello there\"") .. " and the active replacements are applied even if the guild channel or global switch was disabled."
                        .. "|n|n" .. cYellow("Regular Expressions")
                        .. "|nRegEx are very powerful search and replacement patterns commonly used in programming. Technically all searches the addon performs on the input are done with regular expression methods, "
                        .. "however Lua unfortunately does not support full PCRE syntax and is very limited. Nevertheless some patterns can be used like the anchors start of line " .. cPrefix("\"^\"") .. " or end of line " .. cPrefix("\"$\"")
                        .. ", capturing groups " .. cPrefix("\"(hello) (world)\"") .. "character classes like numbers " .. cPrefix("\"%d\"") .. " or (inversed) sets " .. cPrefix("\"[^%p]\"") .. ". "
                        .. "Capture groups can be accessed in the replacement text with %<number> like in " .. cPrefix("\"%2 %1\"").. "."
                        .. "|nAlso there are some mappings using RegEx in the Example section."

L.Options_Help_Examples_Note = cYellow("Note:") .. " This addon does not encourange or intend to hurt or to tease people with speaking disabilities or language disorders. The responsibility rest on the user completely. Please use the features with care and respect to other players."
L.Options_Help_Examples_Header = cYellow("Example")
L.Options_Help_Examples_Text = "Select an example from the dropdown above."
L.Options_Help_Examples_Import_Name = "Import"
L.Options_Help_Examples_Import_Desc = "Imports the selected example into a new profile."
L.Options_Help_Examples_Import_ConfirmText = "This will import the example %s into the nre profile %s."

L.Options_Help_Examples = {
    {
        name = "absent jaw",
        desc = cYellow("S and P will be replaced by sibilant and clack sounds."),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "s",
                replaceText = "ch",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_11 = {
                order = 11,
                searchText = "t",
                replaceText = "ck",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_12 = {
                order = 12,
                searchText = "p",
                replaceText = "b",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
        }
    }, {
        name = "trollifier",
        desc = cYellow("Almost sound like Vol'jin."),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "(%w)(%p?)$",
                replaceText = "%1, mon%2",
                exactCase = false,
                consolidate = false,
                matchWhen = 5,
                stopOnMatch = false,
            },
            replacement_11 = {
                order = 11,
                searchText = "th",
                replaceText = "d",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_12 = {
                order = 12,
                searchText = "what are you",
                replaceText = "whatcha",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_13 = {
                order = 13,
                searchText = "your?s?",
                replaceText = "ya",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_14 = {
                order = 14,
                searchText = "going to",
                replaceText = "gonna",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_15 = {
                order = 15,
                searchText = "want to",
                replaceText = "wanna",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_16 = {
                order = 16,
                searchText = "ing",
                replaceText = "in'",
                exactCase = false,
                consolidate = true,
                matchWhen = 5,
                stopOnMatch = false,
            },
        }
    }, {
        name = "Jar Jar Binks",
        desc = cYellow("Lets you sound like a clumsy Gungan"),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "me",
                replaceText = "mesa",
                exactCase = false,
                consolidate = false,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_11 = {
                order = 11,
                searchText = "I am",
                replaceText = "Mesa",
                exactCase = true,
                consolidate = false,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_12 = {
                order = 12,
                searchText = "I'm",
                replaceText = "Mesa",
                exactCase = true,
                consolidate = false,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_13 = {
                order = 13,
                searchText = "I",
                replaceText = "Me",
                exactCase = true,
                consolidate = false,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_14 = {
                order = 14,
                searchText = "you are",
                replaceText = "yousa",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_15 = {
                order = 15,
                searchText = "you're",
                replaceText = "yousa",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_16 = {
                order = 16,
                searchText = "your",
                replaceText = "yous",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_17 = {
                order = 17,
                searchText = "(s?)he is",
                replaceText = "%1hesa",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_18 = {
                order = 18,
                searchText = "(s?)he's",
                replaceText = "%1hesa",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_19 = {
                order = 19,
                searchText = "they",
                replaceText = "daysa",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_20 = {
                order = 20,
                searchText = "them",
                replaceText = "them-sa",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_21 = {
                order = 21,
                searchText = "ing",
                replaceText = "in'",
                exactCase = false,
                consolidate = true,
                matchWhen = 5,
                stopOnMatch = false,
            },
            replacement_22 = {
                order = 22,
                searchText = "the",
                replaceText = "da",
                exactCase = false,
                consolidate = false,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_23 = {
                order = 23,
                searchText = "th",
                replaceText = "d",
                exactCase = false,
                consolidate = false,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_24 = {
                order = 24,
                searchText = "yes",
                replaceText = "yesa",
                exactCase = false,
                consolidate = false,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_25 = {
                order = 25,
                searchText = "oka?y?",
                replaceText = "okeeday",
                exactCase = false,
                consolidate = false,
                matchWhen = 3,
                stopOnMatch = false,
            },
        }
    }, {
        name = "old-fashioned",
        desc = cYellow("Use an outdated pronounciation."),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "oi",
                replaceText = "oy",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_11 = {
                order = 11,
                searchText = "([^aeiou]*)([aeiou])",
                replaceText = "%1%2e",
                exactCase = false,
                consolidate = true,
                matchWhen = 5,
                stopOnMatch = false,
            },
            replacement_12 = {
                order = 12,
                searchText = "yours",
                replaceText = "thy",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_13 = {
                order = 13,
                searchText = "youe",
                replaceText = "thou",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
        }
    }, {
        name = "abbreviations",
        desc = cYellow("Say much, type less."),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "gz",
                replaceText = "Congratulations",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_11 = {
                order = 11,
                searchText = "gn8",
                replaceText = "Good night",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_12 = {
                order = 12,
                searchText = "afk",
                replaceText = "I'm temporarily unavailable (AFK)",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_13 = {
                order = 13,
                searchText = "MC",
                replaceText = "Molten Core",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
        }
    }, {
        name = "Proper names",
        desc = cYellow("Replace player names, NPCs or locations."),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "Sylvanas",
                replaceText = "the revengeful banshee queen",
                exactCase = true,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_11 = {
                order = 11,
                searchText = "Asmon",
                replaceText = "Asmongold",
                exactCase = true,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
            replacement_12 = {
                order = 12,
                searchText = "x%-?roads",
                replaceText = "Crossroads",
                exactCase = false,
                consolidate = true,
                matchWhen = 3,
                stopOnMatch = false,
            },
        }
    }, {
        name = "Lisp",
        desc = cYellow("S and Z will become sibilant"),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "s",
                replaceText = "th",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_11 = {
                order = 11,
                searchText = "ch",
                replaceText = "tsh",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_12 = {
                order = 12,
                searchText = "z",
                replaceText = "tsh",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
            replacement_13 = {
                order = 13,
                searchText = "dg",
                replaceText = "ck",
                exactCase = false,
                consolidate = true,
                matchWhen = 2,
                stopOnMatch = false,
            },
        }
    }, {
        name = "stammer",
        desc = cYellow("Repeats vowels at the beginning of a sentence"),
        replacements = {
            replacement_10 = {
                order = 10,
                searchText = "^([^aeiouy]-)([aeiouy])",
                replaceText = "%1%2-%1%2-%1%2",
                exactCase = false,
                consolidate = true,
                matchWhen = 4,
                stopOnMatch = false,
            },
        }
    },
}

L.IgnorePattern_Star = "Star"
L.IgnorePattern_Circle = "Circle"
L.IgnorePattern_Diamond = "Diamond"
L.IgnorePattern_Triangle = "Triangle"
L.IgnorePattern_Moon = "Moon"
L.IgnorePattern_Square = "Square"
L.IgnorePattern_Cross = "Cross"
L.IgnorePattern_Skull = "Skull"