Decompiled source of Thorn Core v0.5.0

plugins/Thorn_Core/ThornClient.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using Fireman.Interface;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Notiffy.API;
using NukeLib.Game;
using NukeLib.UI;
using NukeLib.Utils;
using TMPro;
using ThornClient.Core;
using ThornClient.Core.ConfigurableElements;
using ThornClient.Core.DataTypes;
using ThornClient.Core.UI;
using ThornClient.HUD.HUDComponents;
using ThornClient.Managers;
using ThornClient.Patches;
using ThornClient.System;
using ThornClient.System.ClickGUIComponents;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ThornClient")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1a101fb30c637f775dd0986afe4d275e7d2734a3")]
[assembly: AssemblyProduct("ThornClient")]
[assembly: AssemblyTitle("ThornClient")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ThornClient
{
	[BepInPlugin("com.github.end-4.thornClient", "Thorn", "0.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource Log;

		public static string workingPath = Assembly.GetExecutingAssembly().Location;

		public static string workingDir = Path.GetDirectoryName(workingPath);

		public const string PluginGUID = "com.github.end-4.thornClient";

		public const string PluginName = "Thorn";

		public const string PluginVersion = "0.5.0";

		public static string PluginIconPath = Path.Combine(workingDir, "icon.png");

		public static Harmony HarmonyInstance;

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (!((Object)(object)Instance != (Object)null))
			{
				Instance = this;
				AssetManager.Initialize();
				ProfileManager.Initialize();
				HudManager.Initialize();
				EffectManager.Initialize();
				ModuleManager.Initialize();
				RenderManager.Initialize();
				ConfigManager.LoadAll();
				ConfigManager.SetupFileWatcher();
				HarmonyInstance = new Harmony("com.github.end-4.thornClient");
				HarmonyInstance.PatchAll(typeof(OptionsManagerPatches));
				HarmonyInstance.PatchAll(typeof(CheatsManagerPatches));
				HarmonyInstance.PatchAll(typeof(StatsManagerPatches));
				Log.LogInfo((object)"Thorn is loaded");
			}
		}

		private void Update()
		{
			ConfigManager.UpdateMainThreadQueue();
			InputManager.Update();
			ColorManager.Update();
			foreach (ThornClient.Core.Module item in ModuleManager.Items)
			{
				if (item.IsEnabled)
				{
					try
					{
						item.OnUpdate();
					}
					catch (Exception ex)
					{
						NotificationSystem.NotifySend("Thorn > " + item.Name, "Error in Update loop of " + item.Name + ", disabling to prevent further issues. Check BepInEx logs for further details.", (Sprite)null, PluginIconPath, (Urgency)1, "Thorn", 0u, (Dictionary<string, string>)null, -1);
						Log.LogError((object)("Error in module '" + item.Name + "' during Update! Disabling to prevent log spam"));
						Log.LogError((object)ex);
						item.Toggle();
					}
				}
			}
		}

		private void FixedUpdate()
		{
			if (!SceneUtils.IsInGame())
			{
				return;
			}
			foreach (ThornClient.Core.Module item in ModuleManager.Items)
			{
				if (item.IsEnabled)
				{
					try
					{
						item.OnFixedUpdate();
					}
					catch (Exception ex)
					{
						NotificationSystem.NotifySend("Thorn > " + item.Name, "Error in FixedUpdate loop of " + item.Name + ", disabling to prevent further issues. Check BepInEx logs for further details.", (Sprite)null, PluginIconPath, (Urgency)1, "Thorn", 0u, (Dictionary<string, string>)null, -1);
						Log.LogError((object)("Error in module '" + item.Name + "' during FixedUpdate! Disabling to prevent log spam"));
						Log.LogError((object)ex);
						item.Toggle();
					}
				}
			}
		}

		private void OnRenderObject()
		{
			RenderManager.RenderPipeline();
		}
	}
}
namespace ThornClient.System
{
	public class ClickGUI : SystemModule
	{
		public static ClickGUI? Instance;

		private const string PauseGameStateKey = "Thorn_ClickGUI";

		private static readonly string BundlePath = Path.Combine(Plugin.workingDir, "assets", "thorn_clickgui.bundle");

		public static readonly string BundleKey = "clickGui";

		private static GameObject? _layoutedPagePrefab;

		private bool _isInitialized;

		private GameObject? _canvas;

		private GameObject? _tabBar;

		private GameObject? _modulePage;

		private GameObject? _hudPage;

		private GameObject? _settingsPage;

		private GameObject? _profilesPage;

		private readonly Stack<GameObject> _panelStack = new Stack<GameObject>();

		private GameObject? _tooltip;

		private GameObject? _tabBarButtonRow;

		private ModuleSearchWindowController? _moduleSearchController;

		private ModuleSearchWindowController? _hudModuleSearchController;

		private List<Tuple<string, GameObject>> _tabPages = new List<Tuple<string, GameObject>>();

		private const string ModuleTabName = "Modules";

		private const string HudTabName = "HUD";

		private const string SettingsTabName = "Settings";

		private static readonly Vector2 PageHiddenOffset = Vector2.down * 15f;

		private static string _lastTabName = "";

		private static OptionsManager? opts => MonoSingleton<OptionsManager>.Instance;

		public ClickGUI()
			: base("thorn.clickGui", "ClickGUI", "The main interaction panel", hasToggling: true)
		{
			AssetManager.LoadBundle(BundleKey, BundlePath);
			SceneUtils.SafeSceneLoaded += delegate
			{
				_isInitialized = InitializeIfNeeded();
				if (IsEnabled)
				{
					Toggle();
				}
			};
		}

		private bool InitializeIfNeeded()
		{
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Expected O, but got Unknown
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			if (Instance != null || (_isInitialized && (Object)(object)_canvas != (Object)null))
			{
				return true;
			}
			Instance = this;
			GameObject val = AssetManager.Get<GameObject>(BundleKey, "ThornClickGUICanvas");
			GameObject val2 = AssetManager.Get<GameObject>(BundleKey, "TabBar");
			_layoutedPagePrefab = AssetManager.Get<GameObject>(BundleKey, "LayoutedPage");
			GameObject val3 = AssetManager.Get<GameObject>(BundleKey, "Tooltip");
			GameObject val4 = AssetManager.Get<GameObject>(BundleKey, "TabButton");
			GameObject val5 = AssetManager.Get<GameObject>(BundleKey, "ModuleCategory");
			GameObject val6 = AssetManager.Get<GameObject>(BundleKey, "SearchWindow");
			GameObject val7 = AssetManager.Get<GameObject>(BundleKey, "ProfileWindow");
			_canvas = Object.Instantiate<GameObject>(val);
			if ((Object)(object)_canvas == (Object)null)
			{
				return false;
			}
			((Object)_canvas).hideFlags = (HideFlags)52;
			Object.DontDestroyOnLoad((Object)(object)_canvas);
			_canvas.SetActive(true);
			_tabBar = Object.Instantiate<GameObject>(val2, _canvas.transform);
			GameObject? tabBar = _tabBar;
			if (tabBar != null)
			{
				tabBar.SetActive(true);
			}
			GameObject? tabBar2 = _tabBar;
			if (tabBar2 != null)
			{
				GameObjectExtensions.GetOrAddComponent<TabBarController>(tabBar2);
			}
			_modulePage = Object.Instantiate<GameObject>(_layoutedPagePrefab, _canvas.transform);
			_hudPage = Object.Instantiate<GameObject>(_layoutedPagePrefab, _canvas.transform);
			_settingsPage = Object.Instantiate<GameObject>(_layoutedPagePrefab, _canvas.transform);
			_profilesPage = Object.Instantiate<GameObject>(_layoutedPagePrefab, _canvas.transform);
			_tabPages.Add(Tuple.Create<string, GameObject>("Modules", _modulePage));
			_tabPages.Add(Tuple.Create<string, GameObject>("HUD", _hudPage));
			_tabPages.Add(Tuple.Create<string, GameObject>("Settings", _settingsPage));
			_tabPages.Add(Tuple.Create<string, GameObject>("Profiles", _profilesPage));
			_lastTabName = "Modules";
			for (int i = 0; i < Enum.GetValues(typeof(ModuleCategory)).Length; i++)
			{
				ModuleCategory moduleCategory = (ModuleCategory)i;
				if (moduleCategory != ModuleCategory.Hud)
				{
					GameObject val8 = Object.Instantiate<GameObject>(val5);
					AddToLayoutedPage(_modulePage, val8);
					ModuleCategoryController orAddComponent = GameObjectExtensions.GetOrAddComponent<ModuleCategoryController>(val8);
					orAddComponent.Category = moduleCategory;
					orAddComponent.SetupModules();
					UIUtils.UnfuckLayoutHack(val8);
				}
			}
			GameObject val9 = Object.Instantiate<GameObject>(val6);
			AddToLayoutedPage(_modulePage, val9);
			_moduleSearchController = val9.AddComponent<ModuleSearchWindowController>();
			_moduleSearchController.ModuleFilter = (ThornClient.Core.Module module) => !(module is SystemModule) && !(module is HudModule);
			UIUtils.UnfuckLayoutHack(_modulePage);
			GameObject val10 = Object.Instantiate<GameObject>(val5);
			AddToLayoutedPage(_hudPage, val10);
			ModuleCategoryController orAddComponent2 = GameObjectExtensions.GetOrAddComponent<ModuleCategoryController>(val10);
			orAddComponent2.Category = ModuleCategory.Hud;
			orAddComponent2.SetupModules();
			UIUtils.UnfuckLayoutHack(val10);
			RectTransform val11 = (RectTransform)val10.transform;
			UIUtils.UnfuckLayoutHack(val10);
			val11.pivot = new Vector2(0.5f, 0.5f);
			((Transform)val11).localPosition = new Vector3(0f, 0f, 0f);
			GameObject val12 = Object.Instantiate<GameObject>(val6);
			AddToLayoutedPage(_hudPage, val12);
			_hudModuleSearchController = val12.AddComponent<ModuleSearchWindowController>();
			_hudModuleSearchController.ModuleFilter = (ThornClient.Core.Module module) => module is HudModule;
			UIUtils.UnfuckLayoutHack(_hudPage);
			GameObject val13 = Object.Instantiate<GameObject>(val5);
			AddToLayoutedPage(_settingsPage, val13);
			GameObjectExtensions.GetOrAddComponent<ConfigurableWindowController>(val13).TargetConfigurable = ThornModule.Instance;
			UIUtils.UnfuckLayoutHack(_settingsPage);
			GameObject val14 = Object.Instantiate<GameObject>(val7);
			AddToLayoutedPage(_profilesPage, val14);
			GameObjectExtensions.GetOrAddComponent<ProfileWindowController>(val14);
			UIUtils.UnfuckLayoutHack(_profilesPage);
			_tabBarButtonRow = UIUtils.FindRecursive(_tabBar, "Tabs");
			foreach (Tuple<string, GameObject> tabPage in _tabPages)
			{
				string key = tabPage.Item1;
				GameObject? tabBarButtonRow = _tabBarButtonRow;
				GameObject val15 = Object.Instantiate<GameObject>(val4, (tabBarButtonRow != null) ? tabBarButtonRow.transform : null);
				if ((Object)(object)val15 != (Object)null)
				{
					((UnityEvent)val15.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
					{
						SetTab(key);
					});
				}
				object obj;
				if (val15 == null)
				{
					obj = null;
				}
				else
				{
					GameObject obj2 = UIUtils.FindRecursive(val15, "Text");
					obj = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
				}
				TextMeshProUGUI val16 = (TextMeshProUGUI)obj;
				if ((Object)(object)val16 != (Object)null)
				{
					((TMP_Text)val16).text = key;
				}
				SlideFadeToggleEffectExtensions.SetActiveAnimated(tabPage.Item2, false, PageHiddenOffset, 25f);
			}
			GameObject? tabBarButtonRow2 = _tabBarButtonRow;
			if (tabBarButtonRow2 != null)
			{
				UIUtils.UnfuckLayoutHack(tabBarButtonRow2);
			}
			_tooltip = Object.Instantiate<GameObject>(val3, _canvas.transform);
			_tooltip.SetActive(false);
			CanvasGroup component = _canvas.GetComponent<CanvasGroup>();
			if ((Object)(object)component != (Object)null)
			{
				component.alpha = 1f;
			}
			SetTab("Modules", animated: false);
			_canvas.SetActive(false);
			return true;
		}

		internal static Transform? GetPageLayout(GameObject? page)
		{
			if (page == null)
			{
				return null;
			}
			GameObject obj = UIUtils.FindRecursive(page, "Layout");
			if (obj == null)
			{
				return null;
			}
			return obj.transform;
		}

		public static GameObject AddToLayoutedPage(GameObject page, GameObject item)
		{
			Transform pageLayout = GetPageLayout(page);
			if ((Object)(object)pageLayout == (Object)null || (Object)(object)item == (Object)null)
			{
				return item;
			}
			item.transform.SetParent(pageLayout, false);
			UIUtils.UnfuckLayoutHack(((Component)pageLayout).gameObject);
			return item;
		}

		protected override void OnEnable()
		{
			if (!((Object)(object)_canvas == (Object)null))
			{
				_canvas.transform.SetAsLastSibling();
				_canvas.SetActive(true);
				Canvas component = _canvas.GetComponent<Canvas>();
				if ((Object)(object)component != (Object)null)
				{
					component.sortingOrder = 1002;
				}
				UIUtils.UnfuckLayoutHack(_canvas);
				ThornModule? instance = ThornModule.Instance;
				if (instance == null || instance.MenuPausesGame.Value)
				{
					Pauser.Pause(true, "Thorn_ClickGUI");
				}
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				ThornModule.Instance.Accent.OnChanged += UpdateTabsAppearance;
				ThornModule.Instance.Accent.OnEffectiveValueChanged += UpdateTabsAppearance;
				PerformInitialFocus();
			}
		}

		protected override void OnDisable()
		{
			ThornModule.Instance.Accent.OnChanged -= UpdateTabsAppearance;
			ThornModule.Instance.Accent.OnEffectiveValueChanged -= UpdateTabsAppearance;
			if (!((Object)(object)_canvas == (Object)null))
			{
				_canvas.SetActive(false);
				Pauser.Pause(true, "Thorn_ClickGUI");
				Pauser.Pause(false, "Thorn_ClickGUI");
				if ((Object)(object)_tooltip != (Object)null)
				{
					_tooltip.SetActive(false);
				}
			}
		}

		public override void OnUpdate()
		{
			UpdateTooltipPos();
		}

		private void UpdateTooltipPos()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_tooltip == (Object)null) && _tooltip.activeInHierarchy)
			{
				RectTransform val = (RectTransform)_tooltip.transform;
				val.pivot = new Vector2(0f, 1f);
				((Transform)val).position = Input.mousePosition + new Vector3(40f, -40f, 0f);
				_tooltip.transform.SetAsLastSibling();
			}
		}

		public static string GetTooltipText()
		{
			if (Instance == null || (Object)(object)Instance._tooltip == (Object)null)
			{
				return "";
			}
			GameObject val = UIUtils.FindRecursive(Instance._tooltip, "Text");
			if ((Object)(object)val == (Object)null)
			{
				return "";
			}
			return ((TMP_Text)val.GetComponent<TextMeshProUGUI>()).text;
		}

		public static void SetTooltipText(string text)
		{
			if (text.Length == 0)
			{
				return;
			}
			string text2 = TextUtils.WrapText(text, 30);
			if (Instance != null && !((Object)(object)Instance._tooltip == (Object)null))
			{
				GameObject val = UIUtils.FindRecursive(Instance._tooltip, "Text");
				if (!((Object)(object)val == (Object)null))
				{
					((TMP_Text)val.GetComponent<TextMeshProUGUI>()).text = text2;
					Instance._tooltip.SetActive(true);
					UIUtils.UnfuckLayoutHack(Instance._tooltip);
					Instance.UpdateTooltipPos();
				}
			}
		}

		public static void SurrenderTooltipText(string text, bool force = false)
		{
			string text2 = TextUtils.WrapText(text, 30);
			if (Instance == null || (Object)(object)Instance._tooltip == (Object)null)
			{
				return;
			}
			GameObject val = UIUtils.FindRecursive(Instance._tooltip, "Text");
			if (!((Object)(object)val == (Object)null))
			{
				TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
				if (((TMP_Text)component).text == text2 || force)
				{
					Instance._tooltip.SetActive(false);
					((TMP_Text)component).text = "";
				}
			}
		}

		private static void SetTab(string tabName, bool animated = true)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (Instance == null)
			{
				return;
			}
			List<Tuple<string, GameObject>> tabPages = Instance._tabPages;
			for (int i = 0; i < tabPages.Count; i++)
			{
				tabPages[i].Deconstruct(out var item, out var item2);
				string text = item;
				GameObject val = item2;
				bool flag = tabName == text;
				if (animated)
				{
					SlideFadeToggleEffectExtensions.SetActiveAnimated(val, flag, PageHiddenOffset, 25f);
				}
				else
				{
					val.SetActive(flag);
				}
				UIUtils.UnfuckLayoutHack(val);
				if ((Object)(object)val != (Object)null && tabName == text)
				{
					_lastTabName = tabName;
				}
			}
			UpdateTabsAppearance();
			SurrenderTooltipText("", force: true);
			Instance.PerformInitialFocus();
		}

		private static void UpdateTabsAppearance()
		{
			//IL_0089: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00a0: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			GameObject tabBarButtonRow = Instance._tabBarButtonRow;
			List<Tuple<string, GameObject>> tabPages = Instance._tabPages;
			int num = tabPages.FindIndex((Tuple<string, GameObject> tup) => tup.Item1 == _lastTabName);
			if ((Object)(object)tabBarButtonRow == (Object)null)
			{
				return;
			}
			for (int num2 = 0; num2 < tabBarButtonRow.transform.childCount; num2++)
			{
				bool flag = num2 == num;
				bool atLeft = num2 == 0;
				bool atRight = num2 + 1 == tabPages.Count;
				Sprite sprite = ConnectedButtonGroupSettingController.GetSprite(atLeft, atRight, flag);
				Color color = (flag ? ThornModule.Instance.Accent.Value.GetCurrentColor() : Color.white);
				Color color2 = (flag ? Color.black : Color.white);
				Transform child = tabBarButtonRow.transform.GetChild(num2);
				Image val = ((child != null) ? ((Component)child).GetComponent<Image>() : null);
				GameObject val2 = ((child != null) ? UIUtils.FindRecursive(((Component)child).gameObject, "Text") : null);
				if (!((Object)(object)child == (Object)null) && !((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
				{
					val.sprite = sprite;
					((Graphic)val).color = color;
					((Graphic)val2.GetComponent<TextMeshProUGUI>()).color = color2;
				}
			}
		}

		private void PerformInitialFocus()
		{
			if (_lastTabName == "Modules")
			{
				if ((Object)(object)_moduleSearchController != (Object)null)
				{
					_moduleSearchController.FocusSearch();
				}
			}
			else if (_lastTabName == "HUD" && (Object)(object)_hudModuleSearchController != (Object)null)
			{
				_hudModuleSearchController.FocusSearch();
			}
		}

		public static void CycleTab(int diff)
		{
			if (Instance != null && Instance._tabPages.Count != 0 && Instance.IsEnabled)
			{
				int num = Instance._tabPages.FindIndex((Tuple<string, GameObject> p) => p.Item1 == _lastTabName);
				if (num == -1)
				{
					num = 0;
				}
				int count = Instance._tabPages.Count;
				int index = ((num + diff) % count + count) % count;
				SetTab(Instance._tabPages[index].Item1);
			}
		}

		public static void NestPanel(GameObject panelContent)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if (Instance == null || (Object)(object)Instance._canvas == (Object)null || (Object)(object)_layoutedPagePrefab == (Object)null)
			{
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(_layoutedPagePrefab, Instance._canvas.transform);
			AddToLayoutedPage(val, panelContent);
			RectTransform val2 = (RectTransform)panelContent.transform;
			val2.pivot = new Vector2(0.5f, 0.5f);
			((Transform)val2).localPosition = Vector3.zero;
			if ((Object)(object)Instance._tabBarButtonRow != (Object)null)
			{
				Instance._tabBarButtonRow.SetActive(false);
			}
			if (Instance._panelStack.Count > 0)
			{
				SlideFadeToggleEffectExtensions.SetActiveAnimated(Instance._panelStack.Peek(), false, PageHiddenOffset, 25f);
			}
			else
			{
				Instance._tabPages.ForEach(delegate(Tuple<string, GameObject> p)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					SlideFadeToggleEffectExtensions.SetActiveAnimated(p.Item2, false, PageHiddenOffset, 25f);
				});
			}
			SlideFadeToggleEffectExtensions.SetActiveAnimated(val, true, PageHiddenOffset, 25f);
			Instance._panelStack.Push(val);
			SurrenderTooltipText("", force: true);
		}

		public static void SpawnContent(GameObject content)
		{
			if (Instance != null && !((Object)(object)content == (Object)null))
			{
				GameObject val = null;
				val = (GameObject)((Instance._panelStack.Count <= 0) ? ((object)Instance._tabPages.FirstOrDefault((Tuple<string, GameObject> p) => p.Item1 == _lastTabName)?.Item2) : ((object)Instance._panelStack.Peek()));
				if (!((Object)(object)val == (Object)null))
				{
					AddToLayoutedPage(val, content);
				}
			}
		}

		public static void NavigateBack()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			ClickGUI instance = Instance;
			if (instance == null || !instance.IsEnabled)
			{
				return;
			}
			Transform pageLayout = GetPageLayout((Instance._panelStack.Count > 0) ? Instance._panelStack.Peek() : Instance._tabPages.Find((Tuple<string, GameObject> tup) => tup != null && tup.Item1 == _lastTabName && _lastTabName == "Settings")?.Item2);
			if ((Object)(object)pageLayout != (Object)null && pageLayout.childCount > 1)
			{
				Object.Destroy((Object)(object)((Component)pageLayout.GetChild(pageLayout.childCount - 1)).gameObject);
				return;
			}
			if (Instance._panelStack.Count > 0)
			{
				Object.Destroy((Object)(object)Instance._panelStack.Pop());
				if (Instance._panelStack.Count > 0)
				{
					SlideFadeToggleEffectExtensions.SetActiveAnimated(Instance._panelStack.Peek(), true, PageHiddenOffset, 25f);
				}
				else
				{
					SetTab(_lastTabName);
					if ((Object)(object)Instance._tabBarButtonRow != (Object)null)
					{
						Instance._tabBarButtonRow.SetActive(true);
					}
				}
			}
			else if (Instance.IsEnabled)
			{
				Instance.Toggle();
			}
			SurrenderTooltipText("", force: true);
		}

		public static void NestConfigPanel(Configurable? config)
		{
			if (config != null)
			{
				GameObject val = CreateConfigPanel(config);
				if ((Object)(object)val != (Object)null)
				{
					NestPanel(val);
				}
				SurrenderTooltipText("", force: true);
			}
		}

		private static GameObject? CreateConfigPanel(Configurable config)
		{
			if ((Object)(object)AssetManager.Get<GameObject>(BundleKey, "ModuleCategory") == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(BundleKey, "ModuleCategory"));
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			ConfigurableWindowController orAddComponent = GameObjectExtensions.GetOrAddComponent<ConfigurableWindowController>(val);
			orAddComponent.IsPopup = true;
			orAddComponent.TargetConfigurable = config;
			return val;
		}
	}
	internal static class PauseMenuButton
	{
		private const string PauseNotifToggleButtonName = "ThornToggleClickGUI";

		private static GameObject? _clickGuiToggleButton;

		public static void Initialize()
		{
		}

		static PauseMenuButton()
		{
			SceneUtils.SafeSceneLoadedNoParam += PatchPauseMenu;
		}

		private static void PatchPauseMenu()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject val = (from obj in ((Scene)(ref activeScene)).GetRootGameObjects()
				where ((Object)obj).name == "Canvas"
				select obj).FirstOrDefault();
			if ((Object)(object)val == (Object)null || (Object)(object)_clickGuiToggleButton != (Object)null)
			{
				return;
			}
			GameObject val2 = UIUtils.FindRecursive(val, "PauseMenu");
			GameObject val3 = ((val2 != null) ? UIUtils.FindRecursive(val2, "Resume") : null);
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null))
			{
				_clickGuiToggleButton = Object.Instantiate<GameObject>(val3, val2.transform);
				((Object)_clickGuiToggleButton).name = "ThornToggleClickGUI";
				Button component = _clickGuiToggleButton.GetComponent<Button>();
				component.onClick = new ButtonClickedEvent();
				if (ClickGUI.Instance != null)
				{
					((UnityEvent)component.onClick).AddListener(new UnityAction(ClickGUI.Instance.Toggle));
				}
				GameObject val4 = UIUtils.FindRecursive(_clickGuiToggleButton, "Text");
				if ((Object)(object)val4 != (Object)null)
				{
					Object.Destroy((Object)(object)val4);
				}
				RectTransform component2 = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "ThornClickGUIToggleIcon"), _clickGuiToggleButton.transform).GetComponent<RectTransform>();
				component2.anchorMin = new Vector2(0.3f, 0.3f);
				component2.anchorMax = new Vector2(0.7f, 0.7f);
				UpdateAppearance();
			}
		}

		public static void UpdateAppearance()
		{
			//IL_0025: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_clickGuiToggleButton == (Object)null)
			{
				return;
			}
			RectTransform component = _clickGuiToggleButton.GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			component.sizeDelta = new Vector2(component.sizeDelta.y, component.sizeDelta.y);
			ThornModule? instance = ThornModule.Instance;
			int num;
			int num2;
			if (instance == null)
			{
				num = 0;
			}
			else
			{
				num = (instance.MenuButtonPositionForceConfiggyNicePosition.Value ? 1 : 0);
				if (num != 0)
				{
					num2 = -115;
					goto IL_0063;
				}
			}
			num2 = -107;
			goto IL_0063;
			IL_0063:
			float num3 = num2;
			((Transform)component).localPosition = new Vector3(num3, -90f, 0f);
			if (num != 0)
			{
				GameObject val = UIUtils.FindRecursive(((Component)_clickGuiToggleButton.transform.parent).gameObject, "UI_Button_Image(Clone)");
				if ((Object)(object)val != (Object)null)
				{
					RectTransform component2 = val.GetComponent<RectTransform>();
					((Transform)component2).localPosition = new Vector3(115f, ((Transform)component2).localPosition.y, ((Transform)component2).localPosition.z);
				}
			}
		}
	}
	public class ThornModule : SystemModule
	{
		public enum TimeHourFormat
		{
			Twelve,
			TwentyFour
		}

		public static ThornModule? Instance;

		public Setting<TimeHourFormat> TimeFormat;

		public Setting<bool> SnapEnabled;

		public Setting<int> SnapGap;

		public Setting<int> SnapActivationDistance;

		public Setting<int> SnapActivationDistanceAlignment;

		public Setting<Keybind> OpenClickGUI { get; }

		public Setting<bool> MenuPausesGame { get; }

		public Setting<Keybind> OpenClickGUIUnpaused { get; }

		public Setting<Keybind> SwitchTabLeft { get; }

		public Setting<Keybind> SwitchTabRight { get; }

		public Setting<EnhancedColor> Accent { get; }

		public Setting<float> GlobalHuePulseRate { get; }

		public Setting<bool> MenuButtonPositionForceConfiggyNicePosition { get; }

		public Setting<string> LastVersion { get; }

		public override Sprite Icon => AssetManager.Get<Sprite>(ClickGUI.BundleKey, "settings");

		public ThornModule()
			: base("thorn.thorn", "Thorn", "Global settings")
		{
			if (Instance != null)
			{
				return;
			}
			Instance = this;
			UserHints.Initialize();
			CreateHeader("binds", "Keybinds");
			OpenClickGUI = CreateSetting("openClickGui", "Open menu keybind", "Keybind to open Thorn's ClickGUI interface", new Keybind((KeyCode)303, (KeyCode)0));
			OpenClickGUI.OnPress += delegate
			{
				if (ClickGUI.Instance != null)
				{
					ClickGUI.Instance.Toggle();
					PreventSoftlock();
				}
			};
			MenuPausesGame = CreateSetting("menuPausesGame", "Menu pauses game", "Makes the game paused when you open the ClickGUI", defaultValue: true);
			SettingGroup parent = CreateGroup("otherBinds", "More keybinds", "Less important keybinds are here");
			OpenClickGUIUnpaused = CreateSetting("openClickGuiPaused", "Open menu (no pausing)", "Keybind to open Thorn's ClickGUI interface without pausing the game", new Keybind((KeyCode)0, (KeyCode)0), parent);
			OpenClickGUIUnpaused.OnPress += delegate
			{
				if (ClickGUI.Instance != null)
				{
					bool value = MenuPausesGame.Value;
					MenuPausesGame.Value = false;
					ClickGUI.Instance.Toggle();
					MenuPausesGame.Value = value;
					PreventSoftlock();
				}
			};
			SwitchTabLeft = CreateSetting("switchTabLeft", "Switch to tab on the left", "Switch to tab on the left", new Keybind((KeyCode)280, (KeyCode)306), parent);
			SwitchTabLeft.OnPress += delegate
			{
				ClickGUI.CycleTab(-1);
			};
			SwitchTabRight = CreateSetting("switchTabRight", "Switch to tab on the right", "Switch to tab on the right", new Keybind((KeyCode)281, (KeyCode)306), parent);
			SwitchTabRight.OnPress += delegate
			{
				ClickGUI.CycleTab(1);
			};
			CreateHeader("colors", "Colors");
			SettingGroup parent2 = CreateGroup("themeGroup", "Theme", "UI theme");
			Accent = CreateSetting("accentColor", "Accent color", "Color used for highlighting certain elements, preferably a bright one", 9171683.ToEnhancedColor(), parent2);
			SettingGroup parent3 = CreateGroup("otherColorsGroup", "Other settings", "Color pulse rate, etc.");
			GlobalHuePulseRate = CreateSetting("globalHuePulseRate", "Global hue pulse rate", "Speed of the rainbow pulse", 0.4f, parent3);
			CreateHeader("general", "Interface");
			SettingGroup parent4 = CreateGroup("uiGroup", "Interface settings", "Stuff related to the user interface");
			CreateHeader("uiGeneral", "General", "", HeaderType.H1, parent4);
			TimeFormat = CreateSetting("timeFormat", "Time format", "Used on the menu's top bar", TimeHourFormat.Twelve, parent4);
			TimeFormat.Hints = new InterfaceHints
			{
				EnumSubstitutions = new Dictionary<string, string>
				{
					["Twelve"] = "12h",
					["TwentyFour"] = "24h"
				}
			};
			MenuButtonPositionForceConfiggyNicePosition = CreateSetting("menuButtonPosition", "Force nice spacing", "Tries to move the Configgy button on the pause menu a bit so it has proper spacing", defaultValue: false, parent4);
			MenuButtonPositionForceConfiggyNicePosition.OnChanged += PauseMenuButton.UpdateAppearance;
			CreateHeader("uiHud", "HUD", "", HeaderType.H1, parent4);
			CreateHeader("uiHud", "Snapping", "", HeaderType.H2, parent4);
			SnapEnabled = CreateSetting("snapEnabled", "Enable", "Whether widgets snap to others when dragging", defaultValue: true, parent4);
			SnapGap = CreateSetting("snapGap", "Gap", "Gap between two widgets when snapped", 1, parent4);
			SnapActivationDistance = CreateSetting("snapActivationDistance", "Activation distance (facing edges)", "At most how far away should HUD widgets be from a snap target to be snapped (for facing edge snaps)", 8, parent4);
			SnapActivationDistanceAlignment = CreateSetting("snapActivationDistanceAlignment", "Activation distance (alignment)", "At most how far away should HUD widgets be from a snap target to be snapped (for alignment snaps)", 30, parent4);
			CreateHeader("about", "About", "Thorn is an open-source, extensible utility mod for ULTRAKILL with a powerful configuration system.");
			ConfigButtonRow configButtonRow = CreateButtonRow("engagementButtons", "Links", "Links to Thorn stuff", new string[3] { "GitHub", "API Docs", "Donations" });
			configButtonRow.OnClick = (Action<int>)Delegate.Combine(configButtonRow.OnClick, (Action<int>)delegate(int i)
			{
				switch (i)
				{
				case 0:
					Application.OpenURL("https://github.com/end-4/ultrakill-thorn-client");
					break;
				case 1:
					Application.OpenURL("https://github.com/end-4/ultrakill-thorn-client/wiki");
					break;
				case 2:
					Application.OpenURL("https://github.com/sponsors/end-4");
					break;
				}
			});
			SettingGroup parent5 = CreateGroup("devGroup", "Developer", "Developer options, not so interesting");
			LastVersion = CreateSetting("lastVersion", "Last Thorn version", "The version of Thorn run in the previous/current session", "0.0.0", parent5);
			PauseMenuButton.Initialize();
		}

		private void PreventSoftlock()
		{
			ExecutionUtils.RunNextFrame((Action)delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Invalid comparison between Unknown and I4
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Invalid comparison between Unknown and I4
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Invalid comparison between Unknown and I4
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Invalid comparison between Unknown and I4
				if ((int)OpenClickGUI.Value.Key == 323 || (int)OpenClickGUI.Value.Modifier == 323)
				{
					OpenClickGUI.Reset();
				}
				if ((int)OpenClickGUIUnpaused.Value.Key == 323 || (int)OpenClickGUIUnpaused.Value.Modifier == 323)
				{
					OpenClickGUIUnpaused.Reset();
				}
			});
		}
	}
	internal static class UserHints
	{
		internal static void SendLaunchNotifsIfNecessary()
		{
			ThornModule instance = ThornModule.Instance;
			if (instance != null)
			{
				Version value = new Version("0.0.0");
				Version version = new Version(instance.LastVersion.Value ?? "999.999.999");
				if (new Version("0.1.0").CompareTo(version) == 1)
				{
					NotificationSystem.NotifySend("Thorn::<color=#a5f2e2>Hello</color>", "To access the config menu, press " + instance.OpenClickGUI.Value.ToString(pretty: true), (Sprite)null, Path.Combine(Plugin.workingDir, "icon.png"), (Urgency)1, "NotifySend", 0u, (Dictionary<string, string>)null, 10000);
				}
				if (new Version("0.2.0").CompareTo(version) == 1 && version.CompareTo(value) == 1)
				{
					NotificationSystem.NotifySend("Thorn::<color=#a5f2e2>Updated</color>", "<b>0.2.0 note</b>: Position of HUD widgets might've shifted a bit (again); really sorry about that.\nBut we have config profiles now!\nIf further issues arise, yell at @end_4 on Discord.", (Sprite)null, Path.Combine(Plugin.workingDir, "icon.png"), (Urgency)1, "NotifySend", 0u, (Dictionary<string, string>)null, 16000);
				}
				instance.LastVersion.Value = "0.5.0";
				SceneManager.sceneLoaded -= SendLaunchNotifsIfNecessary;
			}
		}

		internal static void SendLaunchNotifsIfNecessary(Scene _, LoadSceneMode __)
		{
			SendLaunchNotifsIfNecessary();
		}

		internal static void Initialize()
		{
		}

		static UserHints()
		{
			SceneManager.sceneLoaded += SendLaunchNotifsIfNecessary;
		}
	}
}
namespace ThornClient.System.ClickGUIComponents
{
	internal class BoolSettingController : MonoBehaviour
	{
		public Setting<bool>? TargetSetting;

