Decompiled source of FATE ModMenu v0.4.2

BepInEx/plugins/FateModMenu/ZombieGhost.ModMenu.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
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("MikhailKillsZombies")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.2.0")]
[assembly: AssemblyInformationalVersion("0.4.2")]
[assembly: AssemblyProduct("ZombieGhost.ModMenu")]
[assembly: AssemblyTitle("ZombieGhost.ModMenu")]
[assembly: AssemblyVersion("0.4.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ZombieGhost.ModMenu
{
	public static class ModMenuApi
	{
		internal static readonly List<ModModule> Modules = new List<ModModule>();

		public static int ApiVersion => 3;

		public static bool IsInputBlocked => ModMenuPlugin.BlocksInput;

		public static IReadOnlyList<ModModule> Registered => Modules;

		public static ModModule RegisterModule(string id, string displayName)
		{
			if (string.IsNullOrWhiteSpace(id) || id.Length > 96 || id.Contains("|"))
			{
				throw new ArgumentException("Use a stable unique mod GUID as the module ID");
			}
			if (Modules.Count >= 64)
			{
				throw new InvalidOperationException("At most 64 modules can register");
			}
			if (Modules.Exists((ModModule module) => module.Id == id))
			{
				throw new InvalidOperationException("Module already registered: " + id);
			}
			ModModule modModule = new ModModule(id, displayName);
			Modules.Add(modModule);
			ModMenuPlugin.RequestRefresh();
			return modModule;
		}
	}
	public sealed class ModModule : IDisposable
	{
		internal readonly List<ModSetting> Settings = new List<ModSetting>();

		internal Action ResetCallback;

		internal Action<string> CategoryResetCallback;

		public string Id { get; }

		public string Name { get; }

		public bool Disposed { get; private set; }

		internal ModModule(string id, string name)
		{
			Id = id;
			Name = (string.IsNullOrWhiteSpace(name) ? id : name);
		}

		public ModToggle RegisterToggle(string id, string label, Func<bool> get, Action<bool> set, string category = null)
		{
			Validate(id, label, get, set);
			bool defaultValue = Read(get, fallback: false);
			ModToggle modToggle = new ModToggle(Id, Name, id, label, category, get, set, defaultValue);
			Add(modToggle);
			return modToggle;
		}

		public ModSlider RegisterSlider(string id, string label, Func<float> get, Action<float> set, float min, float max, float step = 0.05f, string category = null, string format = null)
		{
			Validate(id, label, get, set);
			if (max < min)
			{
				float num = min;
				min = max;
				max = num;
			}
			if (step <= 0f)
			{
				step = 0.01f;
			}
			ModSlider modSlider = new ModSlider(Id, Name, id, label, category, get, set, min, max, step, format, Read(get, min));
			Add(modSlider);
			return modSlider;
		}

		public ModChoice RegisterChoice(string id, string label, Func<int> get, Action<int> set, string[] options, string category = null)
		{
			Validate(id, label, get, set);
			if (options == null || options.Length == 0)
			{
				throw new ArgumentException("A choice needs at least one option");
			}
			int defaultIndex = Math.Max(0, Math.Min(options.Length - 1, Read(get, 0)));
			ModChoice modChoice = new ModChoice(Id, Name, id, label, category, get, set, options, defaultIndex);
			Add(modChoice);
			return modChoice;
		}

		public ModAction RegisterAction(string id, string label, Action invoke, string category = null)
		{
			if (string.IsNullOrWhiteSpace(id) || id.Length > 96 || id.Contains("|"))
			{
				throw new ArgumentException("Unique option ID required");
			}
			if (invoke == null)
			{
				throw new ArgumentException("An action is required");
			}
			ModAction modAction = new ModAction(Id, Name, id, label, category, invoke);
			Add(modAction);
			return modAction;
		}

		public void RegisterTrackRemoveAction(string trackId, Action remove)
		{
			if (string.IsNullOrWhiteSpace(trackId) || remove == null)
			{
				throw new ArgumentException("A track ID and an action are required");
			}
			foreach (ModSetting setting in Settings)
			{
				if (setting is ModTrack modTrack && modTrack.Id == trackId)
				{
					modTrack.RemoveAction = remove;
					ModMenuPlugin.RequestRefresh();
					return;
				}
			}
			throw new ArgumentException("Unknown track: " + trackId);
		}

		public ModAction RegisterWideAction(string id, string label, Action invoke, string category = null)
		{
			if (string.IsNullOrWhiteSpace(id) || id.Length > 96 || id.Contains("|"))
			{
				throw new ArgumentException("Unique option ID required");
			}
			if (invoke == null)
			{
				throw new ArgumentException("An action is required");
			}
			ModAction modAction = new ModAction(Id, Name, id, label, category, invoke, wide: true);
			Add(modAction);
			return modAction;
		}

		public ModTrack RegisterTrack(string id, string label, Func<bool> getEnabled, Action<bool> setEnabled, Action preview, Action stop, Func<bool> playing, Func<bool> selected, Action<bool> setSelected, Func<float> getLoop, Action<float> setLoop, float loopMin, float loopMax, float loopStep, string category = null)
		{
			if (string.IsNullOrWhiteSpace(id) || id.Length > 96 || id.Contains("|"))
			{
				throw new ArgumentException("Unique option ID required");
			}
			if (getEnabled == null || setEnabled == null || preview == null)
			{
				throw new ArgumentException("A track needs an enable getter and setter and a preview action");
			}
			ModTrack modTrack = new ModTrack(Id, Name, id, label, category, getEnabled, setEnabled, preview, stop, playing, selected, setSelected, getLoop, setLoop, loopMin, loopMax, loopStep);
			Add(modTrack);
			return modTrack;
		}

		public ModNote RegisterNote(string id, string text, string category = null)
		{
			if (string.IsNullOrWhiteSpace(id) || id.Length > 96 || id.Contains("|"))
			{
				throw new ArgumentException("Unique option ID required");
			}
			if (string.IsNullOrWhiteSpace(text))
			{
				throw new ArgumentException("Note text is required");
			}
			ModNote modNote = new ModNote(Id, Name, id, text, category);
			Add(modNote);
			return modNote;
		}

		public ModColor RegisterColor(string id, string label, Func<Color> get, Action<Color> set, string category = null)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Validate(id, label, get, set);
			ModColor modColor = new ModColor(Id, Name, id, label, category, get, set, Read(get, Color.white));
			Add(modColor);
			return modColor;
		}

		public ModPreview RegisterPreview(string id, string label, Func<Texture2D> get, string category = null, float height = 150f)
		{
			if (string.IsNullOrWhiteSpace(id) || id.Length > 96 || id.Contains("|"))
			{
				throw new ArgumentException("Unique option ID required");
			}
			if (get == null)
			{
				throw new ArgumentException("An image getter is required");
			}
			ModPreview modPreview = new ModPreview(Id, Name, id, label, category, get, height);
			Add(modPreview);
			return modPreview;
		}

		public void SetResetCallback(Action callback)
		{
			ResetCallback = callback;
		}

		public void SetCategoryResetCallback(Action<string> callback)
		{
			CategoryResetCallback = callback;
		}

		public void ResetDefaults()
		{
			ResetGroup(null);
		}

		public void ResetCategory(string category)
		{
			ResetGroup(category);
		}

		private void ResetGroup(string category)
		{
			ModSetting[] array = Settings.ToArray();
			foreach (ModSetting modSetting in array)
			{
				if (!modSetting.Removed && (category == null || modSetting.Category == category))
				{
					modSetting.Reset();
				}
			}
			try
			{
				if (category == null)
				{
					if (ResetCallback != null)
					{
						ResetCallback();
					}
				}
				else if (CategoryResetCallback != null)
				{
					CategoryResetCallback(category);
				}
			}
			catch
			{
			}
			ModMenuPlugin.RequestRefresh();
		}

		public void Dispose()
		{
			if (Disposed)
			{
				return;
			}
			Disposed = true;
			foreach (ModSetting setting in Settings)
			{
				setting.Removed = true;
			}
			Settings.Clear();
			ModMenuApi.Modules.Remove(this);
			ModMenuPlugin.RequestRefresh();
		}

		private void Add(ModSetting setting)
		{
			if (Disposed)
			{
				throw new ObjectDisposedException("Module " + Id + " is disposed");
			}
			if (Settings.Count >= 256)
			{
				throw new InvalidOperationException("At most 256 options per module");
			}
			foreach (ModSetting setting2 in Settings)
			{
				if (setting2.Id == setting.Id)
				{
					throw new ArgumentException("Duplicate option ID: " + setting.Id);
				}
			}
			Settings.Add(setting);
			ModMenuPlugin.RequestRefresh();
		}

		private static void Validate(string id, string label, Delegate get, Delegate set)
		{
			if (string.IsNullOrWhiteSpace(id) || id.Length > 96 || id.Contains("|"))
			{
				throw new ArgumentException("Unique option ID required");
			}
			if ((object)get == null || (object)set == null)
			{
				throw new ArgumentException("A getter and a setter are required");
			}
			if (string.IsNullOrWhiteSpace(label))
			{
				throw new ArgumentException("A label is required");
			}
		}

		private static bool Read(Func<bool> get, bool fallback)
		{
			try
			{
				return get();
			}
			catch
			{
				return fallback;
			}
		}

		private static float Read(Func<float> get, float fallback)
		{
			try
			{
				return get();
			}
			catch
			{
				return fallback;
			}
		}

		private static int Read(Func<int> get, int fallback)
		{
			try
			{
				return get();
			}
			catch
			{
				return fallback;
			}
		}

		private static Color Read(Func<Color> get, Color fallback)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return get();
			}
			catch
			{
				return fallback;
			}
		}
	}
	public abstract class ModSetting
	{
		internal string Owner;

		internal string OwnerName;

		internal bool Removed;

		public string Id { get; }

		public string Label { get; }

		public string Category { get; }

		internal ModSetting(string owner, string ownerName, string id, string label, string category)
		{
			Owner = owner;
			OwnerName = ownerName;
			Id = id;
			Label = label;
			Category = (string.IsNullOrWhiteSpace(category) ? "General" : category);
		}

		internal abstract void Reset();

		internal abstract string Describe();
	}
	public sealed class ModToggle : ModSetting
	{
		internal Func<bool> Get;

		internal Action<bool> Set;

		internal bool Default;

		public bool Value
		{
			get
			{
				if (!Removed && Get != null)
				{
					return Get();
				}
				return false;
			}
			set
			{
				SetValue(value);
			}
		}

		internal ModToggle(string owner, string ownerName, string id, string label, string category, Func<bool> get, Action<bool> set, bool defaultValue)
			: base(owner, ownerName, id, label, category)
		{
			Get = get;
			Set = set;
			Default = defaultValue;
		}

		public void SetValue(bool value)
		{
			if (!Removed && Set != null)
			{
				Set(value);
				ModMenuPlugin.RequestRefresh();
			}
		}

		internal override void Reset()
		{
			SetValue(Default);
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				if (!Value)
				{
					return "0";
				}
				return "1";
			}
			return "removed";
		}
	}
	public sealed class ModSlider : ModSetting
	{
		internal Func<float> Get;

		internal Action<float> Set;

		internal float Min;

		internal float Max;

		internal float Step;

		internal float Default;

		internal string Format;

		public float Value
		{
			get
			{
				if (Removed || Get == null)
				{
					return Min;
				}
				return Clamp(Get());
			}
			set
			{
				SetValue(value);
			}
		}

		public string Text
		{
			get
			{
				if (Format == null)
				{
					return Value.ToString((Step >= 1f) ? "0" : ((Step >= 0.1f) ? "0.0" : "0.00"));
				}
				return Value.ToString(Format);
			}
		}

		public float Normalized
		{
			get
			{
				if (!(Max <= Min))
				{
					return Mathf.Clamp01((Value - Min) / (Max - Min));
				}
				return 0f;
			}
		}

		internal ModSlider(string owner, string ownerName, string id, string label, string category, Func<float> get, Action<float> set, float min, float max, float step, string format, float defaultValue)
			: base(owner, ownerName, id, label, category)
		{
			Get = get;
			Set = set;
			Min = min;
			Max = max;
			Step = step;
			Format = format;
			Default = defaultValue;
		}

		public void SetValue(float value)
		{
			if (!Removed && Set != null)
			{
				Set(Clamp(Snap(value)));
				ModMenuPlugin.RequestRefresh();
			}
		}

		public void Seek(float normalized)
		{
			SetValue(Min + (Max - Min) * Clamp(normalized));
		}

		public void Nudge(int direction)
		{
			SetValue(Value + (float)direction * Step);
		}

		internal override void Reset()
		{
			SetValue(Default);
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				return Value.ToString("R");
			}
			return "removed";
		}

		private float Clamp(float value)
		{
			return Math.Max(Min, Math.Min(Max, value));
		}

		private float Snap(float value)
		{
			return Min + Mathf.Round((value - Min) / Step) * Step;
		}
	}
	public sealed class ModChoice : ModSetting
	{
		internal Func<int> Get;

		internal Action<int> Set;

		internal string[] Options;

		internal int Default;

		public int Index
		{
			get
			{
				int val = ((!Removed && Get != null) ? Get() : 0);
				return Math.Max(0, Math.Min(Options.Length - 1, val));
			}
		}

		public string Text
		{
			get
			{
				if (Options.Length != 0)
				{
					return Options[Index];
				}
				return "";
			}
		}

		internal ModChoice(string owner, string ownerName, string id, string label, string category, Func<int> get, Action<int> set, string[] options, int defaultIndex)
			: base(owner, ownerName, id, label, category)
		{
			Get = get;
			Set = set;
			Options = options;
			Default = defaultIndex;
		}

		public void SetIndex(int index)
		{
			if (!Removed && Set != null && Options.Length != 0)
			{
				Set(Math.Max(0, Math.Min(Options.Length - 1, index)));
				ModMenuPlugin.RequestRefresh();
			}
		}

		public void Cycle(int direction)
		{
			SetIndex(((Index + direction) % Options.Length + Options.Length) % Options.Length);
		}

		internal override void Reset()
		{
			SetIndex(Default);
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				return Index + "|" + Text;
			}
			return "removed";
		}
	}
	public sealed class ModAction : ModSetting
	{
		internal Action Run;

		internal bool Wide;

		internal ModAction(string owner, string ownerName, string id, string label, string category, Action run, bool wide = false)
			: base(owner, ownerName, id, label, category)
		{
			Run = run;
			Wide = wide;
		}

		public void Invoke()
		{
			if (!Removed && Run != null)
			{
				Run();
				ModMenuPlugin.RequestRefresh();
			}
		}

		internal override void Reset()
		{
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				return "action";
			}
			return "removed";
		}
	}
	public sealed class ModNote : ModSetting
	{
		internal string Content;

		internal ModNote(string owner, string ownerName, string id, string text, string category)
			: base(owner, ownerName, id, text, category)
		{
			Content = text;
		}

		internal override void Reset()
		{
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				return Content;
			}
			return "removed";
		}
	}
	public sealed class ModColor : ModSetting
	{
		internal Func<Color> Get;

		internal Action<Color> Set;

		internal Color Default;

		public Color Value
		{
			get
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: 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_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				Color val = ((Removed || Get == null) ? Default : Get());
				return new Color(Mathf.Clamp01(val.r), Mathf.Clamp01(val.g), Mathf.Clamp01(val.b), Mathf.Clamp01(val.a));
			}
		}

		public string Hex => "#" + ColorUtility.ToHtmlStringRGB(Value);

		internal ModColor(string owner, string ownerName, string id, string label, string category, Func<Color> get, Action<Color> set, Color defaultValue)
			: base(owner, ownerName, id, label, category)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Get = get;
			Set = set;
			Default = defaultValue;
		}

		public float Channel(int index)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			return index switch
			{
				2 => Value.b, 
				1 => Value.g, 
				0 => Value.r, 
				_ => Value.a, 
			};
		}

		public bool SetHex(string text)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (Removed || Set == null)
			{
				return false;
			}
			if (!TryParseHex(text, out var color))
			{
				return false;
			}
			Set(color);
			ModMenuPlugin.RequestRefresh();
			return true;
		}

		public static bool TryParseHex(string text, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			color = default(Color);
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string text2 = text.Trim();
			if (!text2.StartsWith("#"))
			{
				text2 = "#" + text2;
			}
			return ColorUtility.TryParseHtmlString(text2, ref color);
		}

		public void SetChannel(int index, float value)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			if (!Removed && Set != null)
			{
				Color value2 = Value;
				float num = Mathf.Round(Mathf.Clamp01(value) * 255f) / 255f;
				switch (index)
				{
				case 0:
					value2.r = num;
					break;
				case 1:
					value2.g = num;
					break;
				case 2:
					value2.b = num;
					break;
				default:
					value2.a = num;
					break;
				}
				Set(value2);
				ModMenuPlugin.RequestRefresh();
			}
		}

		internal override void Reset()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!Removed && Set != null)
			{
				Set(Default);
				ModMenuPlugin.RequestRefresh();
			}
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				return Hex;
			}
			return "removed";
		}
	}
	public sealed class ModPreview : ModSetting
	{
		internal Func<Texture2D> Get;

		internal float Height;

		public Texture2D Texture
		{
			get
			{
				try
				{
					return (Removed || Get == null) ? null : Get();
				}
				catch
				{
					return null;
				}
			}
		}

		public float ImageHeight => Height;

		internal ModPreview(string owner, string ownerName, string id, string label, string category, Func<Texture2D> get, float height)
			: base(owner, ownerName, id, label, category)
		{
			Get = get;
			Height = Mathf.Clamp(height, 60f, 320f);
		}

		internal override void Reset()
		{
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				return "preview:" + Height;
			}
			return "removed";
		}
	}
	public sealed class ModTrack : ModSetting
	{
		internal Func<bool> GetEnabled;

		internal Action<bool> SetEnabled;

		internal Action PreviewAction;

		internal Action StopAction;

		internal Action RemoveAction;

		internal Func<bool> Playing;

		internal Func<bool> SelectedGetter;

		internal Action<bool> SelectedSetter;

		internal Func<float> GetLoop;

		internal Action<float> SetLoop;

		internal float Min;

		internal float Max;

		internal float Step;

		internal bool DefaultEnabled;

		public bool Enabled
		{
			get
			{
				try
				{
					return !Removed && GetEnabled != null && GetEnabled();
				}
				catch
				{
					return false;
				}
			}
		}

		public bool IsPlaying
		{
			get
			{
				try
				{
					return !Removed && Playing != null && Playing();
				}
				catch
				{
					return false;
				}
			}
		}

		public bool IsSelected
		{
			get
			{
				try
				{
					return !Removed && SelectedGetter != null && SelectedGetter();
				}
				catch
				{
					return false;
				}
			}
		}

		public float LoopSeconds
		{
			get
			{
				try
				{
					return Mathf.Clamp((GetLoop == null) ? Min : GetLoop(), Min, Max);
				}
				catch
				{
					return Min;
				}
			}
		}

		public float LoopNormalized
		{
			get
			{
				if (!(Max <= Min))
				{
					return Mathf.Clamp01((LoopSeconds - Min) / (Max - Min));
				}
				return 0f;
			}
		}

		public float MinValue => Min;

		public float MaxValue => Max;

		public float StepValue => Step;

		public string LoopText
		{
			get
			{
				if (!(Step >= 1f))
				{
					return LoopSeconds.ToString("0.0") + "s";
				}
				return LoopSeconds.ToString("0") + "s";
			}
		}

		internal ModTrack(string owner, string ownerName, string id, string label, string category, Func<bool> getEnabled, Action<bool> setEnabled, Action preview, Action stop, Func<bool> playing, Func<bool> selected, Action<bool> setSelected, Func<float> getLoop, Action<float> setLoop, float min, float max, float step)
			: base(owner, ownerName, id, label, category)
		{
			GetEnabled = getEnabled;
			SetEnabled = setEnabled;
			PreviewAction = preview;
			StopAction = stop;
			Playing = playing;
			SelectedGetter = selected;
			SelectedSetter = setSelected;
			GetLoop = getLoop;
			SetLoop = setLoop;
			if (max < min)
			{
				float num = min;
				min = max;
				max = num;
			}
			Min = min;
			Max = max;
			Step = ((step <= 0f) ? 0.1f : step);
			try
			{
				DefaultEnabled = getEnabled();
			}
			catch
			{
				DefaultEnabled = true;
			}
		}

		public void ToggleEnabled()
		{
			ApplyEnabled(!Enabled);
		}

		public void ApplyEnabled(bool value)
		{
			if (!Removed && SetEnabled != null)
			{
				SetEnabled(value);
				ModMenuPlugin.RequestRefresh();
			}
		}

		public void Preview()
		{
			if (!Removed && PreviewAction != null)
			{
				PreviewAction();
				ModMenuPlugin.RequestRefresh();
			}
		}

		public void Stop()
		{
			if (!Removed && StopAction != null)
			{
				StopAction();
				ModMenuPlugin.RequestRefresh();
			}
		}

		public void Select(bool value)
		{
			if (!Removed && SelectedSetter != null)
			{
				SelectedSetter(value);
				ModMenuPlugin.RequestRefresh();
			}
		}

		public void Remove()
		{
			if (!Removed && RemoveAction != null)
			{
				RemoveAction();
				ModMenuPlugin.RequestRefresh();
			}
		}

		public void SeekLoop(float normalized)
		{
			ApplyLoop(Min + (Max - Min) * Mathf.Clamp01(normalized));
		}

		public void NudgeLoop(int direction)
		{
			ApplyLoop(LoopSeconds + (float)direction * Step);
		}

		private void ApplyLoop(float seconds)
		{
			if (!Removed && SetLoop != null)
			{
				float num = Min + Mathf.Round((Mathf.Clamp(seconds, Min, Max) - Min) / Step) * Step;
				SetLoop(Mathf.Clamp(num, Min, Max));
			}
		}

		internal override void Reset()
		{
			ApplyEnabled(DefaultEnabled);
		}

		internal override string Describe()
		{
			if (!Removed)
			{
				return (Enabled ? "1" : "0") + (IsPlaying ? "|play" : "|idle") + (IsSelected ? "|sel" : "|plain");
			}
			return "removed";
		}
	}
	internal sealed class ModMenuHexField : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		private TextMeshProUGUI caption;

		private Func<string> read;

		private Func<string, bool> apply;

		private Action<string> report;

		private bool editing;

		private string buffer = string.Empty;

		private float nextClick;

		internal static bool Editing { get; private set; }

		internal static void Attach(RectTransform host, TextMeshProUGUI caption, Func<string> read, Func<string, bool> apply, Action<string> report)
		{
			ModMenuHexField modMenuHexField = ((Component)host).gameObject.AddComponent<ModMenuHexField>();
			modMenuHexField.caption = caption;
			modMenuHexField.read = read;
			modMenuHexField.apply = apply;
			modMenuHexField.report = report;
			modMenuHexField.Show();
		}

		public void OnPointerClick(PointerEventData eventData)
		{
			if (!(Time.unscaledTime < nextClick))
			{
				nextClick = Time.unscaledTime + 0.2f;
				if (editing)
				{
					Commit();
				}
				else
				{
					Begin();
				}
			}
		}

		private void Begin()
		{
			buffer = ((read != null) ? read() : "#FFFFFF");
			editing = true;
			Editing = true;
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				current.onTextInput += Type;
			}
			Show();
			Say("Type a code or press Ctrl+V, then Enter. Escape cancels.");
		}

		private void Commit()
		{
			string text = Clean(buffer);
			Finish();
			if (text == null)
			{
				Say("Not a colour code: " + (string.IsNullOrEmpty(buffer) ? "nothing" : buffer) + ".");
			}
			else if (apply != null && apply(text))
			{
				Say("Colour set to " + ((read != null) ? read() : text) + ".");
			}
			else
			{
				Say("That colour could not be applied.");
			}
		}

		private void Cancel()
		{
			Finish();
			Say("Colour unchanged.");
		}

		private void Finish()
		{
			editing = false;
			Editing = false;
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				current.onTextInput -= Type;
			}
			Show();
			ModMenuPlugin.RequestRefresh();
		}

		private void Type(char character)
		{
			if (editing)
			{
				if (character == '#')
				{
					buffer = "#";
					Show();
				}
				else if (IsHex(character) && buffer.Length < 7)
				{
					buffer += char.ToLowerInvariant(character);
					Show();
				}
			}
		}

		private void Update()
		{
			if (!editing)
			{
				return;
			}
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			if (((ButtonControl)current.escapeKey).wasPressedThisFrame)
			{
				Cancel();
			}
			else if (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame)
			{
				Commit();
			}
			else if (((ButtonControl)current.backspaceKey).wasPressedThisFrame)
			{
				if (buffer.Length > 0)
				{
					buffer = buffer.Substring(0, buffer.Length - 1);
				}
				Show();
			}
			else if ((current.ctrlKey.isPressed || ((ButtonControl)current.leftCtrlKey).isPressed) && ((ButtonControl)current.vKey).wasPressedThisFrame)
			{
				Paste();
			}
		}

		private void Paste()
		{
			string text;
			try
			{
				text = GUIUtility.systemCopyBuffer;
			}
			catch
			{
				text = null;
			}
			if (string.IsNullOrWhiteSpace(text))
			{
				Say("Clipboard is empty. Copy a code such as " + ((read != null) ? read() : "#B76063") + ".");
				return;
			}
			string text2 = Clean(text);
			if (text2 == null)
			{
				Say("The clipboard does not hold a colour code.");
				return;
			}
			buffer = text2;
			Show();
			Commit();
		}

		private void Show()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)caption == (Object)null))
			{
				if (editing)
				{
					((TMP_Text)caption).text = buffer + "|";
					((Graphic)caption).color = ModMenuTheme.Gold;
				}
				else
				{
					((TMP_Text)caption).text = ((read != null) ? read() : string.Empty);
					((Graphic)caption).color = ModMenuTheme.Text;
				}
			}
		}

		private void Say(string message)
		{
			if (report != null)
			{
				report(message);
			}
		}

		internal static string Clean(string text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			string text2 = text.Trim();
			if (text2.StartsWith("#"))
			{
				text2 = text2.Substring(1);
			}
			if (text2.Length != 3 && text2.Length != 6)
			{
				return null;
			}
			string text3 = text2;
			for (int i = 0; i < text3.Length; i++)
			{
				if (!IsHex(text3[i]))
				{
					return null;
				}
			}
			return "#" + text2.ToLowerInvariant();
		}

		private static bool IsHex(char character)
		{
			if ((character < '0' || character > '9') && (character < 'a' || character > 'f'))
			{
				if (character >= 'A')
				{
					return character <= 'F';
				}
				return false;
			}
			return true;
		}

		private void OnDestroy()
		{
			if (editing)
			{
				editing = false;
				Editing = false;
				Keyboard current = Keyboard.current;
				if (current != null)
				{
					current.onTextInput -= Type;
				}
			}
		}
	}
	[BepInPlugin("zombieghost.modmenu", "FATE Mod Menu", "0.4.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class ModMenuPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OpenScreen;
		}

		public const string Guid = "zombieghost.modmenu";

		public const string Name = "FATE Mod Menu";

		public const string Version = "0.4.2";

		internal const string ButtonName = "Mod Settings (FATE Mod Menu)";

		private const float PauseRowHeight = 66f;

		private static ManualLogSource log;

		private static ModMenuScreen screen;

		private static Component pause;

		private static Button pauseButton;

		private static RectTransform pauseContent;

		private static Vector2 pauseContentSize;

		private static Type pauseType;

		private static MethodInfo menuButton;

		private static MethodInfo setPause;

		private static bool dirty;

		private static bool hotkeyOpened;

		private static bool pausedByUs;

		private static bool cursorShown;

		private static bool warnedNoPause;

		private static bool legacyInput;

		private static int lastPollFrame = -1;

		private Harmony harmony;

		internal static bool BlocksInput => (Object)(object)screen != (Object)null;

		internal static void RequestRefresh()
		{
			dirty = true;
		}

		internal static void Log(string message)
		{
			if (log != null)
			{
				log.LogInfo((object)message);
			}
		}

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00c6: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("zombieghost.modmenu");
			try
			{
				Input.GetKeyDown((KeyCode)0);
				legacyInput = true;
			}
			catch
			{
				legacyInput = false;
			}
			pauseType = AccessTools.TypeByName("Tableflip.PauseUI");
			if (pauseType == null)
			{
				Log("MOD_MENU_NO_TYPE: Tableflip.PauseUI was not found; only the F10 screen will work.");
				return;
			}
			menuButton = AccessTools.Method(pauseType, "OnMenuButton", (Type[])null, (Type[])null);
			if (menuButton == null)
			{
				Log("MOD_MENU_NO_MENU_METHOD: PauseUI.OnMenuButton was not found; F10 opens the screen on its own.");
			}
			else
			{
				harmony.Patch((MethodBase)menuButton, new HarmonyMethod(typeof(ModMenuPlugin), "BeforeMenuButton", (Type[])null), new HarmonyMethod(typeof(ModMenuPlugin), "AfterMenuButton", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo = AccessTools.Method(pauseType, "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(pauseType, "Start", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ModMenuPlugin), "AfterPauseAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(ModMenuPlugin), "AfterPauseAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Log("MOD_MENU_NO_START: PauseUI.Awake and Start were not found; the row is only added when the pause menu opens.");
			}
			Type type = AccessTools.TypeByName("Cleverous.Prodigy.Input.InputBroker");
			MethodInfo methodInfo3 = ((type == null) ? null : AccessTools.Method(type, "ManagedTick", (Type[])null, (Type[])null));
			if (methodInfo3 != null)
			{
				harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(ModMenuPlugin), "AfterInputTick", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Log("MOD_MENU_NO_TICK: InputBroker.ManagedTick was not found; F10 will not be read.");
			}
			Log("FATE Mod Menu ready: " + ModMenuApi.Modules.Count + " module(s) registered.");
		}

		private static bool BeforeMenuButton()
		{
			if ((Object)(object)screen == (Object)null)
			{
				return true;
			}
			CloseScreen();
			return false;
		}

		private static void AfterMenuButton(object __instance)
		{
			Log("MOD_MENU_PAUSE_TOGGLED");
			InstallButton(__instance);
		}

		private static void AfterPauseAwake(object __instance)
		{
			Log("MOD_MENU_PAUSE_AWAKE");
			InstallButton(__instance);
		}

		private static void AfterInputTick()
		{
			Poll();
		}

		private static void Poll()
		{
			if (Time.frameCount == lastPollFrame)
			{
				return;
			}
			lastPollFrame = Time.frameCount;
			if ((Object)(object)screen == (Object)null)
			{
				if (HotkeyPressed())
				{
					ToggleFromHotkey();
				}
				return;
			}
			if (!hotkeyOpened && (Object)(object)pause != (Object)null && !pause.gameObject.activeInHierarchy)
			{
				CloseScreen();
				return;
			}
			if (dirty)
			{
				dirty = false;
				screen.Invalidate();
			}
			screen.Tick();
		}

		private static bool HotkeyPressed()
		{
			Keyboard current = Keyboard.current;
			if (current != null && ((ButtonControl)current.f10Key).wasPressedThisFrame)
			{
				return true;
			}
			if (legacyInput)
			{
				return Input.GetKeyDown((KeyCode)291);
			}
			return false;
		}

		private static void ToggleFromHotkey()
		{
			Log("MOD_MENU_HOTKEY screen=" + ((Object)(object)screen != (Object)null) + " pause=" + ((Object)(object)pause != (Object)null) + " pauseActive=" + ((Object)(object)pause != (Object)null && pause.gameObject.activeInHierarchy));
			if ((Object)(object)screen != (Object)null)
			{
				CloseScreen();
			}
			else if ((Object)(object)pause == (Object)null || !pause.gameObject.activeInHierarchy)
			{
				if (OpenPauseMenu())
				{
					hotkeyOpened = false;
					OpenScreen();
				}
				else
				{
					OpenStandalone();
				}
			}
			else
			{
				hotkeyOpened = false;
				OpenScreen();
			}
		}

		private static bool OpenPauseMenu()
		{
			if (menuButton == null)
			{
				Log("MOD_MENU_HOTKEY_NO_METHOD: no OnMenuButton to open the pause menu with.");
				return false;
			}
			try
			{
				Component val = FindPauseInstance();
				if ((Object)(object)val == (Object)null)
				{
					Log("MOD_MENU_HOTKEY_NO_PAUSE: no PauseUI instance in the loaded scene.");
					return false;
				}
				if (!val.gameObject.activeSelf)
				{
					menuButton.Invoke(val, Array.Empty<object>());
				}
				pause = val;
				return pause.gameObject.activeInHierarchy;
			}
			catch (Exception ex)
			{
				Log("MOD_MENU_HOTKEY_FAILED: " + ex);
				return false;
			}
		}

		private static Component FindPauseInstance()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (pauseType == null)
			{
				return null;
			}
			Object[] array = Resources.FindObjectsOfTypeAll(pauseType);
			foreach (Object obj in array)
			{
				Component val = (Component)(object)((obj is Component) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					Scene scene = val.gameObject.scene;
					if (((Scene)(ref scene)).IsValid())
					{
						return val;
					}
				}
			}
			if (!warnedNoPause)
			{
				warnedNoPause = true;
				Log("MOD_MENU_NO_PAUSE_INSTANCE: no Tableflip.PauseUI is loaded yet.");
			}
			return null;
		}

		private static void OpenStandalone()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			Transform val = FindScreenCanvas();
			if ((Object)(object)val == (Object)null)
			{
				Log("MOD_MENU_NO_CANVAS: the settings screen needs a canvas and none was active.");
				return;
			}
			try
			{
				screen = ModMenuScreen.Create(val);
				hotkeyOpened = true;
				dirty = false;
				SetGamePaused(paused: true);
				pausedByUs = true;
				cursorShown = (int)Cursor.lockState > 0;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				Log("MOD_MENU_OPENED_HOTKEY canvas=" + ((Object)val).name + " modules=" + ModMenuApi.Modules.Count);
			}
			catch (Exception ex)
			{
				screen = null;
				hotkeyOpened = false;
				OpenFailed(ex);
			}
		}

		private static Transform FindScreenCanvas()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			Transform val = null;
			Transform result = null;
			int num = int.MinValue;
			int num2 = int.MinValue;
			Canvas[] array = Resources.FindObjectsOfTypeAll<Canvas>();
			foreach (Canvas val2 in array)
			{
				if ((Object)(object)val2 == (Object)null || !val2.isRootCanvas || !((Component)val2).gameObject.activeInHierarchy)
				{
					continue;
				}
				if ((int)val2.renderMode == 0)
				{
					if (val2.sortingOrder >= num)
					{
						num = val2.sortingOrder;
						val = ((Component)val2).transform;
					}
				}
				else if ((int)val2.renderMode == 1 && val2.sortingOrder >= num2)
				{
					num2 = val2.sortingOrder;
					result = ((Component)val2).transform;
				}
			}
			if (!((Object)(object)val != (Object)null))
			{
				return result;
			}
			return val;
		}

		private static void OpenFailed(Exception ex)
		{
			if (log != null)
			{
				log.LogError((object)("MOD_MENU_OPEN_FAILED: " + ex));
			}
		}

		private static void SetGamePaused(bool paused)
		{
			try
			{
				if (setPause == null)
				{
					Type type = AccessTools.TypeByName("Tableflip.Fate");
					setPause = ((type == null) ? null : AccessTools.Method(type, "SetPause", new Type[1] { typeof(bool) }, (Type[])null));
				}
				if (setPause != null)
				{
					setPause.Invoke(null, new object[1] { paused });
				}
			}
			catch (Exception)
			{
			}
		}

		private unsafe static void InstallButton(object value)
		{
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			Component val = (Component)((value is Component) ? value : null);
			if (val == null)
			{
				Log("MOD_MENU_SKIP: pause value was not a component.");
				return;
			}
			Type type = ((object)val).GetType();
			object? obj = AccessTools.Field(type, "optionsButton")?.GetValue(val);
			Button val2 = (Button)((obj is Button) ? obj : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).transform.parent == (Object)null)
			{
				Log("MOD_MENU_SKIP: optionsButton or its parent was not found.");
				return;
			}
			pause = val;
			if ((Object)(object)pauseButton == (Object)null || (Object)(object)((Component)pauseButton).transform.parent != (Object)(object)((Component)val2).transform.parent)
			{
				try
				{
					GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Component)val2).transform.parent, false);
					((Object)val3).name = "Mod Settings (FATE Mod Menu)";
					MonoBehaviour[] componentsInChildren = val3.GetComponentsInChildren<MonoBehaviour>(true);
					foreach (MonoBehaviour val4 in componentsInChildren)
					{
						if ((Object)(object)val4 != (Object)null && ((object)val4).GetType().Name == "Localize")
						{
							Object.Destroy((Object)(object)val4);
						}
					}
					TMP_Text componentInChildren = val3.GetComponentInChildren<TMP_Text>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.text = "Mod Settings";
					}
					Button component = val3.GetComponent<Button>();
					if ((Object)(object)component == (Object)null)
					{
						Object.Destroy((Object)(object)val3);
						return;
					}
					((Selectable)component).interactable = true;
					((UnityEventBase)component.onClick).RemoveAllListeners();
					ButtonClickedEvent onClick = component.onClick;
					object obj2 = <>O.<0>__OpenScreen;
					if (obj2 == null)
					{
						UnityAction val5 = OpenScreen;
						<>O.<0>__OpenScreen = val5;
						obj2 = (object)val5;
					}
					((UnityEvent)onClick).AddListener((UnityAction)obj2);
					val3.transform.SetSiblingIndex(((Component)val2).transform.GetSiblingIndex() + 1);
					pauseButton = component;
				}
				catch (Exception ex)
				{
					if (log != null)
					{
						log.LogError((object)("MOD_MENU_CLONE_FAILED: " + ex));
					}
					return;
				}
			}
			Transform parent = ((Component)val2).transform.parent.parent;
			RectTransform val6 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if (val6 != null)
			{
				if ((Object)(object)val6 != (Object)(object)pauseContent)
				{
					pauseContent = val6;
					pauseContentSize = val6.sizeDelta;
				}
				val6.sizeDelta = new Vector2(pauseContentSize.x, pauseContentSize.y + 66f);
				string[] obj3 = new string[10]
				{
					"MOD_MENU_BUTTON_INSTALLED parent=",
					((Object)((Component)val2).transform.parent).name,
					" rows=",
					((Component)val2).transform.parent.childCount.ToString(),
					" native=",
					null,
					null,
					null,
					null,
					null
				};
				Vector2 val7 = pauseContentSize;
				obj3[5] = ((object)(*(Vector2*)(&val7))/*cast due to .constrained prefix*/).ToString();
				obj3[6] = " content=";
				obj3[7] = ((object)val6.sizeDelta/*cast due to .constrained prefix*/).ToString();
				obj3[8] = " active=";
				obj3[9] = ((Component)pauseButton).gameObject.activeSelf.ToString();
				Log(string.Concat(obj3));
			}
			else
			{
				Log("MOD_MENU_SKIP: the button container has no grandparent RectTransform; the new row may be clipped.");
			}
			Chain(pauseButton, type, val);
		}

		private static void Chain(Button added, Type type, Component pauseUi)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			object? obj = AccessTools.Field(type, "saveQuitButton")?.GetValue(pauseUi);
			Button val = (Button)((obj is Button) ? obj : null);
			object? obj2 = AccessTools.Field(type, "optionsButton")?.GetValue(pauseUi);
			Button val2 = (Button)((obj2 is Button) ? obj2 : null);
			object? obj3 = AccessTools.Field(type, "resumeButton")?.GetValue(pauseUi);
			Button val3 = (Button)((obj3 is Button) ? obj3 : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)added == (Object)null))
			{
				Button[] array = (Button[])(object)new Button[4] { val, val2, added, val3 };
				for (int i = 0; i < array.Length; i++)
				{
					Navigation navigation = ((Selectable)array[i]).navigation;
					((Navigation)(ref navigation)).mode = (Mode)4;
					((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)array[(i + array.Length - 1) % array.Length];
					((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)array[(i + 1) % array.Length];
					((Selectable)array[i]).navigation = navigation;
				}
			}
		}

		internal static void OpenScreen()
		{
			if ((Object)(object)screen != (Object)null || (Object)(object)pause == (Object)null)
			{
				return;
			}
			Transform val = FindCanvas(pause.transform);
			if ((Object)(object)val == (Object)null)
			{
				Log("MOD_MENU_NO_PAUSE_CANVAS: no canvas was found for the pause menu.");
				return;
			}
			try
			{
				screen = ModMenuScreen.Create(val);
				dirty = false;
				Log("MOD_MENU_OPENED canvas=" + ((Object)val).name + " modules=" + ModMenuApi.Modules.Count);
			}
			catch (Exception ex)
			{
				screen = null;
				OpenFailed(ex);
			}
		}

		internal static void CloseScreen()
		{
			if ((Object)(object)screen != (Object)null)
			{
				ModMenuScreen modMenuScreen = screen;
				screen = null;
				((Component)modMenuScreen).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)modMenuScreen).gameObject);
			}
			hotkeyOpened = false;
			if (pausedByUs)
			{
				pausedByUs = false;
				SetGamePaused(paused: false);
			}
			if (cursorShown)
			{
				cursorShown = false;
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
			if ((Object)(object)pauseButton != (Object)null && ((Component)pauseButton).gameObject.activeInHierarchy && (Object)(object)EventSystem.current != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject(((Component)pauseButton).gameObject);
			}
		}

		private static Transform FindCanvas(Transform start)
		{
			Transform val = start;
			while ((Object)(object)val != (Object)null)
			{
				Canvas component = ((Component)val).GetComponent<Canvas>();
				if ((Object)(object)component != (Object)null && component.isRootCanvas)
				{
					return val;
				}
				val = val.parent;
			}
			return null;
		}

		private void OnDestroy()
		{
			Log("MOD_MENU_PLUGIN_OBJECT_DESTROYED (screen and patches continue)");
		}
	}
	internal sealed class ModMenuPress : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
	{
		internal Action Pressed;

		public void OnPointerDown(PointerEventData eventData)
		{
			if (Pressed != null)
			{
				Pressed();
			}
		}
	}
	internal sealed class ModMenuScreen : MonoBehaviour
	{
		private const float HeadingHeight = 46f;

		private const float HeadingStep = 58f;

		private const float RowHeight = 52f;

		private const float RowStep = 58f;

		private const float NoteHeight = 40f;

		private const float ModuleRowHeight = 50f;

		private const float ModuleRowStep = 56f;

		private const float Gutter = 0.075f;

		private RectTransform rows;

		private RectTransform area;

		private RectTransform previewHost;

		private RectTransform window;

		private TextMeshProUGUI subtitle;

		private TextMeshProUGUI status;

		private readonly List<Selectable> order = new List<Selectable>();

		private string signature;

		private ModModule open;

		private bool resetScroll;

		private string flash;

		private float flashUntil;

		internal static ModMenuScreen Create(Transform canvas)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			//IL_003b: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("FATE Mod Menu", new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(canvas, false);
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			((Transform)val2).SetAsLastSibling();
			ModMenuScreen modMenuScreen = val.AddComponent<ModMenuScreen>();
			modMenuScreen.Build();
			return modMenuScreen;
		}

		internal void Invalidate()
		{
			signature = null;
		}

		private void Build()
		{
			//IL_003d: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			ModMenuTheme.Font = FindFont();
			((Graphic)((Component)ModMenuTheme.Box(((Component)this).transform, "Backdrop", 0f, 0f, 1f, 1f, (Color?)new Color(0f, 0f, 0f, 0.62f))).GetComponent<Image>()).raycastTarget = true;
			RectTransform val = (window = ModMenuTheme.Box(((Component)this).transform, "Window", 0.17f, 0.055f, 0.83f, 0.945f, ModMenuTheme.Panel));
			Outline obj = ((Component)val).gameObject.AddComponent<Outline>();
			((Shadow)obj).effectColor = new Color(0.55f, 0.4f, 0.2f, 0.9f);
			((Shadow)obj).effectDistance = new Vector2(2f, -2f);
			((Graphic)((Component)ModMenuTheme.Box((Transform)(object)val, "Top rule", 0.03f, 0.936f, 0.97f, 0.944f, ModMenuTheme.Gold)).GetComponent<Image>()).raycastTarget = false;
			((Graphic)((Component)ModMenuTheme.Box((Transform)(object)val, "Bottom rule", 0.03f, 0.145f, 0.97f, 0.151f, (Color?)new Color(0.68f, 0.49f, 0.24f, 0.7f))).GetComponent<Image>()).raycastTarget = false;
			ModMenuTheme.Caption((Transform)(object)val, "MOD SETTINGS", 0.04f, 0.855f, 0.7f, 0.925f, 26, ModMenuTheme.Gold, (FontStyles)1, (TextAlignmentOptions)4097);
			subtitle = ModMenuTheme.Caption((Transform)(object)val, "", 0.04f, 0.8f, 0.96f, 0.855f, 14, ModMenuTheme.Muted, (FontStyles)0, (TextAlignmentOptions)4097);
			area = ModMenuTheme.Box((Transform)(object)val, "List", 0.04f, 0.175f, 0.96f, 0.795f);
			RectTransform val2 = ModMenuTheme.Box((Transform)(object)area, "Viewport", 0f, 0f, 0.965f, 1f, ModMenuTheme.Inset);
			((Component)val2).gameObject.AddComponent<RectMask2D>();
			rows = ModMenuTheme.Box((Transform)(object)val2, "Content", 0f, 1f, 1f, 1f);
			rows.anchorMin = new Vector2(0f, 1f);
			rows.anchorMax = new Vector2(1f, 1f);
			rows.pivot = new Vector2(0.5f, 1f);
			rows.anchoredPosition = Vector2.zero;
			rows.sizeDelta = new Vector2(0f, 58f);
			RectTransform obj2 = ModMenuTheme.Box((Transform)(object)area, "Scrollbar", 0.97f, 0f, 1f, 1f, ModMenuTheme.ScrollTrack);
			RectTransform val3 = ModMenuTheme.Box((Transform)(object)obj2, "Handle", 0f, 0f, 1f, 1f, ModMenuTheme.Gold);
			Scrollbar val4 = ((Component)obj2).gameObject.AddComponent<Scrollbar>();
			val4.handleRect = val3;
			((Selectable)val4).targetGraphic = (Graphic)(object)((Component)val3).GetComponent<Image>();
			val4.direction = (Direction)2;
			ScrollRect obj3 = ((Component)area).gameObject.AddComponent<ScrollRect>();
			obj3.viewport = val2;
			obj3.content = rows;
			obj3.horizontal = false;
			obj3.vertical = true;
			obj3.inertia = false;
			obj3.movementType = (MovementType)2;
			obj3.verticalScrollbar = val4;
			ModMenuScroll.Attach(obj3, rows, val2, 26.099998f);
			previewHost = ModMenuTheme.Box((Transform)(object)val, "Preview", 0.695f, 0.175f, 0.96f, 0.795f, ModMenuTheme.Inset);
			((Component)previewHost).gameObject.AddComponent<RectMask2D>();
			Outline obj4 = ((Component)previewHost).gameObject.AddComponent<Outline>();
			((Shadow)obj4).effectColor = new Color(0.47f, 0.37f, 0.24f, 0.55f);
			((Shadow)obj4).effectDistance = new Vector2(1f, -1f);
			((Component)previewHost).gameObject.SetActive(false);
			ModMenuTheme.Control((Transform)(object)val, "Back", 0.04f, 0.045f, 0.19f, 0.12f, Back);
			status = ModMenuTheme.Caption((Transform)(object)val, "", 0.21f, 0.045f, 0.96f, 0.12f, 14, ModMenuTheme.Muted, (FontStyles)0, (TextAlignmentOptions)4097);
			BuildRows();
		}

		private void Back()
		{
			if (open != null)
			{
				open = null;
				resetScroll = true;
				Invalidate();
				BuildRows();
			}
			else
			{
				ModMenuPlugin.CloseScreen();
			}
		}

		private void BuildRows()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			for (int num = ((Transform)rows).childCount - 1; num >= 0; num--)
			{
				GameObject gameObject = ((Component)((Transform)rows).GetChild(num)).gameObject;
				gameObject.SetActive(false);
				Object.Destroy((Object)(object)gameObject);
			}
			order.Clear();
			signature = Snapshot();
			bool flag = open != null && !open.Disposed;
			bool flag2 = flag && open.Settings.Any((ModSetting s) => s is ModPreview && !s.Removed);
			area.anchorMin = new Vector2(0.04f, 0.175f);
			area.anchorMax = (flag2 ? new Vector2(0.655f, 0.795f) : new Vector2(0.96f, 0.795f));
			((Component)previewHost).gameObject.SetActive(flag2);
			if (resetScroll)
			{
				resetScroll = false;
				rows.anchoredPosition = Vector2.zero;
			}
			float offset = 6f;
			int count = 0;
			offset = (flag ? BuildSettings(open, offset, ref count) : BuildModules(offset));
			rows.sizeDelta = new Vector2(0f, Mathf.Max(offset, 58f));
			((TMP_Text)subtitle).text = (flag ? (open.Name + "  /  " + count + " setting" + ((count == 1) ? "" : "s")) : "Choose a mod to adjust. Key bindings stay in Options > Controls.");
			((TMP_Text)status).text = ((ModMenuApi.Registered.Count((ModModule m) => !m.Disposed) == 0) ? ("FATE Mod Menu 0.4.2 / API v" + ModMenuApi.ApiVersion) : (count + " setting" + ((count == 1) ? "" : "s") + " / API v" + ModMenuApi.ApiVersion));
			if (!string.IsNullOrEmpty(flash) && Time.unscaledTime < flashUntil)
			{
				((TMP_Text)status).text = flash;
			}
			if (flag2)
			{
				BuildPreviewPane(open);
			}
			ChainNavigation();
			if (order.Count > 0 && (Object)(object)EventSystem.current != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject(((Component)order[0]).gameObject);
			}
		}

		private float BuildModules(float offset)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			ModModule[] array = ModMenuApi.Registered.Where((ModModule m) => !m.Disposed && m.Settings.Any((ModSetting s) => !s.Removed)).OrderBy<ModModule, string>((ModModule m) => m.Name, StringComparer.Ordinal).ToArray();
			if (array.Length == 0)
			{
				ModMenuTheme.Caption((Transform)(object)Row(offset, 64f), "No mod settings are registered yet. A mod appears here once it registers with FATE Mod Menu.", 0.02f, 0f, 0.98f, 1f, 15, ModMenuTheme.Muted, (FontStyles)0, (TextAlignmentOptions)4097);
				return offset + 80f;
			}
			ModModule[] array2 = array;
			foreach (ModModule modModule in array2)
			{
				ModModule target = modModule;
				int num2 = modModule.Settings.Count((ModSetting s) => !s.Removed);
				RectTransform row = Row(offset, 50f);
				offset += 56f;
				order.Add((Selectable)(object)RowButton(row, modModule.Name, num2 + ((num2 == 1) ? " setting" : " settings"), delegate
				{
					open = target;
					resetScroll = true;
					Invalidate();
					BuildRows();
				}));
			}
			return offset;
		}

		private float BuildSettings(ModModule module, float offset, ref int count)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0951: Unknown result type (might be due to invalid IL or missing references)
			ModSetting[] source = module.Settings.Where((ModSetting s) => !s.Removed).ToArray();
			string[] array = source.Select((ModSetting s) => s.Category).Distinct().ToArray();
			foreach (string category in array)
			{
				RectTransform val = Row(offset, 46f);
				offset += 58f;
				Image obj = ((Component)val).gameObject.AddComponent<Image>();
				((Graphic)obj).color = ModMenuTheme.Header;
				((Graphic)obj).raycastTarget = false;
				((Graphic)((Component)ModMenuTheme.Box((Transform)(object)val, "Divider", 0.015f, 0f, 0.985f, 0.03f, (Color?)new Color(0.68f, 0.49f, 0.24f, 0.7f))).GetComponent<Image>()).raycastTarget = false;
				ModMenuTheme.Caption((Transform)(object)val, category, 0.02f, 0.06f, 0.62f, 0.96f, 19, ModMenuTheme.Gold, (FontStyles)1, (TextAlignmentOptions)4097);
				order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)val, "Defaults", 0.8f, 0.14f, 0.985f, 0.88f, delegate
				{
					module.ResetCategory(category);
					Invalidate();
				}));
				foreach (ModSetting item in source.Where((ModSetting s) => s.Category == category))
				{
					count++;
					if (!(item is ModNote modNote))
					{
						if (item is ModPreview)
						{
							continue;
						}
						ModColor modColor = item as ModColor;
						if (modColor == null)
						{
							ModTrack modTrack = item as ModTrack;
							if (modTrack != null)
							{
								RectTransform val2 = Row(offset, 52f);
								offset += 58f;
								bool isPlaying = modTrack.IsPlaying;
								order.Add((Selectable)(object)ModMenuTheme.Icon((Transform)(object)val2, isPlaying ? ModMenuTheme.Square() : ModMenuTheme.Triangle(), 0f, 0.22f, 0.04f, 0.78f, (Color)(isPlaying ? new Color(0.85f, 0.55f, 0.3f) : ModMenuTheme.Gold), delegate
								{
									if (modTrack.IsPlaying)
									{
										modTrack.Stop();
									}
									else
									{
										modTrack.Preview();
									}
									Invalidate();
								}));
								float left = 0.046f;
								if (modTrack.RemoveAction != null)
								{
									order.Add((Selectable)(object)ModMenuTheme.Icon((Transform)(object)val2, ModMenuTheme.Cross(), 0.046f, 0.3f, 0.078f, 0.7f, new Color(0.78f, 0.42f, 0.32f), delegate
									{
										modTrack.Remove();
										Invalidate();
									}));
									left = 0.086f;
								}
								((TMP_Text)ModMenuTheme.Caption((Transform)(object)val2, modTrack.Label, left, 0f, 0.55f, 1f, 16, ModMenuTheme.Text, (FontStyles)1, (TextAlignmentOptions)4097)).overflowMode = (TextOverflowModes)1;
								order.Add((Selectable)(object)Checkbox(val2, modTrack.Enabled, delegate
								{
									modTrack.ToggleEnabled();
									Invalidate();
								}));
								order.Add((Selectable)(object)Glyph(val2, "<", 0.605f, 0.3f, 0.635f, 0.72f, delegate
								{
									modTrack.NudgeLoop(-1);
									Invalidate();
								}));
								TextMeshProUGUI caption = ModMenuTheme.Caption((Transform)(object)val2, modTrack.LoopText, 0.64f, 0.58f, 0.965f, 1f, 12, ModMenuTheme.Gold, (FontStyles)0, (TextAlignmentOptions)514);
								ModMenuTrackRow.Attach(val2, modTrack, caption);
								order.Add((Selectable)(object)Glyph(val2, ">", 0.968f, 0.3f, 0.998f, 0.72f, delegate
								{
									modTrack.NudgeLoop(1);
									Invalidate();
								}));
								continue;
							}
							RectTransform val3 = Row(offset, 52f);
							offset += 58f;
							ModToggle modToggle = item as ModToggle;
							if (modToggle == null)
							{
								ModSlider modSlider = item as ModSlider;
								if (modSlider == null)
								{
									if (!(item is ModChoice modChoice))
									{
										ModAction modAction = item as ModAction;
										if (modAction == null)
										{
											continue;
										}
										if (modAction.Wide)
										{
											order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)val3, modAction.Label, 0.45f, 0.06f, 0.996f, 0.94f, delegate
											{
												modAction.Invoke();
												Invalidate();
											}));
											continue;
										}
										ModMenuTheme.Caption((Transform)(object)val3, item.Label, 0.02f, 0f, 0.56f, 1f, 16, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)4097);
										order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)val3, "Run", 0.62f, 0.16f, 1f, 0.86f, delegate
										{
											modAction.Invoke();
											Invalidate();
										}));
									}
									else
									{
										ModMenuTheme.Caption((Transform)(object)val3, item.Label, 0.02f, 0f, 0.56f, 1f, 16, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)4097);
										NumberRow(val3, modChoice.Text, modChoice.Cycle);
									}
								}
								else
								{
									SliderRow(val3, modSlider.Label, () => modSlider.Normalized, delegate(float position)
									{
										modSlider.Seek(position);
									}, delegate(int direction)
									{
										modSlider.Nudge(direction);
									}, (float _) => modSlider.Text);
								}
							}
							else
							{
								ModMenuTheme.Caption((Transform)(object)val3, item.Label, 0.02f, 0f, 0.56f, 1f, 16, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)4097);
								order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)val3, modToggle.Value ? "On" : "Off", 0.62f, 0.16f, 1f, 0.86f, delegate
								{
									modToggle.SetValue(!modToggle.Value);
									Invalidate();
								}));
							}
							continue;
						}
						RectTransform parent = Row(offset, 52f);
						offset += 58f;
						ModMenuTheme.Caption((Transform)(object)parent, modColor.Label, 0.02f, 0f, 0.4f, 1f, 16, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)4097);
						Outline obj2 = ((Component)ModMenuTheme.Box((Transform)(object)parent, "Swatch", 0.42f, 0.22f, 0.5f, 0.78f, modColor.Value)).gameObject.AddComponent<Outline>();
						((Shadow)obj2).effectColor = new Color(0.47f, 0.37f, 0.24f, 0.9f);
						((Shadow)obj2).effectDistance = new Vector2(1f, -1f);
						ModColor target = modColor;
						RectTransform obj3 = ModMenuTheme.Box((Transform)(object)parent, "Hex", 0.52f, 0.18f, 0.845f, 0.82f, ModMenuTheme.Inset);
						Outline obj4 = ((Component)obj3).gameObject.AddComponent<Outline>();
						((Shadow)obj4).effectColor = new Color(0.47f, 0.37f, 0.24f, 0.7f);
						((Shadow)obj4).effectDistance = new Vector2(1f, -1f);
						TextMeshProUGUI caption2 = ModMenuTheme.Caption((Transform)(object)obj3, modColor.Hex, 0.06f, 0f, 0.94f, 1f, 15, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)4097);
						ModMenuHexField.Attach(obj3, caption2, () => target.Hex, (string value) => target.SetHex(value), delegate(string message)
						{
							Flash(message);
						});
						order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)parent, "Copy", 0.855f, 0.18f, 0.99f, 0.82f, delegate
						{
							Copy(target.Hex);
						}));
						for (int num2 = 0; num2 < 3; num2++)
						{
							int index = num2;
							RectTransform row = Row(offset, 52f);
							offset += 58f;
							SliderRow(row, ChannelName(index), () => modColor.Channel(index), delegate(float position)
							{
								modColor.SetChannel(index, position);
							}, delegate(int direction)
							{
								modColor.SetChannel(index, modColor.Channel(index) + (float)direction * 5f / 255f);
							}, (float _) => Mathf.RoundToInt(modColor.Channel(index) * 255f).ToString());
						}
					}
					else
					{
						RectTransform parent2 = Row(offset, 40f);
						offset += 46f;
						ModMenuTheme.Caption((Transform)(object)parent2, modNote.Content, 0.02f, 0f, 0.98f, 1f, 14, ModMenuTheme.Muted, (FontStyles)0, (TextAlignmentOptions)4097);
					}
				}
			}
			return offset;
		}

		private void Copy(string hex)
		{
			try
			{
				GUIUtility.systemCopyBuffer = hex;
				Flash("Copied " + hex + ".");
			}
			catch
			{
				Flash("Could not reach the clipboard.");
			}
		}

		private void Flash(string message, float seconds = 3.5f)
		{
			flash = message;
			flashUntil = Time.unscaledTime + seconds;
			if ((Object)(object)status != (Object)null)
			{
				((TMP_Text)status).text = message;
			}
		}

		private void BuildPreviewPane(ModModule module)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			for (int num = ((Transform)previewHost).childCount - 1; num >= 0; num--)
			{
				GameObject gameObject = ((Component)((Transform)previewHost).GetChild(num)).gameObject;
				gameObject.SetActive(false);
				Object.Destroy((Object)(object)gameObject);
			}
			ModPreview[] array = (from preview in module.Settings.OfType<ModPreview>()
				where !preview.Removed
				select preview).ToArray();
			float num2;
			if ((Object)(object)window != (Object)null)
			{
				Rect rect = window.rect;
				if (((Rect)(ref rect)).width > 1f)
				{
					rect = window.rect;
					num2 = ((Rect)(ref rect)).width * 0.265f;
					goto IL_00b1;
				}
			}
			num2 = 190f;
			goto IL_00b1;
			IL_00b1:
			float num3 = Mathf.Clamp(num2 - 26f, 80f, 260f);
			float num4 = 10f;
			ModPreview[] array2 = array;
			foreach (ModPreview modPreview in array2)
			{
				float num6 = Mathf.Clamp(Mathf.Min(modPreview.ImageHeight, num3), 80f, 260f);
				Pin(((TMP_Text)ModMenuTheme.Caption((Transform)(object)previewHost, modPreview.Label, 0f, 0f, 1f, 0f, 14, ModMenuTheme.Muted, (FontStyles)0, (TextAlignmentOptions)514)).rectTransform, 0f - num4, 22f);
				num4 += 26f;
				RectTransform val = ModMenuTheme.Box((Transform)(object)previewHost, "Frame", 0.5f, 0.5f, 0.5f, 0.5f, ModMenuTheme.Panel);
				val.anchorMin = new Vector2(0.5f, 1f);
				val.anchorMax = new Vector2(0.5f, 1f);
				val.pivot = new Vector2(0.5f, 1f);
				val.anchoredPosition = new Vector2(0f, 0f - num4);
				val.sizeDelta = new Vector2(num6, num6);
				Outline obj = ((Component)val).gameObject.AddComponent<Outline>();
				((Shadow)obj).effectColor = new Color(0.47f, 0.37f, 0.24f, 0.75f);
				((Shadow)obj).effectDistance = new Vector2(1f, -1f);
				Texture2D texture = modPreview.Texture;
				if ((Object)(object)texture == (Object)null)
				{
					ModMenuTheme.Caption((Transform)(object)val, "Preview unavailable", 0.06f, 0.06f, 0.94f, 0.94f, 12, ModMenuTheme.Muted, (FontStyles)0, (TextAlignmentOptions)514);
				}
				else
				{
					RawImage obj2 = ((Component)ModMenuTheme.Box((Transform)(object)val, "Image", 0.04f, 0.04f, 0.96f, 0.96f)).gameObject.AddComponent<RawImage>();
					obj2.texture = (Texture)(object)texture;
					((Graphic)obj2).color = Color.white;
					((Graphic)obj2).raycastTarget = false;
				}
				num4 += num6 + 14f;
			}
		}

		private Button RowButton(RectTransform row, string label, string trailing, Action clicked)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			Image val = ((Component)row).gameObject.AddComponent<Image>();
			((Graphic)val).color = ModMenuTheme.RowFill;
			Outline obj = ((Component)row).gameObject.AddComponent<Outline>();
			((Shadow)obj).effectColor = new Color(0.47f, 0.37f, 0.24f, 0.7f);
			((Shadow)obj).effectDistance = new Vector2(1f, -1f);
			Button obj2 = ((Component)row).gameObject.AddComponent<Button>();
			((Selectable)obj2).targetGraphic = (Graphic)(object)val;
			ColorBlock colors = ((Selectable)obj2).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.86f, 0.62f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.59f, 0.32f, 1f);
			((ColorBlock)(ref colors)).selectedColor = new Color(1f, 0.9f, 0.7f, 1f);
			((Selectable)obj2).colors = colors;
			ModMenuTheme.Caption((Transform)(object)row, label, 0.03f, 0f, 0.68f, 1f, 18, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)4097);
			ModMenuTheme.Caption((Transform)(object)row, trailing, 0.7f, 0f, 0.97f, 1f, 15, ModMenuTheme.Muted, (FontStyles)0, (TextAlignmentOptions)4100);
			((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate
			{
				clicked();
			});
			return obj2;
		}

		private void NumberRow(RectTransform row, string value, Action<int> step)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)row, "<", 0.58f, 0.16f, 0.66f, 0.86f, delegate
			{
				step(-1);
				Invalidate();
			}));
			((TMP_Text)ModMenuTheme.Caption((Transform)(object)row, value, 0.665f, 0.16f, 0.9f, 0.86f, 16, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)514)).overflowMode = (TextOverflowModes)1;
			order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)row, ">", 0.905f, 0.16f, 1f, 0.86f, delegate
			{
				step(1);
				Invalidate();
			}));
		}

		private void SliderRow(RectTransform row, string label, Func<float> read, Action<float> seek, Action<int> nudge, Func<float, string> format)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			ModMenuTheme.Caption((Transform)(object)row, label, 0.09f, 0.46f, 0.6f, 1f, 16, ModMenuTheme.Text, (FontStyles)0, (TextAlignmentOptions)4097);
			TextMeshProUGUI caption = ModMenuTheme.Caption((Transform)(object)row, format(read()), 0.6f, 0.46f, 0.91f, 1f, 16, ModMenuTheme.Gold, (FontStyles)0, (TextAlignmentOptions)4100);
			RectTransform obj = ModMenuTheme.Box((Transform)(object)row, "Track", 0.09f, 0.06f, 0.91f, 0.4f, ModMenuTheme.Inset);
			RectTransform val = ModMenuTheme.Box((Transform)(object)obj, "Fill", 0f, 0f, Mathf.Clamp01(read()), 1f, ModMenuTheme.Gold);
			((Graphic)((Component)val).GetComponent<Image>()).raycastTarget = false;
			RectTransform obj2 = ModMenuTheme.Box((Transform)(object)obj, "Handle", 0f, 0f, 0f, 1f, (Color?)new Color(1f, 0.94f, 0.78f, 1f));
			obj2.anchorMin = new Vector2(Mathf.Clamp01(read()), 0f);
			obj2.anchorMax = new Vector2(Mathf.Clamp01(read()), 1f);
			obj2.sizeDelta = new Vector2(8f, 8f);
			obj2.anchoredPosition = Vector2.zero;
			((Graphic)((Component)obj2).GetComponent<Image>()).raycastTarget = false;
			ModMenuSlider.Attach(obj, val, caption, read, seek, format);
			order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)row, "<", 0f, 0.14f, 0.075f, 0.86f, delegate
			{
				nudge(-1);
				Invalidate();
			}));
			order.Add((Selectable)(object)ModMenuTheme.Control((Transform)(object)row, ">", 0.925f, 0.14f, 1f, 0.86f, delegate
			{
				nudge(1);
				Invalidate();
			}));
		}

		private Button Glyph(RectTransform row, string glyph, float left, float bottom, float right, float top, Action clicked)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			RectTransform val = ModMenuTheme.Box((Transform)(object)row, glyph, left, bottom, right, top, (Color?)new Color(0.22f, 0.16f, 0.1f, 0.55f));
			Button obj = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)((Component)val).GetComponent<Image>();
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(1f, 1f, 1f, 0.35f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.86f, 0.62f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.59f, 0.32f, 1f);
			((ColorBlock)(ref colors)).selectedColor = new Color(1f, 0.9f, 0.7f, 1f);
			((Selectable)obj).colors = colors;
			ModMenuTheme.Caption((Transform)(object)val, glyph, 0.02f, 0f, 0.98f, 1f, 18, ModMenuTheme.Gold, (FontStyles)1, (TextAlignmentOptions)514);
			((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
			{
				clicked();
			});
			return obj;
		}

		private Button Checkbox(RectTransform row, bool on, Action toggle)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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)
			RectTransform val = ModMenuTheme.Box((Transform)(object)row, "Check", 0.565f, 0.24f, 0.595f, 0.76f, ModMenuTheme.Inset);
			Outline obj = ((Component)val).gameObject.AddComponent<Outline>();
			((Shadow)obj).effectColor = new Color(0.62f, 0.47f, 0.26f, 0.95f);
			((Shadow)obj).effectDistance = new Vector2(1f, -1f);
			if (on)
			{
				((Graphic)((Component)ModMenuTheme.Box((Transform)(object)val, "On", 0.18f, 0.18f, 0.82f, 0.82f, ModMenuTheme.Gold)).GetComponent<Image>()).raycastTarget = false;
			}
			Button obj2 = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj2).targetGraphic = (Graphic)(object)((Component)val).GetComponent<Image>();
			ColorBlock colors = ((Selectable)obj2).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.86f, 0.62f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.59f, 0.32f, 1f);
			((ColorBlock)(ref colors)).selectedColor = new Color(1f, 0.9f, 0.7f, 1f);
			((Selectable)obj2).colors = colors;
			((Component)val).gameObject.AddComponent<ModMenuPress>().Pressed = toggle;
			return obj2;
		}

		private RectTransform Row(float offset, float height)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = ModMenuTheme.Box((Transform)(object)rows, "Row", 0f, 1f, 1f, 1f);
			obj.anchorMin = new Vector2(0f, 1f);
			obj.anchorMax = new Vector2(1f, 1f);
			obj.pivot = new Vector2(0.5f, 1f);
			obj.anchoredPosition = new Vector2(0f, 0f - offset);
			obj.sizeDelta = new Vector2(0f, height);
			return obj;
		}

		private static void Pin(RectTransform rect, float top, float height)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = new Vector2(0f, 1f);
			rect.anchorMax = new Vector2(1f, 1f);
			rect.pivot = new Vector2(0.5f, 1f);
			rect.anchoredPosition = new Vector2(0f, top);
			rect.sizeDelta = new Vector2(0f, height);
		}

		private void ChainNavigation()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (order.Count >= 2)
			{
				for (int i = 0; i < order.Count; i++)
				{
					Navigation navigation = order[i].navigation;
					((Navigation)(ref navigation)).mode = (Mode)4;
					((Navigation)(ref navigation)).selectOnUp = order[(i + order.Count - 1) % order.Count];
					((Navigation)(ref navigation)).selectOnDown = order[(i + 1) % order.Count];
					order[i].navigation = navigation;
				}
			}
		}

		internal void Tick()
		{
			if (ModMenuHexField.Editing)
			{
				return;
			}
			Keyboard current = Keyboard.current;
			Gamepad current2 = Gamepad.current;
			if ((current != null && ((ButtonControl)current.escapeKey).wasPressedThisFrame) || (current2 != null && current2.buttonEast.wasPressedThisFrame))
			{
				Back();
			}
			else if (!ModMenuSlider.Dragging)
			{
				string text = Snapshot();
				if (text != signature)
				{
					signature = text;
					BuildRows();
				}
			}
		}

		private string Snapshot()
		{
			StringBuilder stringBuilder = new StringBuilder(256);
			stringBuilder.Append((open == null) ? "<mods>" : open.Id).Append('\n');
			foreach (ModModule item in ModMenuApi.Registered)
			{
				stringBuilder.Append(item.Id).Append('#');
				foreach (ModSetting setting in item.Settings)
				{
					stringBuilder.Append(setting.Id).Append('=').Append(setting.Describe())
						.Append(';');
				}
			}
			return stringBuilder.ToString();
		}

		private static string ChannelName(int index)
		{
			return index switch
			{
				1 => "Green", 
				0 => "Red", 
				_ => "Blue", 
			};
		}

		private static TMP_FontAsset FindFont()
		{
			TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			foreach (TextMeshProUGUI val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null && ((Object)((TMP_Text)val).transform.root).name != "FATE Mod Menu")
				{
					return ((TMP_Text)val).font;
				}
			}
			return null;
		}
	}
	internal sealed class ModMenuScroll : MonoBehaviour, IScrollHandler, IEventSystemHandler
	{
		private RectTransform content;

		private RectTransform viewport;

		private float rowStep;

		internal static void Attach(ScrollRect scroll, RectTransform content, RectTransform viewport, float rowStep)
		{
			scroll.scrollSensitivity = 0f;
			ModMenuScroll modMenuScroll = ((Component)scroll).gameObject.AddComponent<ModMenuScroll>();
			modMenuScroll.content = content;
			modMenuScroll.viewport = viewport;
			modMenuScroll.rowStep = rowStep;
		}

		public void OnScroll(PointerEventData eventData)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_009a: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)content == (Object)null) && !((Object)(object)viewport == (Object)null))
			{
				float y = eventData.scrollDelta.y;
				if (!Mathf.Approximately(y, 0f))
				{
					float num = ((Mathf.Abs(y) > 8f) ? (y / 120f) : y);
					num = Mathf.Clamp(num, -3f, 3f);
					Rect rect = content.rect;
					float height = ((Rect)(ref rect)).height;
					rect = viewport.rect;
					float num2 = Mathf.Max(0f, height - ((Rect)(ref rect)).height);
					float num3 = Mathf.Clamp(content.anchoredPosition.y - num * rowStep, 0f, num2);
					content.anchoredPosition = new Vector2(content.anchoredPosition.x, num3);
				}
			}
		}
	}
	internal sealed class ModMenuSlider : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IDragHandler, IPointerUpHandler
	{
		private RectTransform track;

		private RectTransform fill;

		private TextMeshProUGUI caption;

		private Func<float> read;

		private Action<float> seek;

		private Func<float, string> format;

		internal static bool Dragging { get; private set; }

		internal static ModMenuSlider Attach(RectTransform track, RectTransform fill, TextMeshProUGUI caption, Func<float> read, Action<float> seek, Func<float, string> format)
		{
			ModMenuSlider modMenuSlider = ((Component)track).gameObject.AddComponent<ModMenuSlider>();
			modMenuSlider.track = track;
			modMenuSlider.fill = fill;
			modMenuSlider.caption = caption;
			modMenuSlider.read = read;
			modMenuSlider.seek = seek;
			modMenuSlider.format = format;
			modMenuSlider.Refresh();
			return modMenuSlider;
		}

		public void OnPointerDown(PointerEventData eventData)
		{
			Dragging = true;
			Apply(eventData);
		}

		public void OnDrag(PointerEventData eventData)
		{
			Apply(eventData);
		}

		public void OnPointerUp(PointerEventData eventData)
		{
			Dragging = false;
			ModMenuPlugin.RequestRefresh();
		}

		private void Apply(PointerEventData eventData)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)track == (Object)null || seek == null)
			{
				return;
			}
			Camera pressEventCamera = eventData.pressEventCamera;
			Vector2 val = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(track, eventData.position, pressEventCamera, ref val))
			{
				Rect rect = track.rect;
				float width = ((Rect)(ref rect)).width;
				if (!(width <= 0f))
				{
					Action<float> action = seek;
					float x = val.x;
					rect = track.rect;
					action(Mathf.Clamp01((x - ((Rect)(ref rect)).xMin) / width));
					Refresh();
				}
			}
		}

		internal void Refresh()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)track == (Object)null || (Object)(object)fill == (Object)null || read == null)
			{
				return;
			}
			float num;
			try
			{
				num = Mathf.Clamp01(read());
			}
			catch
			{
				num = 0f;
			}
			fill.anchorMin = new Vector2(0f, 0f);
			fill.anchorMax = new Vector2(num, 1f);
			fill.offsetMin = Vector2.zero;
			fill.offsetMax = Vector2.zero;
			if (!((Object)(object)caption != (Object)null) || format == null)
			{
				return;
			}
			try
			{
				((TMP_Text)caption).text = format(num);
			}
			catch
			{
				((TMP_Text)caption).text = "";
			}
		}
	}
	internal static class ModMenuTheme
	{
		internal static readonly Color Gold = new Color(0.92f, 0.72f, 0.38f);

		internal static readonly Color Muted = new Color(0.64f, 0.56f, 0.42f);

		internal static readonly Color Text = new Color(0.91f, 0.87f, 0.79f);

		internal static readonly Color Panel = new Color(0.1f, 0.075f, 0.055f, 0.99f);

		internal static readonly Color Header = new Color(0.25f, 0.18f, 0.1f, 0.8f);

		internal static readonly Color ButtonFill = new Color(0.24f, 0.18f, 0.12f, 0.98f);

		internal static readonly Color Inset = new Color(0.07f, 0.055f, 0.04f, 0.98f);

		internal static readonly Color ScrollTrack = new Color(0.1f, 0.08f, 0.055f);

		internal static readonly Color RowFill = new Color(0.17f, 0.13f, 0.085f, 0.96f);

		internal static TMP_FontAsset Font;

		private static Sprite triangle;

		private static Sprite square;

		private static Sprite cross;

		internal static RectTransform Box(Transform parent, string name, float left, float bottom, float right, float top, Color? color = null)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = new Vector2(left, bottom);
			val2.anchorMax = new Vector2(right, top);
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			if (color.HasValue)
			{
				((Graphic)val.AddComponent<Image>()).color = color.Value;
			}
			return val2;
		}

		internal static TextMeshProUGUI Caption(Transform parent, string value, float left, float bottom, float right, float top, int size, Color color, FontStyles style = (FontStyles)0, TextAlignmentOptions align = (TextAlignmentOptions)4097)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = ((Component)Box(parent, "Label", left, bottom, right, top)).gameObject.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)Font != (Object)null)
			{
				((TMP_Text)val).font = Font;
				((TMP_Text)val).fontSharedMaterial = ((TMP_Asset)Font).material;
			}
			((TMP_Text)val).fontSize = size;
			((Graphic)val).color = color;
			((TMP_Text)val).text = value;
			((TMP_Text)val).alignment = align;
			((TMP_Text)val).fontStyle = style;
			((TMP_Text)val).richText = false;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)val).overflowMode = (TextOverflowModes)1;
			return val;
		}

		internal static Sprite Triangle()
		{
			if ((Object)(object)triangle != (Object)null)
			{
				return triangle;
			}
			triangle = Build(24, delegate(int x, int y)
			{
				float num = 11.5f;
				float num2 = (23f - (float)x) / 23f * num;
				return Mathf.Abs((float)y - 11.5f) <= num2;
			});
			return triangle;
		}

		internal static Sprite Square()
		{
			if ((Object)(object)square != (Object)null)
			{
				return square;
			}
			square = Build(24, (int x, int y) => x >= 3 && x <= 20 && y >= 3 && y <= 20);
			return square;
		}

		internal static Sprite Cross()
		{
			if ((Object)(object)cross != (Object)null)
			{
				return cross;
			}
			cross = Build(24, (int x, int y) => Mathf.Abs(x - y) <= 2 || Mathf.Abs(x + y - 23) <= 2);
			return cross;
		}

		private static Sprite Build(int size, Func<int, int, bool> opaque)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			Color32[] array = (Color32[])(object)new Color32[size * size];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					array[i * size + j] = (opaque(j, i) ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) : new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)0));
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), (float)size);
		}

		internal static Button Icon(Transform parent, Sprite sprite, float left, float bottom, float right, float top, Color color, Action clicked)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Box(parent, "Icon", left, bottom, right, top);
			Image val = ((Component)obj).gameObject.AddComponent<Image>();
			val.sprite = sprite;
			((Graphic)val).color = color;
			val.preserveAspect = true;
			Button obj2 = ((Component)obj).gameObject.AddComponent<Button>();
			((Selectable)obj2).targetGraphic = (Graphic)(object)val;
			ColorBlock colors = ((Selectable)obj2).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.88f, 0.68f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.59f, 0.32f, 1f);
			((ColorBlock)(ref colors)).selectedColor = new Color(1f, 0.92f, 0.76f, 1f);
			((Selectable)obj2).colors = colors;
			((Component)obj2).gameObject.AddComponent<ModMenuPress>().Pressed = clicked;
			return obj2;
		}

		internal static Button Control(Transform parent, string label, float left, float bottom, float right, float top, Action clicked)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			RectTransform val = Box(parent, label, left, bottom, right, top, ButtonFill);
			Outline obj = ((Component)val).gameObject.AddComponent<Outline>();
			((Shadow)obj).effectColor = new Color(0.47f, 0.37f, 0.24f, 0.9f);
			((Shadow)obj).effectDistance = new Vector2(1f, -1f);
			Button obj2 = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj2).targetGraphic = (Graphic)(object)((Component)val).GetComponent<Image>();
			ColorBlock colors = ((Selectable)obj2).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.86f, 0.62f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.59f, 0.32f, 1f);
			((ColorBlock)(ref colors)).selectedColor = new Color(1f, 0.9f, 0.7f, 1f);
			((Selectable)obj2).colors = colors;
			Caption((Transform)(object)val, label, 0.05f, 0f, 0.95f, 1f, 15, Gold, (FontStyles)0, (TextAlignmentOptions)514);
			((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate
			{
				clicked();
			});
			return obj2;
		}
	}
	internal sealed class ModMenuTrackRow : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IDragHandler, IPointerUpHandler
	{
		private RectTransform track;

		private RectTransform fill;

		private RectTransform handle;

		private TextMeshProUGUI caption;

		private ModTrack setting;

		internal static void Attach(RectTransform row, ModTrack setting, TextMeshProUGUI caption)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = ModMenuTheme.Box((Transform)(object)row, "Loop", 0.64f, 0.06f, 0.965f, 0.46f