Decompiled source of RussianAtlyssNonOfficial v1.1.2

Localyssation.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Localyssation.Patches;
using Nessie.ATLYSS.EasySettings;
using Nessie.ATLYSS.EasySettings.UIElements;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Localyssation")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Localyssation")]
[assembly: AssemblyTitle("Localyssation")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: UnverifiableCode]
namespace Localyssation
{
	internal static class LangAdjustables
	{
		public interface ILangAdjustable
		{
			void AdjustToLanguage(Language newLanguage);
		}

		public class LangAdjustableUIText : MonoBehaviour, ILangAdjustable
		{
			public Text text;

			public Func<int, string> newTextFunc;

			public bool textAutoShrinkable = true;

			public bool textAutoShrunk = false;

			public bool orig_resizeTextForBestFit = false;

			public int orig_resizeTextMaxSize;

			public int orig_resizeTextMinSize;

			public void Awake()
			{
				text = ((Component)this).GetComponent<Text>();
				Localyssation.instance.onLanguageChanged += onLanguageChanged;
			}

			public void Start()
			{
				AdjustToLanguage(Localyssation.currentLanguage);
			}

			private void onLanguageChanged(Language newLanguage)
			{
				AdjustToLanguage(newLanguage);
			}

			public void AdjustToLanguage(Language newLanguage)
			{
				if (newTextFunc != null)
				{
					text.text = newTextFunc(text.fontSize);
				}
				if (newLanguage.info.autoShrinkOverflowingText == textAutoShrunk)
				{
					return;
				}
				if (newLanguage.info.autoShrinkOverflowingText)
				{
					if (textAutoShrinkable)
					{
						orig_resizeTextForBestFit = text.resizeTextForBestFit;
						orig_resizeTextMaxSize = text.resizeTextMaxSize;
						orig_resizeTextMinSize = text.resizeTextMinSize;
						text.resizeTextMaxSize = text.fontSize;
						text.resizeTextMinSize = Math.Min(2, text.resizeTextMinSize);
						text.resizeTextForBestFit = true;
						textAutoShrunk = true;
					}
				}
				else
				{
					text.resizeTextForBestFit = orig_resizeTextForBestFit;
					text.resizeTextMaxSize = orig_resizeTextMaxSize;
					text.resizeTextMinSize = orig_resizeTextMinSize;
					textAutoShrunk = false;
				}
			}

			public void OnDestroy()
			{
				Localyssation.instance.onLanguageChanged -= onLanguageChanged;
			}
		}

		public class LangAdjustableUIDropdown : MonoBehaviour, ILangAdjustable
		{
			public Dropdown dropdown;

			public List<Func<int, string>> newTextFuncs;

			public void Awake()
			{
				dropdown = ((Component)this).GetComponent<Dropdown>();
				Localyssation.instance.onLanguageChanged += onLanguageChanged;
				if (Object.op_Implicit((Object)(object)dropdown.itemText))
				{
					((Component)dropdown.itemText).gameObject.AddComponent<LangAdjustableUIText>();
				}
				if (Object.op_Implicit((Object)(object)dropdown.captionText))
				{
					((Component)dropdown.captionText).gameObject.AddComponent<LangAdjustableUIText>();
				}
			}

			public void Start()
			{
				AdjustToLanguage(Localyssation.currentLanguage);
			}

			private void onLanguageChanged(Language newLanguage)
			{
				AdjustToLanguage(newLanguage);
			}

			public void AdjustToLanguage(Language newLanguage)
			{
				if (newTextFuncs.Count == dropdown.options.Count)
				{
					for (int i = 0; i < dropdown.options.Count; i++)
					{
						OptionData val = dropdown.options[i];
						val.text = newTextFuncs[i](-1);
					}
					dropdown.RefreshShownValue();
				}
			}

			public void OnDestroy()
			{
				Localyssation.instance.onLanguageChanged -= onLanguageChanged;
			}
		}

		public static List<ILangAdjustable> nonMonoBehaviourAdjustables = new List<ILangAdjustable>();

		public static void Init()
		{
			Localyssation.instance.onLanguageChanged += delegate(Language newLanguage)
			{
				List<ILangAdjustable> list = new List<ILangAdjustable>(nonMonoBehaviourAdjustables);
				foreach (ILangAdjustable item in list)
				{
					item.AdjustToLanguage(newLanguage);
				}
			};
		}

		public static Func<int, string> GetStringFunc(string key, string defaultValue = "SAME_AS_KEY")
		{
			return (int fontSize) => Localyssation.GetString(key, fontSize, defaultValue);
		}

		public static void RegisterText(Text text, Func<int, string> newTextFunc)
		{
			if (!Object.op_Implicit((Object)(object)((Component)text).GetComponent<LangAdjustableUIText>()))
			{
				LangAdjustableUIText langAdjustableUIText = ((Component)text).gameObject.AddComponent<LangAdjustableUIText>();
				langAdjustableUIText.newTextFunc = newTextFunc;
			}
		}

		public static void RegisterDropdown(Dropdown dropdown, List<Func<int, string>> newTextFuncs)
		{
			if (!Object.op_Implicit((Object)(object)((Component)dropdown).GetComponent<LangAdjustableUIDropdown>()))
			{
				LangAdjustableUIDropdown langAdjustableUIDropdown = ((Component)dropdown).gameObject.AddComponent<LangAdjustableUIDropdown>();
				langAdjustableUIDropdown.newTextFuncs = newTextFuncs;
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.themysticsword.localyssation", "Localyssation", "0.0.3")]
	public class Localyssation : BaseUnityPlugin
	{
		private delegate string TextEditTagFunc(string str, string arg, int fontSize);

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__24_0;

			public static UnityAction<int> <>9__25_0;

			public static UnityAction <>9__25_1;

			public static UnityAction <>9__25_2;

			internal void <Awake>b__24_0()
			{
				settingsTabReady = true;
				TrySetupSettingsTab();
			}

			internal void <TrySetupSettingsTab>b__25_0(int valueIndex)
			{
				Language language = languagesList[valueIndex];
				ChangeLanguage(language);
				configLanguage.Value = language.info.code;
			}

			internal void <TrySetupSettingsTab>b__25_1()
			{
				foreach (KeyValuePair<string, string> @string in defaultLanguage.strings)
				{
					if (!currentLanguage.strings.ContainsKey(@string.Key))
					{
						currentLanguage.strings[@string.Key] = @string.Value;
					}
				}
				currentLanguage.WriteToFileSystem();
			}

			internal void <TrySetupSettingsTab>b__25_2()
			{
				int num = 0;
				int num2 = 0;
				logger.LogMessage((object)("Logging strings that are the same in " + defaultLanguage.info.name + " and " + currentLanguage.info.name + ":"));
				foreach (KeyValuePair<string, string> @string in currentLanguage.strings)
				{
					if (defaultLanguage.strings.TryGetValue(@string.Key, out var value))
					{
						num2++;
						if (@string.Value == value)
						{
							logger.LogMessage((object)@string.Key);
						}
						else
						{
							num++;
						}
					}
				}
				logger.LogMessage((object)$"Done! {num}/{num2} ({(float)(num / num2) * 100f:0.00}%) strings are different between the languages.");
			}

			internal string <.cctor>b__40_0(string str, string arg, int fontSize)
			{
				if (str.Length > 0)
				{
					string text = str[0].ToString();
					str = str.Remove(0, 1);
					str = str.Insert(0, text.ToUpper());
				}
				return str;
			}

			internal string <.cctor>b__40_1(string str, string arg, int fontSize)
			{
				if (str.Length > 0)
				{
					string text = str[0].ToString();
					str = str.Remove(0, 1);
					str = str.Insert(0, text.ToLower());
				}
				return str;
			}

			internal string <.cctor>b__40_2(string str, string arg, int fontSize)
			{
				if (fontSize > 0)
				{
					try
					{
						float num = float.Parse(arg, CultureInfo.InvariantCulture);
						str = $"<size={Math.Round((float)fontSize * num)}>{str}</size>";
					}
					catch
					{
					}
				}
				else
				{
					str = "<scalefallback=" + arg + ">" + str + "</scalefallback>";
				}
				return str;
			}

			internal string <.cctor>b__40_3(string str, string arg, int fontSize)
			{
				if (fontSize > 0)
				{
					try
					{
						float num = float.Parse(arg, CultureInfo.InvariantCulture);
						str = $"<size={Math.Round((float)fontSize * num)}>{str}</size>";
					}
					catch
					{
					}
				}
				return str;
			}
		}

		public const string PLUGIN_GUID = "com.themysticsword.localyssation";

		public const string PLUGIN_NAME = "Localyssation";

		public const string PLUGIN_VERSION = "0.0.3";

		public static Localyssation instance;

		internal static Assembly assembly;

		internal static string dllPath;

		public static Language defaultLanguage;

		public static Language currentLanguage;

		public static Dictionary<string, Language> languages = new Dictionary<string, Language>();

		public static readonly List<Language> languagesList = new List<Language>();

		internal static ManualLogSource logger;

		internal static ConfigFile config;

		internal static ConfigEntry<string> configLanguage;

		internal static ConfigEntry<bool> configTranslatorMode;

		internal static ConfigEntry<bool> configCreateDefaultLanguageFiles;

		internal static ConfigEntry<KeyCode> configReloadLanguageKeybind;

		internal static bool settingsTabReady = false;

		internal static bool languagesLoaded = false;

		internal static bool settingsTabSetup = false;

		internal static AtlyssDropdown languageDropdown;

		public const string GET_STRING_DEFAULT_VALUE_ARG_UNSPECIFIED = "SAME_AS_KEY";

		private static Dictionary<string, TextEditTagFunc> textEditTags = new Dictionary<string, TextEditTagFunc>
		{
			{
				"firstupper",
				delegate(string str, string arg, int fontSize)
				{
					if (str.Length > 0)
					{
						string text2 = str[0].ToString();
						str = str.Remove(0, 1);
						str = str.Insert(0, text2.ToUpper());
					}
					return str;
				}
			},
			{
				"firstlower",
				delegate(string str, string arg, int fontSize)
				{
					if (str.Length > 0)
					{
						string text = str[0].ToString();
						str = str.Remove(0, 1);
						str = str.Insert(0, text.ToLower());
					}
					return str;
				}
			},
			{
				"scale",
				delegate(string str, string arg, int fontSize)
				{
					if (fontSize > 0)
					{
						try
						{
							float num2 = float.Parse(arg, CultureInfo.InvariantCulture);
							str = $"<size={Math.Round((float)fontSize * num2)}>{str}</size>";
						}
						catch
						{
						}
					}
					else
					{
						str = "<scalefallback=" + arg + ">" + str + "</scalefallback>";
					}
					return str;
				}
			},
			{
				"scalefallback",
				delegate(string str, string arg, int fontSize)
				{
					if (fontSize > 0)
					{
						try
						{
							float num = float.Parse(arg, CultureInfo.InvariantCulture);
							str = $"<size={Math.Round((float)fontSize * num)}>{str}</size>";
						}
						catch
						{
						}
					}
					return str;
				}
			}
		};

		private static List<string> defaultAppliedTextEditTags = new List<string> { "firstupper", "firstlower", "scale" };

		public event Action<Language> onLanguageChanged;

		internal void CallOnLanguageChanged(Language newLanguage)
		{
			if (this.onLanguageChanged != null)
			{
				this.onLanguageChanged(newLanguage);
			}
		}

		private void Awake()
		{
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			instance = this;
			logger = ((BaseUnityPlugin)this).Logger;
			config = ((BaseUnityPlugin)this).Config;
			assembly = Assembly.GetExecutingAssembly();
			dllPath = new Uri(assembly.CodeBase).LocalPath;
			defaultLanguage = CreateDefaultLanguage();
			RegisterLanguage(defaultLanguage);
			ChangeLanguage(defaultLanguage);
			LoadLanguagesFromFileSystem();
			configLanguage = config.Bind<string>("General", "Language", defaultLanguage.info.code, "Currently selected language's code");
			if (languages.TryGetValue(configLanguage.Value, out var value))
			{
				ChangeLanguage(value);
			}
			configTranslatorMode = config.Bind<bool>("Translators", "Translator Mode", false, "Enables the features of this section");
			configCreateDefaultLanguageFiles = config.Bind<bool>("Translators", "Create Default Language Files On Load", true, "If enabled, files for the default game language will be created in the mod's directory on game load");
			configReloadLanguageKeybind = config.Bind<KeyCode>("Translators", "Reload Language Keybind", (KeyCode)291, "When you press this button, your current language's files will be reloaded mid-game");
			UnityEvent onInitialized = Settings.OnInitialized;
			object obj = <>c.<>9__24_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					settingsTabReady = true;
					TrySetupSettingsTab();
				};
				<>c.<>9__24_0 = val;
				obj = (object)val;
			}
			onInitialized.AddListener((UnityAction)obj);
			Harmony val2 = new Harmony("com.themysticsword.localyssation");
			val2.PatchAll();
			val2.PatchAll(typeof(GameLoadPatches));
			val2.PatchAll(typeof(ReplaceTextPatches));
			OnSceneLoaded.Init();
			LangAdjustables.Init();
		}