		private GameObject? _checkMark;

		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener(new UnityAction(ToggleSetting));
			if (TargetSetting != null)
			{
				Setting<bool>? targetSetting = TargetSetting;
				targetSetting.OnValueChanged = (Action<bool>)Delegate.Combine(targetSetting.OnValueChanged, new Action<bool>(UpdateCheckmark));
				_checkMark = UIUtils.FindRecursive(((Component)this).gameObject, "Checkbox/Mark");
				UpdateCheckmark(TargetSetting.Value);
			}
		}

		private void OnDestroy()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).RemoveListener(new UnityAction(ToggleSetting));
			if (TargetSetting != null)
			{
				Setting<bool>? targetSetting = TargetSetting;
				targetSetting.OnValueChanged = (Action<bool>)Delegate.Remove(targetSetting.OnValueChanged, new Action<bool>(UpdateCheckmark));
			}
		}

		private void ToggleSetting()
		{
			if (TargetSetting != null)
			{
				TargetSetting.Value = !TargetSetting.Value;
			}
		}

		private void UpdateCheckmark(bool value)
		{
			if ((Object)(object)_checkMark != (Object)null)
			{
				_checkMark.SetActive(value);
			}
		}
	}
	internal class ButtonRowSettingController : MonoBehaviour
	{
		public ConfigButtonRow? TargetButtonRow;

		private void Start()
		{
			if (TargetButtonRow != null)
			{
				Populate();
			}
		}

		private void Populate()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			if (TargetButtonRow == null)
			{
				return;
			}
			for (int i = 0; i < TargetButtonRow.Texts.Count; i++)
			{
				string text = TargetButtonRow.Texts[i];
				GameObject obj = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "ButtonRowButton"), ((Component)this).transform);
				GameObject val = UIUtils.FindRecursive(obj, "Text");
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)val.GetComponent<TextMeshProUGUI>()).text = text;
				}
				int iCopied = i;
				((UnityEvent)obj.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					Trigger(iCopied);
				});
			}
		}

		private void Trigger(int idx)
		{
			if (TargetButtonRow != null)
			{
				TargetButtonRow.OnClick?.Invoke(idx);
			}
		}
	}
	internal class ClickGUITooltipHandler : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		[CompilerGenerated]
		private string <Text>k__BackingField;

		private string _lastSetText = "";

		public string Text
		{
			[CompilerGenerated]
			get
			{
				return <Text>k__BackingField;
			}
			set
			{
				<Text>k__BackingField = value;
				if (_lastSetText != "")
				{
					SetText();
				}
			}
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			if (Text.Length != 0)
			{
				SetText();
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			UnsetText();
		}

		private void OnDisable()
		{
			UnsetText();
		}

		private void SetText()
		{
			_lastSetText = Text;
			ClickGUI.SetTooltipText(_lastSetText);
		}

		private void UnsetText()
		{
			ClickGUI.SurrenderTooltipText(_lastSetText);
			_lastSetText = "";
		}
	}
	public class Colorizer : MonoBehaviour
	{
		private TextMeshProUGUI? _textComp;

		private Image? _imageComp;

		private Color? _overrideColor;

		private Color? _overrideNormalColor;

		private bool _highlighted;

		public Color HighlightColor
		{
			get
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				return (Color)(((??)_overrideColor) ?? ThornModule.Instance.Accent.Value.GetCurrentColor());
			}
			set
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_imageComp == (Object)null)
				{
					_overrideColor = value;
				}
			}
		}

		public Color NormalColor
		{
			get
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				return (Color)(((??)_overrideNormalColor) ?? Color.white);
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				_overrideNormalColor = value;
			}
		}

		public bool Highlighted
		{
			get
			{
				return _highlighted;
			}
			set
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: 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_0048: Unknown result type (might be due to invalid IL or missing references)
				_highlighted = value;
				Color color = (value ? HighlightColor : NormalColor);
				if ((Object)(object)_textComp != (Object)null)
				{
					((Graphic)_textComp).color = color;
				}
				else if ((Object)(object)_imageComp != (Object)null)
				{
					((Graphic)_imageComp).color = color;
				}
			}
		}

		private void Start()
		{
			_textComp = ((Component)this).GetComponent<TextMeshProUGUI>();
			_imageComp = ((Component)this).GetComponent<Image>();
			if (!_overrideColor.HasValue)
			{
				ThornModule.Instance.Accent.OnChanged += UpdateHighlight;
			}
			UpdateHighlight();
		}

		private void OnEnable()
		{
			ThornModule.Instance.Accent.OnChanged += UpdateHighlight;
			ThornModule.Instance.Accent.OnEffectiveValueChanged += UpdateHighlight;
		}

		private void OnDisable()
		{
			ThornModule.Instance.Accent.OnChanged -= UpdateHighlight;
			ThornModule.Instance.Accent.OnEffectiveValueChanged -= UpdateHighlight;
		}

		private void OnDestroy()
		{
			if (!_overrideColor.HasValue)
			{
				ThornModule.Instance.Accent.OnChanged -= UpdateHighlight;
			}
		}

		private void UpdateHighlight()
		{
			Highlighted = _highlighted;
		}
	}
	internal class ColorSettingController : MonoBehaviour
	{
		public Setting<Color>? TargetSetting;

		private Image? _colorPreview;

		private TMP_InputField? _hexInput;

		private Slider?[] _sliders;

		private TMP_InputField?[] _valueInputs;

		private void Start()
		{
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting == null)
			{
				return;
			}
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/PreviewColumn/ColorBorder/ColorPreview");
			_colorPreview = ((obj != null) ? obj.GetComponent<Image>() : null);
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/PreviewColumn/HexInput");
			_hexInput = ((obj2 != null) ? obj2.GetComponent<TMP_InputField>() : null);
			Slider[] array = new Slider[4];
			GameObject obj3 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Red/Slider");
			array[0] = ((obj3 != null) ? obj3.GetComponent<Slider>() : null);
			GameObject obj4 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Green/Slider");
			array[1] = ((obj4 != null) ? obj4.GetComponent<Slider>() : null);
			GameObject obj5 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Blue/Slider");
			array[2] = ((obj5 != null) ? obj5.GetComponent<Slider>() : null);
			GameObject obj6 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Alpha/Slider");
			array[3] = ((obj6 != null) ? obj6.GetComponent<Slider>() : null);
			_sliders = (Slider?[])(object)array;
			TMP_InputField[] array2 = new TMP_InputField[4];
			GameObject obj7 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Red/Input");
			array2[0] = ((obj7 != null) ? obj7.GetComponent<TMP_InputField>() : null);
			GameObject obj8 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Green/Input");
			array2[1] = ((obj8 != null) ? obj8.GetComponent<TMP_InputField>() : null);
			GameObject obj9 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Blue/Input");
			array2[2] = ((obj9 != null) ? obj9.GetComponent<TMP_InputField>() : null);
			GameObject obj10 = UIUtils.FindRecursive(((Component)this).gameObject, "PickerRow/ValueColumn/Alpha/Input");
			array2[3] = ((obj10 != null) ? obj10.GetComponent<TMP_InputField>() : null);
			_valueInputs = (TMP_InputField?[])(object)array2;
			if ((Object)(object)_hexInput != (Object)null)
			{
				((UnityEvent<string>)(object)_hexInput.onEndEdit).AddListener((UnityAction<string>)TrySaveNewHex);
				ComponentExtensions.GetOrAddComponent<InputFocusGrab>((Component)(object)_hexInput);
			}
			for (int i = 0; i < _sliders.Length; i++)
			{
				Slider val = _sliders[i];
				if ((Object)(object)val != (Object)null)
				{
					val.minValue = 0f;
					val.maxValue = 1f;
					int i2 = i;
					((UnityEvent<float>)(object)val.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
					{
						TrySaveNewValue(value, i2);
					});
				}
			}
			for (int num = 0; num < _valueInputs.Length; num++)
			{
				TMP_InputField val2 = _valueInputs[num];
				ComponentExtensions.GetOrAddComponent<InputFocusGrab>((Component)(object)val2);
				if (!((Object)(object)val2 != (Object)null))
				{
					continue;
				}
				int i3 = num;
				((UnityEvent<string>)(object)val2.onValueChanged).AddListener((UnityAction<string>)delegate(string s)
				{
					if (int.TryParse(s, out var result))
					{
						TrySaveNewValue((float)result / 255f, i3);
					}
				});
			}
			Setting<Color>? targetSetting = TargetSetting;
			targetSetting.OnValueChanged = (Action<Color>)Delegate.Combine(targetSetting.OnValueChanged, new Action<Color>(UpdateDisplay));
			UpdateDisplay(TargetSetting.Value);
		}

		private void TrySaveNewHex(string hex)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_0039: 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_0055: 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)
			if (TargetSetting != null)
			{
				if (!hex.StartsWith("#"))
				{
					hex = "#" + hex;
				}
				Color val = default(Color);
				if (ColorUtility.TryParseHtmlString(hex, ref val))
				{
					TargetSetting.Value = new Color(val.r, val.g, val.b, TargetSetting.Value.a);
				}
				else
				{
					TargetSetting.Value = new Color(TargetSetting.Value.r, TargetSetting.Value.g, TargetSetting.Value.b, TargetSetting.Value.a);
				}
				UpdateDisplay(TargetSetting.Value);
			}
		}

		private void TrySaveNewValue(float value, int index)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting != null)
			{
				float[] source = new float[4] { 0f, 1f, 2f, 3f };
				source = source.Select((float i) => ((int)i != index) ? ColorUtils.GetValues(TargetSetting.Value)[(int)i] : value).ToArray();
				TargetSetting.Value = new Color(source[0], source[1], source[2], source[3]);
			}
		}

		private void OnDestroy()
		{
			if (TargetSetting != null)
			{
				Setting<Color>? targetSetting = TargetSetting;
				targetSetting.OnValueChanged = (Action<Color>)Delegate.Remove(targetSetting.OnValueChanged, new Action<Color>(UpdateDisplay));
			}
		}

		private void UpdateDisplay(Color col)
		{
			//IL_0023: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting == null)
			{
				return;
			}
			if ((Object)(object)_colorPreview != (Object)null)
			{
				((Graphic)_colorPreview).color = TargetSetting.Value;
			}
			if ((Object)(object)_hexInput != (Object)null)
			{
				_hexInput.SetTextWithoutNotify("#" + ColorUtility.ToHtmlStringRGB(col));
			}
			float[] array = new float[4] { col.r, col.g, col.b, col.a };
			for (int i = 0; i < _sliders.Length; i++)
			{
				Slider val = _sliders[i];
				if ((Object)(object)val != (Object)null)
				{
					val.SetValueWithoutNotify(array[i]);
				}
			}
			for (int j = 0; j < _valueInputs.Length; j++)
			{
				TMP_InputField val2 = _valueInputs[j];
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetTextWithoutNotify($"{(int)(255f * array[j])}");
				}
			}
			UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
		}
	}
	internal class ConfigurableWindowController : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__NavigateBack;
		}

		private bool _doneSetup;

		public bool IsPopup;

		public Configurable? TargetConfigurable;

		private void Start()
		{
			SetupStuff();
		}

		public void SetupStuff()
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			if (_doneSetup)
			{
				return;
			}
			_doneSetup = true;
			if (TargetConfigurable == null)
			{
				return;
			}
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton/TitleIcon");
			Image val = ((obj != null) ? obj.GetComponent<Image>() : null);
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleName");
			TextMeshProUGUI obj3 = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
			if (TargetConfigurable is ThornClient.Core.Module module && (Object)(object)val != (Object)null)
			{
				val.sprite = module.Icon;
			}
			((TMP_Text)obj3).text = TargetConfigurable.Name;
			GameObject obj4 = UIUtils.FindRecursive(((Component)this).gameObject, "Header");
			if (obj4 != null)
			{
				obj4.AddComponent<TitlebarDragIgnoreLayoutHandler>();
			}
			GameObject obj5 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton");
			Button val2 = ((obj5 != null) ? obj5.GetComponent<Button>() : null);
			((Selectable)UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton").GetComponent<Button>()).interactable = IsPopup;
			GameObject obj6 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton/BackIcon");
			if (obj6 != null)
			{
				obj6.SetActive(IsPopup);
			}
			if (IsPopup)
			{
				ButtonClickedEvent onClick = val2.onClick;
				object obj7 = <>O.<0>__NavigateBack;
				if (obj7 == null)
				{
					UnityAction val3 = ClickGUI.NavigateBack;
					<>O.<0>__NavigateBack = val3;
					obj7 = (object)val3;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj7);
			}
			Transform transform = UIUtils.FindRecursive(((Component)this).gameObject, "Scroll View/Viewport/Content/Modules").transform;
			((TMP_Text)UIUtils.FindRecursive(Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "ModuleDescription"), transform), "DescText").GetComponent<TextMeshProUGUI>()).text = TargetConfigurable.Description;
			if (TargetConfigurable.HasToggling)
			{
				Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "EnabledButton"), transform).AddComponent<EnabledButtonController>().Configurable = TargetConfigurable;
			}
			if (TargetConfigurable is HudModule hudModule)
			{
				HudElementPositioningController hudElementPositioningController = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "RemoteDrag"), transform).AddComponent<HudElementPositioningController>();
				hudElementPositioningController.TargetModule = hudModule;
				if ((Object)(object)hudModule.UIElement != (Object)null)
				{
					ref RectTransform target = ref ((FreeMoveDragHandler)hudElementPositioningController).target;
					Transform transform2 = hudModule.UIElement.transform;
					target = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
				}
			}
			Populate(transform, TargetConfigurable.Elements);
			UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
		}

		internal static void Populate(Transform parent, IEnumerable<IConfigurableElement> elements)
		{
			foreach (IConfigurableElement element in elements)
			{
				if (UICreatorManager.TryGetUICreator(element.GetType(), out IConfigurableUICreator creator) && creator != null)
				{
					GameObject val = creator.CreateUI(element);
					GameObject val2 = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "SettingRowWrapper"), parent);
					if (element is Setting targetSetting)
					{
						val2.AddComponent<SettingRowController>().TargetSetting = targetSetting;
					}
					if (val != null)
					{
						val.transform.SetParent(val2.transform, false);
					}
					if (!(element is ConfigHeader) && (Object)(object)val != (Object)null)
					{
						val.AddComponent<SettingDescriptionController>().TargetSetting = element;
					}
					UIUtils.UnfuckLayoutHack(val2);
					if (element.Hints?.Hidden == true)
					{
						val2.SetActive(false);
					}
				}
			}
		}
	}
	internal class ConnectedButtonGroupSettingController : MonoBehaviour
	{
		private Type? _enumType;

		private GameObject? _btnRow;

		private string[] _enumNames = Array.Empty<string>();

		private readonly List<(Image image, TMP_Text text)> _cachedButtons = new List<(Image, TMP_Text)>();

		public Setting? TargetSetting { get; set; }

		private void Start()
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			if (TargetSetting == null)
			{
				return;
			}
			object value = TargetSetting.GetValue();
			_enumType = value.GetType();
			if (!_enumType.IsEnum)
			{
				Plugin.Log.LogError((object)("[EnumSettingController] Setting " + TargetSetting.Name + " is not an enum!"));
				return;
			}
			TargetSetting.OnChanged += UpdateDisplay;
			_btnRow = UIUtils.FindRecursive(((Component)this).gameObject, "ButtonRow");
			if ((Object)(object)_btnRow != (Object)null)
			{
				_enumNames = Enum.GetNames(_enumType);
				_cachedButtons.Clear();
				for (int i = 0; i < _enumNames.Length; i++)
				{
					GameObject obj = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "ConnectedChoiceButton"), _btnRow.transform);
					GameObject obj2 = UIUtils.FindRecursive(obj, "Text");
					TMP_Text val = ((obj2 != null) ? obj2.GetComponent<TMP_Text>() : null);
					Image component = obj.GetComponent<Image>();
					if (val != null)
					{
						val.SetText(Substitute(_enumNames[i]), true);
					}
					_cachedButtons.Add((component, val));
					int i2 = i;
					((UnityEvent)obj.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
					{
						TargetSetting.SetValue(Enum.Parse(_enumType, _enumNames[i2]));
					});
				}
			}
			UpdateDisplay();
		}

		private void OnEnable()
		{
			ThornModule.Instance.Accent.OnChanged += UpdateDisplay;
			ThornModule.Instance.Accent.OnEffectiveValueChanged += UpdateDisplay;
		}

		private void OnDisable()
		{
			ThornModule.Instance.Accent.OnChanged -= UpdateDisplay;
			ThornModule.Instance.Accent.OnEffectiveValueChanged -= UpdateDisplay;
		}

		private string Substitute(string enumName)
		{
			if (TargetSetting == null || TargetSetting.Hints == null || TargetSetting.Hints.EnumSubstitutions == null)
			{
				return enumName;
			}
			return TargetSetting.Hints.EnumSubstitutions.GetValueOrDefault(enumName, enumName);
		}

		private void UpdateDisplay()
		{
			//IL_009a: 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_009f: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting == null || _enumType == null || _cachedButtons.Count == 0)
			{
				return;
			}
			string text = TargetSetting.GetValue().ToString();
			int count = _cachedButtons.Count;
			for (int i = 0; i < count; i++)
			{
				(Image image, TMP_Text text) tuple = _cachedButtons[i];
				Image item = tuple.image;
				TMP_Text item2 = tuple.text;
				bool flag = _enumNames[i] == text;
				bool atLeft = i == 0;
				bool atRight = i == count - 1;
				Color val = (flag ? ThornModule.Instance.Accent.Value.GetCurrentColor() : Color.white);
				Color val2 = (flag ? Color.black : Color.white);
				item.sprite = GetSprite(atLeft, atRight, flag);
				if (((Graphic)item).color != val)
				{
					((Graphic)item).color = val;
				}
				if (((Graphic)item2).color != val2)
				{
					((Graphic)item2).color = val2;
				}
			}
			UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
		}

		private void OnDestroy()
		{
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged -= UpdateDisplay;
			}
		}

		public static Sprite GetSprite(bool atLeft, bool atRight, bool active)
		{
			string assetName = ((atLeft || atRight) ? "Round_" : "") + (active ? "Fill" : "Border") + "Large" + (atLeft ? "Left" : (atRight ? "Right" : ""));
			return AssetManager.Get<Sprite>(ClickGUI.BundleKey, assetName);
		}
	}
	internal class DropdownSettingController : MonoBehaviour
	{
		private TMP_Dropdown? _dropdown;

		private Type? _enumType;

		public Setting? TargetSetting { get; set; }

		private void Start()
		{
			if (TargetSetting == null)
			{
				return;
			}
			object value = TargetSetting.GetValue();
			_enumType = value.GetType();
			if (!_enumType.IsEnum)
			{
				Plugin.Log.LogError((object)("[EnumSettingController] Setting " + TargetSetting.Name + " is not an enum!"));
				return;
			}
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Dropdown");
			_dropdown = ((obj != null) ? obj.GetComponent<TMP_Dropdown>() : null);
			if ((Object)(object)_dropdown != (Object)null)
			{
				List<string> list = Enum.GetNames(_enumType).Select(Substitute).ToList();
				_dropdown.ClearOptions();
				_dropdown.AddOptions(list);
				((UnityEvent<int>)(object)_dropdown.onValueChanged).AddListener((UnityAction<int>)OnDropdownValueChanged);
			}
			UpdateDisplay();
			TargetSetting.OnChanged += UpdateDisplay;
		}

		private string Substitute(string enumName)
		{
			if (TargetSetting == null || TargetSetting.Hints == null || TargetSetting.Hints.EnumSubstitutions == null)
			{
				return enumName;
			}
			return TargetSetting.Hints.EnumSubstitutions.GetValueOrDefault(enumName, enumName);
		}

		private void UpdateDisplay()
		{
			if (TargetSetting != null && !((Object)(object)_dropdown == (Object)null) && !(_enumType == null))
			{
				object value = TargetSetting.GetValue();
				int num = Array.IndexOf<string>(Enum.GetNames(_enumType), value.ToString());
				if (num >= 0)
				{
					_dropdown.value = num;
					_dropdown.RefreshShownValue();
				}
			}
		}

		private void OnDropdownValueChanged(int index)
		{
			string text = _dropdown.options[index].text;
			object value = Enum.Parse(_enumType, text);
			TargetSetting?.SetValue(value);
		}

		private void OnDestroy()
		{
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged -= UpdateDisplay;
			}
			if ((Object)(object)_dropdown != (Object)null)
			{
				((UnityEvent<int>)(object)_dropdown.onValueChanged).RemoveListener((UnityAction<int>)OnDropdownValueChanged);
			}
		}
	}
	internal class EnabledButtonController : MonoBehaviour
	{
		public Configurable? Configurable;

		private TextMeshProUGUI? _textComp;

		private Image? _buttonImageComp;

		private Colorizer? _colorizer;

		private void Start()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if (Configurable != null)
			{
				((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener(new UnityAction(ToggleIt));
				GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Text");
				_textComp = ((obj != null) ? obj.GetComponent<TextMeshProUGUI>() : null);
				_buttonImageComp = ((Component)this).gameObject.GetComponent<Image>();
				_colorizer = GameObjectExtensions.GetOrAddComponent<Colorizer>(((Component)this).gameObject);
				Configurable.OnToggleStateChanged += UpdateAppearance;
				UpdateAppearance(Configurable.IsEnabled);
			}
		}

		private void OnDestroy()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if (Configurable != null)
			{
				((UnityEvent)((Component)this).GetComponent<Button>().onClick).RemoveListener(new UnityAction(ToggleIt));
				Configurable.OnToggleStateChanged -= UpdateAppearance;
			}
		}

		private void ToggleIt()
		{
			Configurable?.Toggle();
		}

		private void UpdateAppearance(bool isEnabled)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_textComp != (Object)null)
			{
				((TMP_Text)_textComp).text = (isEnabled ? "Enabled" : "Disabled");
				((Graphic)_textComp).color = (isEnabled ? Color.black : Color.white);
			}
			if ((Object)(object)_buttonImageComp != (Object)null)
			{
				_buttonImageComp.sprite = AssetManager.Get<Sprite>(ClickGUI.BundleKey, isEnabled ? "Round_FillLarge" : "Round_BorderLarge");
			}
			if ((Object)(object)_colorizer != (Object)null)
			{
				_colorizer.Highlighted = isEnabled;
			}
		}
	}
	internal class EnemyListController : MonoBehaviour
	{
		private bool _doneSetup;

		public Setting<EnemyList>? TargetList;

		private Transform? _falseList;

		private Transform? _trueList;

		private void Start()
		{
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Header");
			if (obj != null)
			{
				obj.AddComponent<TitlebarDragIgnoreLayoutHandler>();
			}
			SetupModules();
		}

		public void SetupModules()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			if (_doneSetup)
			{
				return;
			}
			_doneSetup = true;
			if (TargetList == null)
			{
				return;
			}
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleName");
			TextMeshProUGUI obj2 = ((obj != null) ? obj.GetComponent<TextMeshProUGUI>() : null);
			if (obj2 != null)
			{
				((TMP_Text)obj2).SetText(TargetList.Name, true);
			}
			GameObject obj3 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton");
			Button obj4 = ((obj3 != null) ? obj3.GetComponent<Button>() : null);
			if (obj4 != null)
			{
				((UnityEvent)obj4.onClick).AddListener((UnityAction)delegate
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				});
			}
			GameObject obj5 = UIUtils.FindRecursive(((Component)this).gameObject, "Columns/FalseScrollView/Viewport/Content");
			_falseList = ((obj5 != null) ? obj5.transform : null);
			GameObject obj6 = UIUtils.FindRecursive(((Component)this).gameObject, "Columns/TrueScrollView/Viewport/Content");
			_trueList = ((obj6 != null) ? obj6.transform : null);
			PopulateLists();
			Setting<EnemyList>? targetList = TargetList;
			targetList.OnValueChanged = (Action<EnemyList>)Delegate.Combine(targetList.OnValueChanged, (Action<EnemyList>)delegate
			{
				PopulateLists();
			});
		}

		private void OnDestroy()
		{
			if (TargetList != null)
			{
				Setting<EnemyList>? targetList = TargetList;
				targetList.OnValueChanged = (Action<EnemyList>)Delegate.Remove(targetList.OnValueChanged, (Action<EnemyList>)delegate
				{
					PopulateLists();
				});
			}
		}

		private unsafe void PopulateLists()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Expected O, but got Unknown
			if (TargetList == null || (Object)(object)_falseList == (Object)null || (Object)(object)_trueList == (Object)null)
			{
				return;
			}
			foreach (Transform @false in _falseList)
			{
				Object.Destroy((Object)(object)((Component)@false).gameObject);
			}
			foreach (Transform @true in _trueList)
			{
				Object.Destroy((Object)(object)((Component)@true).gameObject);
			}
			foreach (EnemyType enemyType in ((EnemyType[])Enum.GetValues(typeof(EnemyType))).OrderBy((EnemyType e) => ((object)(*(EnemyType*)(&e))/*cast due to .constrained prefix*/).ToString()))
			{
				bool flag = TargetList.Value.Includes(enemyType);
				Transform val = (flag ? _trueList : _falseList);
				GameObject obj = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>(ClickGUI.BundleKey, "EnemyListItem"), val);
				UIUtils.FindRecursive(obj, "Icon").AddComponent<EnemyIconController>().enemyType = enemyType;
				((TMP_Text)UIUtils.FindRecursive(obj, "Name").GetComponent<TextMeshProUGUI>()).text = ((object)Unsafe.As<EnemyType, EnemyType>(ref enemyType)/*cast due to .constrained prefix*/).ToString();
				UIUtils.FindRecursive(obj, "ToggleButton/Icon").GetComponent<Image>().sprite = AssetManager.Get<Sprite>(ClickGUI.BundleKey, flag ? "minus" : "plus");
				((UnityEvent)UIUtils.FindRecursive(obj, "ToggleButton").GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					OnItemClick(enemyType);
				});
				UIUtils.UnfuckLayoutHack(obj);
			}
			UIUtils.UnfuckLayoutHack(((Component)_falseList).gameObject);
			UIUtils.UnfuckLayoutHack(((Component)_trueList).gameObject);
			UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
		}

		private void OnItemClick(EnemyType enemyType)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (TargetList != null)
			{
				EnemyList enemyList = TargetList.Value.Clone();
				enemyList.Toggle(enemyType);
				TargetList.Value = enemyList;
			}
		}
	}
	internal class EnemyListSettingController : MonoBehaviour
	{
		public Setting<EnemyList>? TargetSetting;

		private TextMeshProUGUI? _text;

		private void Start()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if (TargetSetting != null)
			{
				((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener(new UnityAction(OpenList));
				GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Name");
				_text = ((obj != null) ? obj.GetComponent<TextMeshProUGUI>() : null);
				Setting<EnemyList>? targetSetting = TargetSetting;
				targetSetting.OnValueChanged = (Action<EnemyList>)Delegate.Combine(targetSetting.OnValueChanged, new Action<EnemyList>(UpdateText));
				UpdateText(TargetSetting.Value);
				ExecutionUtils.RunNextFrame((Action)delegate
				{
					UpdateText(TargetSetting.Value);
				});
			}
		}

		private void UpdateText(EnemyList elist)
		{
			if ((Object)(object)_text != (Object)null && TargetSetting != null)
			{
				((TMP_Text)_text).text = $"{TargetSetting.Name} ({elist.Count()})";
			}
		}

		private void OnDestroy()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			if (TargetSetting != null)
			{
				Setting<EnemyList>? targetSetting = TargetSetting;
				targetSetting.OnValueChanged = (Action<EnemyList>)Delegate.Remove(targetSetting.OnValueChanged, new Action<EnemyList>(UpdateText));
			}
			Button component = ((Component)this).GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				((UnityEvent)component.onClick).RemoveListener(new UnityAction(OpenList));
			}
		}

		private void OpenList()
		{
			GameObject val = CreateConfigPanel(TargetSetting);
			if ((Object)(object)val != (Object)null)
			{
				ClickGUI.SpawnContent(val);
			}
			ClickGUI.SurrenderTooltipText(TargetSetting?.Description ?? "");
		}

		private GameObject? CreateConfigPanel(Setting<EnemyList>? setting)
		{
			GameObject val = AssetManager.Get<GameObject>(ClickGUI.BundleKey, "EnemyList");
			if ((Object)(object)val == (Object)null || setting == null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObjectExtensions.GetOrAddComponent<EnemyListController>(val2).TargetList = setting;
			return val2;
		}
	}
	public class EnhancedColorSettingController : MonoBehaviour
	{
		public Setting<EnhancedColor>? TargetSetting;

		private Button? _btn;

		private GameObject? _panel;

		private Image? _preview;

		private void Start()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			_btn = ((Component)this).GetComponent<Button>();
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "ValueRow/ColorBorder/ColorPreview");
			_preview = ((obj != null) ? obj.GetComponent<Image>() : null);
			if ((Object)(object)_btn != (Object)null)
			{
				((UnityEvent)_btn.onClick).AddListener(new UnityAction(OpenWindow));
			}
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged += UpdatePreview;
				TargetSetting.OnEffectiveValueChanged += UpdatePreview;
			}
			UpdatePreview();
		}

		private void OnDestroy()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if ((Object)(object)_btn != (Object)null)
			{
				((UnityEvent)_btn.onClick).RemoveListener(new UnityAction(OpenWindow));
			}
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged -= UpdatePreview;
				TargetSetting.OnEffectiveValueChanged -= UpdatePreview;
			}
		}

		private void UpdatePreview()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_preview == (Object)null) && TargetSetting != null)
			{
				((Graphic)_preview).color = TargetSetting.Value.GetCurrentColor();
			}
		}

		private void OpenWindow()
		{
			if (!((Object)(object)_panel != (Object)null))
			{
				_panel = CreateSelectionPanel(TargetSetting);
				if (!((Object)(object)_panel == (Object)null))
				{
					ClickGUI.SpawnContent(_panel);
					ClickGUI.SurrenderTooltipText(TargetSetting?.Description ?? "");
				}
			}
		}

		private GameObject? CreateSelectionPanel(Setting<EnhancedColor>? setting)
		{
			GameObject val = AssetManager.Get<GameObject>(ClickGUI.BundleKey, "EnhancedColorWindow");
			if ((Object)(object)val == (Object)null || setting == null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObjectExtensions.GetOrAddComponent<EnhancedColorWindowController>(val2).TargetSetting = setting;
			return val2;
		}
	}
	internal class EnhancedColorWindowController : MonoBehaviour
	{
		public Setting<EnhancedColor>? TargetSetting;

		private const float InputMax = 255f;

		private const int NumSliders = 4;

		private GameObject? _body;

		private Slider?[] _sliders;

		private TMP_InputField?[] _valueInputs;

		private Image? _preview;

		private TMP_InputField? _hexInput;

		private GameObject?[] _modeButtons;

		private Image?[] _modeBorders;

		private Image?[] _modeIcons;

		private TextMeshProUGUI?[] _modeTexts;

		private readonly string[] SliderPaths = new string[4] { "ActualColorSettings/ValueColumn/Red/Slider", "ActualColorSettings/ValueColumn/Green/Slider", "ActualColorSettings/ValueColumn/Blue/Slider", "ActualColorSettings/ValueColumn/Alpha/Slider" };

		private readonly string[] InputPaths = new string[4] { "ActualColorSettings/ValueColumn/Red/Input", "ActualColorSettings/ValueColumn/Green/Input", "ActualColorSettings/ValueColumn/Blue/Input", "ActualColorSettings/ValueColumn/Alpha/Input" };

		private readonly string[] ModeButtonPaths = new string[2] { "ActualColorSettings/ModeRow/Static", "ActualColorSettings/ModeRow/HueShift" };

		private readonly EnhancedColorMode[] EnhancedColorModes = new EnhancedColorMode[2]
		{
			EnhancedColorMode.Static,
			EnhancedColorMode.HuePulse
		};

		private readonly string[] EnhancedColorTooltips = new string[2] { "Normal single color mode", "Shifts color hue in OKLCH color space.\nTIP: Make sure the base color is not fully white/black, as colors will pulse around same perceptual lightness" };

		private static JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
		{
			Converters = { (JsonConverter)(object)new EnhancedColorJsonConverter() },
			Formatting = (Formatting)1
		};

		private void Start()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Expected O, but got Unknown
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Expected O, but got Unknown
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Expected O, but got Unknown
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Expected O, but got Unknown
			if (TargetSetting == null)
			{
				return;
			}
			_body = UIUtils.FindRecursive(((Component)this).gameObject, "Scroll View/Viewport/Content/Modules");
			if ((Object)(object)_body == (Object)null)
			{
				return;
			}
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Header");
			if (obj != null)
			{
				obj.AddComponent<TitlebarDragIgnoreLayoutHandler>();
			}
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleName");
			TextMeshProUGUI obj3 = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
			if (obj3 != null)
			{
				((TMP_Text)obj3).SetText(TargetSetting.Name, true);
			}
			GameObject obj4 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton");
			Button val = ((obj4 != null) ? obj4.GetComponent<Button>() : null);
			if ((Object)(object)val != (Object)null)
			{
				((Selectable)val).interactable = true;
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				});
			}
			_sliders = SliderPaths.Select(delegate(string path)
			{
				GameObject obj14 = UIUtils.FindRecursive(_body, path);
				return (obj14 == null) ? null : obj14.GetComponent<Slider>();
			}).ToArray();
			_valueInputs = InputPaths.Select(delegate(string path)
			{
				GameObject obj14 = UIUtils.FindRecursive(_body, path);
				return (obj14 == null) ? null : obj14.GetComponent<TMP_InputField>();
			}).ToArray();
			for (int num = 0; num < 4; num++)
			{
				Slider val2 = _sliders[num];
				if ((Object)(object)val2 != (Object)null)
				{
					val2.minValue = 0f;
					val2.maxValue = 1f;
					int i1 = num;
					((UnityEvent<float>)(object)val2.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
					{
						TrySaveNewValue(value, i1);
					});
				}
			}
			for (int num2 = 0; num2 < 4; num2++)
			{
				TMP_InputField val3 = _valueInputs[num2];
				if (!((Object)(object)val3 != (Object)null))
				{
					continue;
				}
				ComponentExtensions.GetOrAddComponent<InputFocusGrab>((Component)(object)val3);
				int i2 = num2;
				((UnityEvent<string>)(object)val3.onEndEdit).AddListener((UnityAction<string>)delegate(string str)
				{
					if (int.TryParse(str, out var result))
					{
						TrySaveNewValue((float)result / 255f, i2);
					}
				});
			}
			GameObject obj5 = UIUtils.FindRecursive(_body, "ActualColorSettings/ModeRow/PreviewColumn/HexInput");
			_hexInput = ((obj5 != null) ? obj5.GetComponent<TMP_InputField>() : null);
			GameObject obj6 = UIUtils.FindRecursive(_body, "ActualColorSettings/ModeRow/PreviewColumn/ColorBorder/ColorPreview");
			_preview = ((obj6 != null) ? obj6.GetComponent<Image>() : null);
			if ((Object)(object)_hexInput != (Object)null)
			{
				ComponentExtensions.GetOrAddComponent<InputFocusGrab>((Component)(object)_hexInput);
				((UnityEvent<string>)(object)_hexInput.onEndEdit).AddListener((UnityAction<string>)TrySaveNewHex);
			}
			_modeButtons = ModeButtonPaths.Select((string path) => UIUtils.FindRecursive(_body, path)).ToArray();
			_modeBorders = _modeButtons.Select((GameObject gob) => (gob == null) ? null : gob.GetComponent<Image>()).ToArray();
			_modeIcons = ((IEnumerable<GameObject>)_modeButtons).Select((Func<GameObject, Image>)delegate(GameObject gob)
			{
				if (gob == null)
				{
					return (Image)null;
				}
				GameObject obj14 = UIUtils.FindRecursive(gob, "Icon");
				return (obj14 == null) ? null : obj14.GetComponent<Image>();
			}).ToArray();
			_modeTexts = ((IEnumerable<GameObject>)_modeButtons).Select((Func<GameObject, TextMeshProUGUI>)delegate(GameObject gob)
			{
				if (gob == null)
				{
					return (TextMeshProUGUI)null;
				}
				GameObject obj14 = UIUtils.FindRecursive(gob, "Text");
				return (obj14 == null) ? null : obj14.GetComponent<TextMeshProUGUI>();
			}).ToArray();
			for (int num3 = 0; num3 < EnhancedColorModes.Length; num3++)
			{
				EnhancedColorMode mode = EnhancedColorModes[num3];
				GameObject? obj7 = _modeButtons[num3];
				Button obj8 = ((obj7 != null) ? obj7.GetComponent<Button>() : null);
				if (obj8 != null)
				{
					((UnityEvent)obj8.onClick).AddListener((UnityAction)delegate
					{
						//IL_001b: Unknown result type (might be due to invalid IL or missing references)
						TargetSetting.Value = new EnhancedColor(TargetSetting.Value.BaseColor, mode);
					});
				}
				Image? obj9 = _modeBorders[num3];
				ClickGUITooltipHandler clickGUITooltipHandler = ((obj9 != null) ? ComponentExtensions.GetOrAddComponent<ClickGUITooltipHandler>((Component)(object)obj9) : null);
				if ((Object)(object)clickGUITooltipHandler != (Object)null)
				{
					clickGUITooltipHandler.Text = EnhancedColorTooltips[num3];
				}
			}
			GameObject obj10 = UIUtils.FindRecursive(_body, "ActionsRow/Reset");
			Button val4 = ((obj10 != null) ? obj10.GetComponent<Button>() : null);
			GameObject obj11 = UIUtils.FindRecursive(_body, "ActionsRow/Copy");
			Button val5 = ((obj11 != null) ? obj11.GetComponent<Button>() : null);
			GameObject obj12 = UIUtils.FindRecursive(_body, "ActionsRow/Paste");
			Button obj13 = ((obj12 != null) ? obj12.GetComponent<Button>() : null);
			if (val4 != null)
			{
				((UnityEvent)val4.onClick).AddListener((UnityAction)delegate
				{
					TargetSetting?.Reset();
				});
			}
			if (val5 != null)
			{
				((UnityEvent)val5.onClick).AddListener(new UnityAction(ClipboardCopy));
			}
			if (obj13 != null)
			{
				((UnityEvent)obj13.onClick).AddListener(new UnityAction(ClipboardPaste));
			}
			TargetSetting.OnChanged += UpdateAll;
			TargetSetting.OnEffectiveValueChanged += UpdatePreview;
			ThornModule.Instance.Accent.OnChanged += UpdateModeSelection;
			ThornModule.Instance.Accent.OnEffectiveValueChanged += UpdateModeSelection;
			UpdateAll();
		}

		private void OnDestroy()
		{
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged -= UpdateAll;
				TargetSetting.OnEffectiveValueChanged -= UpdatePreview;
			}
			ThornModule.Instance.Accent.OnChanged -= UpdateModeSelection;
			ThornModule.Instance.Accent.OnEffectiveValueChanged -= UpdateModeSelection;
		}

		private static float GetSafeColorValue(float value)
		{
			if (!float.IsNaN(value) && !float.IsInfinity(value))
			{
				return value;
			}
			return 0f;
		}

		private void UpdateAll()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting == null)
			{
				return;
			}
			EnhancedColor value = TargetSetting.Value;
			float[] array = new float[4] { value.r, value.g, value.b, value.a };
			for (int i = 0; i < 4; i++)
			{
				Slider val = _sliders[i];
				if ((Object)(object)val != (Object)null)
				{
					val.SetValueWithoutNotify(array[i]);
				}
				TMP_InputField val2 = _valueInputs[i];
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetTextWithoutNotify($"{Mathf.RoundToInt(array[i] * 255f)}");
				}
			}
			UpdatePreview();
			if ((Object)(object)_hexInput != (Object)null)
			{
				_hexInput.SetTextWithoutNotify("#" + ColorUtility.ToHtmlStringRGBA(TargetSetting.Value.BaseColor));
			}
			UpdateModeSelection();
		}

		private void UpdatePreview()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting != null && !((Object)(object)_preview == (Object)null))
			{
				((Graphic)_preview).color = TargetSetting.Value.GetCurrentColor();
			}
		}

		private void UpdateModeSelection()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			for (int i = 0; i < EnhancedColorModes.Length; i++)
			{
				Image val = _modeBorders[i];
				Image val2 = _modeIcons[i];
				TextMeshProUGUI val3 = _modeTexts[i];
				Color color = ((EnhancedColorModes[i] == TargetSetting.Value.Mode) ? ThornModule.Instance.Accent.Value.GetCurrentColor() : Color.white);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null))
				{
					((Graphic)val).color = color;
					((Graphic)val2).color = color;
					((Graphic)val3).color = color;
				}
			}
		}

		private void TrySaveNewHex(string hex)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting == null)
			{
				return;
			}
			if (!hex.StartsWith("#"))
			{
				hex = "#" + hex;
			}
			EnhancedColor value = TargetSetting.Value;
			EnhancedColorMode mode = value.Mode;
			float a = value.a;
			Color val = default(Color);
			if (ColorUtility.TryParseHtmlString(hex, ref val))
			{
				if (hex.Length == 8)
				{
					TargetSetting.Value = new EnhancedColor(val, mode);
				}
				else
				{
					TargetSetting.Value = new EnhancedColor(val.r, val.g, val.b, a, mode);
				}
			}
			else
			{
				TargetSetting.Value = new EnhancedColor(value.r, value.g, value.b, a, mode);
			}
			UpdateAll();
		}

		private void ClipboardCopy()
		{
			if (TargetSetting != null)
			{
				GUIUtility.systemCopyBuffer = JsonConvert.SerializeObject((object)TargetSetting.Value, _serializerSettings);
			}
		}

		private void ClipboardPaste()
		{
			if (TargetSetting == null)
			{
				return;
			}
			try
			{
				EnhancedColor enhancedColor = JsonConvert.DeserializeObject<EnhancedColor>(GUIUtility.systemCopyBuffer, (JsonConverter[])(object)new JsonConverter[1] { (JsonConverter)new EnhancedColorJsonConverter() });
				if (enhancedColor != null)
				{
					TargetSetting.Value = enhancedColor;
				}
			}
			catch (Exception)
			{
			}
		}

		private void TrySaveNewValue(float value, int index)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (TargetSetting != null && index <= 3 && !float.IsNaN(value) && !float.IsInfinity(value))
			{
				EnhancedColor value2 = TargetSetting.Value;
				float[] array = new float[4] { value2.r, value2.g, value2.b, value2.a };
				array[index] = value;
				Color color = default(Color);
				((Color)(ref color))..ctor(array[0], array[1], array[2], array[3]);
				TargetSetting.Value = new EnhancedColor(color, value2.Mode);
			}
		}
	}
	public class EnumWindowController : MonoBehaviour
	{
		private bool _doneSetup;

		public Setting? TargetSetting;

		private void Start()
		{
			SetupStuff();
		}

		public void SetupStuff()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			if (_doneSetup)
			{
				return;
			}
			_doneSetup = true;
			if (TargetSetting != null)
			{
				UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton/TitleIcon").SetActive(false);
				((TMP_Text)UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleName").GetComponent<TextMeshProUGUI>()).text = TargetSetting.Name;
				GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Header");
				if (obj != null)
				{
					obj.AddComponent<TitlebarDragIgnoreLayoutHandler>();
				}
				GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton");
				Button val = ((obj2 != null) ? obj2.GetComponent<Button>() : null);
				((Selectable)UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton").GetComponent<Button>()).interactable = true;
				GameObject obj3 = UIUtils.FindRecursive(((Component)this).gameObject, "Header/TitleButton/BackIcon");
				if (obj3 != null)
				{
					obj3.SetActive(true);
				}
				if ((Object)(object)val != (Object)null)
				{
					((UnityEvent)val.onClick).AddListener(new UnityAction(Back));
				}
				Transform transform = UIUtils.FindRecursive(((Component)this).gameObject, "Scroll View/Viewport/Content/Modules").transform;
				Populate(transform, TargetSetting);
				UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
				if (TargetSetting != null)
				{
					TargetSetting.OnChanged += Back;
				}
			}
		}

		private void Back()
		{
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged -= Back;
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private void Populate(Transform parent, Setting? setting)
		{
			if ((Object)(object)parent == (Object)null || setting == null)
			{
				return;
			}
			GameObject val = AssetManager.Get<GameObject>(ClickGUI.BundleKey, "RadioChoiceButton");
			foreach (object value in Enum.GetValues(setting.GetValue().GetType()))
			{
				RadioChoiceEnumSettingController radioChoiceEnumSettingController = Object.Instantiate<GameObject>(val, parent).AddComponent<RadioChoiceEnumSettingController>();
				radioChoiceEnumSettingController.TargetValue = value;
				radioChoiceEnumSettingController.TargetSetting = setting;
			}
		}
	}
	public abstract class FileSystemPathSettingController<T> : MonoBehaviour where T : FileSystemPath
	{
		private ClickHandler? _clickHandler;

		private TextMeshProUGUI? _valText;

		private FileManager? _fm;

		public Setting<T>? TargetSetting { get; set; }

		protected abstract bool IsFolder { get; }

		protected virtual bool IsMulti => false;

		private void Start()
		{
			_clickHandler = ((Component)this).gameObject.AddComponent<ClickHandler>();
			_clickHandler.OnPress += Pick;
			GameObject val = UIUtils.FindRecursive(((Component)this).gameObject, "Value");
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				GameObject obj2 = UIUtils.FindRecursive(val, "TargetIcon");
				obj = ((obj2 != null) ? obj2.GetComponent<Image>() : null);
			}
			Image val2 = (Image)obj;
			if ((Object)(object)val2 != (Object)null)
			{
				val2.sprite = AssetManager.Get<Sprite>(ClickGUI.BundleKey, IsFolder ? "folder_clear" : "file");
			}
			object valText;
			if (val == null)
			{
				valText = null;
			}
			else
			{
				GameObject obj3 = UIUtils.FindRecursive(val, "CurrentPath");
				valText = ((obj3 != null) ? obj3.GetComponent<TextMeshProUGUI>() : null);
			}
			_valText = (TextMeshProUGUI?)valText;
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged += UpdateValue;
			}
			UpdateValue();
		}

		private void OnDestroy()
		{
			if (TargetSetting != null)
			{
				TargetSetting.OnChanged -= UpdateValue;
			}
			if ((Object)(object)_clickHandler != (Object)null)
			{
				_clickHandler.OnPress -= Pick;
			}
		}

		private void Pick()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_fm != (Object)null))
			{
				_fm = FileManager.CreatePicker(Path.GetDirectoryName(TargetSetting?.Value.Path), IsFolder, false);
				_fm.ItemsPicked += SetValue;
				GameObject gameObject = ((Component)_fm).gameObject;
				GameObjectExtensions.GetOrAddComponent<LayoutElement>(gameObject).ignoreLayout = true;
				RectTransform component = gameObject.GetComponent<RectTransform>();
				ClickGUI.SpawnContent(gameObject);
				component.sizeDelta = new Vector2(570f, 380f);
				component.anchorMax = new Vector2(0f, 1f);
				component.anchorMin = new Vector2(0f, 1f);
				component.pivot = new Vector2(0f, 1f);
				component.anchoredPosition = new Vector2(10f, -10f);
			}
		}

		private void SetValue(string[] paths)
		{
			if (paths.Length >= 1 && TargetSetting != null)
			{
				TargetSetting.Value = (T)Activator.CreateInstance(typeof(T), paths[0]);
			}
		}

		private void UpdateValue()
		{
			if (TargetSetting != null && !((Object)(object)_valText == (Object)null))
			{
				string path = (IsFolder ? new DirectoryInfo(TargetSetting.Value.Path).FullName : new FileInfo(TargetSetting.Value.Path).FullName);
				string text = FishInitialTruncate(path);
				((TMP_Text)_valText).SetText(text, true);
			}
		}

		private string FishInitialTruncate(string path)
		{
			if (string.IsNullOrEmpty(path))
			{
				return path;
			}
			char[] separator = ((!path.Contains('/')) ? new char[2] { '\\', '/' } : new char[1] { '/' });
			string[] array = path.Split(separator, StringSplitOptions.None);
			for (int i = 1; i < array.Length - 2; i++)
			{
				if (!string.IsNullOrEmpty(array[i]))
				{
					array[i] = array[i][0].ToString();
				}
			}
			return string.Join("/", array);
		}
	}
	public class FilePathSettingController : FileSystemPathSettingController<FilePath>
	{
		protected override bool IsFolder => false;
	}
	public class FolderPathSettingController : FileSystemPathSettingController<FolderPath>
	{
		protected override bool IsFolder => true;
	}
	internal class FloatSettingController : NumberSettingController<float>
	{
		protected override void UpdateScrub(float baseValue, float valueDiff)
		{
			if (TargetSetting != null)
			{
				TargetSetting.Value = baseValue + valueDiff;
			}
		}
	}
	internal class HeaderSettingController : MonoBehaviour
	{
		public ConfigHeader? TargetElement;

		private void Start()
		{
			if (TargetElement != null)
			{
				GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Name", false);
				TextMeshProUGUI val = ((obj != null) ? obj.GetComponent<TextMeshProUGUI>() : null);
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)val).text = TargetElement.Name;
					((TMP_Text)val).fontSize = TargetElement.FontSize;
				}
				GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "DescLayout/Description", false);
				TextMeshProUGUI val2 = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					((TMP_Text)val2).text = TargetElement.Description;
				}
				GameObject val3 = UIUtils.FindRecursive(((Component)((Component)this).transform.parent).gameObject, "RevertButtonWrapper");
				if ((Object)(object)val3 != (Object)null)
				{
					val3.SetActive(false);
				}
			}
		}
	}
	internal class InputFocusGrab : MonoBehaviour
	{
		private TMP_InputField? _input;

		private void OnEnable()
		{
			_input = ((Component)this).gameObject.GetComponent<TMP_InputField>();
			if (!((Object)(object)_input == (Object)null))
			{
				((UnityEvent<string>)(object)_input.onSelect).AddListener((UnityAction<string>)Grab);
				((UnityEvent<string>)(object)_input.onDeselect).AddListener((UnityAction<string>)Release);
			}
		}

		private void OnDisable()
		{
			if (!((Object)(object)_input == (Object)null))
			{
				((UnityEvent<string>)(object)_input.onSelect).RemoveListener((UnityAction<string>)Grab);
				((UnityEvent<string>)(object)_input.onDeselect).RemoveListener((UnityAction<string>)Release);
			}
		}

		private void Grab(string _)
		{
			InputManager.BlockInput = true;
		}

		private void Release(string _)
		{
			InputManager.BlockInput = false;
		}
	}
	internal class IntSettingController : NumberSettingController<int>
	{
		protected override void UpdateScrub(int baseValue, float valueDiff)
		{
			if (TargetSetting != null)
			{
				TargetSetting.Value = (int)((float)baseValue + valueDiff);
			}
		}
	}
	internal class KeybindSettingController : MonoBehaviour
	{
		private const string PauseKey = "Thorn_ClickGUI_KeybindListener";

		private static KeybindSettingController? _listeningInstance;

		private Button? _activateButton;

		private Colorizer? _keyBorder;

		private TextMeshProUGUI? _displayText;

		public Setting<Keybind> TargetSetting;

		private KeyCode _caughtModifier;

		private KeyCode _caughtKey;

		private static OptionsManager? opts => MonoSingleton<OptionsManager>.Instance;

		private void Start()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			_activ