Decompiled source of ModMenu v1.0.1

Mods/ModMenu.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using HarmonyLib;
using Il2Cpp;
using Il2CppInterop.Common;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using SpellBrigade.ModMenu;
using SpellBrigade.Shared;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Localization;
using UnityEngine.Localization.Components;
using UnityEngine.Localization.Settings;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(ModMenuMod), "Mod Menu", "1.0.1", "Relsev", null)]
[assembly: MelonGame("BoltBlasterGames", "TheSpellBrigade")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ModMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+9688215a22f9c16196fc6e370f4059e77fce9e0c")]
[assembly: AssemblyProduct("ModMenu")]
[assembly: AssemblyTitle("ModMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 SpellBrigade.Shared
{
	internal static class Hooks
	{
		public static bool Patch(Harmony harmony, Instance log, Type target, string method, Type patchClass, string prefix = null, string postfix = null)
		{
			return Patch(harmony, log, AccessTools.Method(target, method, (Type[])null, (Type[])null), patchClass, prefix, postfix, target.Name + "." + method);
		}

		public static bool Patch(Harmony harmony, Instance log, MethodBase original, Type patchClass, string prefix = null, string postfix = null, string name = null)
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if (name == null)
			{
				name = ((original != null) ? (original.DeclaringType?.Name + "." + original.Name) : ((prefix ?? postfix) + " target"));
			}
			try
			{
				if (original == null)
				{
					throw new MissingMethodException(name + " not found");
				}
				List<string> list = SharedCodeGuard.FindMethodsSharingCode(original);
				if (list.Count > 0)
				{
					log.Warning($"skipped {name}: its native code is shared with {list.Count} other method(s), patching would break them (e.g. {string.Join(", ", list.GetRange(0, Math.Min(5, list.Count)))})");
					return false;
				}
				harmony.Patch(original, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(patchClass, prefix, (Type[])null, (Type[])null)), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(patchClass, postfix, (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				return true;
			}
			catch (Exception ex)
			{
				log.Error($"failed to hook {name} — this part is disabled. {ex.GetType().Name}: {ex.Message}");
				return false;
			}
		}
	}
	internal sealed class Localizer
	{
		private readonly string[] _keys;

		private readonly Dictionary<string, string[]> _table;

		private readonly Func<Instance> _log;

		private readonly Dictionary<string, bool> _fontSupport = new Dictionary<string, bool>();

		private readonly List<(TMP_Text text, Func<string> value)> _bound = new List<(TMP_Text, Func<string>)>();

		private readonly List<Action> _listeners = new List<Action>();

		private string[] _current;

		private string _code;

		private TMP_Text _fontSample;

		private bool _subscribed;

		public Localizer(string[] keys, Dictionary<string, string[]> table, Func<Instance> log)
		{
			_keys = keys;
			_table = table;
			_log = log;
		}

		public string Get(string key)
		{
			if (_current == null || _code != LocaleCode())
			{
				_current = Resolve(_fontSample);
			}
			int num = Array.IndexOf(_keys, key);
			if (num < 0 || num >= _current.Length)
			{
				return key;
			}
			return _current[num];
		}

		public void Bind(TMP_Text text, Func<string> value, TMP_Text fontSample = null)
		{
			if (!((Object)(object)text == (Object)null))
			{
				EnsureSubscribed();
				if (_current == null)
				{
					_current = Resolve(fontSample ?? text);
				}
				text.text = value();
				_bound.Add((text, value));
			}
		}

		public void Bind(TMP_Text text, string key, TMP_Text fontSample = null)
		{
			Bind(text, () => Get(key), fontSample);
		}

		public void OnLanguageChanged(Action listener)
		{
			EnsureSubscribed();
			_listeners.Add(listener);
		}

		public void UseFont(TMP_Text sample)
		{
			_fontSample = sample;
			_current = null;
			EnsureSubscribed();
		}

		private void EnsureSubscribed()
		{
			if (_subscribed)
			{
				return;
			}
			_subscribed = true;
			try
			{
				LocalizationSettings.SelectedLocaleChanged += Action<Locale>.op_Implicit((Action<Locale>)delegate
				{
					Refresh();
				});
			}
			catch (Exception ex)
			{
				Instance obj = _log();
				if (obj != null)
				{
					obj.Warning("[lang] can't follow language changes: " + ex.Message);
				}
			}
		}

		private void Refresh()
		{
			_bound.RemoveAll(((TMP_Text text, Func<string> value) b) => (Object)(object)b.text == (Object)null);
			_current = Resolve((_bound.Count > 0) ? _bound[0].text : _fontSample);
			foreach (var (val, func) in _bound)
			{
				val.text = func();
			}
			foreach (Action listener in _listeners)
			{
				try
				{
					listener();
				}
				catch (Exception ex)
				{
					Instance obj = _log();
					if (obj != null)
					{
						obj.Warning("[lang] " + ex.Message);
					}
				}
			}
		}

		private static string LocaleCode()
		{
			try
			{
				Locale selectedLocale = LocalizationSettings.SelectedLocale;
				return ((selectedLocale != null) ? selectedLocale.Identifier.Code : null) ?? "en";
			}
			catch
			{
				return "en";
			}
		}

		private string[] Resolve(TMP_Text fontSample)
		{
			string text = (_code = LocaleCode());
			string text2 = TableKey(text);
			if (text2 != "en" && (Object)(object)fontSample != (Object)null && !FontHasAll(fontSample, text2))
			{
				Instance obj = _log();
				if (obj != null)
				{
					obj.Warning("[lang] font lacks glyphs for '" + text + "', using English");
				}
				text2 = "en";
			}
			return _table[text2];
		}

		private string TableKey(string code)
		{
			code = code.ToLowerInvariant().Replace('_', '-');
			string text = (code.StartsWith("zh") ? ((code.Contains("hant") || code.Contains("tw") || code.Contains("hk")) ? "zh-hant" : "zh-hans") : (code.StartsWith("pt") ? (code.Contains("br") ? "pt-br" : "pt") : ((!code.StartsWith("es")) ? code.Split('-')[0] : ((code == "es" || code.Contains("es-es")) ? "es" : "es-mx"))));
			if (_table.ContainsKey(text))
			{
				return text;
			}
			string text2 = text.Split('-')[0];
			if (!_table.ContainsKey(text2))
			{
				return "en";
			}
			return text2;
		}

		private bool FontHasAll(TMP_Text sample, string key)
		{
			if (_fontSupport.TryGetValue(key, out var value))
			{
				return value;
			}
			value = true;
			try
			{
				TMP_FontAsset font = sample.font;
				if ((Object)(object)font != (Object)null)
				{
					string[] array = _table[key];
					foreach (string text in array)
					{
						foreach (char c in text)
						{
							if (c > '\u007f' && !char.IsWhiteSpace(c) && !font.HasCharacter(c, true, true))
							{
								value = false;
								break;
							}
						}
						if (!value)
						{
							break;
						}
					}
				}
			}
			catch
			{
				value = true;
			}
			_fontSupport[key] = value;
			return value;
		}
	}
	internal static class MatchmakingGuard
	{
		private const string BlockersKey = "SpellBrigade.Matchmaking.Blockers";

		private const string OwnerKey = "SpellBrigade.Matchmaking.Owner";

		private const string PanelName = "SpellBrigade_MatchmakingLock";

		private static readonly Color Gold = new Color(0.96f, 0.78f, 0.35f);

		private static bool _owner;

		private static bool _wasBlocked;

		private static Instance _log;

		private static MatchmakingPreferencesModal _modal;

		private static TMP_Text _title;

		private static TMP_Text _body;

		private static float _pulse;

		private static float _nextCheck;

		private const string Title = "title";

		private const string Intro = "intro";

		private const string Footer = "footer";

		private static readonly Localizer Text = new Localizer(new string[3] { "title", "intro", "footer" }, new Dictionary<string, string[]>
		{
			["en"] = new string[3] { "Matchmaking is locked by mods", "These mods change the game for everyone in the lobby, so players without them can't be matched with you:", "Play with friends: invite them or share the lobby code. Matchmaking comes back as soon as nothing above applies." },
			["ru"] = new string[3] { "Подбор игроков заблокирован модами", "Эти моды меняют игру для всех в лобби, поэтому игроков без них к вам не подберёт:", "Играйте с друзьями: пригласите их или дайте код лобби. Подбор вернётся сам, как только ничего из списка не будет мешать." },
			["uk"] = new string[3] { "Підбір гравців заблоковано модами", "Ці моди змінюють гру для всіх у лобі, тому гравців без них до вас не підбере:", "Грайте з друзями: запросіть їх або дайте код лобі. Підбір повернеться сам, щойно нічого зі списку не заважатиме." },
			["de"] = new string[3] { "Matchmaking ist durch Mods gesperrt", "Diese Mods verändern das Spiel für alle in der Lobby, daher kannst du nicht mit Spielern ohne sie zusammengebracht werden:", "Spiele mit Freunden: Lade sie ein oder teile den Lobby-Code. Matchmaking kommt zurück, sobald nichts davon mehr zutrifft." },
			["fr"] = new string[3] { "Matchmaking bloqué par des mods", "Ces mods modifient la partie pour tout le salon, vous ne pouvez donc pas être associé à des joueurs qui ne les ont pas :", "Jouez avec des amis : invitez-les ou partagez le code du salon. Le matchmaking revient dès que plus rien ci-dessus ne s'applique." },
			["it"] = new string[3] { "Matchmaking bloccato dalle mod", "Queste mod cambiano la partita per tutta la lobby, quindi non puoi essere abbinato a chi non le ha:", "Gioca con gli amici: invitali o condividi il codice della lobby. Il matchmaking torna appena nulla di tutto ciò si applica." },
			["nl"] = new string[3] { "Matchmaking geblokkeerd door mods", "Deze mods veranderen het spel voor iedereen in de lobby, dus je wordt niet gekoppeld aan spelers zonder deze mods:", "Speel met vrienden: nodig ze uit of deel de lobbycode. Matchmaking komt terug zodra niets hiervan meer geldt." },
			["pl"] = new string[3] { "Dobieranie graczy zablokowane przez mody", "Te mody zmieniają grę wszystkim w lobby, więc gracze bez nich nie zostaną do ciebie dobrani:", "Graj ze znajomymi: zaproś ich lub podaj kod lobby. Dobieranie wróci samo, gdy nic z listy nie będzie przeszkadzać." },
			["pt-br"] = new string[3] { "Matchmaking bloqueado por mods", "Estes mods mudam o jogo para todos no lobby, então jogadores sem eles não serão pareados com você:", "Jogue com amigos: convide-os ou compartilhe o código do lobby. O matchmaking volta assim que nada acima se aplicar." },
			["pt"] = new string[3] { "Matchmaking bloqueado por mods", "Estes mods mudam o jogo para todos no lobby, por isso jogadores sem eles não serão emparelhados contigo:", "Joga com amigos: convida-os ou partilha o código do lobby. O matchmaking volta assim que nada acima se aplicar." },
			["es"] = new string[3] { "Emparejamiento bloqueado por mods", "Estos mods cambian la partida para toda la sala, así que no se te emparejará con jugadores que no los tengan:", "Juega con amigos: invítalos o comparte el código de sala. El emparejamiento vuelve en cuanto nada de lo anterior aplique." },
			["es-mx"] = new string[3] { "Emparejamiento bloqueado por mods", "Estos mods cambian la partida para toda la sala, así que no se te emparejará con jugadores que no los tengan:", "Juega con amigos: invítalos o comparte el código de sala. El emparejamiento regresa en cuanto nada de lo anterior aplique." },
			["ja"] = new string[3] { "MODによりマッチングがロックされています", "これらのMODはロビー全員のゲームを変えるため、MODのないプレイヤーとはマッチングしません:", "フレンドと遊びましょう:招待するかロビーコードを共有してください。上記が当てはまらなくなればマッチングは戻ります。" },
			["ko"] = new string[3] { "모드로 인해 매칭이 잠겼습니다", "이 모드들은 로비 전체의 게임을 바꾸므로, 모드가 없는 플레이어와는 매칭되지 않습니다:", "친구와 플레이하세요: 초대하거나 로비 코드를 공유하세요. 위 항목이 모두 해당되지 않으면 매칭이 다시 열립니다." },
			["zh-hans"] = new string[3] { "匹配已被模组锁定", "这些模组会改变大厅里所有人的游戏,因此不会为你匹配没有这些模组的玩家:", "和好友一起玩:邀请他们或分享大厅代码。只要上面各项都不再适用,匹配就会恢复。" },
			["zh-hant"] = new string[3] { "配對已被模組鎖定", "這些模組會改變大廳裡所有人的遊戲,因此不會為你配對沒有這些模組的玩家:", "和好友一起玩:邀請他們或分享大廳代碼。只要上面各項都不再適用,配對就會恢復。" },
			["th"] = new string[3] { "การจ\u0e31บค\u0e39\u0e48ถ\u0e39กล\u0e47อกโดยม\u0e47อด", "ม\u0e47อดเหล\u0e48าน\u0e35\u0e49เปล\u0e35\u0e48ยนเกมของท\u0e38กคนในล\u0e47อบบ\u0e35\u0e49 จ\u0e36งจะไม\u0e48จ\u0e31บค\u0e39\u0e48ค\u0e38ณก\u0e31บผ\u0e39\u0e49เล\u0e48นท\u0e35\u0e48ไม\u0e48ม\u0e35ม\u0e47อด:", "เล\u0e48นก\u0e31บเพ\u0e37\u0e48อน: เช\u0e34ญเพ\u0e37\u0e48อนหร\u0e37อแชร\u0e4cรห\u0e31สล\u0e47อบบ\u0e35\u0e49 การจ\u0e31บค\u0e39\u0e48จะกล\u0e31บมาเม\u0e37\u0e48อไม\u0e48ม\u0e35ข\u0e49อใดด\u0e49านบนเข\u0e49าเง\u0e37\u0e48อนไข" }
		}, () => _log);

		private static bool _prepareRestore;

		public static bool Blocked => Reasons().Count > 0;

		private static MatchmakingPreferencesManager Prefs => Singleton<MatchmakingPreferencesManager>.Instance;

		public static void Register(Harmony harmony, Instance log, string modName, Func<string> reason)
		{
			AppDomain currentDomain = AppDomain.CurrentDomain;
			List<Func<string>> list = currentDomain.GetData("SpellBrigade.Matchmaking.Blockers") as List<Func<string>>;
			if (list == null)
			{
				currentDomain.SetData("SpellBrigade.Matchmaking.Blockers", list = new List<Func<string>>());
			}
			list.Add(delegate
			{
				string text = reason();
				return (text == null) ? null : ("<b>" + modName + "</b> — " + text);
			});
			object data = currentDomain.GetData("SpellBrigade.Matchmaking.Owner");
			if (!(data is bool) || !(bool)data)
			{
				currentDomain.SetData("SpellBrigade.Matchmaking.Owner", true);
				_owner = true;
				_log = log;
				int num = 0;
				num += Hook(harmony, typeof(RunPreparationManager), "Prepare", "PreparePrefix", "PreparePostfix");
				num += Hook(harmony, typeof(RunPreparationManager), "CanUseMatchmaking", "CanUsePrefix");
				num += Hook(harmony, typeof(MatchmakingToggle), "Toggle", "TogglePrefix");
				num += Hook(harmony, typeof(MatchmakingPreferencesModal), "OnIsMatchmakingEnabledChanged", "EnabledChangedPrefix");
				num += Hook(harmony, typeof(MatchmakingPreferencesModal), "RefreshPanel", null, "RefreshPanelPostfix");
				log.Msg($"matchmaking guard: {num}/5 hooks");
			}
		}

		private static int Hook(Harmony harmony, Type type, string method, string prefix, string postfix = null)
		{
			return Hooks.Patch(harmony, _log, type, method, typeof(MatchmakingGuard), prefix, postfix) ? 1 : 0;
		}

		public static List<string> Reasons()
		{
			List<string> list = new List<string>();
			if (!(AppDomain.CurrentDomain.GetData("SpellBrigade.Matchmaking.Blockers") is List<Func<string>> list2))
			{
				return list;
			}
			foreach (Func<string> item in list2)
			{
				try
				{
					string text = item();
					if (text != null)
					{
						list.Add(text);
					}
				}
				catch
				{
				}
			}
			return list;
		}

		private static void PreparePrefix()
		{
			List<string> list = Reasons();
			MatchmakingPreferencesManager prefs = Prefs;
			if (list.Count != 0 && !((Object)(object)prefs == (Object)null) && prefs.IsMatchmakingEnabled)
			{
				prefs.IsMatchmakingEnabled = false;
				_prepareRestore = true;
				Instance log = _log;
				if (log != null)
				{
					log.Msg("run starts without matchmaking — " + StripTags(string.Join("; ", list)));
				}
			}
		}

		private static void PreparePostfix()
		{
			if (_prepareRestore)
			{
				_prepareRestore = false;
				MatchmakingPreferencesManager prefs = Prefs;
				if ((Object)(object)prefs != (Object)null)
				{
					prefs.IsMatchmakingEnabled = true;
				}
			}
		}

		private static bool CanUsePrefix(ref bool __result)
		{
			if (!Blocked)
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool TogglePrefix(MatchmakingToggle __instance)
		{
			if (!Blocked || !IsMatchmakingToggle(__instance))
			{
				return true;
			}
			_pulse = 1f;
			return false;
		}

		private static bool EnabledChangedPrefix(MatchmakingPreferencesModal __instance, bool isOn)
		{
			if (!isOn || !Blocked)
			{
				return true;
			}
			RefreshPanelPostfix(__instance);
			return false;
		}

		private static bool IsMatchmakingToggle(MatchmakingToggle toggle)
		{
			if ((Object)(object)_modal != (Object)null && (Object)(object)_modal.isMatchmakingEnabledToggle != (Object)null)
			{
				return ((Il2CppObjectBase)_modal.isMatchmakingEnabledToggle).Pointer == ((Il2CppObjectBase)toggle).Pointer;
			}
			return false;
		}

		private static void RefreshPanelPostfix(MatchmakingPreferencesModal __instance)
		{
			try
			{
				_modal = __instance;
				Apply(__instance, Reasons());
			}
			catch (Exception ex)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("matchmaking window: " + ex.Message);
				}
			}
		}

		private static void Apply(MatchmakingPreferencesModal modal, List<string> reasons)
		{
			bool flag = reasons.Count > 0;
			MatchmakingToggle isMatchmakingEnabledToggle = modal.isMatchmakingEnabledToggle;
			if ((Object)(object)isMatchmakingEnabledToggle != (Object)null)
			{
				if (flag)
				{
					isMatchmakingEnabledToggle.isOn = false;
					isMatchmakingEnabledToggle.RefreshUI();
				}
				(((Component)isMatchmakingEnabledToggle).GetComponent<CanvasGroup>() ?? ((Component)isMatchmakingEnabledToggle).gameObject.AddComponent<CanvasGroup>()).alpha = (flag ? 0.4f : 1f);
			}
			if (flag && (Object)(object)modal.matchmakingPreferencesObject != (Object)null)
			{
				modal.matchmakingPreferencesObject.SetActive(false);
			}
			Transform val = ((Component)modal).transform.Find("SpellBrigade_MatchmakingLock");
			if ((Object)(object)val == (Object)null && flag)
			{
				val = BuildPanel(modal);
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			((Component)val).gameObject.SetActive(flag);
			if (!flag)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(Text.Get("intro")).Append('\n');
			foreach (string reason in reasons)
			{
				stringBuilder.Append("\n•  ").Append(reason);
			}
			stringBuilder.Append("\n\n<alpha=#B3>").Append(Text.Get("footer"));
			_title.text = Text.Get("title");
			_body.text = stringBuilder.ToString();
		}

		private static Transform BuildPanel(MatchmakingPreferencesModal modal)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = ((Component)modal).transform.Find("Matchmaking_Description");
			TMP_Text val = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null) ?? ((Component)modal).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			RectTransform val2 = new GameObject("SpellBrigade_MatchmakingLock").AddComponent<RectTransform>();
			((Transform)val2).SetParent(((Component)modal).transform, false);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0f, 1f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			val2.anchoredPosition = new Vector2(250f, -1060f);
			val2.sizeDelta = new Vector2(2250f, 760f);
			float num = (val.enableAutoSizing ? val.fontSizeMax : val.fontSize);
			_title = CloneText(val, (Transform)(object)val2, "Title", num * 1.25f, Gold, (FontStyles)1);
			RectTransform rectTransform = _title.rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.sizeDelta = new Vector2(0f, num * 1.8f);
			rectTransform.anchoredPosition = Vector2.zero;
			_body = CloneText(val, (Transform)(object)val2, "Body", num, Color.white, (FontStyles)0);
			RectTransform rectTransform2 = _body.rectTransform;
			rectTransform2.anchorMin = Vector2.zero;
			rectTransform2.anchorMax = Vector2.one;
			rectTransform2.pivot = new Vector2(0f, 1f);
			rectTransform2.offsetMin = Vector2.zero;
			rectTransform2.offsetMax = new Vector2(0f, (0f - num) * 2f);
			_body.textWrappingMode = (TextWrappingModes)1;
			_body.enableAutoSizing = true;
			_body.fontSizeMin = num * 0.6f;
			_body.fontSizeMax = num;
			return (Transform)(object)val2;
		}

		private static TMP_Text CloneText(TMP_Text template, Transform parent, string name, float size, Color color, FontStyles style)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text component = Object.Instantiate<GameObject>(((Component)template).gameObject, parent).GetComponent<TMP_Text>();
			foreach (LocalizeStringEvent component2 in ((Component)component).GetComponents<LocalizeStringEvent>())
			{
				Object.Destroy((Object)(object)component2);
			}
			foreach (MonoBehaviour component3 in ((Component)component).GetComponents<MonoBehaviour>())
			{
				if ((Object)(object)component3 != (Object)null && (Object)(object)((Il2CppObjectBase)component3).TryCast<TMP_Text>() == (Object)null)
				{
					Object.Destroy((Object)(object)component3);
				}
			}
			((Object)component).name = name;
			component.enableAutoSizing = false;
			component.fontSize = size;
			((Graphic)component).color = color;
			component.fontStyle = style;
			component.alignment = (TextAlignmentOptions)257;
			component.textWrappingMode = (TextWrappingModes)0;
			component.overflowMode = (TextOverflowModes)0;
			((Graphic)component).raycastTarget = false;
			return component;
		}

		private static string StripTags(string s)
		{
			return Regex.Replace(s, "<.*?>", "");
		}

		public static void Tick()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (!_owner)
			{
				return;
			}
			if (_pulse > 0f && (Object)(object)_title != (Object)null)
			{
				_pulse = Mathf.Max(0f, _pulse - Time.unscaledDeltaTime * 2.5f);
				_title.transform.localScale = Vector3.one * (1f + 0.08f * _pulse);
				((Graphic)_title).color = Color.Lerp(Gold, new Color(1f, 0.45f, 0.35f), _pulse);
			}
			if (Time.unscaledTime < _nextCheck)
			{
				return;
			}
			_nextCheck = Time.unscaledTime + 0.25f;
			List<string> list = Reasons();
			bool flag = list.Count > 0;
			if (flag != _wasBlocked)
			{
				_wasBlocked = flag;
				Instance log = _log;
				if (log != null)
				{
					log.Msg(flag ? ("matchmaking locked — " + StripTags(string.Join("; ", list))) : "matchmaking unlocked");
				}
				if ((Object)(object)_modal != (Object)null && ((Component)_modal).gameObject.activeInHierarchy)
				{
					try
					{
						_modal.RefreshPanel();
					}
					catch
					{
					}
				}
			}
			else if (flag && (Object)(object)_modal != (Object)null && ((Component)_modal).gameObject.activeInHierarchy && (Object)(object)_body != (Object)null)
			{
				Apply(_modal, list);
			}
		}
	}
	internal static class SharedCodeGuard
	{
		private static Dictionary<IntPtr, List<IntPtr>> _methodsByCode;

		public static List<string> FindMethodsSharingCode(MethodBase generatedMethod)
		{
			List<string> list = new List<string>();
			if (!(Il2CppInteropUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(generatedMethod)?.GetValue(null) is IntPtr intPtr) || intPtr == IntPtr.Zero)
			{
				return list;
			}
			IntPtr intPtr2 = Marshal.ReadIntPtr(intPtr);
			if (intPtr2 == IntPtr.Zero)
			{
				return list;
			}
			if (_methodsByCode == null)
			{
				_methodsByCode = BuildIndex();
			}
			if (!_methodsByCode.TryGetValue(intPtr2, out var value))
			{
				return list;
			}
			foreach (IntPtr item in value)
			{
				if (item != intPtr)
				{
					list.Add(Describe(item));
				}
			}
			return list;
		}

		private static string Describe(IntPtr method)
		{
			IntPtr intPtr = IL2CPP.il2cpp_method_get_class(method);
			string text = IL2CPP.il2cpp_class_get_namespace_(intPtr);
			return (string.IsNullOrEmpty(text) ? IL2CPP.il2cpp_class_get_name_(intPtr) : (text + "." + IL2CPP.il2cpp_class_get_name_(intPtr))) + "::" + IL2CPP.il2cpp_method_get_name_(method);
		}

		private unsafe static Dictionary<IntPtr, List<IntPtr>> BuildIndex()
		{
			Dictionary<IntPtr, List<IntPtr>> dictionary = new Dictionary<IntPtr, List<IntPtr>>();
			uint num = 0u;
			IntPtr* ptr = IL2CPP.il2cpp_domain_get_assemblies(IL2CPP.il2cpp_domain_get(), ref num);
			for (uint num2 = 0u; num2 < num; num2++)
			{
				IntPtr intPtr = IL2CPP.il2cpp_assembly_get_image(ptr[num2]);
				uint num3 = IL2CPP.il2cpp_image_get_class_count(intPtr);
				for (uint num4 = 0u; num4 < num3; num4++)
				{
					IntPtr intPtr2 = IL2CPP.il2cpp_image_get_class(intPtr, num4);
					if (intPtr2 == IntPtr.Zero)
					{
						continue;
					}
					IntPtr zero = IntPtr.Zero;
					IntPtr intPtr3;
					while ((intPtr3 = IL2CPP.il2cpp_class_get_methods(intPtr2, ref zero)) != IntPtr.Zero)
					{
						IntPtr intPtr4 = Marshal.ReadIntPtr(intPtr3);
						if (!(intPtr4 == IntPtr.Zero))
						{
							if (!dictionary.TryGetValue(intPtr4, out var value))
							{
								value = (dictionary[intPtr4] = new List<IntPtr>(1));
							}
							value.Add(intPtr3);
						}
					}
				}
			}
			return dictionary;
		}
	}
	internal static class WheelSelect
	{
		private sealed class State
		{
			public ScrollRect Blocked;

			public float BlockedSensitivity;

			public Vector2 LastMouse = new Vector2(-1f, -1f);
		}

		private const string FrameKey = "SpellBrigade.WheelSelect.Frame";

		private const string CustomKey = "SpellBrigade.WheelSelect.Custom";

		private static readonly State Own = new State();

		private static List<(GameObject target, Action<int> step)> Custom
		{
			get
			{
				AppDomain currentDomain = AppDomain.CurrentDomain;
				if (currentDomain.GetData("SpellBrigade.WheelSelect.Custom") is List<(GameObject, Action<int>)> result)
				{
					return result;
				}
				List<(GameObject, Action<int>)> list = new List<(GameObject, Action<int>)>();
				currentDomain.SetData("SpellBrigade.WheelSelect.Custom", list);
				return list;
			}
		}

		public static void Register(GameObject target, Action<int> step)
		{
			if ((Object)(object)target != (Object)null && step != null)
			{
				Custom.Add((target, step));
			}
		}

		public static void Tick()
		{
			try
			{
				TickCore();
			}
			catch
			{
			}
		}

		private static void TickCore()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			int frameCount = Time.frameCount;
			AppDomain currentDomain = AppDomain.CurrentDomain;
			if (currentDomain.GetData("SpellBrigade.WheelSelect.Frame") is int num && num == frameCount)
			{
				return;
			}
			currentDomain.SetData("SpellBrigade.WheelSelect.Frame", frameCount);
			object data = currentDomain.GetData("SpellBrigade.Modal");
			if (data is bool && (bool)data)
			{
				return;
			}
			Mouse current = Mouse.current;
			if (current == null)
			{
				return;
			}
			State own = Own;
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
			float y = ((InputControl<Vector2>)(object)current.scroll).ReadValue().y;
			Vector2 val2 = val - own.LastMouse;
			if (!(((Vector2)(ref val2)).sqrMagnitude > 0.25f) && Mathf.Abs(y) < 0.01f)
			{
				return;
			}
			own.LastMouse = val;
			var (val3, action, val4) = Hovered(val);
			BlockScroll(own, ((Object)(object)val4 != (Object)null) ? ScrollRectAbove(val4) : null);
			if (Mathf.Abs(y) < 0.01f || (Object)(object)val4 == (Object)null)
			{
				return;
			}
			int num2 = ((y > 0f) ? 1 : (-1));
			try
			{
				if ((Object)(object)val3 != (Object)null)
				{
					if (num2 > 0)
					{
						val3.SelectNext();
					}
					else
					{
						val3.SelectPrevious();
					}
				}
				else
				{
					action?.Invoke(num2);
				}
			}
			catch
			{
			}
		}

		private static (Selector selector, Action<int> custom, RectTransform rect) Hovered(Vector2 position)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			List<(GameObject target, Action<int> step)> custom = Custom;
			custom.RemoveAll(((GameObject target, Action<int> step) c) => (Object)(object)c.target == (Object)null);
			foreach (var (val, item) in custom)
			{
				if (val.activeInHierarchy && Contains(val.GetComponent<RectTransform>(), position))
				{
					return (selector: null, custom: item, rect: val.GetComponent<RectTransform>());
				}
			}
			foreach (Selector item2 in Object.FindObjectsOfType<Selector>())
			{
				if (!((Object)(object)item2 == (Object)null) && ((Selectable)item2).IsInteractable())
				{
					RectTransform component = ((Component)item2).GetComponent<RectTransform>();
					if (Contains(component, position))
					{
						return (selector: item2, custom: null, rect: component);
					}
				}
			}
			return (selector: null, custom: null, rect: null);
		}

		private static bool Contains(RectTransform rect, Vector2 position)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rect == (Object)null)
			{
				return false;
			}
			Canvas val = null;
			Transform val2 = ((Component)rect).transform;
			while ((Object)(object)val2 != (Object)null)
			{
				CanvasGroup component = ((Component)val2).GetComponent<CanvasGroup>();
				if ((Object)(object)component != (Object)null && (component.alpha < 0.01f || !component.blocksRaycasts))
				{
					return false;
				}
				Canvas component2 = ((Component)val2).GetComponent<Canvas>();
				if ((Object)(object)component2 != (Object)null)
				{
					val = component2;
				}
				val2 = val2.parent;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Camera val3 = (((int)val.renderMode == 0) ? null : val.worldCamera);
			if (!RectTransformUtility.RectangleContainsScreenPoint(rect, position, val3))
			{
				return false;
			}
			Transform parent = ((Transform)rect).parent;
			while ((Object)(object)parent != (Object)null)
			{
				if ((Object)(object)((Component)parent).GetComponent<RectMask2D>() != (Object)null && !RectTransformUtility.RectangleContainsScreenPoint(((Component)parent).GetComponent<RectTransform>(), position, val3))
				{
					return false;
				}
				parent = parent.parent;
			}
			return true;
		}

		private static ScrollRect ScrollRectAbove(RectTransform rect)
		{
			Transform parent = ((Transform)rect).parent;
			while ((Object)(object)parent != (Object)null)
			{
				ScrollRect component = ((Component)parent).GetComponent<ScrollRect>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
				parent = parent.parent;
			}
			return null;
		}

		private static void BlockScroll(State state, ScrollRect scroll)
		{
			if (!((Object)(object)state.Blocked != (Object)null) || !((Object)(object)scroll != (Object)null) || !(((Il2CppObjectBase)state.Blocked).Pointer == ((Il2CppObjectBase)scroll).Pointer))
			{
				if ((Object)(object)state.Blocked != (Object)null)
				{
					state.Blocked.scrollSensitivity = state.BlockedSensitivity;
				}
				state.Blocked = scroll;
				if (!((Object)(object)scroll == (Object)null))
				{
					state.BlockedSensitivity = scroll.scrollSensitivity;
					scroll.scrollSensitivity = 0f;
				}
			}
		}
	}
}
namespace SpellBrigade.ModMenu
{
	public static class Menu
	{
		internal static readonly List<Page> Pages = new List<Page>();