		private static void TrySetupSettingsTab()
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			if (settingsTabSetup || !settingsTabReady || !languagesLoaded)
			{
				return;
			}
			settingsTabSetup = true;
			SettingsTab modTab = Settings.ModTab;
			modTab.AddHeader("Localyssation");
			List<string> list = new List<string>();
			int num = 0;
			for (int i = 0; i < languagesList.Count; i++)
			{
				Language language = languagesList[i];
				list.Add(language.info.name);
				if (language == currentLanguage)
				{
					num = i;
				}
			}
			languageDropdown = modTab.AddDropdown("Language", list, num);
			languageDropdown.OnValueChanged.AddListener((UnityAction<int>)delegate(int valueIndex)
			{
				Language language2 = languagesList[valueIndex];
				ChangeLanguage(language2);
				configLanguage.Value = language2.info.code;
			});
			LangAdjustables.RegisterText(((BaseAtlyssLabelElement)languageDropdown).Label, LangAdjustables.GetStringFunc("SETTINGS_NETWORK_CELL_LOCALYSSATION_LANGUAGE", ((BaseAtlyssLabelElement)languageDropdown).LabelText));
			modTab.AddToggle(configTranslatorMode);
			if (!configTranslatorMode.Value)
			{
				return;
			}
			modTab.AddToggle(configCreateDefaultLanguageFiles);
			modTab.AddKeyButton(configReloadLanguageKeybind);
			object obj = <>c.<>9__25_1;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					foreach (KeyValuePair<string, string> @string in defaultLanguage.strings)
					{
						if (!currentLanguage.strings.ContainsKey(@string.Key))
						{
							currentLanguage.strings[@string.Key] = @string.Value;
						}
					}
					currentLanguage.WriteToFileSystem();
				};
				<>c.<>9__25_1 = val;
				obj = (object)val;
			}
			modTab.AddButton("Add Missing Keys to Current Language", (UnityAction)obj);
			object obj2 = <>c.<>9__25_2;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					int num2 = 0;
					int num3 = 0;
					logger.LogMessage((object)("Logging strings that are the same in " + defaultLanguage.info.name + " and " + currentLanguage.info.name + ":"));
					foreach (KeyValuePair<string, string> string2 in currentLanguage.strings)
					{
						if (defaultLanguage.strings.TryGetValue(string2.Key, out var value))
						{
							num3++;
							if (string2.Value == value)
							{
								logger.LogMessage((object)string2.Key);
							}
							else
							{
								num2++;
							}
						}
					}
					logger.LogMessage((object)$"Done! {num2}/{num3} ({(float)(num2 / num3) * 100f:0.00}%) strings are different between the languages.");
				};
				<>c.<>9__25_2 = val2;
				obj2 = (object)val2;
			}
			modTab.AddButton("Log Untranslated Strings", (UnityAction)obj2);
		}

		private void Update()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (configTranslatorMode.Value && UnityInput.Current.GetKeyDown(configReloadLanguageKeybind.Value))
			{
				currentLanguage.LoadFromFileSystem(forceOverwrite: true);
				CallOnLanguageChanged(currentLanguage);
			}
		}

		public static void LoadLanguagesFromFileSystem()
		{
			string[] files = Directory.GetFiles(Paths.PluginPath, "localyssationLanguage.json", SearchOption.AllDirectories);
			string[] array = files;
			foreach (string path in array)
			{
				string directoryName = Path.GetDirectoryName(path);
				Language language = new Language();
				language.fileSystemPath = directoryName;
				if (language.LoadFromFileSystem())
				{
					RegisterLanguage(language);
				}
			}
			languagesLoaded = true;
			TrySetupSettingsTab();
		}

		public static void RegisterLanguage(Language language)
		{
			if (!languages.ContainsKey(language.info.code))
			{
				languages[language.info.code] = language;
				languagesList.Add(language);
			}
		}

		public static void ChangeLanguage(Language newLanguage)
		{
			if (currentLanguage != newLanguage)
			{
				currentLanguage = newLanguage;
				instance.CallOnLanguageChanged(newLanguage);
			}
		}

		internal static Language CreateDefaultLanguage()
		{
			Language language = new Language();
			language.info.code = "en-US";
			language.info.name = "English (US)";
			language.fileSystemPath = Path.Combine(Path.GetDirectoryName(dllPath), "defaultLanguage");
			language.strings = new Dictionary<string, string>
			{
				{ "GAME_LOADING", "Loading..." },
				{ "EXP_COUNTER_MAX", "MAX" },
				{ "MAIN_MENU_BUTTON_SINGLEPLAY", "Singleplayer" },
				{ "MAIN_MENU_BUTTON_SINGLEPLAY_TOOLTIP", "Start a Singleplayer Game." },
				{ "MAIN_MENU_BUTTON_MULTIPLAY", "Multiplayer" },
				{ "MAIN_MENU_BUTTON_MULTIPLAY_TOOLTIP", "Start a Netplay Game." },
				{ "MAIN_MENU_BUTTON_MULTIPLAY_DISABLED_TOOLTIP", "Multiplayer is disabled on this demo." },
				{ "MAIN_MENU_BUTTON_SETTINGS", "Settings" },
				{ "MAIN_MENU_BUTTON_SETTINGS_TOOLTIP", "Configure Game Settings." },
				{ "MAIN_MENU_BUTTON_QUIT", "Quit" },
				{ "MAIN_MENU_BUTTON_QUIT_TOOLTIP", "End The Application." },
				{ "CHARACTER_SELECT_HEADER", "Character Select" },
				{ "CHARACTER_SELECT_HEADER_GAME_MODE_SINGLEPLAYER", "Singleplayer" },
				{ "CHARACTER_SELECT_HEADER_GAME_MODE_HOST_MULTIPLAYER_PUBLIC", "Host Game (Public)" },
				{ "CHARACTER_SELECT_HEADER_GAME_MODE_HOST_MULTIPLAYER_FRIENDS", "Host Game (Friends)" },
				{ "CHARACTER_SELECT_HEADER_GAME_MODE_HOST_MULTIPLAYER_PRIVATE", "Host Game (Private)" },
				{ "CHARACTER_SELECT_HEADER_GAME_MODE_JOIN_MULTIPLAYER", "Join Game" },
				{ "CHARACTER_SELECT_HEADER_GAME_MODE_LOBBY_QUERY", "Lobby Query" },
				{ "CHARACTER_SELECT_BUTTON_CREATE_CHARACTER", "Create Character" },
				{ "CHARACTER_SELECT_BUTTON_DELETE_CHARACTER", "Delete Character" },
				{ "CHARACTER_SELECT_BUTTON_SELECT_CHARACTER", "Select Character" },
				{ "CHARACTER_SELECT_BUTTON_RETURN", "Return" },
				{ "CHARACTER_SELECT_DATA_ENTRY_EMPTY_SLOT", "Empty Slot" },
				{ "FORMAT_CHARACTER_SELECT_DATA_ENTRY_INFO", "Lv-{0} {1} {2}" },
				{ "CHARACTER_SELECT_CHARACTER_DELETE_PROMPT_TEXT", "Type in the character's name to confirm." },
				{ "CHARACTER_SELECT_CHARACTER_DELETE_PROMPT_PLACEHOLDER_TEXT", "Enter Nickname..." },
				{ "CHARACTER_SELECT_CHARACTER_DELETE_BUTTON_CONFIRM", "Delete Character" },
				{ "CHARACTER_SELECT_CHARACTER_DELETE_BUTTON_RETURN", "Return" },
				{ "CHARACTER_CREATION_HEADER", "Character Creation" },
				{ "CHARACTER_CREATION_HEADER_RACE_NAME", "Race Select" },
				{ "CHARACTER_CREATION_RACE_DESCRIPTOR_HEADER_INITIAL_SKILL", "Initial Skill" },
				{ "CHARACTER_CREATION_BUTTON_SET_TO_DEFAULTS", "Defaults" },
				{ "CHARACTER_CREATION_CHARACTER_NAME_PLACEHOLDER_TEXT", "Enter Name..." },
				{ "CHARACTER_CREATION_BUTTON_CREATE_CHARACTER", "Create Character" },
				{ "CHARACTER_CREATION_BUTTON_RETURN", "Return" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEADER_COLOR", "Color" },
				{ "CHARACTER_CREATION_CUSTOMIZER_COLOR_BODY_HEADER", "Body" },
				{ "CHARACTER_CREATION_CUSTOMIZER_COLOR_BODY_TEXTURE", "Texture" },
				{ "CHARACTER_CREATION_CUSTOMIZER_COLOR_HAIR_HEADER", "Hair" },
				{ "CHARACTER_CREATION_CUSTOMIZER_COLOR_HAIR_LOCK_COLOR", "Lock Color" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEADER_HEAD", "Head" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEAD_HEAD_WIDTH", "Head Width" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEAD_HEAD_MOD", "Modify" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEAD_VOICE_PITCH", "Voice Pitch" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEAD_HAIR_STYLE", "Hair" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEAD_EARS", "Ears" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEAD_EYES", "Eyes" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEAD_MOUTH", "Mouth" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEADER_BODY", "Body" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_HEIGHT", "Height" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_WIDTH", "Width" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_CHEST", "Chest" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_ARMS", "Arms" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_BELLY", "Belly" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_BOTTOM", "Bottom" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_TAIL", "Tail" },
				{ "CHARACTER_CREATION_CUSTOMIZER_BODY_TOGGLE_LEFT_HANDED", "Mirror Body" },
				{ "CHARACTER_CREATION_CUSTOMIZER_HEADER_TRAIT", "Trait" },
				{ "CHARACTER_CREATION_CUSTOMIZER_TRAIT_EQUIPMENT", "Equipment" },
				{ "CHARACTER_CREATION_CUSTOMIZER_TRAIT_WEAPON_LOADOUT", "Weapon" },
				{ "CHARACTER_CREATION_CUSTOMIZER_TRAIT_GEAR_DYE", "Dye" },
				{ "CHARACTER_CREATION_CUSTOMIZER_TRAIT_ATTRIBUTES", "Attributes" },
				{ "CHARACTER_CREATION_CUSTOMIZER_TRAIT_RESET_ATTRIBUTE_POINTS", "Reset Points" },
				{ "SETTINGS_TAB_BUTTON_VIDEO", "Display" },
				{ "SETTINGS_TAB_BUTTON_AUDIO", "Audio" },
				{ "SETTINGS_TAB_BUTTON_INPUT", "Input" },
				{ "SETTINGS_TAB_BUTTON_NETWORK", "Interface" },
				{ "SETTINGS_VIDEO_HEADER_GAME_EFFECT_SETTINGS", "Display Sensitive Settings" },
				{ "SETTINGS_VIDEO_CELL_PROPORTIONS_TOGGLE", "Limit Player Character Proportions" },
				{ "SETTINGS_VIDEO_CELL_JIGGLE_BONES_TOGGLE", "Disable Suggestive Jiggle Bones" },
				{ "SETTINGS_VIDEO_CELL_CLEAR_UNDERCLOTHES_TOGGLE", "Enable Clear Clothing" },
				{ "SETTINGS_VIDEO_HEADER_VIDEO_SETTINGS", "Video Settings" },
				{ "SETTINGS_VIDEO_CELL_FULLSCREEN_TOGGLE", "Fullscreen Mode" },
				{ "SETTINGS_VIDEO_CELL_VERTICAL_SYNC", "Vertical Sync / Lock 60 FPS" },
				{ "SETTINGS_VIDEO_CELL_ANISOTROPIC_FILTERING", "Anisotropic Filtering" },
				{ "SETTINGS_VIDEO_CELL_SCREEN_RESOLUTION", "Screen Resolution" },
				{ "SETTINGS_VIDEO_CELL_ANTI_ALIASING", "Anti Aliasing" },
				{ "SETTINGS_VIDEO_CELL_ANTI_ALIASING_OPTION_1", "Disabled" },
				{ "SETTINGS_VIDEO_CELL_ANTI_ALIASING_OPTION_2", "2x Multi Sampling" },
				{ "SETTINGS_VIDEO_CELL_ANTI_ALIASING_OPTION_3", "4x Multi Sampling" },
				{ "SETTINGS_VIDEO_CELL_ANTI_ALIASING_OPTION_4", "8x Multi Sampling" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_FILTERING", "Texture Filtering" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_FILTERING_OPTION_1", "Bilnear (Smooth)" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_FILTERING_OPTION_2", "Nearest (Crunchy)" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_QUALITY", "Texture Quality" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_QUALITY_OPTION_1", "High" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_QUALITY_OPTION_2", "Medium" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_QUALITY_OPTION_3", "Low" },
				{ "SETTINGS_VIDEO_CELL_TEXTURE_QUALITY_OPTION_4", "Very Low" },
				{ "SETTINGS_VIDEO_HEADER_CAMERA_SETTINGS", "Camera Display Settings" },
				{ "SETTINGS_VIDEO_CELL_FIELD_OF_VIEW", "Field Of View" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_SMOOTHING", "Camera Smoothing" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_HORIZ", "Camera X Position" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_VERT", "Camera Y Position" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_RENDER_DISTANCE", "Render Distance" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_RENDER_DISTANCE_OPTION_1", "Very Near" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_RENDER_DISTANCE_OPTION_2", "Near" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_RENDER_DISTANCE_OPTION_3", "Far" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_RENDER_DISTANCE_OPTION_4", "Very Far" },
				{ "SETTINGS_VIDEO_HEADER_POST_PROCESSING", "Post Processing" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_BITCRUSH_SHADER", "Enable Bitcrush Shader" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_WATER_EFFECT", "Enable Underwater Distortion Shader" },
				{ "SETTINGS_VIDEO_CELL_CAMERA_SHAKE", "Enable Screen Shake" },
				{ "SETTINGS_VIDEO_CELL_WEAPON_GLOW", "Disable Weapon Glow Effect" },
				{ "SETTINGS_AUDIO_HEADER_AUDIO_SETTINGS", "Audio Settings" },
				{ "SETTINGS_AUDIO_CELL_MASTER_VOLUME", "Master Volume" },
				{ "SETTINGS_AUDIO_CELL_MUTE_APPLICATION", "Mute Application" },
				{ "SETTINGS_AUDIO_CELL_MUTE_MUSIC", "Mute Music" },
				{ "SETTINGS_AUDIO_HEADER_AUDIO_CHANNEL_SETTINGS", "Audio Channels" },
				{ "SETTINGS_AUDIO_CELL_GAME_VOLUME", "Game Volume" },
				{ "SETTINGS_AUDIO_CELL_GUI_VOLUME", "GUI Volume" },
				{ "SETTINGS_AUDIO_CELL_AMBIENCE_VOLUME", "Ambience Volume" },
				{ "SETTINGS_AUDIO_CELL_MUSIC_VOLUME", "Music Volume" },
				{ "SETTINGS_AUDIO_CELL_VOICE_VOLUME", "Voice Volume" },
				{ "SETTINGS_INPUT_HEADER_INPUT_SETTINGS", "Input Settings" },
				{ "SETTINGS_INPUT_CELL_AXIS_TYPE", "Analog Stick Axis Type" },
				{ "SETTINGS_INPUT_CELL_AXIS_TYPE_OPTION_1", "WASD (8 Directional)" },
				{ "SETTINGS_INPUT_CELL_AXIS_TYPE_OPTION_2", "Xbox" },
				{ "SETTINGS_INPUT_CELL_AXIS_TYPE_OPTION_3", "Playstation 4" },
				{ "SETTINGS_INPUT_HEADER_CAMERA_CONTROL", "Camera Control" },
				{ "SETTINGS_INPUT_CELL_CAMERA_SENSITIVITY", "Axis Sensitivity" },
				{ "SETTINGS_INPUT_CELL_INVERT_X_CAMERA_AXIS", "Invert X Axis" },
				{ "SETTINGS_INPUT_CELL_INVERT_Y_CAMERA_AXIS", "Invert Y Axis" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_RESET_CAMERA", "Reset Camera" },
				{ "SETTINGS_INPUT_HEADER_MOVEMENT", "Movement" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_UP", "Up" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_DOWN", "Down" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_LEFT", "Left" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_RIGHT", "Right" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_JUMP", "Jump" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_DASH", "Dash" },
				{ "SETTINGS_INPUT_HEADER_STRAFING", "Strafing" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_LOCK_DIRECTION", "Strafe" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_MODE", "Strafe / Aim Mode" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_MODE_OPTION_1", "Hold Strafe Key" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_MODE_OPTION_2", "Toggle Strafe Key" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_WEAPON", "Strafe While Holding Weapon" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_CASTING", "Strafe While Casting Offensive Skills" },
				{ "SETTINGS_INPUT_HEADER_ACTION", "Action" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_ATTACK", "Attack" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_CHARGE_ATTACK", "Charge Attack" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_BLOCK", "Block" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_TARGET", "Lock On" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_INTERACT", "Interact" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_PVP_FLAG", "PvP Flag Toggle" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_01", "Skill Slot 1" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_02", "Skill Slot 2" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_03", "Skill Slot 3" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_04", "Skill Slot 4" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_05", "Skill Slot 5" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_06", "Skill Slot 6" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_RECALL", "Recall" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_QUICKSWAP_WEAPON", "Quickswap Weapon" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SHEATHE_WEAPON", "Sheathe / Unsheathe Weapon" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SIT", "Sit" },
				{ "SETTINGS_INPUT_HEADER_CONSUMABLE_SLOTS", "Consumable Quick Slots" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_01", "Quick Slot 1" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_02", "Quick Slot 2" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_03", "Quick Slot 3" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_04", "Quick Slot 4" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_05", "Quick Slot 5" },
				{ "SETTINGS_INPUT_HEADER_INTERFACE", "Interface" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_HOST_CONSOLE", "Host Console" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_LEXICON", "Open Lexicon" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_TAB_MENU", "Open Tab Menu" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_STATS_TAB", "Stats Tab" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_SKILLS_TAB", "Skills Tab" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_ITEM_TAB", "Item Tab" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_QUEST_TAB", "Quest Tab" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_WHO_TAB", "Who Tab" },
				{ "SETTINGS_INPUT_CELL_KEYBINDING_HIDE_UI", "Hide Game UI" },
				{ "SETTINGS_NETWORK_HEADER_UI_SETTINGS", "UI Settings" },
				{ "SETTINGS_NETWORK_CELL_LOCALYSSATION_LANGUAGE", "Language" },
				{ "SETTINGS_NETWORK_CELL_DISPLAY_CREEP_NAMETAGS", "Display Enemy Nametags" },
				{ "SETTINGS_NETWORK_CELL_DISPLAY_LOCAL_NAMETAG", "Display Local Character Name Tag" },
				{ "SETTINGS_NETWORK_CELL_DISPLAY_HOST_TAG", "Display [HOST] Tag on Host Character" },
				{ "SETTINGS_NETWORK_CELL_HIDE_DUNGEON_MINIMAP", "Hide Dungeon Minimap" },
				{ "SETTINGS_NETWORK_CELL_HIDE_FPS_COUNTER", "Hide FPS Counter" },
				{ "SETTINGS_NETWORK_CELL_HIDE_PING_COUNTER", "Hide Ping Counter" },
				{ "SETTINGS_NETWORK_HEADER_CLIENT_SETTINGS", "Client Settings" },
				{ "SETTINGS_NETWORK_CELL_ENABLE_PVP_ON_MAP_ENTER", "Flag for PvP when available" },
				{ "SETTINGS_BUTTON_RESET_TO_DEFAULTS", "Reset to Defaults" },
				{ "SETTINGS_BUTTON_RESET", "Reset" },
				{ "SETTINGS_BUTTON_CANCEL", "Cancel" },
				{ "SETTINGS_BUTTON_APPLY", "Apply" },
				{ "FORMAT_EQUIP_ITEM_RARITY", "[{0}]" },
				{ "FORMAT_EQUIP_LEVEL_REQUIREMENT", "Lv-{0}" },
				{ "FORMAT_EQUIP_CLASS_REQUIREMENT", "Class: {0}" },
				{ "FORMAT_EQUIP_WEAPON_CONDITION", "\n<color=lime>- <color=yellow>{0}%</color> chance to apply {1}.</color>" },
				{ "EQUIP_TOOLTIP_TYPE_HELM", "Helm (Armor)" },
				{ "EQUIP_TOOLTIP_TYPE_CHESTPIECE", "Chestpiece (Armor)" },
				{ "EQUIP_TOOLTIP_TYPE_LEGGINGS", "Leggings (Armor)" },
				{ "EQUIP_TOOLTIP_TYPE_CAPE", "Cape (Armor)" },
				{ "EQUIP_TOOLTIP_TYPE_RING", "Ring (Armor)" },
				{ "FORMAT_EQUIP_TOOLTIP_TYPE_WEAPON", "{0} (Weapon)" },
				{ "EQUIP_TOOLTIP_TYPE_SHIELD", "Shield" },
				{ "FORMAT_EQUIP_STATS_DAMAGE_SCALED", "<color=#c5e384>({0} - {1})</color> Damage" },
				{ "FORMAT_EQUIP_STATS_DAMAGE_SCALED_POWERFUL", "<color=#efcc00>({0} - {1})</color> Damage" },
				{ "FORMAT_EQUIP_STATS_DAMAGE_COMPARE_BASE", "\n<color=grey>(Base Damage: {0} - {1})</color>" },
				{ "FORMAT_EQUIP_STATS_DAMAGE_UNSCALED", "({0} - {1}) Damage" },
				{ "FORMAT_EQUIP_STATS_BLOCK_THRESHOLD", "Block threshold: {0} damage" },
				{ "TAB_MENU_CELL_STATS_HEADER", "Stats" },
				{ "TAB_MENU_CELL_STATS_ATTRIBUTE_POINT_COUNTER", "Points" },
				{ "TAB_MENU_CELL_STATS_BUTTON_APPLY_ATTRIBUTE_POINTS", "Apply" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_NICK_NAME", "Nickname" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_RACE_NAME", "Race" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_CLASS_NAME", "Class" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_LEVEL_COUNTER", "Level" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_EXPERIENCE", "Experience" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_MAX_HEALTH", "Health" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_MAX_MANA", "Mana" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_MAX_STAMINA", "Stamina" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_ATTACK", "Attack Power" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_RANGED_POWER", "Dex Power" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_PHYS_CRITICAL", "Phys. Crit %" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_MAGIC_POW", "Mgk. Power" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_MAGIC_CRIT", "Mgk. Crit %" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_DEFENSE", "Defense" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_MAGIC_DEF", "Mgk. Defense" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_EVASION", "Evasion %" },
				{ "TAB_MENU_CELL_STATS_INFO_CELL_MOVE_SPD", "Mov Spd %" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_BEGIN", "<b>Base Stat:</b> <i>" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_END_CRIT", "%</i> (Critical %)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_END_EVASION", "%</i> (Evasion %)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_ATTACK_POW", "{0}</i> (Attack Power)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAX_MP", "{0}</i> (Max Mana)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAX_HP", "{0}</i> (Max Health)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_RANGE_POW", "{0}</i> (Dex Power)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_END_MAGIC_CRIT", "%</i> (Magic Critical %)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAGIC_DEF", "{0}</i> (Magic Defense)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_DEFENSE", "{0}</i> (Defense)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAGIC_POW", "{0}</i> (Magic Power)" },
				{ "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAX_STAM", "{0}</i> (Max Stamina)" },
				{ "TAB_MENU_CELL_SKILLS_HEADER", "Skills" },
				{ "TAB_MENU_CELL_SKILLS_SKILL_POINT_COUNTER", "Skill Points" },
				{ "TAB_MENU_CELL_SKILLS_CLASS_TAB_TOOLTIP_NOVICE", "General Skills" },
				{ "TAB_MENU_CELL_SKILLS_CLASS_TAB_TOOLTIP", "{0} Skills" },
				{ "TAB_MENU_CELL_SKILLS_CLASS_HEADER_NOVICE", "General Skillbook" },
				{ "TAB_MENU_CELL_SKILLS_CLASS_HEADER", "{0} Skillbook" },
				{ "SKILL_RANK_SOULBOUND", "Soulbound Skill" },
				{ "FORMAT_SKILL_RANK", "[Rank {0} / {1}]" },
				{ "FORMAT_SKILL_TOOLTIP_DAMAGE_TYPE", "{0} Skill" },
				{ "FORMAT_SKILL_TOOLTIP_ITEM_COST", "x{0} {1}" },
				{ "FORMAT_SKILL_TOOLTIP_MANA_COST", "{0} Mana" },
				{ "FORMAT_SKILL_TOOLTIP_HEALTH_COST", "{0} Health" },
				{ "FORMAT_SKILL_TOOLTIP_STAMINA_COST", "{0} Stamina" },
				{ "SKILL_TOOLTIP_CAST_TIME_INSTANT", "Instant Cast" },
				{ "FORMAT_SKILL_TOOLTIP_CAST_TIME", "{0} sec Cast" },
				{ "FORMAT_SKILL_TOOLTIP_COOLDOWN", "{0} sec Cooldown" },
				{ "SKILL_TOOLTIP_PASSIVE", "Passive Skill" },
				{ "SKILL_TOOLTIP_RANK_DESCRIPTOR_NEXT_RANK", "\n<color=white><i>[Next Rank]</i></color>" },
				{ "FORMAT_SKILL_TOOLTIP_RANK_DESCRIPTOR_CURRENT_RANK", "\n<color=white><i>[Rank {0}]</i></color>" },
				{ "FORMAT_SKILL_TOOLTIP_RANK_DESCRIPTOR_REQUIRED_LEVEL", "<color=red>\n(Requires Lv. {0})</color>" },
				{ "FORMAT_SKILL_TOOLTIP_RANK_DESCRIPTOR_COOLDOWN", "<color=yellow>{0} sec cooldown.</color>" },
				{ "FORMAT_SKILL_TOOLTIP_RANK_DESCRIPTOR_CAST_TIME", "<color=yellow>{0} sec cast time.</color>" },
				{ "SKILL_TOOLTIP_RANK_DESCRIPTOR_CAST_TIME_INSTANT", "<color=yellow>instant cast time.</color>" },
				{ "SKILL_TOOLTIP_RANK_DESCRIPTOR_CONDITION_CANCEL_ON_HIT", " <color=yellow>Cancels if hit.</color>" },
				{ "SKILL_TOOLTIP_RANK_DESCRIPTOR_CONDITION_IS_PERMANENT", " <color=yellow>Permanent.</color>" },
				{ "FORMAT_SKILL_TOOLTIP_RANK_DESCRIPTOR_CONDITION_DURATION", " <color=yellow>Lasts for {0} seconds.</color>" },
				{ "SKILL_TOOLTIP_RANK_DESCRIPTOR_CONDITION_IS_STACKABLE", " <color=yellow>Stackable.</color>" },
				{ "SKILL_TOOLTIP_RANK_DESCRIPTOR_CONDITION_IS_REFRESHABLE", " <color=yellow>Refreshes when re-applied.</color>" },
				{ "FORMAT_QUEST_REQUIRED_LEVEL", "(lv-{0})" },
				{ "QUEST_TYPE_CLASS", "(Class Tome)" },
				{ "QUEST_TYPE_MASTERY", "(Mastery Scroll)" },
				{ "QUEST_MENU_SUMMARY_NO_QUESTS", "No Quests in Quest Log." },
				{ "QUEST_MENU_HEADER_UNSELECTED", "Select a Quest." },
				{ "FORMAT_QUEST_MENU_CELL_QUEST_LOG_COUNTER", "Quest Log: ({0} / {1})" },
				{ "FORMAT_QUEST_MENU_CELL_FINISHED_QUEST_COUNTER", "Completed Quests: {0}" },
				{ "FORMAT_QUEST_MENU_CELL_REWARD_EXP", "{0} exp" },
				{ "FORMAT_QUEST_MENU_CELL_REWARD_CURRENCY", "{0} Crowns" },
				{ "QUEST_MENU_CELL_SLOT_EMPTY", "Empty Slot" },
				{ "QUEST_SELECTION_MANAGER_QUEST_ACCEPT_BUTTON_ACCEPT", "Accept Quest" },
				{ "QUEST_SELECTION_MANAGER_QUEST_ACCEPT_BUTTON_LOCKED", "Quest Locked" },
				{ "QUEST_SELECTION_MANAGER_QUEST_ACCEPT_BUTTON_INCOMPLETE", "Quest Incomplete" },
				{ "QUEST_SELECTION_MANAGER_QUEST_ACCEPT_BUTTON_TURN_IN", "Complete Quest" },
				{ "QUEST_SELECTION_MANAGER_QUEST_ACCEPT_BUTTON_UNSELECTED", "Select a Quest" },
				{ "FORMAT_QUEST_PROGRESS", "{0}: ({1} / {2})" },
				{ "FORMAT_QUEST_PROGRESS_CREEPS_KILLED", "{0} slain" }
			};
			return language;
		}

		public static string GetStringRaw(string key, string defaultValue = "SAME_AS_KEY")
		{
			if (currentLanguage.strings.TryGetValue(key, out var value))
			{
				return value;
			}
			if (defaultLanguage.strings.TryGetValue(key, out value))
			{
				return value;
			}
			return (defaultValue == "SAME_AS_KEY") ? key : defaultValue;
		}

		public static string ApplyTextEditTags(string str, int fontSize = -1, List<string> appliedTextEditTags = null)
		{
			if (appliedTextEditTags == null)
			{
				appliedTextEditTags = defaultAppliedTextEditTags;
			}
			string text = str;
			foreach (KeyValuePair<string, TextEditTagFunc> textEditTag in textEditTags)
			{
				if (!appliedTextEditTags.Contains(textEditTag.Key))
				{
					continue;
				}
				while (true)
				{
					string text2 = "<" + textEditTag.Key;
					int num = text.IndexOf(text2);
					if (num == -1)
					{
						break;
					}
					int num2 = text.IndexOf(">", num + text2.Length);
					if (num2 == -1)
					{
						break;
					}
					string text3 = "</" + textEditTag.Key + ">";
					int num3 = text.IndexOf(text3, num2 + 1);
					if (num3 == -1)
					{
						break;
					}
					string text4 = text.Substring(num + 1, num2 - 1);
					string arg = "";
					if (text4.Contains("="))
					{
						string[] array = text4.Split(new char[1] { '=' });
						if (array.Length == 2)
						{
							arg = array[1];
						}
					}
					string text5 = "";
					if (num2 + 1 <= num3 - 1)
					{
						text5 = text.Substring(num2 + 1, num3 - num2 - 1);
					}
					string value = textEditTag.Value(text5, arg, fontSize);
					text = text.Remove(num3, text3.Length).Remove(num, num2 - num + 1);
					text = text.Remove(num, text5.Length).Insert(num, value);
				}
			}
			return text;
		}

		public static string GetString(string key, int fontSize = -1, string defaultValue = "SAME_AS_KEY")
		{
			return ApplyTextEditTags(GetStringRaw(key, defaultValue), fontSize);
		}

		public static string GetFormattedString(string formatKey, int fontSize = -1, params object[] formatArgs)
		{
			return ApplyTextEditTags(string.Format(GetStringRaw(formatKey), formatArgs), fontSize);
		}
	}
	public class Language
	{
		public class LanguageInfo
		{
			public string code = "";

			public string name = "";

			public bool autoShrinkOverflowingText = false;
		}

		public LanguageInfo info = new LanguageInfo();

		public string fileSystemPath;

		public Dictionary<string, string> strings = new Dictionary<string, string>();

		public void RegisterKey(string key, string defaultValue)
		{
			if (!strings.ContainsKey(key))
			{
				strings[key] = defaultValue;
			}
		}

		public bool LoadFromFileSystem(bool forceOverwrite = false)
		{
			if (string.IsNullOrEmpty(fileSystemPath))
			{
				return false;
			}
			string path = Path.Combine(fileSystemPath, "localyssationLanguage.json");
			string path2 = Path.Combine(fileSystemPath, "strings.tsv");
			string text = Path.Combine(fileSystemPath, "stringScaleFactors.tsv");
			try
			{
				info = JsonConvert.DeserializeObject<LanguageInfo>(File.ReadAllText(path));
				foreach (Dictionary<string, string> item in TSVUtil.parseTsvWithHeaders(File.ReadAllText(path2)))
				{
					if (!forceOverwrite)
					{
						RegisterKey(item["key"], item["value"]);
					}
					else
					{
						strings[item["key"]] = item["value"];
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				Localyssation.logger.LogError((object)ex);
				return false;
			}
		}

		public bool WriteToFileSystem()
		{
			if (string.IsNullOrEmpty(fileSystemPath))
			{
				return false;
			}
			try
			{
				Directory.CreateDirectory(fileSystemPath);
				string path = Path.Combine(fileSystemPath, "localyssationLanguage.json");
				File.WriteAllText(path, JsonConvert.SerializeObject((object)info, (Formatting)1));
				string path2 = Path.Combine(fileSystemPath, "strings.tsv");
				List<List<string>> list = strings.Select((KeyValuePair<string, string> x) => new List<string> { x.Key, x.Value }).ToList();
				list.Insert(0, new List<string> { "key", "value" });
				File.WriteAllText(path2, TSVUtil.makeTsv(list));
				return true;
			}
			catch (Exception ex)
			{
				Localyssation.logger.LogError((object)ex);
				return false;
			}
		}
	}
	public static class TSVUtil
	{
		public static string makeTsv(List<List<string>> rows, string delimeter = "\t")
		{
			List<string> list = new List<string>();
			List<string> list2 = null;
			for (int i = 0; i < rows.Count; i++)
			{
				List<string> list3 = rows[i];
				for (int j = 0; j < list3.Count; j++)
				{
					list3[j] = list3[j].Replace("\n", "\\n").Replace("\t", "\\t");
				}
				string text = string.Join(delimeter, list3);
				if (list2 == null)
				{
					list2 = list3;
				}
				else if (list2.Count != list3.Count)
				{
					Localyssation.logger.LogError((object)$"Row {i} has {list3.Count} columns, which does not match header column count (${list2.Count})");
					Localyssation.logger.LogError((object)("Row content: " + text));
					return string.Join(delimeter, list2);
				}
				list.Add(text);
			}
			return string.Join("\n", list);
		}

		public static List<List<string>> parseTsv(string tsv, string delimeter = "\t")
		{
			List<List<string>> list = new List<List<string>>();
			List<string> list2 = null;
			string[] array = tsv.Split(new string[1] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i];
				if (text.EndsWith("\r"))
				{
					text = text.Substring(0, text.Length - 2);
				}
				List<string> list3 = new List<string>(Split(text, delimeter));
				for (int j = 0; j < list3.Count; j++)
				{
					list3[j] = list3[j].Replace("\\n", "\n").Replace("\\t", "\t");
				}
				if (list2 == null)
				{
					list2 = list3;
				}
				else if (list2.Count != list3.Count)
				{
					Localyssation.logger.LogError((object)$"Row {i} has {list3.Count} columns, which does not match header column count (${list2.Count})");
					Localyssation.logger.LogError((object)("Row content: " + text));
					return new List<List<string>> { list2 };
				}
				list.Add(list3);
			}
			return list;
		}

		public static List<Dictionary<string, string>> parseTsvWithHeaders(string tsv, string delimeter = "\t")
		{
			List<List<string>> list = parseTsv(tsv, delimeter);
			List<Dictionary<string, string>> list2 = new List<Dictionary<string, string>>();
			if (list.Count <= 0)
			{
				return list2;
			}
			List<string> headerRow = list[0];
			for (int i = 1; i < list.Count; i++)
			{
				Dictionary<string, string> item = list[i].Select((string x, int y) => new KeyValuePair<string, string>(headerRow[y], x)).ToDictionary((KeyValuePair<string, string> x) => x.Key, (KeyValuePair<string, string> x) => x.Value);
				list2.Add(item);
			}
			return list2;
		}

		public static List<string> Split(string str, string delimeter)
		{
			List<string> list = new List<string>();
			bool flag = delimeter.StartsWith("\\");
			int num = 0;
			int num2 = 0;
			while (true)
			{
				int num3 = str.IndexOf(delimeter, num2);
				if (num3 == -1)
				{
					list.Add(str.Substring(num, str.Length - num));
					break;
				}
				num2 = num3 + delimeter.Length;
				if (!flag || (num3 > 0 && str[num3 - 1] != '\\'))
				{
					list.Add(str.Substring(num, num3 - num));
					num = num2;
				}
				if (num2 >= str.Length)
				{
					list.Add(str.Substring(num, str.Length - num));
					break;
				}
			}
			return list;
		}
	}
	public static class Util
	{
		public static string GetChildTransformPath(Transform transform, int depth = 0)
		{
			string text = ((Object)transform).name;
			if (depth > 0)
			{
				Transform parent = transform.parent;
				if ((Object)(object)parent != (Object)null)
				{
					text = GetChildTransformPath(parent, depth - 1) + "/" + text;
				}
			}
			return text;
		}
	}
	public static class KeyUtil
	{
		public static string Normalize(string key)
		{
			return new string((from x in key.ToUpper().Replace(" ", "_").Replace("/", "_")
				where Enumerable.Contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789", x)
				select x).ToArray());
		}

		public static string GetForAsset(ScriptableItem asset)
		{
			return "ITEM_" + Normalize(asset._itemName);
		}

		public static string GetForAsset(ScriptableWeaponType asset)
		{
			return "WEAPON_TYPE_" + Normalize(asset._weaponTypeName);
		}

		public static string GetForAsset(ScriptableCreep asset)
		{
			return "CREEP_" + Normalize(asset._creepName);
		}

		public static string GetForAsset(ScriptableQuest asset)
		{
			return "QUEST_" + Normalize(asset._questName);
		}

		public static string GetForAsset(QuestTriggerRequirement asset)
		{
			return "QUEST_TRIGGER_" + Normalize(asset._questTriggerTag);
		}

		public static string GetForAsset(ScriptableCondition asset)
		{
			return "CONDITION_" + Normalize(asset._conditionName);
		}

		public static string GetForAsset(ScriptableStatModifier asset)
		{
			return "STAT_MODIFIER_" + Normalize(asset._modifierTag);
		}

		public static string GetForAsset(ScriptablePlayerRace asset)
		{
			return "RACE_" + Normalize(asset._raceName);
		}

		public static string GetForAsset(ScriptableCombatElement asset)
		{
			return "COMBAT_ELEMENT_" + Normalize(asset._elementName);
		}

		public static string GetForAsset(ScriptablePlayerBaseClass asset)
		{
			return "PLAYER_CLASS_" + Normalize(asset._className);
		}

		public static string GetForAsset(ScriptableSkill asset)
		{
			return "SKILL_" + Normalize(asset._skillName);
		}

		public static string GetForAsset(ScriptableStatAttribute asset)
		{
			return "STAT_ATTRIBUTE_" + Normalize(asset._attributeName);
		}

		public static string GetForAsset(ItemRarity asset)
		{
			return "ITEM_RARITY_" + Normalize(((object)(ItemRarity)(ref asset)).ToString());
		}

		public static string GetForAsset(DamageType asset)
		{
			return "DAMAGE_TYPE_" + Normalize(((object)(DamageType)(ref asset)).ToString());
		}

		public static string GetForAsset(ScriptableDialogData asset)
		{
			return Normalize(((Object)asset).name.ToString()) ?? "";
		}
	}
	internal static class OnSceneLoaded
	{
		public static void Init()
		{
			SceneManager.sceneLoaded += SceneManager_sceneLoaded;
		}

		private static void SceneManager_sceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Scene)(ref scene)).name;
			string text = name;
			if (!(text == "00_bootStrapper"))
			{
				if (text == "01_rootScene")
				{
				}
				return;
			}
			List<GameObject> source = GetRootGameObjects();
			GameObject val = source.First((GameObject x) => ((Object)x).name == "Canvas_loading");
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			Text[] componentsInChildren = val.GetComponentsInChildren<Text>();
			foreach (Text val2 in componentsInChildren)
			{
				if (val2.text == "Loading...")
				{
					LangAdjustables.RegisterText(val2, LangAdjustables.GetStringFunc("GAME_LOADING", val2.text));
					val2.alignment = (TextAnchor)5;
				}
			}
			List<GameObject> GetRootGameObjects()
			{
				List<GameObject> list = new List<GameObject>();
				((Scene)(ref scene)).GetRootGameObjects(list);
				return list;
			}
		}
	}
}
namespace Localyssation.Patches
{
	internal static class GameLoadPatches
	{
		[HarmonyPatch(typeof(GameManager), "Cache_ScriptableAssets")]
		[HarmonyPostfix]
		public static void GameManager_Cache_ScriptableAssets(GameManager __instance)
		{
			//IL_0821: Unknown result type (might be due to invalid IL or missing references)
			//IL_0826: Unknown result type (might be due to invalid IL or missing references)
			//IL_082d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0888: Unknown result type (might be due to invalid IL or missing references)
			//IL_088d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0894: Unknown result type (might be due to invalid IL or missing references)
			foreach (ScriptableItem value3 in __instance._cachedScriptableItems.Values)
			{
				string forAsset = KeyUtil.GetForAsset(value3);
				Localyssation.defaultLanguage.RegisterKey(forAsset + "_NAME", value3._itemName);
				Localyssation.defaultLanguage.RegisterKey(forAsset + "_DESCRIPTION", value3._itemDescription);
			}
			foreach (ScriptableCreep value4 in __instance._cachedScriptableCreeps.Values)
			{
				string forAsset2 = KeyUtil.GetForAsset(value4);
				Localyssation.defaultLanguage.RegisterKey(forAsset2 + "_NAME", value4._creepName);
				Localyssation.defaultLanguage.RegisterKey(forAsset2 + "_NAME_VARIANT_MANY", value4._creepName + "s");
			}
			foreach (ScriptableQuest value5 in __instance._cachedScriptableQuests.Values)
			{
				string forAsset3 = KeyUtil.GetForAsset(value5);
				Localyssation.defaultLanguage.RegisterKey(forAsset3 + "_NAME", value5._questName);
				Localyssation.defaultLanguage.RegisterKey(forAsset3 + "_DESCRIPTION", value5._questDescription);
				Localyssation.defaultLanguage.RegisterKey(forAsset3 + "_COMPLETE_RETURN_MESSAGE", value5._questCompleteReturnMessage);
				QuestTriggerRequirement[] questTriggerRequirements = value5._questObjective._questTriggerRequirements;
				foreach (QuestTriggerRequirement val in questTriggerRequirements)
				{
					Localyssation.defaultLanguage.RegisterKey(KeyUtil.GetForAsset(val) + "_PREFIX", val._prefix);
					Localyssation.defaultLanguage.RegisterKey(KeyUtil.GetForAsset(val) + "_SUFFIX", val._suffix);
				}
			}
			foreach (ScriptableCondition value6 in __instance._cachedScriptableConditions.Values)
			{
				string text = KeyUtil.GetForAsset(value6) ?? "";
				Localyssation.defaultLanguage.RegisterKey(text + "_NAME", value6._conditionName);
				Localyssation.defaultLanguage.RegisterKey($"{text}_{value6._conditionRank}_DESCRIPTION", value6._conditionDescription);
			}
			foreach (ScriptableStatModifier value7 in __instance._cachedScriptableStatModifiers.Values)
			{
				string forAsset4 = KeyUtil.GetForAsset(value7);
				Localyssation.defaultLanguage.RegisterKey(forAsset4 + "_TAG", value7._modifierTag);
			}
			foreach (ScriptablePlayerRace value8 in __instance._cachedScriptableRaces.Values)
			{
				string forAsset5 = KeyUtil.GetForAsset(value8);
				Localyssation.defaultLanguage.RegisterKey(forAsset5 + "_NAME", value8._raceName);
				Localyssation.defaultLanguage.RegisterKey(forAsset5 + "_DESCRIPTION", value8._raceDescription);
				Localyssation.defaultLanguage.RegisterKey(forAsset5 + "_MISC", value8._miscName);
			}
			foreach (ScriptableCombatElement value9 in __instance._cachedScriptableCombatElements.Values)
			{
				string forAsset6 = KeyUtil.GetForAsset(value9);
				Localyssation.defaultLanguage.RegisterKey(forAsset6 + "_NAME", value9._elementName);
			}
			Localyssation.defaultLanguage.RegisterKey("PLAYER_CLASS_EMPTY_NAME", GameManager._current._statLogics._emptyClassName);
			foreach (ScriptablePlayerBaseClass value10 in __instance._cachedScriptablePlayerClasses.Values)
			{
				string forAsset7 = KeyUtil.GetForAsset(value10);
				Localyssation.defaultLanguage.RegisterKey(forAsset7 + "_NAME", value10._className);
			}
			foreach (ScriptableSkill value11 in __instance._cachedScriptableSkills.Values)
			{
				string forAsset8 = KeyUtil.GetForAsset(value11);
				Localyssation.defaultLanguage.RegisterKey(forAsset8 + "_NAME", value11._skillName);
				Localyssation.defaultLanguage.RegisterKey(forAsset8 + "_DESCRIPTION", value11._skillDescription);
				for (int j = 0; j < value11._skillRanks.Length; j++)
				{
					SkillRanking val2 = value11._skillRanks[j];
					Localyssation.defaultLanguage.RegisterKey($"{forAsset8}_RANK_{j + 1}_DESCRIPTOR", val2._rankDescriptor);
				}
			}
			ScriptableStatAttribute[] statAttributes = GameManager._current._statLogics._statAttributes;
			foreach (ScriptableStatAttribute val3 in statAttributes)
			{
				string forAsset9 = KeyUtil.GetForAsset(val3);
				Localyssation.defaultLanguage.RegisterKey(forAsset9 + "_NAME", val3._attributeName);
				Localyssation.defaultLanguage.RegisterKey(forAsset9 + "_DESCRIPTOR", val3._attributeDescriptor);
			}
			ScriptableWeaponType[] array = Resources.LoadAll<ScriptableWeaponType>("");
			foreach (ScriptableWeaponType val4 in array)
			{
				string forAsset10 = KeyUtil.GetForAsset(val4);
				Localyssation.defaultLanguage.RegisterKey(forAsset10 + "_NAME", val4._weaponTypeName);
			}
			ScriptableDialogData[] array2 = Resources.LoadAll<ScriptableDialogData>("");
			foreach (ScriptableDialogData val5 in array2)
			{
				string forAsset11 = KeyUtil.GetForAsset(val5);
				Localyssation.defaultLanguage.RegisterKey(forAsset11 + "_NAME_TAG", val5._nameTag);
				Dictionary<DialogBranch[], string> dictionary = new Dictionary<DialogBranch[], string>
				{
					{ val5._dialogBranches, "BRANCH" },
					{ val5._introductionBranches, "INTRODUCTION_BRANCH" }
				};
				foreach (KeyValuePair<DialogBranch[], string> item in dictionary)
				{
					DialogBranch[] key = item.Key;
					string value = item.Value;
					for (int n = 0; n < key.Length; n++)
					{
						DialogBranch branch = key[n];
						RegisterKeysForDialogBranch(forAsset11, $"{value}_{n}", branch);
					}
				}
				Dictionary<string[], string> dictionary2 = new Dictionary<string[], string>
				{
					{ val5._shopkeepResponses, "SHOPKEEP_RESPONSE" },
					{ val5._shopkeepRejections, "SHOPKEEP_REJECTION" },
					{ val5._questAcceptResponses, "QUEST_ACCEPT_RESPONSE" },
					{ val5._questCompleteResponses, "QUEST_COMPLETE_RESPONSE" }
				};
				foreach (KeyValuePair<string[], string> item2 in dictionary2)
				{
					string[] key2 = item2.Key;
					string value2 = item2.Value;
					for (int num = 0; num < key2.Length; num++)
					{
						string key3 = key2[num];
						ReplaceTextPatches.dialogManagerQuickSentencesHack[key3] = $"{forAsset11}_{value2}_{num}";
					}
				}
			}
			foreach (ItemRarity value12 in Enum.GetValues(typeof(ItemRarity)))
			{
				ItemRarity asset = value12;
				Localyssation.defaultLanguage.RegisterKey(KeyUtil.GetForAsset(asset), ((object)(ItemRarity)(ref asset)).ToString());
			}
			foreach (DamageType value13 in Enum.GetValues(typeof(DamageType)))
			{
				DamageType asset2 = value13;
				Localyssation.defaultLanguage.RegisterKey(KeyUtil.GetForAsset(asset2), ((object)(DamageType)(ref asset2)).ToString());
			}
			if (Localyssation.configTranslatorMode.Value && Localyssation.configCreateDefaultLanguageFiles.Value)
			{
				((MonoBehaviour)Localyssation.instance).StartCoroutine(RegisterSceneSpecificStrings());
			}
			Localyssation.defaultLanguage.strings["FORMAT_QUEST_MENU_CELL_REWARD_CURRENCY"] = "{0} " + GameManager._current._statLogics._currencyName;
			if (Localyssation.configTranslatorMode.Value && Localyssation.configCreateDefaultLanguageFiles.Value)
			{
				Localyssation.defaultLanguage.WriteToFileSystem();
			}
		}

