public static bool UwuifyText(RandomizationOption option)
        {
            bool keepCasing   = option.HasSubOptionSelected(RTexts.SUBOPTIONKEY_UWU_KEEPCASING);
            bool addReactions = option.HasSubOptionSelected(RTexts.SUBOPTIONKEY_REACTIONS_ENABLED);

            var existingTLK = TLKHandler.GetBuildingTLK();
            var skipIDs     = existingTLK.StringRefs.Select(x => x.StringID).ToList();
            var MERTlks     = TLKHandler.GetMERTLKs();

            var nonMerTLKs = TLKHandler.GetAllTLKs().Where(x => !MERTlks.Contains(x));

            option.ProgressValue         = 0;
            option.ProgressMax           = nonMerTLKs.Where(x => x.name.EndsWith(@"INT.tlk")).Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data)));
            option.ProgressMax          += MERTlks.Where(x => x.name.EndsWith(@"INT.tlk")).Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data)));
            option.ProgressIndeterminate = false;


            // UwUify MER TLK first
            foreach (TalkFile tf in MERTlks)
            {
                UwuifyTalkFile(tf, keepCasing, addReactions, skipIDs, true, option);
            }

            // UwUify non MER TLK
            foreach (TalkFile tf in nonMerTLKs)
            {
                UwuifyTalkFile(tf, keepCasing, addReactions, skipIDs, false, option);
            }
            return(true);
        }
        /// <summary>
        /// Swap the vowels around. Optional hard mode allows swapping 2 consonants to make it extra difficult to read
        /// </summary>
        /// <param name="Tlks"></param>
        public static bool RandomizeVowels(RandomizationOption option)
        {
            // Map of what letter maps to what other letter
            MERLog.Information("Randomizing vowels in words");
            var hardMode = option.HasSubOptionSelected(RTexts.SUBOPTIONKEY_VOWELS_HARDMODE);


            var existingTLK = TLKHandler.GetBuildingTLK();
            var skipIDs     = existingTLK.StringRefs.Select(x => x.StringID).ToList();
            var MERTLKs     = TLKHandler.GetMERTLKs();
            Dictionary <char, char> vowels      = null;
            List <char>             vowelValues = null;

            bool retryMapping = true;

            while (retryMapping)
            {
                bool failed = false;
                vowels      = GetVowelMap();
                vowelValues = vowels.Values.ToList();

                int numAttemptsRemaining = 10;

                foreach (var sourceVowel in vowels.Keys)
                {
                    var value = vowelValues.RandomElement();
                    while (hardMode && value == sourceVowel && numAttemptsRemaining > 0)
                    {
                        value = vowelValues.RandomElement();
                        numAttemptsRemaining--;
                    }

                    if (numAttemptsRemaining == 0 && hardMode && value == sourceVowel)
                    {
                        // This attempt has failed
                        MERLog.Warning(@"Hard mode vowel randomization failed, retrying");
                        failed = true;
                        break;
                    }

                    vowelValues.Remove(value); // Do not allow reassignment of same vowel
                    Debug.WriteLine($"Vowel Randomizer: {sourceVowel} -> {value}");
                    vowels[sourceVowel] = value;
                }

                if (!failed)
                {
                    retryMapping = false;
                }
            }

            var consonants = GetConsonantMap();

            if (hardMode)
            {
                // Swap some consontants around
                var numConsonantsToRandomize = 2;
                var consonantValues          = consonants.Values.ToList();
                while (numConsonantsToRandomize > 0)
                {
                    var sourceValue = consonantValues.RandomElement();
                    var value       = consonantValues.RandomElement();
                    while (sourceValue == value)
                    {
                        value = consonantValues.RandomElement();
                    }
                    consonantValues.Remove(value);       // Do not allow reassignment of same vowel
                    consonantValues.Remove(sourceValue); // Do not allow reassignment of same vowel

                    Debug.WriteLine($"Vowel Randomizer Hard Mode: {sourceValue} -> {value}");

                    consonants[sourceValue] = value;
                    consonants[value]       = sourceValue;
                    numConsonantsToRandomize--;
                }
            }

            // Build full translation map (uppercase)
            var translationMapUC = new[] { vowels, consonants }.SelectMany(dict => dict)
            .ToDictionary(pair => pair.Key, pair => pair.Value);

            // Add lowercase translation
            var lowerCaseMap = translationMapUC.ToDictionary(x => char.ToLowerInvariant(x.Key), x => char.ToLowerInvariant(x.Value));

            // Build a full translation
            var translationMap = new[] { translationMapUC, lowerCaseMap }.SelectMany(dict => dict)
            .ToDictionary(pair => pair.Key, pair => pair.Value);

            var nonMERTLKs = TLKHandler.GetAllTLKs().Where(x => !MERTLKs.Contains(x)).ToList();

            // MER

            option.ProgressValue         = 0;
            option.ProgressMax           = nonMERTLKs.Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data)));
            option.ProgressMax          += MERTLKs.Sum(x => x.StringRefs.Count(y => y.StringID > 0 && !string.IsNullOrWhiteSpace(y.Data)));
            option.ProgressIndeterminate = false;

            foreach (var merTLK in MERTLKs)
            {
                RandomizeVowelsInternal(merTLK, skipIDs, translationMap, true, option);
            }

            // Non MER
            Parallel.ForEach(nonMERTLKs, tf =>
            {
                RandomizeVowelsInternal(tf, skipIDs, translationMap, false, option);
            });
            return(true);
        }