		private static readonly HashSet<string> Claimed = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal static event Action RefreshRequested;

		public static Page AddPage(string id, Func<string> title)
		{
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("page id is required", "id");
			}
			foreach (Page page2 in Pages)
			{
				if (page2.Id == id)
				{
					return page2;
				}
			}
			Page page = new Page(id, title ?? ((Func<string>)(() => id)));
			Pages.Add(page);
			HideCategory(id);
			return page;
		}

		public static Page AddPage(string id, string title)
		{
			return AddPage(id, () => title);
		}

		public static void HideCategory(string categoryIdentifier)
		{
			if (!string.IsNullOrEmpty(categoryIdentifier))
			{
				Claimed.Add(categoryIdentifier);
			}
		}

		public static void Refresh()
		{
			Menu.RefreshRequested?.Invoke();
		}

		internal static bool IsClaimed(string categoryIdentifier)
		{
			return Claimed.Contains(categoryIdentifier);
		}
	}
	public enum ButtonLayout
	{
		Stretch,
		Left,
		Center,
		Right,
		Value
	}
	public readonly struct MenuButton
	{
		internal readonly Func<string> Text;

		internal readonly Action OnClick;

		public MenuButton(Func<string> text, Action onClick)
		{
			Text = text;
			OnClick = onClick;
		}

		public MenuButton(string text, Action onClick)
			: this(() => text, onClick)
		{
		}
	}
	public sealed class Page
	{
		internal Func<string> Title;

		internal readonly List<Item> Items = new List<Item>();

		public string Id { get; }

		internal Page(string id, Func<string> title)
		{
			Id = id;
			Title = title;
		}

		public Page Header(Func<string> text)
		{
			return Add(new HeaderItem
			{
				Label = text
			});
		}

		public Page Header(string text)
		{
			return Header(() => text);
		}

		public Page Toggle(Func<string> label, Func<bool> get, Action<bool> set, bool? @default = null)
		{
			return Add(new OptionItem
			{
				Label = label,
				Read = () => (options: new List<string>
				{
					Strings.Get("on"),
					Strings.Get("off")
				}, current: (!get()) ? 1 : 0),
				Apply = delegate(int i)
				{
					set(i == 0);
				},
				IsDefault = (@default.HasValue ? ((Func<bool>)(() => get() == @default.Value)) : null),
				Reset = (@default.HasValue ? ((Action)delegate
				{
					set(@default.Value);
				}) : null)
			});
		}

		public Page Toggle(string label, Func<bool> get, Action<bool> set, bool? @default = null)
		{
			return Toggle(() => label, get, set, @default);
		}

		public Page Choice(Func<string> label, Func<IList<string>> options, Func<int> get, Action<int> set, int? @default = null)
		{
			return Add(new OptionItem
			{
				Label = label,
				Read = () => (options: new List<string>(options()), current: get()),
				Apply = set,
				IsDefault = (@default.HasValue ? ((Func<bool>)(() => get() == @default.Value)) : null),
				Reset = (@default.HasValue ? ((Action)delegate
				{
					set(@default.Value);
				}) : null)
			});
		}

		public Page Choice(string label, IList<string> options, Func<int> get, Action<int> set, int? @default = null)
		{
			return Choice(() => label, () => options, get, set, @default);
		}

		public Page Number(Func<string> label, float min, float max, float step, Func<float> get, Action<float> set, Func<float, string> format = null, float? @default = null)
		{
			return Numbers(label, Values.Range(min, max, step), get, set, format, @default);
		}

		public Page Number(string label, float min, float max, float step, Func<float> get, Action<float> set, Func<float, string> format = null, float? @default = null)
		{
			return Number(() => label, min, max, step, get, set, format, @default);
		}

		public Page Number(Func<string> label, IEnumerable<float> values, Func<float> get, Action<float> set, Func<float, string> format = null, float? @default = null)
		{
			return Numbers(label, new List<float>(values), get, set, format, @default);
		}

		public Page Number(string label, IEnumerable<float> values, Func<float> get, Action<float> set, Func<float, string> format = null, float? @default = null)
		{
			return Number(() => label, values, get, set, format, @default);
		}

		public Page Note(Func<string> text)
		{
			return Add(new NoteItem
			{
				Label = text
			});
		}

		public Page Note(string text)
		{
			return Note(() => text);
		}

		public Page Button(Func<string> text, Action onClick, ButtonLayout layout = ButtonLayout.Center)
		{
			return Buttons(layout, new MenuButton(text, onClick));
		}

		public Page Button(string text, Action onClick, ButtonLayout layout = ButtonLayout.Center)
		{
			return Button(() => text, onClick, layout);
		}

		public Page Buttons(params MenuButton[] buttons)
		{
			return Buttons(ButtonLayout.Stretch, buttons);
		}

		public Page Buttons(ButtonLayout layout, params MenuButton[] buttons)
		{
			if (buttons != null && buttons.Length != 0)
			{
				return Add(new ButtonItem
				{
					Layout = layout,
					Buttons = new List<MenuButton>(buttons)
				});
			}
			return this;
		}

		public Page Action(Func<string> label, Func<string> button, Action onClick)
		{
			return Add(new ButtonItem
			{
				Label = label,
				Layout = ButtonLayout.Value,
				Buttons = new List<MenuButton>
				{
					new MenuButton(button, onClick)
				}
			});
		}

		public Page Action(string label, string button, Action onClick)
		{
			return Action(() => label, () => button, onClick);
		}

		public Page Custom(float height, Func<RectTransform, Selectable> build)
		{
			return Add(new CustomItem
			{
				Height = height,
				Build = build
			});
		}

		public Page Entry(MelonPreferences_Entry entry, Func<string> label = null)
		{
			if (entry == null)
			{
				return this;
			}
			MelonPreferences_Category category = entry.Category;
			Menu.HideCategory((category != null) ? category.Identifier : null);
			return AddEntry(entry, label);
		}

		public Page Category(MelonPreferences_Category category)
		{
			if (category == null)
			{
				return this;
			}
			Menu.HideCategory(category.Identifier);
			return AddCategory(category);
		}

		internal Page AddCategory(MelonPreferences_Category category)
		{
			foreach (MelonPreferences_Entry entry in category.Entries)
			{
				if (entry != null && !entry.IsHidden)
				{
					AddEntry(entry, null);
				}
			}
			return this;
		}

		private Page AddEntry(MelonPreferences_Entry entry, Func<string> label)
		{
			if (label == null)
			{
				label = () => (!string.IsNullOrEmpty(entry.DisplayName)) ? entry.DisplayName : entry.Identifier;
			}
			Type type = entry.GetReflectedType();
			Page result;
			if (type == typeof(bool))
			{
				result = Toggle(label, () => (bool)entry.BoxedValue, delegate(bool v)
				{
					Store(v);
				});
			}
			else if (type.IsEnum)
			{
				string[] names = Enum.GetNames(type);
				result = Choice(label, () => names, () => Array.IndexOf<string>(names, entry.BoxedValue.ToString()), delegate(int i)
				{
					Store(Enum.Parse(type, names[i]));
				});
			}
			else
			{
				if (!(type == typeof(int)) && !(type == typeof(long)) && !(type == typeof(float)) && !(type == typeof(double)))
				{
					return this;
				}
				bool whole = type == typeof(int) || type == typeof(long);
				(float? min, float? max) tuple = Values.RangeOf(entry.Validator);
				float? item = tuple.min;
				float? item2 = tuple.max;
				List<float> candidates = Values.Candidates(item, item2, whole);
				result = Numbers(label, candidates, () => Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture), delegate(float v)
				{
					Store(Convert.ChangeType(whole ? Math.Round(v) : ((double)v), type, CultureInfo.InvariantCulture));
				}, null, null);
			}
			List<Item> items = Items;
			OptionItem obj = (OptionItem)items[items.Count - 1];
			obj.IsDefault = () => entry.GetValueAsString() == entry.GetDefaultValueAsString();
			obj.Reset = delegate
			{
				entry.ResetToDefault();
				MelonPreferences_Category category = entry.Category;
				if (category != null)
				{
					category.SaveToFile(false);
				}
			};
			return result;
			void Store(object value)
			{
				if (!object.Equals(entry.BoxedValue, value))
				{
					entry.BoxedValue = value;
					MelonPreferences_Category category = entry.Category;
					if (category != null)
					{
						category.SaveToFile(false);
					}
				}
			}
		}

		private Page Numbers(Func<string> label, IReadOnlyList<float> candidates, Func<float> get, Action<float> set, Func<float, string> format, float? @default)
		{
			if (format == null)
			{
				format = (float v) => v.ToString("0.##", CultureInfo.InvariantCulture);
			}
			List<float> shown = new List<float>();
			return Add(new OptionItem
			{
				Label = label,
				Read = delegate
				{
					float item = get();
					shown.Clear();
					shown.AddRange(candidates);
					if (!shown.Contains(item))
					{
						shown.Add(item);
						shown.Sort();
					}
					return (options: shown.ConvertAll((float v) => format(v)), current: shown.IndexOf(item));
				},
				Apply = delegate(int i)
				{
					if (i >= 0 && i < shown.Count)
					{
						set(shown[i]);
					}
				},
				IsDefault = (@default.HasValue ? ((Func<bool>)(() => Math.Abs(get() - @default.Value) < 0.0001f)) : null),
				Reset = (@default.HasValue ? ((Action)delegate
				{
					set(@default.Value);
				}) : null)
			});
		}

		private Page Add(Item item)
		{
			Items.Add(item);
			return this;
		}
	}
	internal abstract class Item
	{
		public Func<string> Label;
	}
	internal sealed class HeaderItem : Item
	{
		public bool IsPageTitle;
	}
	internal sealed class NoteItem : Item
	{
	}
	internal sealed class ButtonItem : Item
	{
		public ButtonLayout Layout;

		public List<MenuButton> Buttons;
	}
	internal sealed class CustomItem : Item
	{
		public float Height;

		public Func<RectTransform, Selectable> Build;
	}
	internal sealed class OptionItem : Item
	{
		public Func<(List<string> options, int current)> Read;

		public Action<int> Apply;

		public Func<bool> IsDefault;

		public Action Reset;
	}
	internal static class AutoPages
	{
		public static List<Page> Build()
		{
			List<Page> list = new List<Page>();
			foreach (MelonPreferences_Category category in MelonPreferences.Categories)
			{
				if (category != null && !category.IsHidden && !Menu.IsClaimed(category.Identifier))
				{
					MelonPreferences_Category c = category;
					Page page = new Page("auto:" + c.Identifier, () => (!string.IsNullOrEmpty(c.DisplayName)) ? c.DisplayName : c.Identifier);
					page.AddCategory(c);
					if (page.Items.Count > 0)
					{
						list.Add(page);
					}
				}
			}
			list.Sort((Page a, Page b) => string.Compare(a.Title(), b.Title(), StringComparison.CurrentCultureIgnoreCase));
			return list;
		}
	}
	internal static class Icons
	{
		private static readonly Dictionary<string, Sprite> Cache = new Dictionary<string, Sprite>();

		public static Sprite Search => Get("search.png");

		public static Sprite Reset => Get("reset.png");

		public static Sprite Chevron => Get("chevron.png");

		private static Sprite Get(string file)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (Cache.TryGetValue(file, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			using Stream stream = typeof(Icons).Assembly.GetManifestResourceStream(file);
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61
			};
			ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array));
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)val2).hideFlags = (HideFlags)61;
			return Cache[file] = val2;
		}
	}
	internal static class KeyboardCapture
	{
		private static readonly string[] PointerActions = new string[7] { "Point", "Click", "RightClick", "MiddleClick", "ScrollWheel", "TrackedDevicePosition", "TrackedDeviceOrientation" };

		private static readonly List<InputAction> Disabled = new List<InputAction>();

		public static bool Active { get; private set; }

		public static void Begin()
		{
			if (Active)
			{
				return;
			}
			Active = true;
			AppDomain.CurrentDomain.SetData("SpellBrigade.Typing", true);
			foreach (InputActionAsset item in Resources.FindObjectsOfTypeAll<InputActionAsset>())
			{
				InputActionMap val = (((Object)(object)item != (Object)null) ? item.FindActionMap("UI", false) : null);
				if (val == null || !val.enabled)
				{
					continue;
				}
				ReadOnlyArray<InputAction> actions = val.actions;
				for (int i = 0; i < actions.Count; i++)
				{
					InputAction val2 = actions[i];
					if (val2 != null && val2.enabled && Array.IndexOf(PointerActions, val2.name) < 0)
					{
						val2.Disable();
						Disabled.Add(val2);
					}
				}
			}
		}

		public static void End()
		{
			if (!Active)
			{
				return;
			}
			Active = false;
			AppDomain.CurrentDomain.SetData("SpellBrigade.Typing", false);
			foreach (InputAction item in Disabled)
			{
				try
				{
					if (item != null)
					{
						item.Enable();
					}
				}
				catch
				{
				}
			}
			Disabled.Clear();
		}
	}
	internal static class MenuTab
	{
		private sealed class Row
		{
			public Item Item;

			public GameObject Go;

			public TMP_Text Label;

			public Selector Selector;

			public List<string> Options = new List<string>();

			public readonly List<Selectable> Focus = new List<Selectable>();

			public string Raw = "";

			public GameObject Reset;

			public readonly List<(TMP_Text text, LayoutElement element, MenuButton spec)> Buttons = new List<(TMP_Text, LayoutElement, MenuButton)>();
		}

		private sealed class Section
		{
			public string Id;

			public Row Title;

			public RectTransform Spacer;

			public RectTransform Chevron;

			public GameObject ResetAll;

			public bool Expanded;

			public readonly List<Row> Rows = new List<Row>();
		}

		private sealed class Screen
		{
			public GameObject Panel;

			public NavigateablePanel Navigateable;

			public Button Tab;

			public ScrollRect Scroll;

			public readonly List<Row> Rows = new List<Row>();

			public readonly List<Section> Sections = new List<Section>();

			public GameObject Empty;

			public TMP_InputField Search;

			public Image SearchLine;

			public GameObject Clear;

			public string Query = "";

			public readonly Dictionary<IntPtr, RectTransform> RowOf = new Dictionary<IntPtr, RectTransform>();

			public readonly Dictionary<IntPtr, Row> RowByFocus = new Dictionary<IntPtr, Row>();

			public Selectable First;

			public bool WasActive;
		}

		private sealed class Templates
		{
			public Transform SelectorRow;

			public GameObject Button;

			public Sprite Banner;

			public Sprite Arrow;

			public float RowWidth;

			public float ValueWidth;

			public float LabelSize;
		}

		private const string ButtonName = "ModMenu_Button";

		private const string PanelName = "ModMenu_Panel";

		private const float SectionGap = 24f;

		private const float NoteHeight = 110f;

		private const float ScrollbarX = 40f;

		private const float ScrollbarWidth = 6f;

		private const float RowGap = 24f;

		private const float OptionRowHeight = 126f;

		private const float HeaderHeight = 110f;

		private const float SubHeaderHeight = 90f;

		private const float TopArea = 140f;

		private const float SearchX = 100f;

		private const float SearchHeight = 80f;

		private const float ArrowReach = 150f;

		private const float IconColumn = 210f;

		private const float IconSize = 56f;

		private const float LabelScale = 0.9f;

		private const float LabelHeight = 130f;

		private const float ButtonHeight = 110f;

		private const float ButtonRowHeight = 126f;

		private const float ButtonGap = 30f;

		private const float ButtonPadding = 150f;

		private const float MinButtonWidth = 320f;

		private const float SideSlack = 400f;

		private static readonly Color Gold = new Color(0.96f, 0.78f, 0.35f);

		private static readonly Color NoteColor = new Color(1f, 1f, 1f, 0.55f);

		private static readonly Color Dim = new Color(1f, 1f, 1f, 0.55f);

		private static readonly List<Screen> Screens = new List<Screen>();

		private static bool _subscribed;

		private static bool _refreshing;

		private static bool _wasTyping;

		private static IntPtr _lastSelected;

		private static HashSet<string> _expanded;

		private static HashSet<string> Expanded
		{
			get
			{
				if (_expanded != null)
				{
					return _expanded;
				}
				_expanded = new HashSet<string>();
				string[] array = (ModMenuMod.ExpandedEntry?.Value ?? "").Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
				foreach (string item in array)
				{
					_expanded.Add(item);
				}
				return _expanded;
			}
		}

		public static void InjectPrefix(SettingsPanel __instance)
		{
			try
			{
				Inject(__instance);
			}
			catch (Exception value)
			{
				ModMenuMod.Log.Error($"can't build the Mods tab: {value}");
			}
		}

		private static void Inject(SettingsPanel settings)
		{
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0766: Unknown result type (might be due to invalid IL or missing references)
			//IL_076b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0773: Unknown result type (might be due to invalid IL or missing references)
			//IL_0780: Expected O, but got Unknown
			List<SubPanel> subPanels = settings.subPanels;
			if (subPanels == null || subPanels.Count == 0)
			{
				return;
			}
			for (int i = 0; i < subPanels.Count; i++)
			{
				if ((Object)(object)subPanels[i].Panel != (Object)null && ((Object)subPanels[i].Panel).name == "ModMenu_Panel")
				{
					return;
				}
			}
			List<Page> list = new List<Page>(Menu.Pages);
			list.AddRange(AutoPages.Build());
			list.RemoveAll((Page p) => p.Items.Count == 0);
			if (list.Count == 0)
			{
				return;
			}
			list.Sort((Page a, Page b) => string.Compare(Safe(a.Title, a.Id), Safe(b.Title, b.Id), StringComparison.CurrentCultureIgnoreCase));
			SubPanel val = null;
			SubPanel val2 = null;
			int num = subPanels.Count;
			for (int num2 = 0; num2 < subPanels.Count; num2++)
			{
				SubPanel val3 = subPanels[num2];
				if (!((Object)(object)val3.Button == (Object)null) && !((Object)(object)val3.Panel == (Object)null))
				{
					if (((Object)val3.Panel).name.StartsWith("General"))
					{
						val = val3;
					}
					if (((Object)val3.Button).name.StartsWith("Controls"))
					{
						val2 = val3;
					}
					if (((Object)val3.Button).name.StartsWith("Credits"))
					{
						num = num2;
					}
				}
			}
			if (val == null)
			{
				val = subPanels[0];
			}
			if (val2 == null)
			{
				val2 = subPanels[0];
			}
			if (!_subscribed)
			{
				_subscribed = true;
				Strings.OnLanguageChanged(RefreshAll);
				Menu.RefreshRequested += RefreshAll;
			}
			GameObject val4 = Object.Instantiate<GameObject>(((Component)val2.Button).gameObject, ((Component)val2.Button).transform.parent);
			((Object)val4).name = "ModMenu_Button";
			if (num < subPanels.Count)
			{
				val4.transform.SetSiblingIndex(((Component)subPanels[num].Button).transform.GetSiblingIndex());
			}
			TMP_Text componentInChildren = val4.GetComponentInChildren<TMP_Text>(true);
			StripLocalization(componentInChildren);
			Strings.Bind(componentInChildren, "tab");
			MuteSerializedClicks(val4.GetComponent<Button>());
			SelectableButton component = val4.GetComponent<SelectableButton>();
			GameObject val5 = Object.Instantiate<GameObject>(((Component)val.Panel).gameObject, ((Component)val.Panel).transform.parent);
			((Object)val5).name = "ModMenu_Panel";
			val5.SetActive(false);
			NavigateablePanel component2 = val5.GetComponent<NavigateablePanel>();
			Screen screen = new Screen
			{
				Panel = val5,
				Navigateable = component2,
				Tab = val4.GetComponent<Button>()
			};
			VerticalLayoutGroup componentInChildren2 = val5.GetComponentInChildren<VerticalLayoutGroup>(true);
			RectTransform val6 = ((componentInChildren2 != null) ? ((Component)componentInChildren2).GetComponent<RectTransform>() : null) ?? throw new InvalidOperationException("row container not found");
			Templates templates = new Templates();
			Transform val7 = null;
			for (int num3 = 0; num3 < ((Transform)val6).childCount; num3++)
			{
				Transform child = ((Transform)val6).GetChild(num3);
				if (((Object)child).name.StartsWith("DamageNumbers"))
				{
					templates.SelectorRow = child;
				}
				if ((Object)(object)val7 == (Object)null && (Object)(object)((Component)child).GetComponentInChildren<ClickableButton>(true) != (Object)null)
				{
					val7 = child;
				}
			}
			for (int num4 = 0; num4 < ((Transform)val6).childCount; num4++)
			{
				if (!((Object)(object)templates.SelectorRow == (Object)null))
				{
					break;
				}
				if ((Object)(object)((Component)((Transform)val6).GetChild(num4)).GetComponentInChildren<Selector>(true) != (Object)null)
				{
					templates.SelectorRow = ((Transform)val6).GetChild(num4);
				}
			}
			if ((Object)(object)templates.SelectorRow == (Object)null)
			{
				throw new InvalidOperationException("selector row template not found");
			}
			templates.SelectorRow.SetParent((Transform)null, false);
			if (val7 != null)
			{
				val7.SetParent((Transform)null, false);
			}
			for (int num5 = ((Transform)val6).childCount - 1; num5 >= 0; num5--)
			{
				Object.DestroyImmediate((Object)(object)((Component)((Transform)val6).GetChild(num5)).gameObject);
			}
			StripGameLogic(((Component)templates.SelectorRow).gameObject);
			templates.RowWidth = ((Component)templates.SelectorRow).GetComponent<RectTransform>().sizeDelta.x;
			Selector componentInChildren3 = ((Component)templates.SelectorRow).GetComponentInChildren<Selector>(true);
			templates.ValueWidth = ((Component)componentInChildren3).GetComponent<RectTransform>().sizeDelta.x;
			templates.Arrow = (((Object)(object)componentInChildren3.nextButton != (Object)null && (Object)(object)((Selectable)componentInChildren3.nextButton).image != (Object)null) ? ((Selectable)componentInChildren3.nextButton).image.sprite : null);
			Transform obj = ((Component)val2.Button).transform.Find("Button_Image");
			object banner;
			if (obj == null)
			{
				banner = null;
			}
			else
			{
				Image component3 = ((Component)obj).GetComponent<Image>();
				banner = ((component3 != null) ? component3.sprite : null);
			}
			templates.Banner = (Sprite)banner;
			VerticalLayoutGroup component4 = ((Component)val6).GetComponent<VerticalLayoutGroup>();
			if ((Object)(object)component4 != (Object)null)
			{
				((HorizontalOrVerticalLayoutGroup)component4).spacing = 24f;
			}
			TMP_Text val8 = FirstLabel(((Component)templates.SelectorRow).gameObject);
			templates.LabelSize = (val8.enableAutoSizing ? val8.fontSizeMax : val8.fontSize) * 0.9f;
			if ((Object)(object)val7 != (Object)null)
			{
				templates.Button = ((Component)((Component)val7).GetComponentInChildren<ClickableButton>(true)).gameObject;
				templates.Button.transform.SetParent((Transform)null, false);
				Object.DestroyImmediate((Object)(object)((Component)val7).gameObject);
			}
			RectTransform component5 = val5.GetComponent<RectTransform>();
			BuildScrollView(screen, component5, val6);
			BuildSearch(screen, component5, templates);
			for (int num6 = 0; num6 < list.Count; num6++)
			{
				Page page = list[num6];
				Section section = new Section
				{
					Id = page.Id,
					Expanded = Expanded.Contains(page.Id)
				};
				if (num6 > 0)
				{
					section.Spacer = Spacer(val6, templates.RowWidth, 24f);
				}
				section.Title = AddRow(screen, new HeaderItem
				{
					Label = page.Title,
					IsPageTitle = true
				}, val6, templates, page.Id);
				if (section.Title == null)
				{
					continue;
				}
				MakeCollapsible(screen, section, templates);
				foreach (Item item in page.Items)
				{
					Row row = AddRow(screen, item, val6, templates, page.Id);
					if (row != null)
					{
						section.Rows.Add(row);
					}
				}
				section.ResetAll = SectionReset(section, templates);
				screen.Sections.Add(section);
			}
			screen.Empty = TextRow(templates, val6, out var label);
			((Graphic)label).color = NoteColor;
			Strings.Bind(label, "none");
			screen.Empty.SetActive(false);
			Object.DestroyImmediate((Object)(object)((Component)templates.SelectorRow).gameObject);
			if ((Object)(object)templates.Button != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)templates.Button);
			}
			List<Selectable> list2 = new List<Selectable>();
			foreach (Row row2 in screen.Rows)
			{
				if ((Object)(object)row2.Selector != (Object)null)
				{
					list2.Add((Selectable)(object)row2.Selector);
				}
			}
			RegisterInputReceivers(settings, ((Component)val.Panel).GetComponentInChildren<Selector>(true), list2);
			subPanels.Insert(num, new SubPanel
			{
				Button = component,
				Panel = (Panel)(object)component2
			});
			Screens.Add(screen);
			Refresh(screen);
			Filter(screen);
		}

		private static void MakeCollapsible(Screen screen, Section section, Templates t)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			Row title = section.Title;
			Image obj = title.Go.GetComponent<Image>() ?? title.Go.AddComponent<Image>();
			((Graphic)obj).color = new Color(0f, 0f, 0f, 0f);
			((Graphic)obj).raycastTarget = true;
			Image val = ((Component)NewRect("Highlight", title.Go.transform)).gameObject.AddComponent<Image>();
			val.sprite = t.Banner;
			((Graphic)val).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0.5f);
			rectTransform.anchorMax = new Vector2(1f, 0.5f);
			rectTransform.pivot = new Vector2(0f, 0.5f);
			rectTransform.offsetMin = new Vector2(-40f, -55f);
			rectTransform.offsetMax = new Vector2(((Object)(object)t.Banner != (Object)null) ? ((0f - t.ValueWidth) * 0.3f) : 0f, 55f);
			((Transform)rectTransform).SetAsFirstSibling();
			Button val2 = title.Go.AddComponent<Button>();
			((Selectable)val2).targetGraphic = (Graphic)(object)val;
			ColorBlock colors = ((Selectable)val2).colors;
			Color val3 = (((Object)(object)t.Banner != (Object)null) ? Color.white : Gold);
			float num = (((Object)(object)t.Banner != (Object)null) ? 1f : 0.15f);
			((ColorBlock)(ref colors)).normalColor = new Color(val3.r, val3.g, val3.b, 0f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(val3.r, val3.g, val3.b, 0.75f * num);
			((ColorBlock)(ref colors)).selectedColor = new Color(val3.r, val3.g, val3.b, 1f * num);
			((ColorBlock)(ref colors)).pressedColor = new Color(val3.r, val3.g, val3.b, 1f * num);
			((ColorBlock)(ref colors)).fadeDuration = 0.1f;
			((Selectable)val2).colors = colors;
			string id = section.Id;
			((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Toggle(id);
			}));
			Image obj2 = ((Component)NewRect("Arrow", title.Go.transform)).gameObject.AddComponent<Image>();
			obj2.sprite = t.Arrow ?? Icons.Chevron;
			obj2.preserveAspect = true;
			((Graphic)obj2).color = new Color(1f, 1f, 1f, 0.85f);
			((Graphic)obj2).raycastTarget = false;
			RectTransform rectTransform2 = ((Graphic)obj2).rectTransform;
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(0f, 0.5f);
			rectTransform2.anchorMax = val4;
			rectTransform2.anchorMin = val4;
			rectTransform2.pivot = new Vector2(0.5f, 0.5f);
			rectTransform2.sizeDelta = new Vector2(52f, 52f);
			rectTransform2.anchoredPosition = new Vector2(26f, 0f);
			section.Chevron = rectTransform2;
			title.Label.rectTransform.offsetMin = new Vector2(72f, title.Label.rectTransform.offsetMin.y);
			title.Focus.Add((Selectable)(object)val2);
			screen.RowOf[((Il2CppObjectBase)((Component)val2).gameObject).Pointer] = title.Go.GetComponent<RectTransform>();
			screen.RowByFocus[((Il2CppObjectBase)((Component)val2).gameObject).Pointer] = title;
		}

		private static void SetHeight(GameObject row, float height)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = row.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(component.sizeDelta.x, height);
			LayoutElement component2 = row.GetComponent<LayoutElement>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.preferredHeight = height;
			}
		}

		private static void Toggle(string id)
		{
			bool flag = !Expanded.Contains(id);
			if (flag)
			{
				Expanded.Add(id);
			}
			else
			{
				Expanded.Remove(id);
			}
			ModMenuMod.ExpandedEntry.Value = string.Join(",", Expanded);
			ModMenuMod.Save();
			Screens.RemoveAll((Screen s) => (Object)(object)s.Panel == (Object)null);
			foreach (Screen screen in Screens)
			{
				foreach (Section section in screen.Sections)
				{
					if (section.Id == id)
					{
						section.Expanded = flag;
					}
				}
				Filter(screen, resetScroll: false);
			}
		}

		private static Row AddRow(Screen screen, Item item, RectTransform container, Templates t, string pageId)
		{
			try
			{
				Row row = CreateRow(item, container, t);
				if (row == null)
				{
					return null;
				}
				((Object)row.Go).name = $"ModMenu_{pageId}_{screen.Rows.Count}";
				foreach (Selectable item2 in row.Focus)
				{
					screen.RowOf[((Il2CppObjectBase)((Component)item2).gameObject).Pointer] = row.Go.GetComponent<RectTransform>();
					screen.RowByFocus[((Il2CppObjectBase)((Component)item2).gameObject).Pointer] = row;
				}
				screen.Rows.Add(row);
				return row;
			}
			catch (Exception ex)
			{
				ModMenuMod.Log.Warning("page '" + pageId + "': skipped a row — " + ex.Message);
				return null;
			}
		}

		private static Row CreateRow(Item item, RectTransform container, Templates t)
		{
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			Row row = new Row
			{
				Item = item
			};
			OptionItem optionItem = item as OptionItem;
			if (optionItem == null)
			{
				if (!(item is HeaderItem headerItem))
				{
					if (!(item is NoteItem))
					{
						if (!(item is ButtonItem buttonItem))
						{
							if (item is CustomItem customItem)
							{
								RectTransform val = Spacer(container, t.RowWidth, customItem.Height);
								((Object)val).name = "Custom";
								row.Go = ((Component)val).gameObject;
								Selectable val2 = customItem.Build?.Invoke(val);
								if ((Object)(object)val2 != (Object)null)
								{
									row.Focus.Add(val2);
								}
							}
						}
						else
						{
							if ((Object)(object)t.Button == (Object)null || buttonItem.Buttons.Count == 0)
							{
								return null;
							}
							BuildButtons(row, buttonItem, container, t);
						}
					}
					else
					{
						row.Go = TextRow(t, container, out row.Label);
						row.Label.fontSize = t.LabelSize * 0.75f;
						((Graphic)row.Label).color = NoteColor;
						row.Label.alignment = (TextAlignmentOptions)257;
						row.Label.textWrappingMode = (TextWrappingModes)1;
						RectTransform component = row.Go.GetComponent<RectTransform>();
						component.sizeDelta = new Vector2(component.sizeDelta.x, 110f);
						RectTransform rectTransform = row.Label.rectTransform;
						rectTransform.anchorMin = Vector2.zero;
						rectTransform.anchorMax = Vector2.one;
						rectTransform.pivot = new Vector2(0f, 1f);
						Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero);
						rectTransform.offsetMin = offsetMin;
					}
				}
				else
				{
					row.Go = TextRow(t, container, out row.Label);
					if (headerItem.IsPageTitle)
					{
						SetHeight(row.Go, 110f);
						row.Label.fontSize = t.LabelSize * 1.25f;
						((Graphic)row.Label).color = Color.white;
						row.Label.rectTransform.offsetMax = new Vector2(0f - t.ValueWidth * 0.6f, row.Label.rectTransform.offsetMax.y);
					}
					else
					{
						SetHeight(row.Go, 90f);
						row.Label.fontSize = t.LabelSize * 0.8f;
						TMP_Text label = row.Label;
						label.fontStyle = (FontStyles)(label.fontStyle | 1);
						((Graphic)row.Label).color = Gold;
						row.Label.characterSpacing = 4f;
					}
				}
			}
			else
			{
				row.Go = Object.Instantiate<GameObject>(((Component)t.SelectorRow).gameObject, (Transform)(object)container);
				SetHeight(row.Go, 126f);
				row.Label = FirstLabel(row.Go);
				StyleSettingLabel(row.Label, t);
				row.Selector = SetupSelector(row.Go, delegate(string value)
				{
					int num = row.Options.IndexOf(value);
					if (num >= 0)
					{
						try
						{
							optionItem.Apply(num);
						}
						catch (Exception value2)
						{
							ModMenuMod.Log.Error($"setting '{row.Raw}': {value2}");
						}
						UpdateReset(row);
					}
				});
				row.Focus.Add((Selectable)(object)row.Selector);
				if (optionItem.Reset != null)
				{
					row.Reset = IconButton(row.Go.transform, "ModMenu_Reset", delegate
					{
						ResetRow(row);
						EventSystem current = EventSystem.current;
						if (current != null)
						{
							current.SetSelectedGameObject(((Component)row.Selector).gameObject);
						}
					});
				}
			}
			return row;
		}

		private static void BuildButtons(Row row, ButtonItem item, RectTransform container, Templates t)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val;
			if (item.Label != null)
			{
				row.Go = TextRow(t, container, out row.Label);
				StyleSettingLabel(row.Label, t);
				val = row.Go.GetComponent<RectTransform>();
			}
			else
			{
				val = Spacer(container, t.RowWidth, 126f);
				row.Go = ((Component)val).gameObject;
			}
			val.sizeDelta = new Vector2(t.RowWidth, 126f);
			(row.Go.GetComponent<LayoutElement>() ?? row.Go.AddComponent<LayoutElement>()).preferredHeight = 126f;
			RectTransform val2 = NewRect("Buttons", (Transform)(object)val);
			if (item.Layout == ButtonLayout.Value)
			{
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(1f, 0.5f);
				val2.anchorMax = val3;
				val2.anchorMin = val3;
				val2.pivot = new Vector2(0.5f, 0.5f);
				val2.anchoredPosition = new Vector2((0f - t.ValueWidth) / 2f, 0f);
				val2.sizeDelta = new Vector2(t.ValueWidth + 300f, 110f);
			}
			else
			{
				val2.anchorMin = new Vector2(0f, 0.5f);
				val2.anchorMax = new Vector2(1f, 0.5f);
				val2.pivot = new Vector2(0.5f, 0.5f);
				val2.sizeDelta = new Vector2(0f, 110f);
			}
			HorizontalLayoutGroup val4 = ((Component)val2).gameObject.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val4).spacing = 30f;
			HorizontalLayoutGroup val5 = val4;
			((LayoutGroup)val5).childAlignment = (TextAnchor)(item.Layout switch
			{
				ButtonLayout.Left => 3, 
				ButtonLayout.Right => 5, 
				_ => 4, 
			});
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)val4).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)val4).childControlWidth = childControlWidth;
			((HorizontalOrVerticalLayoutGroup)val4).childForceExpandHeight = true;
			((HorizontalOrVerticalLayoutGroup)val4).childForceExpandWidth = item.Layout == ButtonLayout.Stretch;
			foreach (MenuButton button in item.Buttons)
			{
				GameObject val6 = Object.Instantiate<GameObject>(t.Button, (Transform)(object)val2);
				((Object)val6).name = "Button";
				val6.SetActive(true);
				MuteSerializedClicks(val6.GetComponent<Button>());
				foreach (Image componentsInChild in val6.GetComponentsInChildren<Image>(true))
				{
					((Graphic)componentsInChild).color = new Color(1f, 1f, 1f, ((Graphic)componentsInChild).color.a);
				}
				TMP_Text text = val6.GetComponentInChildren<TMP_Text>(true);
				StripLocalization(text);
				text.enableAutoSizing = false;
				text.fontSize = t.LabelSize * 0.85f;
				text.textWrappingMode = (TextWrappingModes)0;
				text.overflowMode = (TextOverflowModes)1;
				text.alignment = (TextAlignmentOptions)514;
				LayoutElement val7 = val6.GetComponent<LayoutElement>() ?? val6.AddComponent<LayoutElement>();
				val7.preferredHeight = 110f;
				if (item.Layout == ButtonLayout.Stretch)
				{
					val7.flexibleWidth = 1f;
					val7.preferredWidth = 0f;
				}
				Action action = button.OnClick;
				((ButtonInteractionHook)val6.GetComponent<ClickableButton>()).OnClicked += Action.op_Implicit((Action)delegate
				{
					try
					{
						action?.Invoke();
					}
					catch (Exception value)
					{
						ModMenuMod.Log.Error($"button '{text.text}': {value}");
					}
					RefreshAll();
				});
				row.Focus.Add((Selectable)(object)val6.GetComponent<Button>());
				row.Buttons.Add((text, val7, button));
			}
		}

		private static void StyleSettingLabel(TMP_Text label, Templates t)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			label.enableAutoSizing = false;
			label.fontSize = t.LabelSize;
			label.textWrappingMode = (TextWrappingModes)1;
			label.overflowMode = (TextOverflowModes)1;
			label.maxVisibleLines = 2;
			label.alignment = (TextAlignmentOptions)4097;
			RectTransform rectTransform = label.rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0.5f);
			rectTransform.anchorMax = new Vector2(1f, 0.5f);
			rectTransform.pivot = new Vector2(0f, 0.5f);
			rectTransform.offsetMin = new Vector2(0f, -65f);
			rectTransform.offsetMax = new Vector2(0f - (t.ValueWidth + 150f + 10f), 65f);
		}

		private static GameObject TextRow(Templates t, RectTransform container, out TMP_Text label)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)t.SelectorRow).gameObject, (Transform)(object)container);
			Object.DestroyImmediate((Object)(object)((Component)val.GetComponentInChildren<Selector>(true)).gameObject);
			label = FirstLabel(val);
			label.enableAutoSizing = false;
			label.fontSize = t.LabelSize;
			RectTransform rectTransform = label.rectTransform;
			rectTransform.offsetMax = new Vector2(0f, rectTransform.offsetMax.y);
			return val;
		}

		private static RectTransform Spacer(RectTransform container, float width, float height)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = NewRect("Spacer", (Transform)(object)container);
			obj.sizeDelta = new Vector2(width, height);
			LayoutElement obj2 = ((Component)obj).gameObject.AddComponent<LayoutElement>();
			obj2.preferredHeight = height;
			obj2.preferredWidth = width;
			return obj;
		}

		private static GameObject IconButton(Transform row, string name, Action onClick)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			Image obj = ((Component)NewRect(name, row)).gameObject.AddComponent<Image>();
			obj.sprite = Icons.Reset;
			obj.preserveAspect = true;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(1f, 0.5f);
			rectTransform.anchorMax = val;
			rectTransform.anchorMin = val;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = new Vector2(56f, 56f);
			rectTransform.anchoredPosition = new Vector2(210f, 0f);
			Clickable((Graphic)(object)obj, onClick);
			((Component)obj).gameObject.SetActive(false);
			return ((Component)obj).gameObject;
		}

		private static Button Clickable(Graphic graphic, Action onClick)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			graphic.color = Color.white;
			Button obj = ((Component)graphic).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = graphic;
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).normalColor = Dim;
			((ColorBlock)(ref colors)).highlightedColor = Gold;
			((ColorBlock)(ref colors)).selectedColor = Dim;
			((ColorBlock)(ref colors)).pressedColor = new Color(Gold.r * 0.8f, Gold.g * 0.8f, Gold.b * 0.8f);
			((Selectable)obj).colors = colors;
			NoNavigation((Selectable)(object)obj);
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				try
				{
					onClick();
				}
				catch (Exception ex)
				{
					ModMenuMod.Log.Error(ex.ToString());
				}
			}));
			return obj;
		}

		private static GameObject SectionReset(Section section, Templates t)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			foreach (Row row in section.Rows)
			{
				flag |= (Object)(object)row.Reset != (Object)null;
			}
			if (!flag)
			{
				return null;
			}
			RectTransform val = NewRect("ModMenu_ResetAll", section.Title.Go.transform);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(1f, 0.5f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(1f, 0.5f);
			val.anchoredPosition = new Vector2(238f, 0f);
			val.sizeDelta = new Vector2(t.ValueWidth + 150f, 56f);
			Image obj = ((Component)NewRect("Icon", (Transform)(object)val)).gameObject.AddComponent<Image>();
			obj.sprite = Icons.Reset;
			obj.preserveAspect = true;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			((Vector2)(ref val2))..ctor(1f, 0.5f);
			rectTransform.anchorMax = val2;
			rectTransform.anchorMin = val2;
			rectTransform.pivot = new Vector2(1f, 0.5f);
			rectTransform.sizeDelta = new Vector2(56f, 56f);
			Clickable((Graphic)(object)obj, ResetSection);
			TMP_Text component = Object.Instantiate<GameObject>(((Component)section.Title.Label).gameObject, (Transform)(object)val).GetComponent<TMP_Text>();
			((Object)((Component)component).gameObject).name = "Text";
			component.fontStyle = (FontStyles)0;
			component.fontSize = t.LabelSize * 0.75f;
			component.alignment = (TextAlignmentOptions)4100;
			component.textWrappingMode = (TextWrappingModes)0;
			((Graphic)component).raycastTarget = true;
			for (int num = component.transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)component.transform.GetChild(num)).gameObject);
			}
			RectTransform rectTransform2 = component.rectTransform;
			rectTransform2.anchorMin = Vector2.zero;
			rectTransform2.anchorMax = Vector2.one;
			rectTransform2.pivot = new Vector2(1f, 0.5f);
			rectTransform2.offsetMin = Vector2.zero;
			rectTransform2.offsetMax = new Vector2(-70f, 0f);
			Strings.Bind(component, "defaults");
			Clickable((Graphic)(object)component, ResetSection);
			((Component)val).gameObject.SetActive(false);
			return ((Component)val).gameObject;
			void ResetSection()
			{
				foreach (Row row2 in section.Rows)
				{
					if (row2.Item is OptionItem { Reset: not null } optionItem && !SafeIsDefault(optionItem))
					{
						try
						{
							optionItem.Reset();
						}
						catch (Exception value)
						{
							ModMenuMod.Log.Error($"reset '{row2.Raw}': {value}");
						}
					}
				}
				RefreshAll();
			}
		}

		private static Selector SetupSelector(GameObject rowGo, Action<string> onSelected)
		{
			Selector componentInChildren = rowGo.GetComponentInChildren<Selector>(true);
			componentInChildren.localizationMode = (LocalizationMode)2;
			if ((Object)(object)componentInChildren.valueLocalizeString != (Object)null)
			{
				((Behaviour)componentInChildren.valueLocalizeString).enabled = false;
			}
			componentInChildren.OnOptionSelected += Action<string>.op_Implicit((Action<string>)delegate(string option)
			{
				if (_refreshing)
				{
					return;
				}
				try
				{
					onSelected(option);
				}
				catch (Exception ex)
				{
					ModMenuMod.Log.Error(ex.ToString());
				}
			});
			return componentInChildren;
		}

		private static void BuildScrollView(Screen screen, RectTransform panel, RectTransform container)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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)
			RectTransform val = NewRect("ModMenu_Viewport", (Transform)(object)panel);
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			val.pivot = new Vector2(0.5f, 0.5f);
			val.offsetMin = new Vector2(0f, 0f);
			val.offsetMax = new Vector2(400f, -140f);
			((Component)val).gameObject.AddComponent<RectMask2D>();
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.001f);
			((Transform)container).SetParent((Transform)(object)val, false);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 1f);
			container.pivot = val2;
			Vector2 anchorMin = (container.anchorMax = val2);
			container.anchorMin = anchorMin;
			container.anchoredPosition = Vector2.zero;
			ScrollRect val4 = ((Component)val).gameObject.AddComponent<ScrollRect>();
			val4.content = container;
			val4.viewport = val;
			val4.horizontal = false;
			val4.vertical = true;
			val4.movementType = (MovementType)2;
			val4.scrollSensitivity = 60f;
			val4.verticalScrollbar = BuildScrollbar(panel);
			val4.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			screen.Scroll = val4;
		}

		private static Scrollbar BuildScrollbar(RectTransform panel)
		{
			//IL_000d: 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)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = NewRect("ModMenu_Scrollbar", (Transform)(object)panel);
			val.anchorMin = Vector2.zero;
			val.anchorMax = new Vector2(0f, 1f);
			val.pivot = new Vector2(0f, 0.5f);
			val.offsetMin = new Vector2(40f, 40f);
			val.offsetMax = new Vector2(46f, -140f);
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(1f, 1f, 1f, 0.05f);
			RectTransform val2 = NewRect("Sliding Area", (Transform)(object)val);
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			Vector2 offsetMin = (val2.offsetMax = Vector2.zero);
			val2.offsetMin = offsetMin;
			RectTransform val3 = NewRect("Handle", (Transform)(object)val2);
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			offsetMin = (val3.offsetMax = Vector2.zero);
			val3.offsetMin = offsetMin;
			Image val4 = ((Component)val3).gameObject.AddComponent<Image>();
			((Graphic)val4).color = Color.white;
			Scrollbar obj = ((Component)val).gameObject.AddComponent<Scrollbar>();
			obj.handleRect = val3;
			((Selectable)obj).targetGraphic = (Graphic)(object)val4;
			obj.direction = (Direction)2;
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(1f, 1f, 1f, 0.3f);
			((ColorBlock)(ref colors)).highlightedColor = Gold;
			((ColorBlock)(ref colors)).pressedColor = Gold;
			((ColorBlock)(ref colors)).selectedColor = new Color(1f, 1f, 1f, 0.3f);
			((Selectable)obj).colors = colors;
			NoNavigation((Selectable)(object)obj);
			return obj;
		}

		private static void BuildSearch(Screen screen, RectTransform panel, Templates t)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)t.SelectorRow).gameObject);
			TMP_Text obj = FirstLabel(val);
			obj.enableAutoSizing = false;
			obj.fontSize = t.LabelSize;
			RectTransform val2 = NewRect("ModMenu_Search", (Transform)(object)panel);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0f, 1f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			val2.anchoredPosition = new Vector2(100f, -30f);
			val2.sizeDelta = new Vector2(t.RowWidth, 80f);
			Image val5 = ((Component)val2).gameObject.AddComponent<Image>();
			((Graphic)val5).color = new Color(0f, 0f, 0f, 0.35f);
			Image val6 = ((Component)NewRect("Underline", (Transform)(object)val2)).gameObject.AddComponent<Image>();
			((Graphic)val6).color = new Color(1f, 1f, 1f, 0.2f);
			screen.SearchLine = val6;
			((Graphic)val6).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)val6).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = new Vector2(1f, 0f);
			rectTransform.pivot = new Vector2(0.5f, 0f);
			rectTransform.sizeDelta = new Vector2(0f, 3f);
			Image obj2 = ((Component)NewRect("Icon", (Transform)(object)val2)).gameObject.AddComponent<Image>();
			obj2.sprite = Icons.Search;
			((Graphic)obj2).color = new Color(1f, 1f, 1f, 0.6f);
			((Graphic)obj2).raycastTarget = false;
			RectTransform rectTransform2 = ((Graphic)obj2).rectTransform;
			((Vector2)(ref val3))..ctor(0f, 0.5f);
			rectTransform2.pivot = val3;
			anchorMin = (rectTransform2.anchorMax = val3);
			rectTransform2.anchorMin = anchorMin;
			rectTransform2.sizeDelta = new Vector2(46f, 46f);
			rectTransform2.anchoredPosition = new Vector2(24f, 0f);
			RectTransform val8 = NewRect("Text Area", (Transform)(object)val2);
			val8.anchorMin = Vector2.zero;
			val8.anchorMax = Vector2.one;
			val8.offsetMin = new Vector2(90f, 6f);
			val8.offsetMax = new Vector2(-90f, -6f);
			((Component)val8).gameObject.AddComponent<RectMask2D>();
			obj.transform.SetParent((Transform)(object)val8, false);
			Object.Destroy((Object)(object)val);
			TMP_Text val9 = PlainText(obj, "Placeholder");
			((Graphic)val9).color = new Color(1f, 1f, 1f, 0.35f);
			Strings.Bind(val9, "search");
			TMP_Text val10 = PlainText(Object.Instantiate<GameObject>(((Component)obj).gameObject, (Transform)(object)val8).GetComponent<TMP_Text>(), "Text");
			((Graphic)val10).color = Color.white;
			TMP_Text val11 = PlainText(Object.Instantiate<GameObject>(((Component)obj).gameObject, (Transform)(object)val2).GetComponent<TMP_Text>(), "Clear");
			val11.text = "×";
			val11.alignment = (TextAlignmentOptions)514;
			val11.fontSize *= 1.3f;
			((Graphic)val11).raycastTarget = true;
			RectTransform rectTransform3 = val11.rectTransform;
			rectTransform3.anchorMin = new Vector2(1f, 0f);
			rectTransform3.anchorMax = Vector2.one;
			rectTransform3.pivot = new Vector2(1f, 0.5f);
			rectTransform3.offsetMin = new Vector2(-80f, 0f);
			rectTransform3.offsetMax = Vector2.zero;
			screen.Clear = ((Component)val11).gameObject;
			TMP_InputField input = ((Component)val2).gameObject.AddComponent<TMP_InputField>();
			input.textViewport = val8;
			input.textComponent = val10;
			input.placeholder = (Graphic)(object)val9;
			input.fontAsset = val10.font;
			input.pointSize = val10.fontSize;
			input.lineType = (LineType)0;
			input.richText = false;
			input.restoreOriginalTextOnEscape = false;
			input.caretColor = Gold;
			input.customCaretColor = true;
			input.caretWidth = 3;
			input.selectionColor = new Color(Gold.r, Gold.g, Gold.b, 0.35f);
			((Selectable)input).targetGraphic = (Graphic)(object)val5;
			NoNavigation((Selectable)(object)input);
			screen.Search = input;
			Clickable((Graphic)(object)val11, delegate
			{
				input.text = "";
				input.ActivateInputField();
			});
			screen.Clear.SetActive(false);
			((UnityEvent<string>)(object)inpu