		private static void RegisterKeysForDialogBranch(string dialogDataKey, string keySuffixBranch, DialogBranch branch)
		{
			for (int i = 0; i < branch.dialogs.Length; i++)
			{
				Dialog val = branch.dialogs[i];
				Localyssation.defaultLanguage.RegisterKey($"{dialogDataKey}_{keySuffixBranch}_DIALOG_{i}_INPUT", val._dialogInput);
				if (val._altInputs != null && val._altInputs.Length != 0)
				{
					for (int j = 0; j < val._altInputs.Length; j++)
					{
						Localyssation.defaultLanguage.RegisterKey($"{dialogDataKey}_{keySuffixBranch}_DIALOG_{i}_INPUT_ALT_{j}", val._altInputs[j]);
					}
				}
				for (int k = 0; k < val._dialogSelections.Length; k++)
				{
					DialogSelection val2 = val._dialogSelections[k];
					Localyssation.defaultLanguage.RegisterKey($"{dialogDataKey}_{keySuffixBranch}_DIALOG_{i}_SELECTION_{k}", val2._selectionCaption);
				}
			}
		}

		private static IEnumerator RegisterSceneSpecificStrings()
		{
			List<string> excludedSceneNames = new List<string> { "00_bootStrapper", "01_rootScene" };
			for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
			{
				string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
				if (excludedSceneNames.Any((string x) => scenePath.Contains(x)))
				{
					continue;
				}
				yield return SceneManager.LoadSceneAsync(scenePath, (LoadSceneMode)1);
				Scene scene = SceneManager.GetSceneByPath(scenePath);
				if (((Scene)(ref scene)).IsValid())
				{
					string sceneName = ((Scene)(ref scene)).name;
					DialogTrigger[] array = Object.FindObjectsOfType<DialogTrigger>(true);
					foreach (DialogTrigger dialogTrigger in array)
					{
						int num;
						if (dialogTrigger._useLocalDialogBranch)
						{
							Scene scene2 = ((Component)dialogTrigger).gameObject.scene;
							num = ((((Scene)(ref scene2)).name == sceneName) ? 1 : 0);
						}
						else
						{
							num = 0;
						}
						if (num != 0)
						{
							string key = KeyUtil.GetForAsset(dialogTrigger._scriptDialogData);
							RegisterKeysForDialogBranch(key, KeyUtil.Normalize("LOCAL_BRANCH_" + sceneName + "_" + Util.GetChildTransformPath(((Component)dialogTrigger).transform, 2)), dialogTrigger._localDialogBranch);
						}
					}
					yield return SceneManager.UnloadSceneAsync(scene);
				}
				scene = default(Scene);
			}
			yield return Resources.UnloadUnusedAssets();
			Localyssation.defaultLanguage.WriteToFileSystem();
		}
	}
	internal static class ReplaceTextPatches
	{
		private static List<string> fallbackTextEditTags = new List<string> { "scalefallback" };

		internal static Dictionary<string, string> dialogManagerQuickSentencesHack = new Dictionary<string, string>();

		internal static IEnumerable<CodeInstruction> SimpleStringReplaceTranspiler(IEnumerable<CodeInstruction> instructions, Dictionary<string, string> stringReplacements)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			List<string> replacedStrings = new List<string>();
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instr) => instr.opcode == OpCodes.Ldstr && stringReplacements.ContainsKey((string)instr.operand) && !replacedStrings.Contains((string)instr.operand)), (string)null)
			}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
			{
				string key = (string)matcher.Instruction.operand;
				matcher.Advance(1);
				matcher.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<string, string>>((Func<string, string>)((string origString) => Localyssation.GetString(stringReplacements[key], -1, key))) });
				replacedStrings.Add(key);
			}, (Action<string>)null).InstructionEnumeration();
		}

		internal static int GetIntOperand(CodeMatcher matcher)
		{
			object obj = matcher.Operand;
			if (obj == null)
			{
				obj = int.Parse(matcher.Opcode.Name.Substring(matcher.Opcode.Name.Length - 1));
			}
			return (int)obj;
		}

		public static void RemapAllTextUnderObject(GameObject gameObject, Dictionary<string, string> textRemaps, Action<Transform, string> onRemap = null)
		{
			Text[] componentsInChildren = gameObject.GetComponentsInChildren<Text>();
			foreach (Text val in componentsInChildren)
			{
				if (!TryRemapSingle(((Component)val).transform, val))
				{
					Transform parent = ((Component)val).transform.parent;
					if (Object.op_Implicit((Object)(object)parent))
					{
						TryRemapSingle(parent, val);
					}
				}
			}
			bool TryRemapSingle(Transform lookupNameTransform, Text text)
			{
				if (textRemaps.TryGetValue(((Object)lookupNameTransform).name, out var value))
				{
					LangAdjustables.RegisterText(text, LangAdjustables.GetStringFunc(value, text.text));
					if (onRemap != null)
					{
						onRemap(lookupNameTransform, value);
					}
					return true;
				}
				return false;
			}
		}

		public static void RemapChildTextsByPath(Transform parentTransform, Dictionary<string, string> textRemaps, Action<Transform, string> onRemap = null)
		{
			foreach (KeyValuePair<string, string> textRemap in textRemaps)
			{
				Transform val = parentTransform.Find(textRemap.Key);
				if (Object.op_Implicit((Object)(object)val))
				{
					Text component = ((Component)val).GetComponent<Text>();
					if (Object.op_Implicit((Object)(object)component))
					{
						LangAdjustables.RegisterText(component, LangAdjustables.GetStringFunc(textRemap.Value, component.text));
						onRemap?.Invoke(val, textRemap.Value);
					}
				}
			}
		}

		public static void RemapAllInputPlaceholderTextUnderObject(GameObject gameObject, Dictionary<string, string> textRemaps, Action<Transform, string> onRemap = null)
		{
			InputField[] componentsInChildren = gameObject.GetComponentsInChildren<InputField>();
			foreach (InputField val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val.placeholder))
				{
					Text component = ((Component)val.placeholder).GetComponent<Text>();
					if (Object.op_Implicit((Object)(object)component) && textRemaps.TryGetValue(((Object)val).name, out var value))
					{
						LangAdjustables.RegisterText(component, LangAdjustables.GetStringFunc(value, component.text));
						onRemap?.Invoke(((Component)val).transform, value);
					}
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static void Text_set_text(Text __instance, ref string value)
		{
			if ((Object)(object)__instance != (Object)null && value != null && value.Contains("scalefallback"))
			{
				value = Localyssation.ApplyTextEditTags(value, __instance.fontSize, fallbackTextEditTags);
			}
		}

		[HarmonyPatch(typeof(MainMenuManager), "Awake")]
		[HarmonyPostfix]
		public static void MainMenuManager_Awake(MainMenuManager __instance)
		{
			Transform parent = ((Component)__instance).transform.parent;
			if (!Object.op_Implicit((Object)(object)parent))
			{
				return;
			}
			Transform val = parent.Find("_mainMenu/Canvas_MainMenu");
			if (Object.op_Implicit((Object)(object)val))
			{
				Transform val2 = val.Find("_dolly_selectBar");
				Transform obj_text_toolTipHelp = val.Find("_backdrop_lowBar/_text_toolTipHelp");
				if (Object.op_Implicit((Object)(object)val2))
				{
					RemapAllTextUnderObject(((Component)val2).gameObject, new Dictionary<string, string>
					{
						{ "_button_singleplay", "MAIN_MENU_BUTTON_SINGLEPLAY" },
						{ "_button_multiplay", "MAIN_MENU_BUTTON_MULTIPLAY" },
						{ "_button_settings", "MAIN_MENU_BUTTON_SETTINGS" },
						{ "_button_quit", "MAIN_MENU_BUTTON_QUIT" }
					}, delegate(Transform textParent, string key)
					{
						//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
						//IL_0102: Expected O, but got Unknown
						//IL_0106: Unknown result type (might be due to invalid IL or missing references)
						//IL_010b: Unknown result type (might be due to invalid IL or missing references)
						if (Object.op_Implicit((Object)(object)obj_text_toolTipHelp))
						{
							Text tooltipText = ((Component)obj_text_toolTipHelp).GetComponent<Text>();
							EventTrigger component = ((Component)textParent).GetComponent<EventTrigger>();
							if (Object.op_Implicit((Object)(object)component))
							{
								for (int i = 0; i < component.triggers.Count; i++)
								{
									Entry val9 = component.triggers[i];
									foreach (PersistentCall call in ((UnityEventBase)val9.callback).m_PersistentCalls.m_Calls)
									{
										if (call.methodName == "set_text" && call.arguments.stringArgument != "" && call.target == (Object)(object)tooltipText)
										{
											Entry val10 = new Entry();
											val10.eventID = val9.eventID;
											((UnityEvent<BaseEventData>)(object)val10.callback).AddListener((UnityAction<BaseEventData>)delegate
											{
												tooltipText.text = Localyssation.GetString(key + "_TOOLTIP", tooltipText.fontSize, call.arguments.stringArgument);
											});
											component.triggers.Add(val10);
											return;
										}
									}
								}
							}
						}
					});
				}
			}
			Transform val3 = parent.Find("_characterSelectMenu/Canvas_characterSelect");
			if (Object.op_Implicit((Object)(object)val3))
			{
				RemapAllTextUnderObject(((Component)val3).gameObject, new Dictionary<string, string>
				{
					{ "_text_header", "CHARACTER_SELECT_HEADER" },
					{ "_button_createCharacter", "CHARACTER_SELECT_BUTTON_CREATE_CHARACTER" },
					{ "_button_deleteCharacter", "CHARACTER_SELECT_BUTTON_DELETE_CHARACTER" },
					{ "_button_select", "CHARACTER_SELECT_BUTTON_SELECT_CHARACTER" },
					{ "_button_return", "CHARACTER_SELECT_BUTTON_RETURN" },
					{ "_text_characterDeletePrompt", "CHARACTER_SELECT_CHARACTER_DELETE_PROMPT_TEXT" },
					{ "_button_confirmDeleteCharacter", "CHARACTER_SELECT_CHARACTER_DELETE_BUTTON_CONFIRM" },
					{ "_button_deletePrompt_return", "CHARACTER_SELECT_CHARACTER_DELETE_BUTTON_RETURN" }
				});
				RemapAllInputPlaceholderTextUnderObject(((Component)val3).gameObject, new Dictionary<string, string> { { "_input_characterDeleteConfirm", "CHARACTER_SELECT_CHARACTER_DELETE_PROMPT_PLACEHOLDER_TEXT" } });
			}
			Transform val4 = parent.Find("_characterSelectMenu/Canvas_characterCreation");
			if (Object.op_Implicit((Object)(object)val4))
			{
				RemapAllTextUnderObject(((Component)val4).gameObject, new Dictionary<string, string>
				{
					{ "_text_header", "CHARACTER_CREATION_HEADER" },
					{ "_header_raceName_01", "CHARACTER_CREATION_HEADER" },
					{ "_header_initialSkill", "CHARACTER_CREATION_RACE_DESCRIPTOR_HEADER_INITIAL_SKILL" },
					{ "_button_createCharacter", "CHARACTER_CREATION_BUTTON_CREATE_CHARACTER" },
					{ "_button_return", "CHARACTER_CREATION_BUTTON_RETURN" }
				});
				RemapAllInputPlaceholderTextUnderObject(((Component)val3).gameObject, new Dictionary<string, string> { { "_input_characterName", "CHARACTER_CREATION_CHARACTER_NAME_PLACEHOLDER_TEXT" } });
				Transform val5 = ((Component)val4).transform.Find("_dolly_customizer/_customizer_color");
				Transform val6 = ((Component)val4).transform.Find("_dolly_customizer/_customizer_head");
				Transform val7 = ((Component)val4).transform.Find("_dolly_customizer/_customizer_body");
				Transform val8 = ((Component)val4).transform.Find("_dolly_customizer/_customizer_trait");
				if (Object.op_Implicit((Object)(object)val5))
				{
					RemapAllTextUnderObject(((Component)val5).gameObject, new Dictionary<string, string>
					{
						{ "_customizer_header", "CHARACTER_CREATION_CUSTOMIZER_HEADER_COLOR" },
						{ "Image_01", "CHARACTER_CREATION_CUSTOMIZER_COLOR_BODY_HEADER" },
						{ "_characterButtonSelector", "CHARACTER_CREATION_CUSTOMIZER_COLOR_BODY_TEXTURE" },
						{ "Image", "CHARACTER_CREATION_CUSTOMIZER_COLOR_HAIR_HEADER" },
						{ "Toggle_lockColor", "CHARACTER_CREATION_CUSTOMIZER_COLOR_HAIR_LOCK_COLOR" },
						{ "_button_defaultColor", "CHARACTER_CREATION_BUTTON_SET_TO_DEFAULTS" }
					});
				}
				if (Object.op_Implicit((Object)(object)val6))
				{
					RemapAllTextUnderObject(((Component)val6).gameObject, new Dictionary<string, string>
					{
						{ "_customizer_header", "CHARACTER_CREATION_CUSTOMIZER_HEADER_HEAD" },
						{ "_characterSlider_headWidth", "CHARACTER_CREATION_CUSTOMIZER_HEAD_HEAD_WIDTH" },
						{ "_characterSlider_headMod", "CHARACTER_CREATION_CUSTOMIZER_HEAD_HEAD_MOD" },
						{ "_characterSlider_voicePitch", "CHARACTER_CREATION_CUSTOMIZER_HEAD_VOICE_PITCH" },
						{ "_characterButtons_hairStyle", "CHARACTER_CREATION_CUSTOMIZER_HEAD_HAIR_STYLE" },
						{ "_characterButtons_ears", "CHARACTER_CREATION_CUSTOMIZER_HEAD_EARS" },
						{ "_characterButtons_eyes", "CHARACTER_CREATION_CUSTOMIZER_HEAD_EYES" },
						{ "_characterButtons_mouth", "CHARACTER_CREATION_CUSTOMIZER_HEAD_MOUTH" }
					});
				}
				if (Object.op_Implicit((Object)(object)val7))
				{
					RemapAllTextUnderObject(((Component)val7).gameObject, new Dictionary<string, string>
					{
						{ "_customizer_header", "CHARACTER_CREATION_CUSTOMIZER_HEADER_BODY" },
						{ "_characterSlider_height", "CHARACTER_CREATION_CUSTOMIZER_BODY_HEIGHT" },
						{ "_characterSlider_width", "CHARACTER_CREATION_CUSTOMIZER_BODY_WIDTH" },
						{ "_characterSlider_chest", "CHARACTER_CREATION_CUSTOMIZER_BODY_CHEST" },
						{ "_characterSlider_arms", "CHARACTER_CREATION_CUSTOMIZER_BODY_ARMS" },
						{ "_characterSlider_belly", "CHARACTER_CREATION_CUSTOMIZER_BODY_BELLY" },
						{ "_characterSlider_bottom", "CHARACTER_CREATION_CUSTOMIZER_BODY_BOTTOM" },
						{ "_characterButtonSelector_tail", "CHARACTER_CREATION_CUSTOMIZER_BODY_TAIL" },
						{ "_toggle_leftHanded", "CHARACTER_CREATION_CUSTOMIZER_BODY_TOGGLE_LEFT_HANDED" },
						{ "_button_defaultBody", "CHARACTER_CREATION_BUTTON_SET_TO_DEFAULTS" }
					});
				}
				if (Object.op_Implicit((Object)(object)val8))
				{
					RemapAllTextUnderObject(((Component)val8).gameObject, new Dictionary<string, string>
					{
						{ "_customizer_header", "CHARACTER_CREATION_CUSTOMIZER_HEADER_TRAIT" },
						{ "_header_equipment", "CHARACTER_CREATION_CUSTOMIZER_TRAIT_EQUIPMENT" },
						{ "_selector_weaponLoadout", "CHARACTER_CREATION_CUSTOMIZER_TRAIT_WEAPON_LOADOUT" },
						{ "_selector_gearDye", "CHARACTER_CREATION_CUSTOMIZER_TRAIT_GEAR_DYE" },
						{ "_header_attributes", "CHARACTER_CREATION_CUSTOMIZER_TRAIT_ATTRIBUTES" },
						{ "_text_strengthAttribute", "STAT_ATTRIBUTE_STRENGTH_NAME" },
						{ "_text_mindAttribute", "STAT_ATTRIBUTE_MIND_NAME" },
						{ "_text_dexterityAttribute", "STAT_ATTRIBUTE_DEXTERITY_NAME" },
						{ "_text_vitalityAttribute", "STAT_ATTRIBUTE_VITALITY_NAME" },
						{ "_button_resetAtbPoints", "CHARACTER_CREATION_CUSTOMIZER_TRAIT_RESET_ATTRIBUTE_POINTS" }
					});
				}
			}
		}

		[HarmonyPatch(typeof(CharacterSelectManager), "Handle_HeaderText")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> CharacterSelectManager_Handle_HeaderText_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return SimpleStringReplaceTranspiler(instructions, new Dictionary<string, string>
			{
				{ "Singleplayer", "CHARACTER_SELECT_HEADER_GAME_MODE_SINGLEPLAYER" },
				{ "Host Game (Public)", "CHARACTER_SELECT_HEADER_GAME_MODE_HOST_MULTIPLAYER_PUBLIC" },
				{ "Host Game (Friends)", "CHARACTER_SELECT_HEADER_GAME_MODE_HOST_MULTIPLAYER_FRIENDS" },
				{ "Host Game (Private)", "CHARACTER_SELECT_HEADER_GAME_MODE_HOST_MULTIPLAYER_PRIVATE" },
				{ "Join Game", "CHARACTER_SELECT_HEADER_GAME_MODE_JOIN_MULTIPLAYER" },
				{ "Lobby Query", "CHARACTER_SELECT_HEADER_GAME_MODE_LOBBY_QUERY" }
			});
		}

		[HarmonyPatch(typeof(CharacterSelectListDataEntry), "Update")]
		[HarmonyPostfix]
		public static void CharacterSelectListDataEntry_Update(CharacterSelectListDataEntry __instance)
		{
			if (__instance._characterFileData._isEmptySlot)
			{
				__instance._characterNicknameText.text = Localyssation.GetString("CHARACTER_SELECT_DATA_ENTRY_EMPTY_SLOT", __instance._characterNicknameText.fontSize, __instance._characterNicknameText.text);
				return;
			}
			int fontSize = __instance._characterInfoText.fontSize;
			string text = "";
			string @string = Localyssation.GetString("PLAYER_CLASS_EMPTY_NAME", fontSize, GameManager._current._statLogics._emptyClassName);
			ScriptablePlayerRace val = GameManager._current.LocateRace(__instance._characterFileData._appearanceProfile._setRaceTag);
			if (Object.op_Implicit((Object)(object)val))
			{
				text = Localyssation.GetString(KeyUtil.GetForAsset(val) + "_NAME", fontSize, val._raceName);
			}
			if (!string.IsNullOrEmpty(__instance._characterFileData._statsProfile._classID))
			{
				ScriptablePlayerBaseClass val2 = GameManager._current.LocateClass(__instance._characterFileData._statsProfile._classID);
				if (Object.op_Implicit((Object)(object)val2))
				{
					@string = Localyssation.GetString(KeyUtil.GetForAsset(val2) + "_NAME", fontSize, val2._className);
				}
			}
			__instance._characterInfoText.text = Localyssation.GetFormattedString("FORMAT_CHARACTER_SELECT_DATA_ENTRY_INFO", __instance._characterInfoText.fontSize, __instance._characterFileData._statsProfile._currentLevel, text, @string);
		}

		[HarmonyPatch(typeof(CharacterCreationManager), "Handle_InterfaceParameters")]
		[HarmonyPostfix]
		public static void CharacterCreationManager_Handle_InterfaceParameters(CharacterCreationManager __instance)
		{
			ScriptablePlayerRace val = __instance._scriptablePlayerRaces[__instance._currentRaceSelected];
			if (Object.op_Implicit((Object)(object)val))
			{
				string forAsset = KeyUtil.GetForAsset(val);
				__instance._raceDescriptionHeader.text = Localyssation.GetString(forAsset + "_NAME", __instance._raceDescriptionHeader.fontSize, __instance._raceDescriptionHeader.text) ?? "";
				__instance._raceDescriptorField.text = Localyssation.GetString(forAsset + "_DESCRIPTION", __instance._raceDescriptorField.fontSize, __instance._raceDescriptorField.text) ?? "";
				__instance._colorMiscTag.text = Localyssation.GetString(forAsset + "_MISC", __instance._colorMiscTag.fontSize, __instance._colorMiscTag.text) ?? "";
				__instance._miscTag.text = Localyssation.GetString(forAsset + "_MISC", __instance._miscTag.fontSize, __instance._miscTag.text) ?? "";
				if (val._racialSkills.Length >= 1)
				{
					string forAsset2 = KeyUtil.GetForAsset(val._racialSkills[0]);
					__instance._raceInitialSkillTag.text = Localyssation.GetString(forAsset2 + "_NAME", __instance._raceInitialSkillTag.fontSize, __instance._raceInitialSkillTag.text) ?? "";
					__instance._raceInitialSkillDescriptor.text = Localyssation.GetString(forAsset2 + "_DESCRIPTION", __instance._raceInitialSkillDescriptor.fontSize, __instance._raceInitialSkillDescriptor.text) ?? "";
				}
			}
		}

		[HarmonyPatch(typeof(SettingsManager), "Start")]
		[HarmonyPostfix]
		public static void SettingsManager_Start(SettingsManager __instance)
		{
			RemapAllTextUnderObject(((Component)__instance).gameObject, new Dictionary<string, string>
			{
				{ "Button_videoTab", "SETTINGS_TAB_BUTTON_VIDEO" },
				{ "_header_GameEffectSettings", "SETTINGS_VIDEO_HEADER_GAME_EFFECT_SETTINGS" },
				{ "_cell_proportionsToggle", "SETTINGS_VIDEO_CELL_PROPORTIONS_TOGGLE" },
				{ "_cell_jiggleBonesToggle", "SETTINGS_VIDEO_CELL_JIGGLE_BONES_TOGGLE" },
				{ "_cell_clearUnderclothesToggle", "SETTINGS_VIDEO_CELL_CLEAR_UNDERCLOTHES_TOGGLE" },
				{ "_header_videoSettings", "SETTINGS_VIDEO_HEADER_VIDEO_SETTINGS" },
				{ "_cell_fullscreenToggle", "SETTINGS_VIDEO_CELL_FULLSCREEN_TOGGLE" },
				{ "_cell_verticalSync", "SETTINGS_VIDEO_CELL_VERTICAL_SYNC" },
				{ "_cell_anisotropicFiltering", "SETTINGS_VIDEO_CELL_ANISOTROPIC_FILTERING" },
				{ "_cell_screenResolution", "SETTINGS_VIDEO_CELL_SCREEN_RESOLUTION" },
				{ "_cell_antiAliasing", "SETTINGS_VIDEO_CELL_ANTI_ALIASING" },
				{ "_cell_textureFiltering", "SETTINGS_VIDEO_CELL_TEXTURE_FILTERING" },
				{ "_cell_textureQuality", "SETTINGS_VIDEO_CELL_TEXTURE_QUALITY" },
				{ "_header_CameraSettings", "SETTINGS_VIDEO_HEADER_CAMERA_SETTINGS" },
				{ "_cell_fieldOfView", "SETTINGS_VIDEO_CELL_FIELD_OF_VIEW" },
				{ "_cell_cameraSmoothing", "SETTINGS_VIDEO_CELL_CAMERA_SMOOTHING" },
				{ "_cell_cameraHoriz", "SETTINGS_VIDEO_CELL_CAMERA_HORIZ" },
				{ "_cell_cameraVert", "SETTINGS_VIDEO_CELL_CAMERA_VERT" },
				{ "_cell_cameraRenderDistance", "SETTINGS_VIDEO_CELL_CAMERA_RENDER_DISTANCE" },
				{ "_header_PostProcessing", "SETTINGS_VIDEO_HEADER_POST_PROCESSING" },
				{ "_cell_cameraBitcrushShader", "SETTINGS_VIDEO_CELL_CAMERA_BITCRUSH_SHADER" },
				{ "_cell_cameraWaterEffect", "SETTINGS_VIDEO_CELL_CAMERA_WATER_EFFECT" },
				{ "_cell_cameraShake", "SETTINGS_VIDEO_CELL_CAMERA_SHAKE" },
				{ "_cell_weaponGlow", "SETTINGS_VIDEO_CELL_WEAPON_GLOW" },
				{ "Button_audioTab", "SETTINGS_TAB_BUTTON_AUDIO" },
				{ "_header_audioSettings", "SETTINGS_AUDIO_HEADER_AUDIO_SETTINGS" },
				{ "_cell_masterVolume", "SETTINGS_AUDIO_CELL_MASTER_VOLUME" },
				{ "_cell_muteApplication", "SETTINGS_AUDIO_CELL_MUTE_APPLICATION" },
				{ "_cell_muteMusic", "SETTINGS_AUDIO_CELL_MUTE_MUSIC" },
				{ "_header_audioChannelSettings", "SETTINGS_AUDIO_HEADER_AUDIO_CHANNEL_SETTINGS" },
				{ "_cell_gameVolume", "SETTINGS_AUDIO_CELL_GAME_VOLUME" },
				{ "_cell_guiVolume", "SETTINGS_AUDIO_CELL_GUI_VOLUME" },
				{ "_cell_ambienceVolume", "SETTINGS_AUDIO_CELL_AMBIENCE_VOLUME" },
				{ "_cell_musicVolume", "SETTINGS_AUDIO_CELL_MUSIC_VOLUME" },
				{ "_cell_voiceVolume", "SETTINGS_AUDIO_CELL_VOICE_VOLUME" },
				{ "Button_inputTab", "SETTINGS_TAB_BUTTON_INPUT" },
				{ "Image_05", "SETTINGS_INPUT_HEADER_INPUT_SETTINGS" },
				{ "_cell_axisType", "SETTINGS_INPUT_CELL_AXIS_TYPE" },
				{ "_cell_resetToDefaults", "SETTINGS_BUTTON_RESET_TO_DEFAULTS" },
				{ "Image_06", "SETTINGS_INPUT_HEADER_CAMERA_CONTROL" },
				{ "_cell_cameraSensitivity", "SETTINGS_INPUT_CELL_CAMERA_SENSITIVITY" },
				{ "_cell_invertXCameraAxis", "SETTINGS_INPUT_CELL_INVERT_X_CAMERA_AXIS" },
				{ "_cell_invertYCameraAxis", "SETTINGS_INPUT_CELL_INVERT_Y_CAMERA_AXIS" },
				{ "_cell_keybinding_37", "SETTINGS_INPUT_CELL_KEYBINDING_RESET_CAMERA" },
				{ "Header_Movement", "SETTINGS_INPUT_HEADER_MOVEMENT" },
				{ "_cell_keybinding_up", "SETTINGS_INPUT_CELL_KEYBINDING_UP" },
				{ "_cell_keybinding_down", "SETTINGS_INPUT_CELL_KEYBINDING_DOWN" },
				{ "_cell_keybinding_left", "SETTINGS_INPUT_CELL_KEYBINDING_LEFT" },
				{ "_cell_keybinding_right", "SETTINGS_INPUT_CELL_KEYBINDING_RIGHT" },
				{ "_cell_keybinding_jump", "SETTINGS_INPUT_CELL_KEYBINDING_JUMP" },
				{ "_cell_keybinding_dash", "SETTINGS_INPUT_CELL_KEYBINDING_DASH" },
				{ "Header_Strafing", "SETTINGS_INPUT_HEADER_STRAFING" },
				{ "_cell_keybinding_lockDirection", "SETTINGS_INPUT_CELL_KEYBINDING_LOCK_DIRECTION" },
				{ "_cell_strafeMode", "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_MODE" },
				{ "_cell_strafeWeapon", "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_WEAPON" },
				{ "_cell_strafeCasting", "SETTINGS_INPUT_CELL_KEYBINDING_STRAFE_CASTING" },
				{ "Header_Action", "SETTINGS_INPUT_HEADER_ACTION" },
				{ "_cell_keybinding_attack", "SETTINGS_INPUT_CELL_KEYBINDING_ATTACK" },
				{ "_cell_keybinding_chargeAttack", "SETTINGS_INPUT_CELL_KEYBINDING_CHARGE_ATTACK" },
				{ "_cell_keybinding_block", "SETTINGS_INPUT_CELL_KEYBINDING_BLOCK" },
				{ "_cell_keybinding_target", "SETTINGS_INPUT_CELL_KEYBINDING_TARGET" },
				{ "_cell_keybinding_interact", "SETTINGS_INPUT_CELL_KEYBINDING_INTERACT" },
				{ "_cell_keybinding_pvpFlag", "SETTINGS_INPUT_CELL_KEYBINDING_PVP_FLAG" },
				{ "_cell_keybinding_skillSlot01", "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_01" },
				{ "_cell_keybinding_skillSlot02", "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_02" },
				{ "_cell_keybinding_skillSlot03", "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_03" },
				{ "_cell_keybinding_skillSlot04", "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_04" },
				{ "_cell_keybinding_skillSlot05", "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_05" },
				{ "_cell_keybinding_skillSlot06", "SETTINGS_INPUT_CELL_KEYBINDING_SKILL_SLOT_06" },
				{ "_cell_keybinding_recall", "SETTINGS_INPUT_CELL_KEYBINDING_RECALL" },
				{ "_cell_keybinding_quickswapWeapon", "SETTINGS_INPUT_CELL_KEYBINDING_QUICKSWAP_WEAPON" },
				{ "_cell_keybinding_sheatheWeapon", "SETTINGS_INPUT_CELL_KEYBINDING_SHEATHE_WEAPON" },
				{ "_cell_keybinding_sit", "SETTINGS_INPUT_CELL_KEYBINDING_SIT" },
				{ "Header_ConsumableSlots", "SETTINGS_INPUT_HEADER_CONSUMABLE_SLOTS" },
				{ "_cell_keybinding_quickSlot01", "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_01" },
				{ "_cell_keybinding_quickSlot02", "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_02" },
				{ "_cell_keybinding_quickSlot03", "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_03" },
				{ "_cell_keybinding_quickSlot04", "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_04" },
				{ "_cell_keybinding_quickSlot05", "SETTINGS_INPUT_CELL_KEYBINDING_QUICK_SLOT_05" },
				{ "Header_Interface", "SETTINGS_INPUT_HEADER_INTERFACE" },
				{ "_cell_keybinding_38", "SETTINGS_INPUT_CELL_KEYBINDING_HOST_CONSOLE" },
				{ "_cell_keybinding_lexicon", "SETTINGS_INPUT_CELL_KEYBINDING_LEXICON" },
				{ "_cell_keybinding_tabMenu", "SETTINGS_INPUT_CELL_KEYBINDING_TAB_MENU" },
				{ "_cell_keybinding_statsTab", "SETTINGS_INPUT_CELL_KEYBINDING_STATS_TAB" },
				{ "_cell_keybinding_skillsTab", "SETTINGS_INPUT_CELL_KEYBINDING_SKILLS_TAB" },
				{ "_cell_keybinding_itemTab", "SETTINGS_INPUT_CELL_KEYBINDING_ITEM_TAB" },
				{ "_cell_keybinding_questTab", "SETTINGS_INPUT_CELL_KEYBINDING_QUEST_TAB" },
				{ "_cell_keybinding_whoTab", "SETTINGS_INPUT_CELL_KEYBINDING_WHO_TAB" },
				{ "_cell_keybinding_hideUI", "SETTINGS_INPUT_CELL_KEYBINDING_HIDE_UI" },
				{ "Button_networkTab", "SETTINGS_TAB_BUTTON_NETWORK" },
				{ "_header_uiSettings", "SETTINGS_NETWORK_HEADER_UI_SETTINGS" },
				{ "_cell_displayCreepNametags", "SETTINGS_NETWORK_CELL_DISPLAY_CREEP_NAMETAGS" },
				{ "_cell_displayLocalNametag", "SETTINGS_NETWORK_CELL_DISPLAY_LOCAL_NAMETAG" },
				{ "_cell_displayHostTag", "SETTINGS_NETWORK_CELL_DISPLAY_HOST_TAG" },
				{ "_cell_hideDungeonMinimap", "SETTINGS_NETWORK_CELL_HIDE_DUNGEON_MINIMAP" },
				{ "_cell_hideFPSCounter", "SETTINGS_NETWORK_CELL_HIDE_FPS_COUNTER" },
				{ "_cell_hidePingCounter", "SETTINGS_NETWORK_CELL_HIDE_PING_COUNTER" },
				{ "_header_clientSettings", "SETTINGS_NETWORK_HEADER_CLIENT_SETTINGS" },
				{ "_cell_enablePvPOnMapEnter", "SETTINGS_NETWORK_CELL_ENABLE_PVP_ON_MAP_ENTER" },
				{ "Button_cancelSettings", "SETTINGS_BUTTON_CANCEL" },
				{ "Button_applySettings", "SETTINGS_BUTTON_APPLY" }
			}, delegate(Transform textParent, string key)
			{
				Dropdown componentInChildren = ((Component)textParent).GetComponentInChildren<Dropdown>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					List<Func<int, string>> list = new List<Func<int, string>>();
					for (int i = 0; i < componentInChildren.options.Count; i++)
					{
						OptionData val = componentInChildren.options[i];
						string key2 = $"{key}_OPTION_{i + 1}";
						if (Localyssation.defaultLanguage.strings.TryGetValue(key2, out var _))
						{
							list.Add(LangAdjustables.GetStringFunc(key2, val.text));
						}
					}
					if (list.Count == componentInChildren.options.Count)
					{
						LangAdjustables.RegisterDropdown(componentInChildren, list);
					}
				}
			});
			RemapChildTextsByPath(((Component)__instance).transform, new Dictionary<string, string>
			{
				{ "Canvas_SettingsMenu/_dolly_settingsMenu/_dolly_videoSettingsTab/_backdrop_videoSettings/Scroll View/Viewport/Content/_cell_fieldOfView/Button/Text", "SETTINGS_BUTTON_RESET" },
				{ "Canvas_SettingsMenu/_dolly_settingsMenu/_dolly_videoSettingsTab/_backdrop_videoSettings/Scroll View/Viewport/Content/_cell_cameraSmoothing/Button_01/Text", "SETTINGS_BUTTON_RESET" },
				{ "Canvas_SettingsMenu/_dolly_settingsMenu/_dolly_videoSettingsTab/_backdrop_videoSettings/Scroll View/Viewport/Content/_cell_cameraHoriz/Button_01/Text", "SETTINGS_BUTTON_RESET" },
				{ "Canvas_SettingsMenu/_dolly_settingsMenu/_dolly_videoSettingsTab/_backdrop_videoSettings/Scroll View/Viewport/Content/_cell_cameraVert/Button_01/Text", "SETTINGS_BUTTON_RESET" },
				{ "Canvas_SettingsMenu/_dolly_settingsMenu/_dolly_inputSettingsTab/_backdrop/Scroll View/Viewport/Content/_cell_cameraSensitivity/Button_01/Text", "SETTINGS_BUTTON_RESET" }
			});
		}

		[HarmonyPatch(typeof(EquipToolTip), "Apply_EquipStats")]
		[HarmonyPostfix]
		public static void EquipToolTip_Apply_EquipStats(EquipToolTip __instance, ScriptableEquipment _scriptEquip, ItemData _itemData)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_scriptEquip))
			{
				return;
			}
			string forAsset = KeyUtil.GetForAsset((ScriptableItem)(object)_scriptEquip);
			ItemRarity val = ((ScriptableItem)_scriptEquip)._itemRarity;
			if (!string.IsNullOrWhiteSpace(_itemData._modifierTag) && Object.op_Implicit((Object)(object)GameManager._current.LocateStatModifier(_itemData._modifierTag)))
			{
				val = (ItemRarity)(byte)(val + 1);
			}
			if (!string.IsNullOrEmpty(((ScriptableItem)_scriptEquip)._itemName))
			{
				((TooltipElement)__instance)._toolTipName.text = ((TooltipElement)__instance)._toolTipName.text.Replace(((ScriptableItem)_scriptEquip)._itemName, Localyssation.GetString(forAsset + "_NAME", ((TooltipElement)__instance)._toolTipName.fontSize, ((TooltipElement)__instance)._toolTipName.text));
			}
			((TooltipElement)__instance)._toolTipSubName.text = Localyssation.GetFormattedString("FORMAT_EQUIP_ITEM_RARITY", ((TooltipElement)__instance)._toolTipSubName.fontSize, Localyssation.GetString(KeyUtil.GetForAsset(val), ((TooltipElement)__instance)._toolTipSubName.fontSize, ((object)(ItemRarity)(ref ((ScriptableItem)_scriptEquip)._itemRarity)).ToString()));
			if (!string.IsNullOrEmpty(((ScriptableItem)_scriptEquip)._itemDescription))
			{
				((TooltipElement)__instance)._toolTipDescription.text = Localyssation.GetString(forAsset + "_DESCRIPTION", ((TooltipElement)__instance)._toolTipDescription.fontSize, ((TooltipElement)__instance)._toolTipDescription.text);
			}
			if (Object.op_Implicit((Object)(object)_scriptEquip._classRequirement))
			{
				__instance._equipClassRequirement.text = Localyssation.GetFormattedString("FORMAT_EQUIP_CLASS_REQUIREMENT", __instance._equipClassRequirement.fontSize, Localyssation.GetString(KeyUtil.GetForAsset(_scriptEquip._classRequirement) + "_NAME", __instance._equipClassRequirement.fontSize, __instance._equipClassRequirement.text));
			}
			if (!(((object)_scriptEquip).GetType() == typeof(ScriptableWeapon)))
			{
				return;
			}
			ScriptableWeapon val2 = (ScriptableWeapon)_scriptEquip;
			if (Object.op_Implicit((Object)(object)val2._weaponConditionSlot._scriptableCondition))
			{
				Text toolTipDescription = ((TooltipElement)__instance)._toolTipDescription;
				toolTipDescription.text += Localyssation.GetFormattedString("FORMAT_EQUIP_WEAPON_CONDITION", ((TooltipElement)__instance)._toolTipDescription.fontSize, val2._weaponConditionSlot._chance * 100f, Localyssation.GetString(KeyUtil.GetForAsset(val2._weaponConditionSlot._scriptableCondition) + "_NAME", ((TooltipElement)__instance)._toolTipDescription.fontSize, val2._weaponConditionSlot._scriptableCondition._conditionName));
			}
			if (Enum.TryParse<DamageType>(__instance._equipWeaponDamageType.text, out DamageType result))
			{
				__instance._equipWeaponDamageType.text = __instance._equipWeaponDamageType.text.Replace(((object)(DamageType)(ref result)).ToString(), Localyssation.GetString(KeyUtil.GetForAsset(result), __instance._equipWeaponDamageType.fontSize, ((object)(DamageType)(ref result)).ToString()));
			}
			if (Object.op_Implicit((Object)(object)val2._combatElement))
			{
				if (!string.IsNullOrEmpty(val2._combatElement._elementName))
				{
					__instance._equipElementText.text = __instance._equipElementText.text.Replace(val2._combatElement._elementName, Localyssation.GetString(KeyUtil.GetForAsset(val2._combatElement) + "_NAME", __instance._equipElementText.fontSize, val2._combatElement._elementName));
				}
			}
			else
			{
				__instance._equipElementText.text = __instance._equipElementText.text.Replace("Normal", Localyssation.GetString("COMBAT_ELEMENT_NORMAL_NAME", __instance._equipElementText.fontSize, "Normal"));
			}
		}

		[HarmonyPatch(typeof(EquipToolTip), "Apply_EquipStats")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> EquipToolTip_Apply_EquipStats_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return SimpleStringReplaceTranspiler(instructions, new Dictionary<string, string>
			{
				{ "Lv-{0}", "FORMAT_EQUIP_LEVEL_REQUIREMENT" },
				{ "Helm (Armor)", "EQUIP_TOOLTIP_TYPE_HELM" },
				{ "Chestpiece (Armor)", "EQUIP_TOOLTIP_TYPE_CHESTPIECE" },
				{ "Leggings (Armor)", "EQUIP_TOOLTIP_TYPE_LEGGINGS" },
				{ "Cape (Armor)", "EQUIP_TOOLTIP_TYPE_CAPE" },
				{ "Ring (Armor)", "EQUIP_TOOLTIP_TYPE_RING" },
				{ "Shield", "EQUIP_TOOLTIP_TYPE_SHIELD" },
				{ "<color=#efcc00>({0} - {1})</color> Damage", "FORMAT_EQUIP_STATS_DAMAGE_SCALED_POWERFUL" },
				{ "<color=#c5e384>({0} - {1})</color> Damage", "FORMAT_EQUIP_STATS_DAMAGE_SCALED" },
				{ "\n<color=grey>(Base Damage: {0} - {1})</color>", "FORMAT_EQUIP_STATS_DAMAGE_COMPARE_BASE" },
				{ "({0} - {1}) Damage", "FORMAT_EQUIP_STATS_DAMAGE_UNSCALED" },
				{ "Block threshold: {0} damage", "FORMAT_EQUIP_STATS_BLOCK_THRESHOLD" }
			});
		}

		[HarmonyPatch(typeof(StatsMenuCell), "Cell_OnAwake")]
		[HarmonyPostfix]
		public static void StatsMenuCell_Cell_OnAwake(StatsMenuCell __instance)
		{
			RemapAllTextUnderObject(((Component)__instance).gameObject, new Dictionary<string, string>
			{
				{ "_text_statsHeader", "TAB_MENU_CELL_STATS_HEADER" },
				{ "_text_attributePointCounter (1)", "TAB_MENU_CELL_STATS_ATTRIBUTE_POINT_COUNTER" },
				{ "_button_applyAttributePoints", "TAB_MENU_CELL_STATS_BUTTON_APPLY_ATTRIBUTE_POINTS" }
			});
			RemapChildTextsByPath(((Component)__instance).transform, new Dictionary<string, string>
			{
				{ "_infoStatPanel/_statInfoCell_nickName/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_NICK_NAME" },
				{ "_infoStatPanel/_statInfoCell_raceName/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_RACE_NAME" },
				{ "_infoStatPanel/_statInfoCell_className/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_CLASS_NAME" },
				{ "_infoStatPanel/_statInfoCell_levelCounter/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_LEVEL_COUNTER" },
				{ "_infoStatPanel/_statInfoCell_experience/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_EXPERIENCE" },
				{ "_infoStatPanel/_statInfoCell_maxHealth/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_MAX_HEALTH" },
				{ "_infoStatPanel/_statInfoCell_maxMana/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_MAX_MANA" },
				{ "_infoStatPanel/_statInfoCell_maxStamina/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_MAX_STAMINA" },
				{ "_infoStatPanel/_statInfoCell_attack/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_ATTACK" },
				{ "_infoStatPanel/_statInfoCell_rangedPower/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_RANGED_POWER" },
				{ "_infoStatPanel/_statInfoCell_physCritical/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_PHYS_CRITICAL" },
				{ "_infoStatPanel/_statInfoCell_magicPow/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_MAGIC_POW" },
				{ "_infoStatPanel/_statInfoCell_magicCrit/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_MAGIC_CRIT" },
				{ "_infoStatPanel/_statInfoCell_defense/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_DEFENSE" },
				{ "_infoStatPanel/_statInfoCell_magicDef/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_MAGIC_DEF" },
				{ "_infoStatPanel/_statInfoCell_evasion/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_EVASION" },
				{ "_infoStatPanel/_statInfoCell_moveSpd/Image_01/Text", "TAB_MENU_CELL_STATS_INFO_CELL_MOVE_SPD" }
			});
		}

		[HarmonyPatch(typeof(StatsMenuCell), "Apply_StatsCellData")]
		[HarmonyPostfix]
		public static void StatsMenuCell_Apply_StatsCellData(StatsMenuCell __instance)
		{
			if (!TabMenu._current._isOpen && !((TabMenuCell)__instance)._mainPlayer._bufferingStatus)
			{
				return;
			}
			if (!string.IsNullOrEmpty(((TabMenuCell)__instance)._mainPlayer._pVisual._playerAppearanceStruct._setRaceTag))
			{
				ScriptablePlayerRace val = GameManager._current.LocateRace(((TabMenuCell)__instance)._mainPlayer._pVisual._playerAppearanceStruct._setRaceTag);
				if (Object.op_Implicit((Object)(object)val))
				{
					__instance._statsCell_raceTag.text = Localyssation.GetString(KeyUtil.GetForAsset(val) + "_NAME", __instance._statsCell_raceTag.fontSize, __instance._statsCell_raceTag.text);
				}
			}
			if (((TabMenuCell)__instance)._mainPlayer._pStats._currentLevel >= GameManager._current._statLogics._maxMainLevel)
			{
				__instance._statsCell_experience.text = Localyssation.GetString("EXP_COUNTER_MAX", __instance._statsCell_experience.fontSize, __instance._statsCell_experience.text);
			}
			int fontSize = __instance._statsCell_baseClassTag.fontSize;
			string text = ((!Object.op_Implicit((Object)(object)((TabMenuCell)__instance)._mainPlayer._pStats._class)) ? Localyssation.GetString("PLAYER_CLASS_EMPTY_NAME", fontSize, GameManager._current._statLogics._emptyClassName) : Localyssation.GetString(KeyUtil.GetForAsset(((TabMenuCell)__instance)._mainPlayer._pStats._class) + "_NAME", fontSize, ((TabMenuCell)__instance)._mainPlayer._pStats._class._className));
			__instance._statsCell_baseClassTag.text = text;
		}

		[HarmonyPatch(typeof(StatsMenuCell), "ToolTip_DisplayBaseStat")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> StatsMenuCell_ToolTip_DisplayBaseStat_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return SimpleStringReplaceTranspiler(instructions, new Dictionary<string, string>
			{
				{ "<b>Base Stat:</b> <i>", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_BEGIN" },
				{ "%</i> (Critical %)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_END_CRIT" },
				{ "%</i> (Evasion %)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_END_EVASION" },
				{ "{0}</i> (Attack Power)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_ATTACK_POW" },
				{ "{0}</i> (Max Mana)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAX_MP" },
				{ "{0}</i> (Max Health)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAX_HP" },
				{ "{0}</i> (Dex Power)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_RANGE_POW" },
				{ "%</i> (Magic Critical %)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_END_MAGIC_CRIT" },
				{ "{0}</i> (Magic Defense)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAGIC_DEF" },
				{ "{0}</i> (Defense)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_DEFENSE" },
				{ "{0}</i> (Magic Power)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAGIC_POW" },
				{ "{0}</i> (Max Stamina)", "TAB_MENU_CELL_STATS_TOOLTIP_BASE_STAT_FORMAT_MAX_STAM" }
			});
		}

		[HarmonyPatch(typeof(AttributeListDataEntry), "Handle_AttributeData")]
		[HarmonyPostfix]
		public static void AttributeListDataEntry_Handle_AttributeData(AttributeListDataEntry __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)GameManager._current) && Object.op_Implicit((Object)(object)Player._mainPlayer) && !string.IsNullOrEmpty(__instance._pStats._playerAttributes[((ListDataEntry)__instance)._dataID]._attributeName))
			{
				string forAsset = KeyUtil.GetForAsset(__instance._gm._statLogics._statAttributes[((ListDataEntry)__instance)._dataID]);
				((ListDataEntry)__instance)._dataNameText.text = Localyssation.GetString(forAsset + "_NAME", ((ListDataEntry)__instance)._dataNameText.fontSize, ((ListDataEntry)__instance)._dataNameText.text);
			}
		}

		[HarmonyPatch(typeof(AttributeListDataEntry), "Init_TooltipInfo")]
		[HarmonyPostfix]
		public static void AttributeListDataEntry_Init_TooltipInfo(AttributeListDataEntry __instance)
		{
			if (!string.IsNullOrEmpty(__instance._scriptableAttribute._attributeDescriptor))
			{
				string forAsset = KeyUtil.GetForAsset(__instance._scriptableAttribute);
				ToolTipManager._current.Apply_GenericToolTip(Localyssation.GetString(forAsset + "_DESCRIPTOR", -1, __instance._scriptableAttribute._attributeDescriptor));
			}
		}

		[HarmonyPatch(typeof(SkillsMenuCell), "Cell_OnAwake")]
		[HarmonyPostfix]
		public static void SkillsMenuCell_Cell_OnAwake(SkillsMenuCell __instance)
		{
			RemapAllTextUnderObject(((Component)__instance).gameObject, new Dictionary<string, string> { { "_text_skillsHeader", "TAB_MENU_CELL_SKILLS_HEADER" } });
			RemapChildTextsByPath(((Component)__instance).transform, new Dictionary<string, string>
			{
				{ "_backdrop_skillPoints/_text_skillPointsTag", "TAB_MENU_CELL_SKILLS_SKILL_POINT_COUNTER" },
				{ "Content_noviceSkills/_skillsCell_skillListObject_recall/_text_skillRank", "SKILL_RANK_SOULBOUND" }
			}, delegate(Transform transform, string key)
			{
				if (key == "TAB_MENU_CELL_SKILLS_SKILL_POINT_COUNTER")
				{
					Text component = ((Component)transform).GetComponent<Text>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.alignment = (TextAnchor)3;
					}
				}
			});
		}

		[HarmonyPatch(typeof(SkillsMenuCell), "Init_ClassTabTooltip")]
		[HarmonyPostfix]
		public static void SkillsMenuCell_Init_ClassTabTooltip(SkillsMenuCell __instance, int _tabValue)
		{
			switch (_tabValue)
			{
			case 0:
				ToolTipManager._current.Apply_GenericToolTip(Localyssation.GetString("TAB_MENU_CELL_SKILLS_CLASS_TAB_TOOLTIP_NOVICE"));
				break;
			case 1:
			{
				ScriptablePlayerBaseClass @class = Player._mainPlayer._pStats._class;
				if (Object.op_Implicit((Object)(object)@class))
				{
					string text = KeyUtil.GetForAsset(@class) + "_NAME";
					if (Localyssation.currentLanguage.strings.ContainsKey(text + "_VARIANT_OF"))
					{
						text += "_VARIANT_OF";
					}
					ToolTipManager._current.Apply_GenericToolTip(Localyssation.GetFormattedString("TAB_MENU_CELL_SKILLS_CLASS_TAB_TOOLTIP", -1, Localyssation.GetString(text, -1, @class._className)));
				}
				break;
			}
			}
		}

		[HarmonyPatch(typeof(SkillsMenuCell), "Handle_CellUpdate")]
		[HarmonyPostfix]
		public static void SkillsMenuCell_Handle_CellUpdate(SkillsMenuCell __instance)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			if (!TabMenu._current._isOpen || !Object.op_Implicit((Object)(object)Player._mainPlayer))
			{
				return;
			}
			string text = __instance._skillsCell_classHeader.text;
			int fontSize = __instance._skillsCell_classHeader.fontSize;
			SkillTier currentSkillTab = __instance._currentSkillTab;
			SkillTier val = currentSkillTab;
			if ((int)val != 0)
			{
				if ((int)val == 1)
				{
					string text2 = KeyUtil.GetForAsset(__instance._pStats._class) + "_NAME";
					if (Localyssation.currentLanguage.strings.ContainsKey(text2 + "_VARIANT_OF"))
					{
						text2 += "_VARIANT_OF";
					}
					text = Localyssation.GetFormattedString("TAB_MENU_CELL_SKILLS_CLASS_HEADER", fontSize, Localyssation.GetString(text2, fontSize, __instance._pStats._class._className));
				}
			}
			else
			{
				text = Localyssation.GetString("TAB_MENU_CELL_SKILLS_CLASS_HEADER_NOVICE", fontSize, text);
			}
			__instance._skillsCell_classHeader.text = text;
		}

		[HarmonyPatch(typeof(SkillListDataEntry), "Handle_SkillData")]
		[HarmonyPostfix]
		public static void SkillListDataEntry_Handle_SkillData(SkillListDataEntry __instance)
		{
			if (Object.op_Implicit((Object)(object)Player._mainPlayer) && !Player._mainPlayer._bufferingStatus && Object.op_Implicit((Object)(object)__instance._scriptSkill))
			{
				__instance._skillNameText.text = Localyssation.GetString(KeyUtil.GetForAsset(__instance._scriptSkill) + "_NAME", __instance._skillNameText.fontSize, __instance._skillNameText.text);
				if (Object.op

EasySettings.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Nessie.ATLYSS.EasySettings.Extensions;
using Nessie.ATLYSS.EasySettings.UIElements;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EasySettings")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: AssemblyInformationalVersion("1.1.3+a9b24740d8cfb770c731c6ff5a76ba3fb64e0e4f")]
[assembly: AssemblyProduct("Easy Settings API")]
[assembly: AssemblyTitle("EasySettings")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Nessie.ATLYSS.EasySettings
{
	public class ComponentReferences : MonoBehaviour
	{
		public List<Component> components = new List<Component>();
	}
	[BepInPlugin("EasySettings", "Easy Settings API", "1.1.3")]
	[BepInProcess("ATLYSS.exe")]
	public class EasySettingsPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__2_0;

			internal void <AddModTabButton>b__2_0()
			{
				SettingsManager._current.Set_SettingMenuSelectionIndex(Settings.ModTabIndex);
			}
		}

		internal static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			new Harmony("EasySettings").PatchAll();
			SettingsPatches.OnSettingsMenuInitialized.AddListener((UnityAction)delegate
			{
				AddModTabButton();
				AddModTabBottomSpace();
				Settings.OnInitialized.Invoke();
			});
		}

		private void AddModTabButton()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			Settings.ModTabIndex = 4;
			AtlyssTabButton atlyssTabButton = Settings.AddTabButton("Mods");
			UnityEvent onClicked = atlyssTabButton.OnClicked;
			object obj = <>c.<>9__2_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					SettingsManager._current.Set_SettingMenuSelectionIndex(Settings.ModTabIndex);
				};
				<>c.<>9__2_0 = val;
				obj = (object)val;
			}
			onClicked.AddListener((UnityAction)obj);
			Settings.ModTab.TabButton = atlyssTabButton;
		}

		private void AddModTabBottomSpace()
		{
			Settings.ModTab.BottomSpace = Settings.ModTab.AddSpace();
		}
	}
	public static class SettingsPatches
	{
		[HarmonyPatch(typeof(SettingsManager), "Start")]
		private static class MenuInitialization
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static UnityAction <>9__0_0;

				internal void <InitializeModTab>b__0_0()
				{
					Settings.OnCancelSettings.Invoke();
				}
			}

			[HarmonyPostfix]
			private static void InitializeModTab(SettingsManager __instance)
			{
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Expected O, but got Unknown
				Transform val = Utility.FindTabsContainer(__instance);
				if (!Object.op_Implicit((Object)(object)val))
				{
					EasySettingsPlugin.Logger.LogError((object)"Unable to find settings tabs container GameObject. EasySettings won't be available.");
					return;
				}
				HorizontalLayoutGroup component = ((Component)val).GetComponent<HorizontalLayoutGroup>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					EasySettingsPlugin.Logger.LogError((object)"Settings tabs container GameObject does not have a HorizontalLayoutGroup. EasySettings won't be available.");
					return;
				}
				((HorizontalOrVerticalLayoutGroup)component).spacing = 8f;
				((LayoutGroup)component).padding.right = ((LayoutGroup)component).padding.left;
				((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
				Button val2 = Utility.FindCancelButton(__instance);
				if (Object.op_Implicit((Object)(object)val2))
				{
					ButtonClickedEvent onClick = val2.onClick;
					object obj = <>c.<>9__0_0;
					if (obj == null)
					{
						UnityAction val3 = delegate
						{
							Settings.OnCancelSettings.Invoke();
						};
						<>c.<>9__0_0 = val3;
						obj = (object)val3;
					}
					((UnityEvent)onClick).AddListener((UnityAction)obj);
				}
				Button val4 = Utility.FindApplyButton(__instance);
				if (!Object.op_Implicit((Object)(object)val4))
				{
					EasySettingsPlugin.Logger.LogWarning((object)"Unable to find Apply Button. Saving the settings will not be possible during this play session.");
				}
				TemplateManager.Initialize();
				OnSettingsMenuInitialized.Invoke();
			}
		}

		[HarmonyPatch(typeof(SettingsManager), "Close_SettingsMenu")]
		private static class MenuClose
		{
			[HarmonyPostfix]
			private static void CloseSettings()
			{
				Settings.OnCloseSettings.Invoke();
			}
		}

		[HarmonyPatch(typeof(SettingsManager), "Save_SettingsData")]
		private static class SaveSettings
		{
			[HarmonyPostfix]
			private static void ApplySettings()
			{
				Settings.OnApplySettings.Invoke();
			}
		}

		[HarmonyPatch(typeof(SettingsManager), "Set_SettingMenuSelectionIndex")]
		private static class MenuSelection
		{
			[HarmonyPostfix]
			private static void ApplySelection(SettingsManager __instance)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Invalid comparison between Unknown and I4
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)ModTab.Element))
				{
					ModTab.Element.isEnabled = (int)__instance._currentSettingsMenuSelection == Settings.ModTabIndex;
				}
				if (Object.op_Implicit((Object)(object)ModTab.Content))
				{
					ModTab.Content.anchoredPosition = Vector2.zero;
				}
			}
		}

		[HarmonyPatch(typeof(SettingsManager), "Handle_InputParameters")]
		private static class ListenForKeyChanges
		{
			[HarmonyPrefix]
			private static void RecordKeys(SettingsManager __instance, out string[] __state)
			{
				if (!__instance._waitingForKey)
				{
					__state = null;
					return;
				}
				KeyBindButton[] keyBindButtons = __instance.keyBindButtons;
				string[] array = new string[keyBindButtons.Length];
				for (int i = 0; i < keyBindButtons.Length; i++)
				{
					array[i] = keyBindButtons[i]?._keyBind;
				}
				__state = array;
			}

			[HarmonyPostfix]
			private static void CompareKeys(SettingsManager __instance, string[] __state)
			{
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				if (__state == null)
				{
					return;
				}
				KeyBindButton[] keyBindButtons = __instance.keyBindButtons;
				for (int i = 0; i < keyBindButtons.Length; i++)
				{
					string text = __state[i];
					string keyBind = keyBindButtons[i]._keyBind;
					if (!(text == keyBind) && SettingsTab.KeyButtonIndexToKeyButton.ContainsKey(i))
					{
						SettingsTab.KeyButtonIndexToKeyButton[i].SetValue(Enum.Parse<KeyCode>(keyBind));
					}
				}
			}
		}

		[HarmonyPatch(typeof(SettingsManager), "OnGUI")]
		private static class ListenForKeyChanges2
		{
			[HarmonyPrefix]
			private static void RecordKeys(SettingsManager __instance, out string[] __state)
			{
				if (!__instance._waitingForKey)
				{
					__state = null;
					return;
				}
				KeyBindButton[] keyBindButtons = __instance.keyBindButtons;
				string[] array = new string[keyBindButtons.Length];
				for (int i = 0; i < keyBindButtons.Length; i++)
				{
					array[i] = keyBindButtons[i]?._keyBind;
				}
				__state = array;
			}

			[HarmonyPostfix]
			private static void CompareKeys(SettingsManager __instance, string[] __state)
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				if (__state == null)
				{
					return;
				}
				KeyBindButton[] keyBindButtons = __instance.keyBindButtons;
				for (int i = 0; i < keyBindButtons.Length; i++)
				{
					string text = __state[i];
					string keyBind = keyBindButtons[i]._keyBind;
					if (!(text == keyBind) && SettingsTab.KeyButtonIndexToKeyButton.TryGetValue(i, out var value))
					{
						value.SetValue(Enum.Parse<KeyCode>(keyBind));
					}
				}
			}
		}

		internal static UnityEvent OnSettingsMenuInitialized { get; } = new UnityEvent();


		private static SettingsTab ModTab => Settings.ModTab;
	}
	public static class Settings
	{
		private const string CREATE_TAB_NOTE = "Sorry, but this mod currently doesn't have any way to handle overflowing the tabs container, so the functions to create more tabs will have to be inaccessible for now.";

		public static SettingsTab ModTab { get; } = new SettingsTab();


		public static UnityEvent OnInitialized { get; } = new UnityEvent();


		public static UnityEvent OnCancelSettings { get; } = new UnityEvent();


		public static UnityEvent OnApplySettings { get; } = new UnityEvent();


		public static UnityEvent OnCloseSettings { get; } = new UnityEvent();


		internal static int ModTabIndex { get; set; }

		internal static SettingsTab AddTab(string label)
		{
			return new SettingsTab();
		}

		internal static AtlyssTabButton AddTabButton(string label)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			SettingsManager current = SettingsManager._current;
			Transform val = Utility.FindTabsContainer(current);
			AtlyssTabButton atlyssTabButton = TemplateManager.CreateTabButton((RectTransform)val);
			atlyssTabButton.Label.text = label;
			((Component)atlyssTabButton.Root).gameObject.SetActive(true);
			return atlyssTabButton;
		}
	}
	public class SettingsTab
	{
		private const float DEFAULT_SLIDER_MIN = 0f;

		private const float DEFAULT_SLIDER_MAX = 1f;

		public AtlyssTabButton TabButton;

		public MenuElement Element;

		public RectTransform Content;

		public List<BaseAtlyssElement> ContentElements = new List<BaseAtlyssElement>();

		internal AtlyssSpace BottomSpace;

		internal static Dictionary<int, AtlyssKeyButton> KeyButtonIndexToKeyButton = new Dictionary<int, AtlyssKeyButton>();

		public AtlyssSpace AddSpace()
		{
			AtlyssSpace atlyssSpace = TemplateManager.CreateSpace(Content);
			((Component)atlyssSpace.Root).gameObject.SetActive(true);
			PushElement(atlyssSpace);
			return atlyssSpace;
		}

		public AtlyssHeader AddHeader(string label)
		{
			AtlyssHeader atlyssHeader = TemplateManager.CreateHeader(Content);
			atlyssHeader.Label.text = label;
			((Component)atlyssHeader.Root).gameObject.SetActive(true);
			PushElement(atlyssHeader);
			return atlyssHeader;
		}

		public AtlyssButton AddButton(string buttonLabel, UnityAction onClick)
		{
			AtlyssButton atlyssButton = AddButton(buttonLabel);
			((UnityEvent)atlyssButton.Button.onClick).AddListener(onClick);
			return atlyssButton;
		}

		public AtlyssButton AddButton(string buttonLabel)
		{
			AtlyssButton atlyssButton = TemplateManager.CreateButton(Content);
			atlyssButton.ButtonLabel.text = buttonLabel;
			((Component)atlyssButton.Root).gameObject.SetActive(true);
			PushElement(atlyssButton);
			return atlyssButton;
		}

		public AtlyssToggle AddToggle(ConfigEntry<bool> config)
		{
			return AddToggle(((ConfigEntryBase)config).Definition.Key, config);
		}

		public AtlyssToggle AddToggle(string label, ConfigEntry<bool> config)
		{
			AtlyssToggle atlyssToggle = AddToggle(label, config.Value);
			atlyssToggle.OnValueChanged.AddListener((UnityAction<bool>)delegate(bool newValue)
			{
				config.Value = newValue;
			});
			return atlyssToggle;
		}

		public AtlyssToggle AddToggle(string label, bool value = false)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			AtlyssToggle element = TemplateManager.CreateToggle(Content);
			Settings.OnCloseSettings.AddListener((UnityAction)delegate
			{
				element.Revert();
			});
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				element.Apply();
			});
			element.Label.text = label;
			element.Toggle.SetIsOnWithoutNotify(value);
			element.Apply();
			((Component)element.Root).gameObject.SetActive(true);
			PushElement(element);
			return element;
		}

		public AtlyssSimpleSlider AddSlider(ConfigEntry<float> config, bool wholeNumbers = false)
		{
			return AddSlider(((ConfigEntryBase)config).Definition.Key, config, wholeNumbers);
		}

		public AtlyssSimpleSlider AddSlider(string label, ConfigEntry<float> config, bool wholeNumbers = false)
		{
			float min = 0f;
			float max = 1f;
			if (((ConfigEntryBase)config).Description.AcceptableValues is AcceptableValueRange<float> val)
			{
				min = val.MinValue;
				max = val.MaxValue;
			}
			AtlyssSimpleSlider atlyssSimpleSlider = AddSlider(label, config.Value, min, max, wholeNumbers);
			atlyssSimpleSlider?.OnValueChanged.AddListener((UnityAction<float>)delegate(float newValue)
			{
				config.Value = newValue;
			});
			return atlyssSimpleSlider;
		}

		public AtlyssSimpleSlider AddSlider(string label, float value = 0f, float min = 0f, float max = 1f, bool wholeNumbers = false)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			AtlyssSimpleSlider element = TemplateManager.CreateSimpleSlider(Content);
			Settings.OnCloseSettings.AddListener((UnityAction)delegate
			{
				element.Revert();
			});
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				element.Apply();
			});
			element.Label.text = label;
			element.Slider.wholeNumbers = wholeNumbers;
			element.Slider.minValue = min;
			element.Slider.maxValue = max;
			element.Slider.SetValueWithoutNotify(value);
			element.Apply();
			((Component)element.Root).gameObject.SetActive(true);
			PushElement(element);
			return element;
		}

		public AtlyssAdvancedSlider AddAdvancedSlider(ConfigEntry<int> config)
		{
			return AddAdvancedSlider(((ConfigEntryBase)config).Definition.Key, config);
		}

		public AtlyssAdvancedSlider AddAdvancedSlider(string label, ConfigEntry<int> config)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			float min = 0f;
			float max = 1f;
			if (((ConfigEntryBase)config).Description.AcceptableValues is AcceptableValueRange<float> val)
			{
				min = val.MinValue;
				max = val.MaxValue;
			}
			AtlyssAdvancedSlider element = AddAdvancedSlider(label, config.Value, min, max, wholeNumbers: true);
			element?.OnValueChanged.AddListener((UnityAction<float>)delegate(float newValue)
			{
				config.Value = Mathf.RoundToInt(newValue);
			});
			AtlyssAdvancedSlider atlyssAdvancedSlider = element;
			if (atlyssAdvancedSlider != null)
			{
				atlyssAdvancedSlider.OnResetClicked.AddListener((UnityAction)delegate
				{
					element.SetValue((float)((ConfigEntryBase)config).DefaultValue);
				});
			}
			return element;
		}

		public AtlyssAdvancedSlider AddAdvancedSlider(ConfigEntry<float> config, bool wholeNumbers = false)
		{
			return AddAdvancedSlider(((ConfigEntryBase)config).Definition.Key, config, wholeNumbers);
		}

		public AtlyssAdvancedSlider AddAdvancedSlider(string label, ConfigEntry<float> config, bool wholeNumbers = false)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			float min = 0f;
			float max = 1f;
			if (((ConfigEntryBase)config).Description.AcceptableValues is AcceptableValueRange<float> val)
			{
				min = val.MinValue;
				max = val.MaxValue;
			}
			AtlyssAdvancedSlider element = AddAdvancedSlider(label, config.Value, min, max, wholeNumbers);
			element?.OnValueChanged.AddListener((UnityAction<float>)delegate(float newValue)
			{
				config.Value = newValue;
			});
			AtlyssAdvancedSlider atlyssAdvancedSlider = element;
			if (atlyssAdvancedSlider != null)
			{
				atlyssAdvancedSlider.OnResetClicked.AddListener((UnityAction)delegate
				{
					element.SetValue((float)((ConfigEntryBase)config).DefaultValue);
				});
			}
			return element;
		}

		public AtlyssAdvancedSlider AddAdvancedSlider(string label, float value = 0f, float min = 0f, float max = 1f, bool wholeNumbers = false)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			AtlyssAdvancedSlider element = TemplateManager.CreateAdvancedSlider(Content);
			Settings.OnCloseSettings.AddListener((UnityAction)delegate
			{
				element.Revert();
			});
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				element.Apply();
			});
			element.Label.text = label;
			element.ValueText.text = value.ToString(CultureInfo.InvariantCulture);
			element.Slider.wholeNumbers = wholeNumbers;
			element.Slider.minValue = min;
			element.Slider.maxValue = max;
			element.Slider.SetValueWithoutNotify(value);
			element.Apply();
			((UnityEvent<float>)(object)element.Slider.onValueChanged).AddListener((UnityAction<float>)delegate(float newValue)
			{
				element.ValueText.text = newValue.ToString(CultureInfo.InvariantCulture);
			});
			((Component)element.Root).gameObject.SetActive(true);
			PushElement(element);
			return element;
		}

		public AtlyssDropdown AddDropdown<T>(ConfigEntry<T> config) where T : Enum
		{
			return AddDropdown<T>(((ConfigEntryBase)config).Definition.Key, config);
		}

		public AtlyssDropdown AddDropdown<T>(string label, ConfigEntry<T> config) where T : Enum
		{
			string[] names = Enum.GetNames(config.Value.GetType());
			AtlyssDropdown atlyssDropdown = AddDropdown(label, names, (int)(object)config.Value);
			atlyssDropdown.OnValueChanged.AddListener((UnityAction<int>)delegate(int newValue)
			{
				config.Value = (T)(object)newValue;
			});
			return atlyssDropdown;
		}

		public AtlyssDropdown AddDropdown(string label, string[] options, int value = 0)
		{
			return AddDropdown(label, options.ToList(), value);
		}

		public AtlyssDropdown AddDropdown(string label, List<string> options, int value = 0)
		{
			AtlyssDropdown atlyssDropdown = AddDropdown(label);
			atlyssDropdown.Dropdown.AddOptions(options);
			atlyssDropdown.Dropdown.SetValueWithoutNotify(value);
			atlyssDropdown.Apply();
			PushElement(atlyssDropdown);
			return atlyssDropdown;
		}

		public AtlyssDropdown AddDropdown(string label, List<Sprite> options, int value = 0)
		{
			AtlyssDropdown atlyssDropdown = AddDropdown(label);
			atlyssDropdown.Dropdown.AddOptions(options);
			atlyssDropdown.Dropdown.SetValueWithoutNotify(value);
			atlyssDropdown.Apply();
			PushElement(atlyssDropdown);
			return atlyssDropdown;
		}

		public AtlyssDropdown AddDropdown(string label)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			AtlyssDropdown element = TemplateManager.CreateDropdown(Content);
			Settings.OnCloseSettings.AddListener((UnityAction)delegate
			{
				element.Revert();
			});
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				element.Apply();
			});
			element.Label.text = label;
			((Component)element.Root).gameObject.SetActive(true);
			PushElement(element);
			return element;
		}

		public AtlyssKeyButton AddKeyButton(ConfigEntry<KeyCode> config)
		{
			return AddKeyButton(((ConfigEntryBase)config).Definition.Key, config);
		}

		public AtlyssKeyButton AddKeyButton(string label, ConfigEntry<KeyCode> config)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			AtlyssKeyButton atlyssKeyButton = AddKeyButton(label, config.Value);
			atlyssKeyButton.OnValueChanged.AddListener((UnityAction<KeyCode>)delegate(KeyCode newValue)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				config.Value = newValue;
			});
			return atlyssKeyButton;
		}

		public AtlyssKeyButton AddKeyButton(string label, KeyCode value = 0)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			AtlyssKeyButton element = TemplateManager.CreateKeyButton(Content);
			Settings.OnCloseSettings.AddListener((UnityAction)delegate
			{
				element.Revert();
			});
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				element.Apply();
			});
			element.Label.text = label;
			element.SetValue(value);
			element.Apply();
			((Component)element.Root).gameObject.SetActive(true);
			RegisterKeyButton(element);
			PushElement(element);
			return element;
		}

		private static void RegisterKeyButton(AtlyssKeyButton element)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			SettingsManager manager = SettingsManager._current;
			KeyBindButton keyButton = new KeyBindButton
			{
				_inputReference = "",
				_keyBind = element.ButtonLabel.text,
				_button = element.Button,
				_buttonLabel = element.ButtonLabel
			};
			int newButtonIndex = manager.keyBindButtons.Length;
			((UnityEvent)keyButton._button.onClick).AddListener((UnityAction)delegate
			{
				manager.OnClick_KeybindButton(newButtonIndex);
			});
			KeyButtonIndexToKeyButton.Add(newButtonIndex, element);
			Settings.OnCloseSettings.AddListener((UnityAction)delegate
			{
				keyButton._keyBind = element.ButtonLabel.text;
			});
			manager.keyBindButtons = CollectionExtensions.AddToArray<KeyBindButton>(manager.keyBindButtons, keyButton);
		}

		private void PushElement(BaseAtlyssElement element)
		{
			ContentElements.Add(element);
			AtlyssSpace bottomSpace = BottomSpace;
			if (bottomSpace != null)
			{
				((Transform)bottomSpace.Root).SetSiblingIndex(((Transform)Content).childCount);
			}
		}
	}
	internal static class TemplateManager
	{
		internal static AtlyssTabButton TabTemplate;

		internal static AtlyssSpace SpaceTemplate;

		internal static AtlyssHeader HeaderTemplate;

		internal static AtlyssButton ButtonTemplate;

		internal static AtlyssToggle ToggleTemplate;

		internal static AtlyssSimpleSlider SimpleSliderTemplate;

		internal static AtlyssAdvancedSlider AdvancedSliderTemplate;

		internal static AtlyssDropdown DropdownTemplate;

		internal static AtlyssKeyButton KeyButtonTemplate;

		internal static void Initialize()
		{
			FindTemplateElements();
		}

		private static void FindTemplateElements()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			SettingsManager val = Object.FindObjectOfType<SettingsManager>(true);
			Transform val2 = Utility.FindTabsContainer(val);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				EasySettingsPlugin.Logger.LogError((object)"Unable to find settings tabs container GameObject. EasySettings won't be available.");
				return;
			}
			RectTransform template = (RectTransform)val2.GetChild(0);
			TabTemplate = CreateTabButton((RectTransform)val2, template);
			((Component)TabTemplate.Root).gameObject.SetActive(false);
			SettingsTab modTab = Settings.ModTab;
			Transform val3 = Object.Instantiate<Transform>(((Component)val._videoTabElement).transform, ((Component)val._videoTabElement).transform.parent);
			modTab.Element = ((Component)val3).GetComponent<MenuElement>();
			modTab.Content = (RectTransform)((Component)((Component)val3).GetComponentInChildren<VerticalLayoutGroup>()).transform;
			InitializeTabContent(modTab.Content);
			RectTransform val4 = FindSpace(val);
			if (Object.op_Implicit((Object)(object)val4))
			{
				SpaceTemplate = CreateSpace(modTab.Content, val4);
				((Component)SpaceTemplate.Root).gameObject.SetActive(false);
			}
			RectTransform val5 = FindHeader(val);
			if (Object.op_Implicit((Object)(object)val5))
			{
				HeaderTemplate = CreateHeader(modTab.Content, val5);
				((Component)HeaderTemplate.Root).gameObject.SetActive(false);
			}
			RectTransform val6 = FindButton(val);
			if (Object.op_Implicit((Object)(object)val6))
			{
				ButtonTemplate = CreateButton(modTab.Content, val6);
				((Component)ButtonTemplate.Root).gameObject.SetActive(false);
			}
			RectTransform val7 = FindToggle(val);
			if (Object.op_Implicit((Object)(object)val7))
			{
				ToggleTemplate = CreateToggle(modTab.Content, val7);
				((Component)ToggleTemplate.Root).gameObject.SetActive(false);
			}
			RectTransform val8 = FindSimpleSlider(val);
			if (Object.op_Implicit((Object)(object)val8))
			{
				SimpleSliderTemplate = CreateSimpleSlider(modTab.Content, val8);
				((Component)SimpleSliderTemplate.Root).gameObject.SetActive(false);
			}
			RectTransform val9 = FindAdvancedSlider(val);
			if (Object.op_Implicit((Object)(object)val9))
			{
				AdvancedSliderTemplate = CreateAdvancedSlider(modTab.Content, val9);
				((Component)AdvancedSliderTemplate.Root).gameObject.SetActive(false);
			}
			RectTransform val10 = FindDropdown(val);
			if (Object.op_Implicit((Object)(object)val10))
			{
				DropdownTemplate = CreateDropdown(modTab.Content, val10);
				((Component)DropdownTemplate.Root).gameObject.SetActive(false);
			}
			RectTransform val11 = FindKeyButton(val);
			if (Object.op_Implicit((Object)(object)val11))
			{
				KeyButtonTemplate = CreateKeyButton(modTab.Content, val11);
				((Component)KeyButtonTemplate.Root).gameObject.SetActive(false);
			}
		}

		private static void InitializeTabContent(RectTransform tabContent)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			foreach (RectTransform item in (Transform)tabContent)
			{
				RectTransform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private static RectTransform FindSpace(SettingsManager manager)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			RectTransform[] array = (RectTransform[])(object)new RectTransform[4] { manager._videoTabContent, manager._audioTabContent, manager._inputTabContent, manager._networkTabContent };
			RectTransform[] array2 = array;
			foreach (RectTransform val in array2)
			{
				foreach (RectTransform item in (Transform)val)
				{
					RectTransform val2 = item;
					if (((Transform)val2).childCount == 0)
					{
						Component[] components = ((Component)val2).GetComponents<Component>();
						if (components.Length <= 1)
						{
							return val2;
						}
					}
				}
			}
			return null;
		}

		private static RectTransform FindHeader(SettingsManager manager)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			RectTransform[] array = (RectTransform[])(object)new RectTransform[4] { manager._videoTabContent, manager._audioTabContent, manager._inputTabContent, manager._networkTabContent };
			RectTransform[] array2 = array;
			foreach (RectTransform val in array2)
			{
				foreach (RectTransform item in (Transform)val)
				{
					RectTransform val2 = item;
					Selectable componentInChildren = ((Component)val2).GetComponentInChildren<Selectable>(true);
					if (!Object.op_Implicit((Object)(object)componentInChildren))
					{
						Text componentInChildren2 = ((Component)val2).GetComponentInChildren<Text>(true);
						if (Object.op_Implicit((Object)(object)componentInChildren2))
						{
							return val2;
						}
					}
				}
			}
			return null;
		}

		private static RectTransform FindButton(SettingsManager manager)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			Transform[] array = (Transform[])(object)new Transform[4]
			{
				(Transform)manager._videoTabContent,
				(Transform)manager._audioTabContent,
				(Transform)manager._inputTabContent,
				(Transform)manager._networkTabContent
			};
			Transform[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RectTransform val = (RectTransform)array2[i];
				foreach (RectTransform item in (Transform)val)
				{
					RectTransform val2 = item;
					Button componentInChildren = ((Component)val2).GetComponentInChildren<Button>(true);
					if (!Object.op_Implicit((Object)(object)componentInChildren))
					{
						continue;
					}
					Text componentInChildren2 = ((Component)val2).GetComponentInChildren<Text>(true);
					if (Object.op_Implicit((Object)(object)componentInChildren2))
					{
						Selectable[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Selectable>(true);
						if (componentsInChildren.Length <= 1)
						{
							return val2;
						}
					}
				}
			}
			return null;
		}

		private static RectTransform FindToggle(SettingsManager manager)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			Transform[] contents = (Transform[])(object)new Transform[4]
			{
				(Transform)manager._videoTabContent,
				(Transform)manager._audioTabContent,
				(Transform)manager._inputTabContent,
				(Transform)manager._networkTabContent
			};
			Toggle fullScreenToggle = manager._fullScreenToggle;
			if (!Utility.TryGetElementRoot(contents, ((Component)fullScreenToggle).transform, out var root))
			{
				return null;
			}
			List<Component> components = ((Component)root).gameObject.AddComponent<ComponentReferences>().components;
			components.Add((Component)(object)fullScreenToggle);
			return (RectTransform)root;
		}

		private static RectTransform FindSimpleSlider(SettingsManager manager)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			Transform[] contents = (Transform[])(object)new Transform[4]
			{
				(Transform)manager._videoTabContent,
				(Transform)manager._audioTabContent,
				(Transform)manager._inputTabContent,
				(Transform)manager._networkTabContent
			};
			Slider masterVolumeSlider = manager._masterVolumeSlider;
			if (!Utility.TryGetElementRoot(contents, ((Component)masterVolumeSlider).transform, out var root))
			{
				return null;
			}
			List<Component> components = ((Component)root).gameObject.AddComponent<ComponentReferences>().components;
			components.Add((Component)(object)masterVolumeSlider);
			return (RectTransform)root;
		}

		private static RectTransform FindAdvancedSlider(SettingsManager manager)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			Transform[] contents = (Transform[])(object)new Transform[4]
			{
				(Transform)manager._videoTabContent,
				(Transform)manager._audioTabContent,
				(Transform)manager._inputTabContent,
				(Transform)manager._networkTabContent
			};
			Slider cameraFieldOfViewSlider = manager._cameraFieldOfViewSlider;
			Text cameraFieldOfViewText = manager._cameraFieldOfViewText;
			if (!Utility.TryGetElementRoot(contents, ((Component)cameraFieldOfViewSlider).transform, out var root))
			{
				return null;
			}
			List<Component> components = ((Component)root).gameObject.AddComponent<ComponentReferences>().components;
			components.Add((Component)(object)cameraFieldOfViewSlider);
			components.Add((Component)(object)cameraFieldOfViewText);
			return (RectTransform)root;
		}

		private static RectTransform FindDropdown(SettingsManager manager)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			Transform[] contents = (Transform[])(object)new Transform[4]
			{
				(Transform)manager._videoTabContent,
				(Transform)manager._audioTabContent,
				(Transform)manager._inputTabContent,
				(Transform)manager._networkTabContent
			};
			Dropdown fullScreenResolutionDropdown = manager._fullScreenResolutionDropdown;
			if (!Utility.TryGetElementRoot(contents, ((Component)fullScreenResolutionDropdown).transform, out var root))
			{
				return null;
			}
			List<Component> components = ((Component)root).gameObject.AddComponent<ComponentReferences>().components;
			components.Add((Component)(object)fullScreenResolutionDropdown);
			return (RectTransform)root;
		}

		private static RectTransform FindKeyButton(SettingsManager manager)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			Transform[] contents = (Transform[])(object)new Transform[4]
			{
				(Transform)manager._videoTabContent,
				(Transform)manager._audioTabContent,
				(Transform)manager._inputTabContent,
				(Transform)manager._networkTabContent
			};
			KeyBindButton[] keyBindButtons = manager.keyBindButtons;
			if (keyBindButtons == null || keyBindButtons.Length <= 0)
			{
				return null;
			}
			KeyBindButton[] array = keyBindButtons;
			foreach (KeyBindButton val in array)
			{
				if (val != null)
				{
					Button button = val._button;
					Text buttonLabel = val._buttonLabel;
					if (Utility.TryGetElementRoot(contents, ((Component)button).transform, out var root))
					{
						List<Component> components = ((Component)root).gameObject.AddComponent<ComponentReferences>().components;
						components.Add((Component)(object)button);
						components.Add((Component)(object)buttonLabel);
						return (RectTransform)root;
					}
				}
			}
			return null;
		}

		internal static AtlyssTabButton CreateTabButton(RectTransform container)
		{
			return CreateTabButton(container, TabTemplate);
		}

		internal static AtlyssTabButton CreateTabButton(RectTransform container, AtlyssTabButton template)
		{
			return CreateTabButton(container, template.Root);
		}

		internal static AtlyssTabButton CreateTabButton(RectTransform container, RectTransform template)
		{
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			AtlyssTabButton atlyssTabButton = new AtlyssTabButton
			{
				Root = val,
				Label = ((Component)val).GetComponentInChildren<Text>(true),
				Button = ((Component)val).GetComponentInChildren<Button>(true)
			};
			atlyssTabButton.Initialize();
			return atlyssTabButton;
		}

		internal static AtlyssHeader CreateHeader(RectTransform container)
		{
			return CreateHeader(container, HeaderTemplate);
		}

		internal static AtlyssHeader CreateHeader(RectTransform container, AtlyssHeader template)
		{
			return CreateHeader(container, template.Root);
		}

		internal static AtlyssHeader CreateHeader(RectTransform container, RectTransform template)
		{
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			AtlyssHeader atlyssHeader = new AtlyssHeader
			{
				Root = val,
				Label = ((Component)val).GetComponentInChildren<Text>(true)
			};
			atlyssHeader.Initialize();
			return atlyssHeader;
		}

		internal static AtlyssButton CreateButton(RectTransform container)
		{
			return CreateButton(container, ButtonTemplate);
		}

		internal static AtlyssButton CreateButton(RectTransform container, AtlyssButton template)
		{
			return CreateButton(container, template.Root);
		}

		internal static AtlyssButton CreateButton(RectTransform container, RectTransform template)
		{
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			AtlyssButton atlyssButton = new AtlyssButton
			{
				Root = val,
				ButtonLabel = ((Component)val).GetComponentInChildren<Text>(true),
				Button = ((Component)val).GetComponentInChildren<Button>(true)
			};
			atlyssButton.Initialize();
			return atlyssButton;
		}

		internal static AtlyssToggle CreateToggle(RectTransform container)
		{
			return CreateToggle(container, ToggleTemplate);
		}

		internal static AtlyssToggle CreateToggle(RectTransform container, AtlyssToggle template)
		{
			return CreateToggle(container, template.Root);
		}

		internal static AtlyssToggle CreateToggle(RectTransform container, RectTransform template)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			AtlyssToggle atlyssToggle = new AtlyssToggle
			{
				Root = val,
				Label = ((Component)val).GetComponentInChildren<Text>(true),
				Toggle = (Toggle)((Component)val).GetComponentInChildren<ComponentReferences>(true).components[0]
			};
			atlyssToggle.Initialize();
			return atlyssToggle;
		}

		internal static AtlyssSimpleSlider CreateSimpleSlider(RectTransform container)
		{
			return CreateSimpleSlider(container, SimpleSliderTemplate);
		}

		internal static AtlyssSimpleSlider CreateSimpleSlider(RectTransform container, AtlyssSimpleSlider template)
		{
			return CreateSimpleSlider(container, template.Root);
		}

		internal static AtlyssSimpleSlider CreateSimpleSlider(RectTransform container, RectTransform template)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			List<Component> components = ((Component)val).GetComponentInChildren<ComponentReferences>(true).components;
			AtlyssSimpleSlider atlyssSimpleSlider = new AtlyssSimpleSlider
			{
				Root = val,
				Label = ((Component)val).GetComponentInChildren<Text>(true),
				Slider = (Slider)components[0]
			};
			atlyssSimpleSlider.Initialize();
			return atlyssSimpleSlider;
		}

		internal static AtlyssAdvancedSlider CreateAdvancedSlider(RectTransform container)
		{
			return CreateAdvancedSlider(container, AdvancedSliderTemplate);
		}

		internal static AtlyssAdvancedSlider CreateAdvancedSlider(RectTransform container, AtlyssAdvancedSlider template)
		{
			return CreateAdvancedSlider(container, template.Root);
		}

		internal static AtlyssAdvancedSlider CreateAdvancedSlider(RectTransform container, RectTransform template)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			List<Component> components = ((Component)val).GetComponentInChildren<ComponentReferences>(true).components;
			AtlyssAdvancedSlider atlyssAdvancedSlider = new AtlyssAdvancedSlider
			{
				Root = val,
				Label = ((Component)val).GetComponentInChildren<Text>(true),
				ValueText = (Text)components[1],
				Slider = (Slider)components[0],
				ResetButton = ((Component)val).GetComponentInChildren<Button>(true)
			};
			atlyssAdvancedSlider.Initialize();
			return atlyssAdvancedSlider;
		}

		internal static AtlyssDropdown CreateDropdown(RectTransform container)
		{
			return CreateDropdown(container, DropdownTemplate);
		}

		internal static AtlyssDropdown CreateDropdown(RectTransform container, AtlyssDropdown template)
		{
			return CreateDropdown(container, template.Root);
		}

		internal static AtlyssDropdown CreateDropdown(RectTransform container, RectTransform template)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			List<Component> components = ((Component)val).GetComponentInChildren<ComponentReferences>(true).components;
			AtlyssDropdown atlyssDropdown = new AtlyssDropdown
			{
				Root = val,
				Label = ((Component)val).GetComponentInChildren<Text>(true),
				Dropdown = (Dropdown)components[0]
			};
			atlyssDropdown.Initialize();
			return atlyssDropdown;
		}

		internal static AtlyssKeyButton CreateKeyButton(RectTransform container)
		{
			return CreateKeyButton(container, KeyButtonTemplate);
		}

		internal static AtlyssKeyButton CreateKeyButton(RectTransform container, AtlyssKeyButton template)
		{
			return CreateKeyButton(container, template.Root);
		}

		internal static AtlyssKeyButton CreateKeyButton(RectTransform container, RectTransform template)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			RectTransform val = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			List<Component> components = ((Component)val).GetComponentInChildren<ComponentReferences>(true).components;
			AtlyssKeyButton atlyssKeyButton = new AtlyssKeyButton
			{
				Root = val,
				Label = ((Component)val).GetComponentInChildren<Text>(true),
				ButtonLabel = (Text)components[1],
				Button = (Button)components[0]
			};
			atlyssKeyButton.Initialize();
			return atlyssKeyButton;
		}

		internal static AtlyssSpace CreateSpace(RectTransform container)
		{
			return CreateSpace(container, SpaceTemplate);
		}

		internal static AtlyssSpace CreateSpace(RectTransform container, AtlyssSpace template)
		{
			return CreateSpace(container, template.Root);
		}

		internal static AtlyssSpace CreateSpace(RectTransform container, RectTransform template)
		{
			RectTransform root = Object.Instantiate<RectTransform>(template, (Transform)(object)container);
			return new AtlyssSpace
			{
				Root = root
			};
		}
	}
	public static class Utility
	{
		public static bool TryGetRelativeRoot(Transform relativeParent, Transform child, out Transform root)
		{
			root = child;
			while (Object.op_Implicit((Object)(object)root))
			{
				if ((Object)(object)root.parent == (Object)(object)relativeParent)
				{
					return true;
				}
				root = root.parent;
			}
			root = null;
			return false;
		}

		public static bool TryGetElementRoot(Transform[] contents, Transform elementChild, out Transform root)
		{
			foreach (Transform relativeParent in contents)
			{
				if (TryGetRelativeRoot(relativeParent, ((Component)elementChild).transform, out root))
				{
					return true;
				}
			}
			root = null;
			return false;
		}

		public static Transform FindTabsContainer(SettingsManager instance)
		{
			Button[] componentsInChildren = ((Component)instance).GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				foreach (PersistentCall call in ((UnityEventBase)val.onClick).m_PersistentCalls.m_Calls)
				{
					if (call == null || call.target != (Object)(object)instance || call.methodName != "Set_SettingMenuSelectionIndex")
					{
						continue;
					}
					return ((Component)val).transform.parent;
				}
			}
			return null;
		}

		public static Button FindCancelButton(SettingsManager instance)
		{
			Button[] componentsInChildren = ((Component)instance).GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				foreach (PersistentCall call in ((UnityEventBase)val.onClick).m_PersistentCalls.m_Calls)
				{
					if (call == null || call.target != (Object)(object)instance || call.methodName != "Close_SettingsMenu")
					{
						continue;
					}
					return val;
				}
			}
			return null;
		}

		public static Button FindApplyButton(SettingsManager instance)
		{
			Button[] componentsInChildren = ((Component)instance).GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				foreach (PersistentCall call in ((UnityEventBase)val.onClick).m_PersistentCalls.m_Calls)
				{
					if (call == null || call.target != (Object)(object)instance || call.methodName != "Save_SettingsData")
					{
						continue;
					}
					return val;
				}
			}
			return null;
		}

		public static bool IsKeyBound(SettingsManager instance, KeyCode key)
		{
			return IsKeyBound(instance, ((object)(KeyCode)(ref key)).ToString());
		}

		public static bool IsKeyBound(SettingsManager instance, string key)
		{
			KeyBindButton[] keyBindButtons = instance.keyBindButtons;
			foreach (KeyBindButton val in keyBindButtons)
			{
				if (val._keyBind == key)
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "EasySettings";

		public const string PLUGIN_NAME = "Easy Settings API";

		public const string PLUGIN_VERSION = "1.1.3";
	}
}
namespace Nessie.ATLYSS.EasySettings.Extensions
{
	public static class UnityEventExtensions
	{
		public static void SetAllPersistentListenerStates(this UnityEventBase unityEvent, UnityEventCallState state)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < unityEvent.GetPersistentEventCount(); i++)
			{
				unityEvent.SetPersistentListenerState(i, state);
			}
		}

		public static void DisablePersistentListeners(this UnityEventBase unityEvent)
		{
			unityEvent.SetAllPersistentListenerStates((UnityEventCallState)0);
		}

		public static void RemoveAndDisableAllListeners(this UnityEventBase unityEvent)
		{
			unityEvent.RemoveAllListeners();
			unityEvent.DisablePersistentListeners();
		}
	}
}
namespace Nessie.ATLYSS.EasySettings.UIElements
{
	public class AtlyssAdvancedSlider : BaseAtlyssLabelElement, IValueElement
	{
		public Text ValueText;

		private Slider _slider;

		private Button _resetButton;

		public Slider Slider
		{
			get
			{
				return _slider;
			}
			set
			{
				if (Object.op_Implicit((Object)(object)_slider))
				{
					((UnityEvent<float>)(object)_slider.onValueChanged).RemoveListener((UnityAction<float>)ValueChanged);
				}
				_slider = value;
				if (Object.op_Implicit((Object)(object)_slider))
				{
					((UnityEvent<float>)(object)_slider.onValueChanged).AddListener((UnityAction<float>)ValueChanged);
				}
			}
		}

		public Button ResetButton
		{
			get
			{
				return _resetButton;
			}
			set
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				if (Object.op_Implicit((Object)(object)_resetButton))
				{
					((UnityEvent)_resetButton.onClick).RemoveListener(new UnityAction(ResetClicked));
				}
				_resetButton = value;
				if (Object.op_Implicit((Object)(object)_resetButton))
				{
					((UnityEvent)_resetButton.onClick).AddListener(new UnityAction(ResetClicked));
				}
			}
		}

		public UnityEvent<float> OnValueChanged { get; } = new UnityEvent<float>();


		public UnityEvent OnResetClicked { get; } = new UnityEvent();


		public float AppliedValue { get; private set; }

		public void Initialize()
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			base.Label.text = "Advanced Slider";
			ValueText.text = $"{AppliedValue}";
			((UnityEventBase)(object)Slider.onValueChanged).RemoveAndDisableAllListeners();
			((UnityEvent<float>)(object)Slider.onValueChanged).AddListener((UnityAction<float>)ValueChanged);
			Slider.wholeNumbers = false;
			Slider.minValue = 0f;
			Slider.maxValue = 1f;
			Slider.SetValueWithoutNotify(AppliedValue);
			((UnityEventBase)(object)ResetButton.onClick).RemoveAndDisableAllListeners();
			((UnityEvent)ResetButton.onClick).AddListener(new UnityAction(ResetClicked));
		}

		public void SetValue(float value)
		{
			_slider.value = value;
		}

		public void Apply()
		{
			AppliedValue = _slider.value;
		}

		public void Revert()
		{
			_slider.value = AppliedValue;
		}

		private void ValueChanged(float newValue)
		{
			OnValueChanged.Invoke(newValue);
		}

		private void ResetClicked()
		{
			OnResetClicked.Invoke();
		}
	}
	public abstract class BaseAtlyssElement
	{
		public RectTransform Root;
	}
	public abstract class BaseAtlyssLabelElement : BaseAtlyssElement
	{
		public Text Label { get; set; }

		public string LabelText
		{
			get
			{
				return Label.text;
			}
			set
			{
				Label.text = value;
			}
		}
	}
	public interface IValueElement
	{
		private void Apply()
		{
		}

		void Revert()
		{
		}
	}
	public class AtlyssButton : BaseAtlyssElement
	{
		public Text ButtonLabel;

		private Button _button;

		public Button Button
		{
			get
			{
				return _button;
			}
			set
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				if (Object.op_Implicit((Object)(object)_button))
				{
					((UnityEvent)_button.onClick).RemoveListener(new UnityAction(Clicked));
				}
				_button = value;
				if (Object.op_Implicit((Object)(object)_button))
				{
					((UnityEvent)_button.onClick).RemoveListener(new UnityAction(Clicked));
				}
			}
		}

		public UnityEvent OnClicked { get; } = new UnityEvent();


		public void Initialize()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			ButtonLabel.text = "Button";
			((UnityEventBase)(object)Button.onClick).RemoveAndDisableAllListeners();
			((UnityEvent)Button.onClick).AddListener(new UnityAction(Clicked));
		}

		private void Clicked()
		{
			OnClicked.Invoke();
		}
	}
	public class AtlyssDropdown : BaseAtlyssLabelElement, IValueElement
	{
		private Dropdown _dropdown;

		public Dropdown Dropdown
		{
			get
			{
				return _dropdown;
			}
			set
			{
				if (Object.op_Implicit((Object)(object)_dropdown))
				{
					((UnityEvent<int>)(object)_dropdown.onValueChanged).RemoveListener((UnityAction<int>)ValueChanged);
				}
				_dropdown = value;
				if (Object.op_Implicit((Object)(object)_dropdown))
				{
					((UnityEvent<int>)(object)_dropdown.onValueChanged).AddListener((UnityAction<int>)ValueChanged);
				}
			}
		}

		public UnityEvent<int> OnValueChanged { get; } = new UnityEvent<int>();


		public int AppliedValue { get; private set; }

		public void Initialize()
		{
			base.Label.text = "Dropdown";
			((UnityEventBase)(object)Dropdown.onValueChanged).RemoveAndDisableAllListeners();
			((UnityEvent<int>)(object)Dropdown.onValueChanged).AddListener((UnityAction<int>)ValueChanged);
			Dropdown.options.Clear();
			Dropdown.SetValueWithoutNotify(AppliedValue);
		}

		public void Apply()
		{
			AppliedValue = Dropdown.value;
		}

		public void Revert()
		{
			Dropdown.value = AppliedValue;
		}

		private void ValueChanged(int newValue)
		{
			OnValueChanged.Invoke(newValue);
		}
	}
	public class AtlyssHeader : BaseAtlyssLabelElement
	{
		public void Initialize()
		{
			base.LabelText = "Header";
		}
	}
	public class AtlyssKeyButton : BaseAtlyssLabelElement, IValueElement
	{
		public Text ButtonLabel;

		private Button _button;

		private KeyCode _value;

		public Button Button
		{
			get
			{
				return _button;
			}
			set
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				if (Object.op_Implicit((Object)(object)_button))
				{
					((UnityEvent)_button.onClick).RemoveListener(new UnityAction(Clicked));
				}
				_button = value;
				if (Object.op_Implicit((Object)(object)_button))
				{
					((UnityEvent)_button.onClick).RemoveListener(new UnityAction(Clicked));
				}
			}
		}

		public UnityEvent<KeyCode> OnValueChanged { get; } = new UnityEvent<KeyCode>();


		public UnityEvent OnClicked { get; } = new UnityEvent();


		public KeyCode AppliedValue { get; private set; }

		public void Initialize()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			base.Label.text = "Key Button";
			_value = AppliedValue;
			Text buttonLabel = ButtonLabel;
			KeyCode appliedValue = AppliedValue;
			buttonLabel.text = ((object)(KeyCode)(ref appliedValue)).ToString();
			((UnityEventBase)(object)Button.onClick).RemoveAndDisableAllListeners();
			((UnityEvent)Button.onClick).AddListener(new UnityAction(Clicked));
		}

		public void SetValue(KeyCode key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			_value = key;
			ButtonLabel.text = ((object)(KeyCode)(ref key)).ToString();
			ValueChanged(key);
		}

		public void Apply()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			AppliedValue = _value;
		}

		public void Revert()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			SetValue(AppliedValue);
		}

		private void ValueChanged(KeyCode newValue)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			OnValueChanged.Invoke(newValue);
		}

		private void Clicked()
		{
			OnClicked.Invoke();
		}
	}
	public class AtlyssSimpleSlider : BaseAtlyssLabelElement, IValueElement
	{
		private Slider _slider;

		public Slider Slider
		{
			get
			{
				return _slider;
			}
			set
			{
				if (Object.op_Implicit((Object)(object)_slider))
				{
					((UnityEvent<float>)(object)_slider.onValueChanged).RemoveListener((UnityAction<float>)ValueChanged);
				}
				_slider = value;
				if (Object.op_Implicit((Object)(object)_slider))
				{
					((UnityEvent<float>)(object)_slider.onValueChanged).AddListener((UnityAction<float>)ValueChanged);
				}
			}
		}

		public UnityEvent<float> OnValueChanged { get; } = new UnityEvent<float>();


		public float AppliedValue { get; private set; }

		public void Initialize()
		{
			base.LabelText = "Slider";
			((UnityEventBase)(object)Slider.onValueChanged).RemoveAndDisableAllListeners();
			((UnityEvent<float>)(object)Slider.onValueChanged).AddListener((UnityAction<float>)ValueChanged);
			Slider.wholeNumbers = false;
			Slider.minValue = 0f;
			Slider.maxValue = 1f;
			Slider.SetValueWithoutNotify(AppliedValue);
		}

		public void Apply()
		{
			AppliedValue = _slider.value;
		}

		public void Revert()
		{
			_slider.value = AppliedValue;
		}

		private void ValueChanged(float newValue)
		{
			OnValueChanged.Invoke(newValue);
		}
	}
	public class AtlyssSpace : BaseAtlyssElement
	{
	}
	public class AtlyssTabButton : BaseAtlyssElement
	{
		public Text Label;

		private Button _resetButton;

		public Button Button
		{
			get
			{
				return _resetButton;
			}
			set
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				if (Object.op_Implicit((Object)(object)_resetButton))
				{
					((UnityEvent)_resetButton.onClick).RemoveListener(new UnityAction(Clicked));
				}
				_resetButton = value;
				if (Object.op_Implicit((Object)(object)_resetButton))
				{
					((UnityEvent)_resetButton.onClick).AddListener(new UnityAction(Clicked));
				}
			}
		}

		public UnityEvent OnClicked { get; } = new UnityEvent();


		public void Initialize()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			Label.text = "Tab";
			((UnityEventBase)Button.onClick).RemoveAllListeners();
			((UnityEvent)Button.onClick).AddListener(new UnityAction(Clicked));
		}

		private void Clicked()
		{
			OnClicked.Invoke();
		}
	}
	public class AtlyssToggle : BaseAtlyssLabelElement, IValueElement
	{
		private Toggle _toggle;

		public Toggle Toggle
		{
			get
			{
				return _toggle;
			}
			set
			{
				if (Object.op_Implicit((Object)(object)_toggle))
				{
					((UnityEvent<bool>)(object)_toggle.onValueChanged).RemoveListener((UnityAction<bool>)ValueChanged);
				}
				_toggle = value;
				if (Object.op_Implicit((Object)(object)_toggle))
				{
					((UnityEvent<bool>)(object)_toggle.onValueChanged).AddListener((UnityAction<bool>)ValueChanged);
				}
			}
		}

		public UnityEvent<bool> OnValueChanged { get; } = new UnityEvent<bool>();


		public bool AppliedValue { get; private set; }

		public void Initialize()
		{
			base.LabelText = "Toggle";
			((UnityEventBase)(object)Toggle.onValueChanged).RemoveAndDisableAllListeners();
			((UnityEvent<bool>)(object)Toggle.onValueChanged).AddListener((UnityAction<bool>)ValueChanged);
			Toggle.SetIsOnWithoutNotify(AppliedValue);
		}

		public void Apply()
		{
			AppliedValue = _toggle.isOn;
		}

		public void Revert()
		{
			_toggle.isOn = AppliedValue;
		}

		private void ValueChanged(bool newValue)
		{
			OnValueChanged.Invoke(newValue);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}