Decompiled source of Bindrune v0.4.0

Bindrune.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Bindrune.Conflicts;
using Bindrune.Context;
using Bindrune.Discovery;
using Bindrune.Hints;
using Bindrune.Personal;
using Bindrune.UI;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("isimp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 isimp")]
[assembly: AssemblyDescription("Every keybind from every mod and the game itself in one panel, with the clashes between them explained.")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyInformationalVersion("0.4.0+90d0807d9744c0c1dd8f6157f783f0b481960f7b")]
[assembly: AssemblyProduct("Bindrune")]
[assembly: AssemblyTitle("Bindrune")]
[assembly: AssemblyVersion("0.4.0.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 Bindrune
{
	public enum BindSource
	{
		Vanilla,
		Gamepad,
		Jotunn,
		ModTyped,
		ModText
	}
	public enum ModifierBehavior
	{
		Strict,
		SingleKey,
		Unknown,
		Required
	}
	public class BindEntry
	{
		public string Id;

		public string OwnerName;

		public string OwnerGuid;

		public string Label;

		public string Section;

		public string Description;

		public BindSource Source;

		public ModifierBehavior Modifiers;

		public KeyCombo Combo;

		public bool Internal;

		public bool Compared = true;

		public bool Editable;

		public string ReadOnlyReason;

		public object Handle;

		public override string ToString()
		{
			return $"{OwnerName} / {Label} = {Combo}";
		}
	}
	public static class BindIds
	{
		public static string Config(string guid, string section, string key)
		{
			return "cfg:" + guid + ":" + section + ":" + key;
		}

		public static string Jotunn(string buttonKey)
		{
			return "jotunn:" + buttonKey;
		}

		public static string Vanilla(string buttonName)
		{
			return "vanilla:" + buttonName;
		}

		public static string Game(string name)
		{
			return "game:" + name;
		}

		public static string Gamepad(string buttonName, string layout)
		{
			return "gamepad:" + layout + ":" + buttonName;
		}
	}
	public static class BindWriter
	{
		public const string UnseenByMods = "mods read keys through Unity's older input, which cannot see this key, so only the game's own controls can use it";

		public static string Refusal(BindEntry bind, KeyCombo combo)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if (!bind.Editable)
			{
				return bind.ReadOnlyReason ?? "this bind cannot be changed from here";
			}
			if (bind.Source != BindSource.Vanilla)
			{
				if ((int)combo.Main != 0 || !combo.IsBound)
				{
					return null;
				}
				return "mods read keys through Unity's older input, which cannot see this key, so only the game's own controls can use it";
			}
			object handle = bind.Handle;
			ButtonDef val = (ButtonDef)((handle is ButtonDef) ? handle : null);
			bool flag = val != null && FixedKeys.IsHotbar(val.Name);
			if (combo.Modifiers.Length > (flag ? 1 : 0))
			{
				if (!flag)
				{
					return "the game stores one key per bind and has no modifier support, so pick a single key";
				}
				return "a hotbar key can have one modifier at most";
			}
			if (combo.Modifiers.Length == 1 && KeyPaths.ToPath(combo.Modifiers[0]) == null)
			{
				return $"the game has no input path for {combo.Modifiers[0]}";
			}
			if (string.IsNullOrEmpty(combo.RawPath) && KeyPaths.ToPath(combo.Main) == null)
			{
				return $"the game has no input path for {combo.Main}";
			}
			return null;
		}

		public static string Apply(BindEntry bind, KeyCombo combo, SaveTarget target = SaveTarget.Personal)
		{
			string text = Refusal(bind, combo);
			if (text != null)
			{
				return text;
			}
			try
			{
				bool wrote = false;
				string text2;
				switch (bind.Source)
				{
				case BindSource.Vanilla:
					text2 = ApplyVanilla(bind, combo);
					wrote = text2 == null;
					break;
				case BindSource.Jotunn:
					text2 = ApplyJotunn(bind, combo, out wrote);
					break;
				default:
					text2 = ApplyConfig(bind, combo, out wrote);
					break;
				}
				if (wrote)
				{
					Remember(bind, target);
				}
				return text2;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Bindrune: writing {bind.Id} failed: {arg}");
				return "writing the new key failed, see the log";
			}
		}

		public static KeyCombo DefaultOf(BindEntry bind)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				switch (bind.Source)
				{
				case BindSource.Vanilla:
				{
					object handle3 = bind.Handle;
					ButtonDef val3 = (ButtonDef)((handle3 is ButtonDef) ? handle3 : null);
					if (val3 == null)
					{
						return KeyCombo.None;
					}
					return new KeyCombo(KeyPaths.FromPath(AccessTools.Method(typeof(ButtonDef), "GetActionPath", (Type[])null, (Type[])null)?.Invoke(val3, new object[1] { false }) as string), null);
				}
				case BindSource.Jotunn:
				{
					object handle2 = bind.Handle;
					ButtonConfig val2 = (ButtonConfig)((handle2 is ButtonConfig) ? handle2 : null);
					if (((val2 != null) ? val2.ShortcutConfig : null) != null)
					{
						return FromDefault((ConfigEntryBase)(object)val2.ShortcutConfig);
					}
					return (((val2 != null) ? val2.Config : null) != null) ? FromDefault((ConfigEntryBase)(object)val2.Config) : KeyCombo.None;
				}
				default:
				{
					object handle = bind.Handle;
					ConfigEntryBase val = (ConfigEntryBase)((handle is ConfigEntryBase) ? handle : null);
					return (val != null) ? FromDefault(val) : KeyCombo.None;
				}
				}
			}
			catch (Exception ex)
			{
				Plugin.WarnOnce("Bindrune: no default for " + bind.Id + ": " + ex.Message, null, "/home/runner/work/Bindrune/Bindrune/src/BindWriter.cs", 106);
				return KeyCombo.None;
			}
		}

		private static KeyCombo FromDefault(ConfigEntryBase entry)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			object defaultValue = entry.DefaultValue;
			if (defaultValue is KeyboardShortcut val)
			{
				return new KeyCombo(((KeyboardShortcut)(ref val)).MainKey, ((KeyboardShortcut)(ref val)).Modifiers);
			}
			if (defaultValue is KeyCode main)
			{
				return new KeyCombo(main, null);
			}
			return KeyCombo.None;
		}

		public static string Reset(BindEntry bind)
		{
			if (!bind.Editable)
			{
				return bind.ReadOnlyReason ?? "this bind cannot be changed from here";
			}
			try
			{
				if (bind.Source == BindSource.Vanilla)
				{
					object handle = bind.Handle;
					ButtonDef val = (ButtonDef)((handle is ButtonDef) ? handle : null);
					if (val == null)
					{
						return "this game bind is not writable";
					}
					(FixedKeys.Live(val.Name) ?? val).ResetBinding();
					if (FixedKeys.IsHotbar(val.Name))
					{
						FixedKeys.Forget(val.Name);
					}
					ZInput instance = ZInput.instance;
					if (instance != null)
					{
						AccessTools.Method(typeof(ZInput), "Save", (Type[])null, (Type[])null)?.Invoke(instance, null);
					}
					bind.Combo = DefaultOf(bind);
					PersonalKeys.Forget(bind.Id);
					return null;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Bindrune: resetting {bind.Id} failed: {arg}");
				return "resetting the key failed, see the log";
			}
			KeyCombo combo = DefaultOf(bind);
			return Apply(bind, combo, SaveTarget.Profile);
		}

		private static void Remember(BindEntry bind, SaveTarget target)
		{
			if (target != SaveTarget.Unrecorded && PersonalKeys.Eligible(bind))
			{
				PersonalKeys.RecordRebind(bind.Id, bind.Combo, target == SaveTarget.Personal);
			}
		}

		private static string ApplyConfig(BindEntry bind, KeyCombo combo, out bool wrote)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			wrote = false;
			object handle = bind.Handle;
			ConfigEntryBase val = (ConfigEntryBase)((handle is ConfigEntryBase) ? handle : null);
			if (val == null)
			{
				return "this bind has no config entry behind it";
			}
			if (val.SettingType == typeof(KeyboardShortcut))
			{
				val.BoxedValue = (object)(KeyboardShortcut)(((int)combo.Main == 0) ? KeyboardShortcut.Empty : new KeyboardShortcut(combo.Main, combo.Modifiers));
			}
			else
			{
				if (!(val.SettingType == typeof(KeyCode)))
				{
					return "this setting is not a key type";
				}
				val.BoxedValue = combo.Main;
				if (combo.Modifiers.Length != 0)
				{
					Save(val);
					bind.Combo = new KeyCombo(combo.Main, null);
					wrote = true;
					return bind.OwnerName + " stores a single key here, so the modifiers were dropped";
				}
			}
			Save(val);
			bind.Combo = combo;
			wrote = true;
			return null;
		}

		private static string ApplyJotunn(BindEntry bind, KeyCombo combo, out bool wrote)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			wrote = false;
			object handle = bind.Handle;
			ButtonConfig val = (ButtonConfig)((handle is ButtonConfig) ? handle : null);
			if (val == null)
			{
				return "this button has no config behind it";
			}
			if (val.ShortcutConfig != null)
			{
				val.ShortcutConfig.Value = (KeyboardShortcut)(((int)combo.Main == 0) ? KeyboardShortcut.Empty : new KeyboardShortcut(combo.Main, combo.Modifiers));
				Save((ConfigEntryBase)(object)val.ShortcutConfig);
			}
			else
			{
				if (val.Config == null)
				{
					return "this button has no config behind it";
				}
				val.Config.Value = combo.Main;
				Save((ConfigEntryBase)(object)val.Config);
				if (combo.Modifiers.Length != 0)
				{
					bind.Combo = new KeyCombo(combo.Main, null);
					wrote = true;
					return bind.OwnerName + " stores a single key here, so the modifiers were dropped";
				}
			}
			bind.Combo = combo;
			wrote = true;
			return null;
		}

		private static string ApplyVanilla(BindEntry bind, KeyCombo combo)
		{
			//IL_0023: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			object handle = bind.Handle;
			ButtonDef val = (ButtonDef)((handle is ButtonDef) ? handle : null);
			if (val == null)
			{
				return "this game bind is not writable";
			}
			string text = ((!string.IsNullOrEmpty(combo.RawPath)) ? combo.RawPath : KeyPaths.ToPath(combo.Main));
			string text2 = ((combo.Modifiers.Length == 1) ? KeyPaths.ToPath(combo.Modifiers[0]) : null);
			if (FixedKeys.IsDigit(val.Name) || (FixedKeys.IsAlt(val.Name) && text2 != null))
			{
				FixedKeys.Set(val.Name, (text2 == null) ? text : (text2 + "+" + text));
			}
			else
			{
				if (FixedKeys.IsAlt(val.Name))
				{
					FixedKeys.Forget(val.Name);
				}
				(FixedKeys.Live(val.Name) ?? val).Rebind(text);
			}
			ZInput instance = ZInput.instance;
			if (instance != null)
			{
				AccessTools.Method(typeof(ZInput), "Save", (Type[])null, (Type[])null)?.Invoke(instance, null);
			}
			if (FixedKeys.IsHotbar(val.Name))
			{
				FixedKeys.Relabel();
			}
			bind.Combo = ((!combo.IsBound) ? KeyCombo.None : (((int)combo.Main != 0) ? new KeyCombo(combo.Main, combo.Modifiers) : new KeyCombo((KeyCode)0, combo.Modifiers, text)));
			return null;
		}

		private static void Save(ConfigEntryBase entry)
		{
			ConfigFile configFile = entry.ConfigFile;
			if (configFile != null)
			{
				bool saveOnConfigSet = configFile.SaveOnConfigSet;
				configFile.SaveOnConfigSet = false;
				configFile.Save();
				configFile.SaveOnConfigSet = saveOnConfigSet;
			}
		}
	}
	internal static class FixedKeys
	{
		private static readonly string[] Digits;

		private static readonly string[] Alts;

		private static readonly string[] Hotbar;

		private const string None = "none";

		private const string HotbarWord = "$radial_hotbar";

		private static FieldInfo _buttonsField;

		private static MethodInfo _getPath;

		private static Dictionary<string, string> _moved;

		private static List<string> _other;

		private static readonly HashSet<string> Applied;

		private static ZInput _restoredFor;

		public static int Version { get; private set; }

		public static bool BarChanged
		{
			get
			{
				Dictionary<string, string> moved = Moved;
				string[] digits = Digits;
				foreach (string key in digits)
				{
					if (moved.ContainsKey(key))
					{
						return true;
					}
				}
				return false;
			}
		}

		private static Dictionary<string, string> Moved
		{
			get
			{
				if (_moved == null)
				{
					Load();
				}
				return _moved;
			}
		}

		static FixedKeys()
		{
			Digits = new string[8] { "Hotbar1", "Hotbar2", "Hotbar3", "Hotbar4", "Hotbar5", "Hotbar6", "Hotbar7", "Hotbar8" };
			Alts = Digits.Select((string d) => d + "Alt").ToArray();
			Hotbar = Digits.Concat(Alts).ToArray();
			Applied = new HashSet<string>();
			PersonalStore.Reloaded += delegate
			{
				_moved = null;
				_restoredFor = null;
			};
		}

		public static bool IsDigit(string button)
		{
			return Array.IndexOf(Digits, button) >= 0;
		}

		public static bool IsAlt(string button)
		{
			return Array.IndexOf(Alts, button) >= 0;
		}

		public static bool IsHotbar(string button)
		{
			return Array.IndexOf(Hotbar, button) >= 0;
		}

		public static ButtonDef Live(string name)
		{
			ZInput instance = ZInput.instance;
			if (instance != null)
			{
				return Button(instance, name);
			}
			return null;
		}

		public static void Patch(Harmony harmony)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			try
			{
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(FixedKeys), "AfterControlsLoaded", (Type[])null, (Type[])null));
				MethodInfo methodInfo = AccessTools.Method(typeof(ZInput), "Load", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.WarnOnce("Bindrune: the game's control loading was not found, so a moved hotbar key comes back when the game starts but not after the Controls screen.", null, "/home/runner/work/Bindrune/Bindrune/src/FixedKeys.cs", 118);
				}
				MethodInfo methodInfo2 = AccessTools.Method(typeof(ZInput), "ResetToDefault", (Type[])null, (Type[])null);
				if (methodInfo2 != null)
				{
					harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.WarnOnce("Bindrune: the game's control reset was not found, so resetting the controls also resets a moved hotbar key until the game next loads them.", null, "/home/runner/work/Bindrune/Bindrune/src/FixedKeys.cs", 124);
				}
				MethodInfo methodInfo3 = AccessTools.Method(typeof(ZInput), "StartBindKey", (Type[])null, (Type[])null);
				if (methodInfo3 != null)
				{
					harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(AccessTools.Method(typeof(FixedKeys), "BeforeGameRebind", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.WarnOnce("Bindrune: the game's own rebinding was not found, so an Alt hotbar key with a modifier comes back after you rebind it in the Controls screen.", null, "/home/runner/work/Bindrune/Bindrune/src/FixedKeys.cs", 131);
				}
			}
			catch (Exception ex)
			{
				Plugin.WarnOnce("Bindrune: could not follow the game reloading its controls: " + ex.Message, ex, "/home/runner/work/Bindrune/Bindrune/src/FixedKeys.cs", 136);
			}
		}

		private static void AfterControlsLoaded(ZInput __instance)
		{
			RestoreFor(__instance);
		}

		private static void BeforeGameRebind(string name)
		{
			try
			{
				if (IsAlt(name) && Moved.ContainsKey(name))
				{
					Forget(name);
				}
			}
			catch (Exception ex)
			{
				Plugin.WarnOnce("Bindrune: could not hand " + name + " back to the game: " + ex.Message, ex, "/home/runner/work/Bindrune/Bindrune/src/FixedKeys.cs", 159);
			}
		}

		public static void EnsureRestored()
		{
			ZInput instance = ZInput.instance;
			if (instance != null && instance != _restoredFor)
			{
				RestoreFor(instance);
			}
		}

		public static void Relabel()
		{
			ZInput instance = ZInput.instance;
			if (instance == null)
			{
				return;
			}
			Version++;
			try
			{
				ShowInPrompts(instance);
			}
			catch (Exception ex)
			{
				Plugin.WarnOnce("Bindrune: could not rename the hotbar keys in the game's prompts: " + ex.Message, ex, "/home/runner/work/Bindrune/Bindrune/src/FixedKeys.cs", 184);
			}
		}

		public static void Set(string button, string stored)
		{
			PersonalStore.Sync();
			Moved[button] = (IsNone(stored) ? "none" : stored);
			Save();
			Apply();
		}

		public static void Forget(string button)
		{
			PersonalStore.Sync();
			if (Moved.Remove(button))
			{
				Save();
			}
			Apply();
		}

		public static string SlotLabel(ZInput zinput, int index)
		{
			string text = (index + 1).ToString(CultureInfo.InvariantCulture);
			string text2 = "Hotbar" + text;
			if (!Moved.ContainsKey(text2))
			{
				return text;
			}
			string text3 = KeyOn(zinput, text2);
			if (text3.Length <= 0)
			{
				return KeyOn(zinput, text2 + "Alt");
			}
			return text3;
		}

		private static string KeyOn(ZInput zinput, string name)
		{
			if (Moved.TryGetValue(name, out var value))
			{
				if (!(value == "none"))
				{
					return LabelOf(value);
				}
				return "";
			}
			string text = PathOf(Button(zinput, name));
			if (!IsNone(text))
			{
				return LabelOf(text);
			}
			return "";
		}

		private static void Apply()
		{
			ZInput instance = ZInput.instance;
			if (instance != null)
			{
				RestoreFor(instance);
			}
		}

		private static void RestoreFor(ZInput zinput)
		{
			_restoredFor = zinput;
			try
			{
				Restore(zinput);
			}
			catch (Exception ex)
			{
				Plugin.WarnOnce("Bindrune: could not put the moved hotbar keys back: " + ex.Message, ex, "/home/runner/work/Bindrune/Bindrune/src/FixedKeys.cs", 257);
			}
		}

		private static void Restore(ZInput zinput)
		{
			string[] hotbar = Hotbar;
			foreach (string text in hotbar)
			{
				ButtonDef val = Button(zinput, text);
				if (val != null)
				{
					if (Moved.TryGetValue(text, out var value))
					{
						Put(val, value);
					}
					else if (Applied.Contains(text))
					{
						Put(val, null);
					}
				}
			}
			Applied.Clear();
			Applied.UnionWith(Moved.Keys);
			Version++;
			ShowInPrompts(zinput);
		}

		private static void Put(ButtonDef button, string stored)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			//IL_00a8: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			InputAction buttonAction = button.ButtonAction;
			buttonAction.Disable();
			while (buttonAction.bindings.Count > 1)
			{
				BindingSyntax val = InputActionSetupExtensions.ChangeBinding(buttonAction, 1);
				((BindingSyntax)(ref val)).Erase();
			}
			buttonAction.Enable();
			if (stored == null)
			{
				button.ResetBinding();
				return;
			}
			string[] array = stored.Split(new char[1] { '+' });
			string text = ((array[^1] == "none") ? KeyPaths.ToPath((KeyCode)0) : array[^1]);
			if (text == null)
			{
				return;
			}
			if (array.Length == 1)
			{
				button.Rebind(text);
				return;
			}
			string text2 = KeyPaths.ToPath((KeyCode)0);
			if (text2 != null)
			{
				button.Rebind(text2);
				buttonAction.Disable();
				CompositeSyntax val2 = InputActionSetupExtensions.AddCompositeBinding(buttonAction, "OneModifier", (string)null, (string)null);
				val2 = ((CompositeSyntax)(ref val2)).With("Modifier", array[0], (string)null, (string)null);
				((CompositeSyntax)(ref val2)).With("Binding", text, (string)null, (string)null);
				buttonAction.Enable();
			}
		}

		public static KeyCombo? Composite(ButtonDef button)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected I4, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			string path = null;
			string text = null;
			Enumerator<InputBinding> enumerator = button.ButtonAction.bindings.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					InputBinding current = enumerator.Current;
					if (((InputBinding)(ref current)).isPartOfComposite)
					{
						if (string.Equals(((InputBinding)(ref current)).name, "modifier", StringComparison.OrdinalIgnoreCase))
						{
							path = ((InputBinding)(ref current)).effectivePath;
						}
						else if (string.Equals(((InputBinding)(ref current)).name, "binding", StringComparison.OrdinalIgnoreCase))
						{
							text = ((InputBinding)(ref current)).effectivePath;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (text == null)
			{
				return null;
			}
			KeyCode val = KeyPaths.FromPath(text);
			KeyCode val2 = KeyPaths.FromPath(path);
			return new KeyCombo(val, (IEnumerable<KeyCode>)(object)(((int)val2 == 0) ? null : new KeyCode[1] { (KeyCode)(int)val2 }), ((int)val == 0) ? text : null);
		}

		private static void ShowInPrompts(ZInput zinput)
		{
			ButtonDef val = Button(zinput, "HotbarUse");
			if (val != null)
			{
				List<string> list = Summarise(from i in Enumerable.Range(0, Digits.Length)
					select SlotLabel(zinput, i));
				string text = ((list.Count <= 2) ? string.Join("/", list.ToArray()) : "$radial_hotbar");
				if (!(val.DisplayNameOverride == text))
				{
					val.DisplayNameOverride = text;
					ForgetTranslations();
				}
			}
		}

		private static List<string> Summarise(IEnumerable<string> labels)
		{
			List<string> list = labels.Where((string l) => l.Length > 0).ToList();
			List<string> list2 = new List<string>();
			int num = 0;
			while (num < list.Count)
			{
				int num2;
				for (num2 = num; num2 + 1 < list.Count && Follows(list[num2], list[num2 + 1]); num2++)
				{
				}
				if (num2 - num >= 2)
				{
					list2.Add(Range(list[num], list[num2]));
				}
				else
				{
					for (int num3 = num; num3 <= num2; num3++)
					{
						list2.Add(list[num3]);
					}
				}
				num = num2 + 1;
			}
			return list2;
		}

		private static string Range(string first, string last)
		{
			Split(first, out var prefix, out var _);
			Split(last, out var _, out var number2);
			if (!prefix.TrimEnd(Array.Empty<char>()).EndsWith("+", StringComparison.Ordinal))
			{
				return first + "-" + last;
			}
			return first + "-" + number2.ToString(CultureInfo.InvariantCulture);
		}

		private static bool Follows(string a, string b)
		{
			if (Split(a, out var prefix, out var number) && Split(b, out var prefix2, out var number2) && prefix == prefix2)
			{
				return number2 == number + 1;
			}
			return false;
		}

		private static bool Split(string label, out string prefix, out int number)
		{
			int num = label.Length;
			while (num > 0 && label[num - 1] >= '0' && label[num - 1] <= '9')
			{
				num--;
			}
			prefix = label.Substring(0, num);
			return int.TryParse(label.Substring(num), NumberStyles.None, CultureInfo.InvariantCulture, out number);
		}

		private static void ForgetTranslations()
		{
			object obj = AccessTools.Field(typeof(Localization), "m_instance")?.GetValue(null);
			object obj2 = ((obj == null) ? null : AccessTools.Field(typeof(Localization), "m_cache")?.GetValue(obj));
			if (obj2 != null)
			{
				AccessTools.Method(obj2.GetType(), "EvictAll", (Type[])null, (Type[])null)?.Invoke(obj2, null);
			}
		}

		private static string LabelOf(string stored)
		{
			//IL_002a: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			string[] array = stored.Split(new char[1] { '+' });
			string text = KeyOf(array[^1]);
			if (array.Length == 1)
			{
				return text;
			}
			KeyCode val = KeyPaths.FromPath(array[0]);
			return (((int)val != 0) ? KeyLabels.Modifier(val) : KeyLabels.OfPath(array[0])) + "\u00a0+\u00a0" + text;
		}

		private static string KeyOf(string path)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			KeyCode val = KeyPaths.FromPath(path);
			if ((int)val == 0)
			{
				return KeyLabels.OfPath(path);
			}
			return KeyLabels.Of(val);
		}

		private static bool IsNone(string path)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(path) && !(path == "none"))
			{
				if ((int)KeyPaths.FromPath(path) == 0)
				{
					return path.EndsWith("/None", StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}
			return true;
		}

		private static ButtonDef Button(ZInput zinput, string name)
		{
			if (_buttonsField == null)
			{
				_buttonsField = AccessTools.Field(typeof(ZInput), "m_buttons");
			}
			if (!(_buttonsField?.GetValue(zinput) is IDictionary dictionary) || !dictionary.Contains(name))
			{
				return null;
			}
			object? obj = dictionary[name];
			return (ButtonDef)((obj is ButtonDef) ? obj : null);
		}

		private static string PathOf(ButtonDef button)
		{
			if (button == null)
			{
				return null;
			}
			if (_getPath == null)
			{
				_getPath = AccessTools.Method(typeof(ButtonDef), "GetActionPath", (Type[])null, (Type[])null);
			}
			return _getPath?.Invoke(button, new object[1] { true }) as string;
		}

		private static void Load()
		{
			_moved = new Dictionary<string, string>();
			_other = new List<string>();
			foreach (string item in PersonalStore.Lines("fixed"))
			{
				string[] array = item.Split(new char[1] { '\t' });
				if (array.Length == 2 && IsHotbar(array[0]) && array[1].Length > 0)
				{
					_moved[array[0]] = array[1];
				}
				else
				{
					_other.Add(item);
				}
			}
		}

		private static void Save()
		{
			Dictionary<string, string> moved = Moved;
			PersonalStore.Replace("fixed", _other.Concat(from e in moved.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> e) => e.Key, StringComparer.Ordinal)
				select e.Key + "\t" + e.Value));
		}
	}
	public readonly struct KeyCombo : IEquatable<KeyCombo>
	{
		public static readonly KeyCombo None = new KeyCombo((KeyCode)0, null);

		public readonly KeyCode Main;

		public readonly KeyCode[] Modifiers;

		public readonly string RawPath;

		private readonly string _token;

		public bool IsBound
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)Main == 0)
				{
					return !string.IsNullOrEmpty(RawPath);
				}
				return true;
			}
		}

		public string MainLabel
		{
			get
			{
				//IL_0001: 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)
				if ((int)Main == 0)
				{
					if (!string.IsNullOrEmpty(RawPath))
					{
						return RawPath;
					}
					return "not bound";
				}
				return ((object)Main/*cast due to .constrained prefix*/).ToString();
			}
		}

		public string MainToken => _token ?? Token(Main, RawPath);

		public KeyCombo(KeyCode main, IEnumerable<KeyCode> modifiers, string rawPath = null)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			Main = main;
			Modifiers = ((modifiers == null) ? Array.Empty<KeyCode>() : (from k in modifiers.Where((KeyCode k) => IsModifier(k) && k != main).Distinct()
				orderby (int)k
				select k).ToArray());
			RawPath = rawPath;
			_token = Token(main, rawPath);
		}

		private unsafe static string Token(KeyCode main, string rawPath)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)main == 0)
			{
				if (!string.IsNullOrEmpty(rawPath))
				{
					return "path:" + rawPath.ToLowerInvariant();
				}
				return "none";
			}
			return "key:" + ((object)(*(KeyCode*)(&main))/*cast due to .constrained prefix*/).ToString();
		}

		public static bool IsModifier(KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			if ((int)k != 306 && (int)k != 305 && (int)k != 308 && (int)k != 307 && (int)k != 304 && (int)k != 303 && (int)k != 310)
			{
				return (int)k == 309;
			}
			return true;
		}

		public bool SameModifiers(KeyCombo other)
		{
			return Modifiers.SequenceEqual(other.Modifiers);
		}

		public bool Equals(KeyCombo other)
		{
			if (MainToken == other.MainToken)
			{
				return SameModifiers(other);
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is KeyCombo other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return MainToken.GetHashCode() ^ Modifiers.Length;
		}

		public unsafe override string ToString()
		{
			return Format((KeyCode k) => ((object)(*(KeyCode*)(&k))/*cast due to .constrained prefix*/).ToString());
		}

		internal string Format(Func<KeyCode, string> name, Func<string, string> path = null)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!IsBound)
			{
				return "<unbound>";
			}
			string text = (((int)Main != 0) ? name(Main) : ((path != null) ? path(RawPath) : RawPath));
			if (Modifiers.Length != 0)
			{
				return string.Join(" + ", Modifiers.Select(name).ToArray()) + " + " + text;
			}
			return text;
		}
	}
	public static class KeyGrid
	{
		private struct Spot
		{
			public readonly float X;

			public readonly float Y;

			public Spot(float x, float y)
			{
				X = x;
				Y = y;
			}
		}

		private static readonly Dictionary<KeyCode, Spot> Places = Build();

		public static IEnumerable<KeyCode> Around(KeyCode key)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!Places.TryGetValue(key, out var from))
			{
				return Enumerable.Empty<KeyCode>();
			}
			return from p in Places
				where p.Key != key
				orderby Distance(@from, p.Value)
				select p.Key;
		}

		public static float? Distance(KeyCode a, KeyCode b)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!Places.TryGetValue(a, out var value) || !Places.TryGetValue(b, out var value2))
			{
				return null;
			}
			return Distance(value, value2);
		}

		private static float Distance(Spot a, Spot b)
		{
			return (float)Math.Sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y));
		}

		private static Dictionary<KeyCode, Spot> Build()
		{
			Dictionary<KeyCode, Spot> places = new Dictionary<KeyCode, Spot>();
			KeyCode[] array = new KeyCode[4];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(0f, 2f, (KeyCode[])(object)array);
			KeyCode[] array2 = new KeyCode[4];
			RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(0f, 6.5f, (KeyCode[])(object)array2);
			KeyCode[] array3 = new KeyCode[4];
			RuntimeHelpers.InitializeArray(array3, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(0f, 11f, (KeyCode[])(object)array3);
			KeyCode[] array4 = new KeyCode[13];
			RuntimeHelpers.InitializeArray(array4, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(1.5f, 0f, (KeyCode[])(object)array4);
			Run(1.5f, 13.5f, (KeyCode[])(object)new KeyCode[1] { (KeyCode)8 });
			KeyCode[] array5 = new KeyCode[3];
			RuntimeHelpers.InitializeArray(array5, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(1.5f, 15.5f, (KeyCode[])(object)array5);
			Run(2.5f, 0.25f, (KeyCode[])(object)new KeyCode[1] { (KeyCode)9 });
			KeyCode[] array6 = new KeyCode[12];
			RuntimeHelpers.InitializeArray(array6, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(2.5f, 1.5f, (KeyCode[])(object)array6);
			Run(2.5f, 13.75f, (KeyCode[])(object)new KeyCode[1] { (KeyCode)92 });
			KeyCode[] array7 = new KeyCode[3];
			RuntimeHelpers.InitializeArray(array7, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(2.5f, 15.5f, (KeyCode[])(object)array7);
			KeyCode[] array8 = new KeyCode[11];
			RuntimeHelpers.InitializeArray(array8, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(3.5f, 1.75f, (KeyCode[])(object)array8);
			Run(3.5f, 13.4f, (KeyCode[])(object)new KeyCode[1] { (KeyCode)13 });
			KeyCode[] array9 = new KeyCode[10];
			RuntimeHelpers.InitializeArray(array9, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(4.5f, 2.25f, (KeyCode[])(object)array9);
			Run(4.5f, 16.5f, (KeyCode[])(object)new KeyCode[1] { (KeyCode)273 });
			Run(5.5f, 6.25f, (KeyCode[])(object)new KeyCode[1] { (KeyCode)32 });
			KeyCode[] array10 = new KeyCode[3];
			RuntimeHelpers.InitializeArray(array10, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Run(5.5f, 15.5f, (KeyCode[])(object)array10);
			return places;
			void Run(float y, float x, params KeyCode[] keys)
			{
				for (int i = 0; i < keys.Length; i++)
				{
					places[keys[i]] = new Spot(x + (float)i, y);
				}
			}
		}
	}
	public static class KeyLabels
	{
		private static readonly Dictionary<KeyCode, string> Cache = new Dictionary<KeyCode, string>();

		private static readonly Dictionary<string, string> PathCache = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		public static void Forget()
		{
			Cache.Clear();
			PathCache.Clear();
		}

		public static string Of(KeyCombo combo)
		{
			if (!Plugin.KeyboardLabels)
			{
				return combo.ToString();
			}
			return combo.Format(Of, OfPath);
		}

		public unsafe static string Of(KeyCode key)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.KeyboardLabels)
			{
				return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			}
			if (Cache.TryGetValue(key, out var value))
			{
				return value;
			}
			bool settled;
			string text = Resolve(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(), () => ZInput.KeyCodeToDisplayName(key), anyLength: false, out settled);
			if (settled)
			{
				Cache[key] = text;
			}
			return text;
		}

		public static string OfPath(string path)
		{
			if (string.IsNullOrEmpty(path) || !Plugin.KeyboardLabels)
			{
				return path;
			}
			if (PathCache.TryGetValue(path, out var value))
			{
				return value;
			}
			bool settled;
			string text = Resolve(path, delegate
			{
				InputControl obj = InputSystem.FindControl(path);
				return (obj == null) ? null : obj.displayName;
			}, anyLength: true, out settled);
			if (settled)
			{
				PathCache[path] = text;
			}
			return text;
		}

		public static string Modifier(KeyCode modifier)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((int)modifier != 308)
			{
				if ((int)modifier != 306)
				{
					if ((int)modifier != 304)
					{
						return Of(modifier);
					}
					return "Shift";
				}
				return "Ctrl";
			}
			return "Alt";
		}

		public static string Heading(KeyCombo combo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)combo.Main == 0)
			{
				if (!string.IsNullOrEmpty(combo.RawPath))
				{
					return OfPath(combo.RawPath);
				}
				return combo.MainLabel;
			}
			return Of(combo.Main);
		}

		public unsafe static bool Answers(KeyCode key, string query)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key == 0 || string.IsNullOrEmpty(query))
			{
				return false;
			}
			if (string.Equals(Of(key), query, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (query.Length > 1)
			{
				return string.Equals(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(), query, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		public static bool Answers(string path, string query)
		{
			if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(query))
			{
				return false;
			}
			if (string.Equals(OfPath(path), query, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (query.Length > 1)
			{
				return string.Equals(path, query, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static string Resolve(string name, Func<string> displayName, bool anyLength, out bool settled)
		{
			settled = false;
			try
			{
				if (Keyboard.current == null)
				{
					return name;
				}
				settled = true;
				string text = displayName()?.Trim();
				if (string.IsNullOrEmpty(text))
				{
					return name;
				}
				string text2 = text;
				for (int i = 0; i < text2.Length; i++)
				{
					if (char.IsControl(text2[i]))
					{
						return name;
					}
				}
				if (text.Length == 1)
				{
					return char.IsWhiteSpace(text[0]) ? name : char.ToUpperInvariant(text[0]).ToString();
				}
				return anyLength ? text : name;
			}
			catch (Exception ex)
			{
				Plugin.WarnOnce("Bindrune: no label for " + name + ", keeping its name: " + ex.Message, null, "/home/runner/work/Bindrune/Bindrune/src/KeyLabels.cs", 134);
				settled = true;
				return name;
			}
		}
	}
	public static class KeyPaths
	{
		private static Dictionary<string, KeyCode> _suffixToKey;

		private static Dictionary<KeyCode, string> _keyToPath;

		public static void Build()
		{
			if (_suffixToKey == null)
			{
				_suffixToKey = new Dictionary<string, KeyCode>(StringComparer.OrdinalIgnoreCase);
				_keyToPath = new Dictionary<KeyCode, string>();
				Absorb("s_keyCodeToKeyMap", null, "<Keyboard>", GameKeyPath());
				Absorb("s_keyCodeToMouseButtonMap", "button", "<Mouse>", null);
			}
		}

		private static Func<object, string> GameKeyPath()
		{
			MethodInfo method = AccessTools.Method(typeof(ZInput), "KeyToPath", new Type[1] { typeof(Key) }, (Type[])null);
			if (method == null)
			{
				return null;
			}
			return (object key) => method.Invoke(null, new object[1] { key }) as string;
		}

		public static string ToPath(KeyCode key)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Build();
			if (!_keyToPath.TryGetValue(key, out var value))
			{
				return null;
			}
			return value;
		}

		private static void Absorb(string fieldName, string suffixWord, string device, Func<object, string> gamePath)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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)
			try
			{
				if (!(AccessTools.Field(typeof(ZInput), fieldName)?.GetValue(null) is IDictionary dictionary))
				{
					return;
				}
				foreach (DictionaryEntry item in dictionary)
				{
					if (!(item.Key is KeyCode val) || item.Value == null)
					{
						continue;
					}
					string text = item.Value.ToString();
					_suffixToKey[text] = val;
					string text2 = gamePath?.Invoke(item.Value);
					if (!string.IsNullOrEmpty(text2))
					{
						int num = text2.LastIndexOf('/');
						_suffixToKey[(num >= 0) ? text2.Substring(num + 1) : text2] = val;
						if (!_keyToPath.ContainsKey(val))
						{
							_keyToPath[val] = text2;
						}
						continue;
					}
					string text3 = text;
					if (suffixWord != null && !text.EndsWith(suffixWord, StringComparison.OrdinalIgnoreCase))
					{
						text3 = text + char.ToUpperInvariant(suffixWord[0]) + suffixWord.Substring(1);
						_suffixToKey[text + suffixWord] = val;
					}
					if (text3.Length > 0 && !_keyToPath.ContainsKey(val))
					{
						_keyToPath[val] = device + "/" + char.ToLowerInvariant(text3[0]) + text3.Substring(1);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("KeyPaths: could not read ZInput." + fieldName + ": " + ex.Message));
			}
		}

		public static KeyCode FromPath(string path)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Build();
			if (string.IsNullOrEmpty(path))
			{
				return (KeyCode)0;
			}
			int num = path.LastIndexOf('/');
			string key = ((num >= 0) ? path.Substring(num + 1) : path);
			if (!_suffixToKey.TryGetValue(key, out var value))
			{
				return (KeyCode)0;
			}
			return value;
		}

		public static bool IsKeyboardOrMouse(string path)
		{
			if (!string.IsNullOrEmpty(path))
			{
				if (!path.StartsWith("<Keyboard>", StringComparison.OrdinalIgnoreCase))
				{
					return path.StartsWith("<Mouse>", StringComparison.OrdinalIgnoreCase);
				}
				return true;
			}
			return false;
		}
	}
	[BepInPlugin("isimp.Bindrune", "Bindrune", "0.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("valheim.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "isimp.Bindrune";

		public static ManualLogSource Log;

		private static readonly HashSet<string> Warned = new HashSet<string>();

		private static ConfigEntry<float> _scrollSpeed;

		private static ConfigEntry<bool> _keyboardLabels;

		private static ConfigEntry<float> _panelWidth;

		private static ConfigEntry<float> _panelHeight;

		private static ConfigEntry<bool> _hintsVisible;

		private static ConfigEntry<int> _hintFontSize;

		private static ConfigEntry<HintAlign> _hintAlign;

		private static ConfigEntry<HintGrowth> _hintGrowth;

		private static ConfigEntry<bool> _hintModNames;

		private static ConfigEntry<HintOrder> _hintOrder;

		private static ConfigEntry<float> _hintX;

		private static ConfigEntry<float> _hintY;

		private ConfigEntry<KeyboardShortcut> _openKey;

		private static ConfigEntry<KeyboardShortcut> _hintsKey;

		private bool _restored;

		private float _restoreAt;

		private bool _restoreInWorld;

		public static float ScrollSpeed => _scrollSpeed?.Value ?? 300f;

		public static bool KeyboardLabels
		{
			get
			{
				if (_keyboardLabels != null)
				{
					return _keyboardLabels.Value;
				}
				return true;
			}
		}

		public static bool HintsVisible
		{
			get
			{
				if (_hintsVisible != null)
				{
					return _hintsVisible.Value;
				}
				return false;
			}
			set
			{
				if (_hintsVisible != null)
				{
					_hintsVisible.Value = value;
				}
			}
		}

		public static int HintFontSize => _hintFontSize?.Value ?? 15;

		public static HintAlign HintAlign
		{
			get
			{
				return _hintAlign?.Value ?? HintAlign.Left;
			}
			set
			{
				if (_hintAlign != null)
				{
					_hintAlign.Value = value;
				}
			}
		}

		public static bool HintModNames
		{
			get
			{
				if (_hintModNames != null)
				{
					return _hintModNames.Value;
				}
				return false;
			}
			set
			{
				if (_hintModNames != null)
				{
					_hintModNames.Value = value;
				}
			}
		}

		public static HintOrder HintOrder
		{
			get
			{
				return _hintOrder?.Value ?? HintOrder.KeyFirst;
			}
			set
			{
				if (_hintOrder != null)
				{
					_hintOrder.Value = value;
				}
			}
		}

		public static HintGrowth HintGrowth
		{
			get
			{
				return _hintGrowth?.Value ?? HintGrowth.Up;
			}
			set
			{
				if (_hintGrowth != null)
				{
					_hintGrowth.Value = value;
				}
			}
		}

		public static Vector2 HintPosition
		{
			get
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				return new Vector2(_hintX?.Value ?? 0.02f, _hintY?.Value ?? 0.06f);
			}
			set
			{
				//IL_0014: 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)
				if (_hintX != null && _hintY != null)
				{
					_hintX.Value = value.x;
					_hintY.Value = value.y;
				}
			}
		}

		public static Vector2 PanelSize
		{
			get
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				return new Vector2(_panelWidth?.Value ?? 1280f, _panelHeight?.Value ?? 820f);
			}
			set
			{
				//IL_0014: 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)
				if (_panelWidth != null && _panelHeight != null)
				{
					_panelWidth.Value = value.x;
					_panelHeight.Value = value.y;
				}
			}
		}

		public static string HintsKeyText
		{
			get
			{
				//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_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references)
				if (_hintsKey == null)
				{
					return "the hints key";
				}
				KeyboardShortcut value = _hintsKey.Value;
				KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
				value = _hintsKey.Value;
				return KeyLabels.Of(new KeyCombo(mainKey, ((KeyboardShortcut)(ref value)).Modifiers));
			}
		}

		public static void WarnOnce(string message, Exception detail = null, [CallerFilePath] string file = null, [CallerLineNumber] int line = 0)
		{
			if (Warned.Add(file + ":" + line))
			{
				Log.LogWarning((object)((detail != null) ? (message + "\n" + detail) : message));
			}
			else
			{
				Log.LogDebug((object)message);
			}
		}

		private void Awake()
		{
			//IL_0026: 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_0072: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Expected O, but got Unknown
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Expected O, but got Unknown
			//IL_02f8: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_openKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "OpenKey", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Opens the Bindrune panel.");
			_panelWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Panel", "Width", 1280f, new ConfigDescription("Panel width in pixels. Set by dragging the corner handle.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(900f, 3840f), Array.Empty<object>()));
			_panelHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Panel", "Height", 820f, new ConfigDescription("Panel height in pixels. Set by dragging the corner handle.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(520f, 2160f), Array.Empty<object>()));
			_scrollSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Panel", "ScrollSpeed", 300f, new ConfigDescription("Mouse wheel distance per notch in the bind list. Takes effect next time the panel is opened.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 1200f), Array.Empty<object>()));
			_keyboardLabels = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "KeyboardLayoutLabels", true, "Show keys as your keyboard labels them, so the key marked Y on a German keyboard reads Y rather than Z. Only the display changes; keys are stored and compared the same way either way. Takes effect when the panel is reopened.");
			_hintsKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hints", "ToggleKey", new KeyboardShortcut((KeyCode)104, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Shows or hides the on-screen key hints.");
			_hintsVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Hints", "Visible", false, "Whether the on-screen hints are showing. Set by the toggle key; kept so they come back as you left them.");
			_hintFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Hints", "FontSize", 15, new ConfigDescription("Text size of the on-screen hints.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(9, 32), Array.Empty<object>()));
			_hintX = ((BaseUnityPlugin)this).Config.Bind<float>("Hints", "X", 0.02f, new ConfigDescription("Where the hints sit across the screen: 0 is the left edge, 1 the right. Set by dragging them while the panel is open.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_hintY = ((BaseUnityPlugin)this).Config.Bind<float>("Hints", "Y", 0.06f, new ConfigDescription("Where the hints sit up the screen: 0 is the bottom, 1 the top. Set by dragging them while the panel is open.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_hintAlign = ((BaseUnityPlugin)this).Config.Bind<HintAlign>("Hints", "TextAlignment", HintAlign.Left, "Where the text sits inside the hint box.");
			_hintGrowth = ((BaseUnityPlugin)this).Config.Bind<HintGrowth>("Hints", "Growth", HintGrowth.Up, "Which way the list extends as hints are added: Up pins its bottom edge, Down pins its top.");
			_hintModNames = ((BaseUnityPlugin)this).Config.Bind<bool>("Hints", "ShowModNames", false, "Whether each hint names the mod it comes from as well as the action.");
			_hintOrder = ((BaseUnityPlugin)this).Config.Bind<HintOrder>("Hints", "Order", HintOrder.KeyFirst, "Whether each hint leads with the key you press or with what it does.");
			HintChoice.Changed = HintOverlay.Invalidate;
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				KeyLabels.Forget();
				HintOverlay.Invalidate();
				FixedKeys.Relabel();
			};
			Harmony val = new Harmony("isimp.Bindrune");
			StartMenuKeys.Patch(val);
			FixedKeys.Patch(val);
			HotbarLabels.Patch(val);
			Upkeep.Run(((BaseUnityPlugin)this).Config);
			ContextIndex.Warm();
			Log.LogInfo((object)"Bindrune loaded.");
		}

		private void OnDestroy()
		{
			BindrunePanel.Close(quietly: true);
			HintOverlay.Close();
		}

		private void Update()
		{
			//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_0069: 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)
			try
			{
				FixedKeys.EnsureRestored();
				RestoreOnce();
				bool active = KeyCapture.Active;
				if (BindrunePanel.IsOpen)
				{
					BindrunePanel.Tick();
				}
				if (active || KeyCapture.Active)
				{
					return;
				}
				HintOverlay.Tick();
				if (BindrunePanel.Typing)
				{
					if (Input.GetKeyDown((KeyCode)27))
					{
						BindrunePanel.Close();
					}
					return;
				}
				KeyboardShortcut value = _openKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					BindrunePanel.Toggle();
					return;
				}
				value = _hintsKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					HintOverlay.Toggle();
					Sfx.Play("sfx_gui_select");
				}
				else if (BindrunePanel.IsOpen && Input.GetKeyDown((KeyCode)27))
				{
					BindrunePanel.Close();
				}
			}
			catch (Exception ex)
			{
				WarnOnce("Bindrune input check failed: " + ex.Message, ex, "/home/runner/work/Bindrune/Bindrune/src/Plugin.cs", 261);
			}
		}

		private void RestoreOnce()
		{
			if (_restored || ZInput.instance == null)
			{
				return;
			}
			if (_restoreInWorld)
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					_restoreAt = 0f;
					return;
				}
				if (_restoreAt == 0f)
				{
					_restoreAt = Time.realtimeSinceStartup + 2f;
				}
				if (!(Time.realtimeSinceStartup < _restoreAt))
				{
					BindRegistry.Refresh();
					_restored = true;
				}
				return;
			}
			if (_restoreAt == 0f)
			{
				_restoreAt = Time.realtimeSinceStartup + 3f;
			}
			if (Time.realtimeSinceStartup < _restoreAt)
			{
				return;
			}
			if (PersonalKeys.Count == 0 && HintChoice.Count == 0)
			{
				_restored = true;
				return;
			}
			BindRegistry.Refresh();
			if (PersonalKeys.Reconcile() == 0)
			{
				_restored = true;
				return;
			}
			_restoreInWorld = true;
			_restoreAt = 0f;
		}

		public static string ResolveModName(string guid)
		{
			if (string.IsNullOrEmpty(guid))
			{
				return "unknown";
			}
			if (!Chainloader.PluginInfos.TryGetValue(guid, out var value) || ((value != null) ? value.Metadata : null) == null)
			{
				return guid;
			}
			return value.Metadata.Name;
		}
	}
	internal static class StartMenuKeys
	{
		public static void Patch(Harmony harmony)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(FejdStartup), "UpdateKeyboard", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Plugin.WarnOnce("Bindrune: the start menu's keyboard handling was not found, so Return may reach the menu while you type in the panel.", null, "/home/runner/work/Bindrune/Bindrune/src/StartMenuKeys.cs", 28);
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(StartMenuKeys), "Skip", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception ex)
			{
				Plugin.WarnOnce("Bindrune: could not hold the start menu's keys back while you type: " + ex.Message, ex, "/home/runner/work/Bindrune/Bindrune/src/StartMenuKeys.cs", 37);
			}
		}

		private static bool Skip()
		{
			return !BindrunePanel.Typing;
		}
	}
	public static class TextStore
	{
		public static string Ours(string root, string name)
		{
			return Path.Combine(Path.Combine(root, "Bindrune"), name);
		}

		public static IEnumerable<string> Read(string path)
		{
			TryRead(path, out var lines);
			return lines;
		}

		public static bool TryRead(string path, out IEnumerable<string> lines)
		{
			lines = new string[0];
			try
			{
				if (File.Exists(path))
				{
					lines = File.ReadAllLines(path);
				}
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Bindrune: could not read " + Path.GetFileName(path) + ": " + ex.Message));
				return false;
			}
		}

		public static string Stamp(string path)
		{
			try
			{
				FileInfo fileInfo = new FileInfo(path);
				return fileInfo.Exists ? (fileInfo.LastWriteTimeUtc.Ticks + ":" + fileInfo.Length) : "missing";
			}
			catch (Exception)
			{
				return null;
			}
		}

		public static bool ChangedSince(string path, string stamp)
		{
			string text = Stamp(path);
			if (text != null && stamp != null)
			{
				return text != stamp;
			}
			return false;
		}

		public static bool IsNoise(string line)
		{
			if (line.Length != 0)
			{
				return line.StartsWith("#");
			}
			return true;
		}

		public static void Write(string path, IEnumerable<string> header, IEnumerable<string> body, bool atomic = false)
		{
			try
			{
				string directoryName = Path.GetDirectoryName(path);
				if (!string.IsNullOrEmpty(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				List<string> list = new List<string>(header);
				list.AddRange(body);
				if (!atomic)
				{
					File.WriteAllLines(path, list.ToArray());
					return;
				}
				string text = path + ".tmp";
				File.WriteAllLines(text, list.ToArray());
				if (File.Exists(path))
				{
					File.Delete(path);
				}
				File.Move(text, path);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Bindrune: could not save " + Path.GetFileName(path) + ": " + ex.Message));
			}
		}
	}
	public static class Upkeep
	{
		public static void Run(ConfigFile config)
		{
			try
			{
				DropOrphanedSettings(config);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Bindrune: could not tidy up after an older version: " + ex.Message));
			}
		}

		private static void DropOrphanedSettings(ConfigFile config)
		{
			if (config == null)
			{
				return;
			}
			if (!(AccessTools.Property(typeof(ConfigFile), "OrphanedEntries")?.GetValue(config) is IDictionary dictionary))
			{
				Plugin.Log.LogDebug((object)"Bindrune: orphaned settings are not readable on this BepInEx; leaving them.");
			}
			else
			{
				if (dictionary.Count == 0)
				{
					return;
				}
				List<string> list = new List<string>();
				foreach (DictionaryEntry item in dictionary)
				{
					list.Add(item.Key?.ToString() ?? "?");
				}
				dictionary.Clear();
				config.Save();
				Plugin.Log.LogInfo((object)string.Format("Bindrune: dropped {0} setting(s) we no longer have: {1}.", list.Count, string.Join(", ", list.ToArray())));
			}
		}
	}
}
namespace Bindrune.UI
{
	public static class BindrunePanel
	{
		private struct RowColumns
		{
			public float Mark;

			public float Label;

			public float Key;

			public float Profile;
		}

		private enum DetailPage
		{
			Bind,
			Legend,
			Hints
		}

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

			public static Func<BindEntry, bool> <>9__66_0;

			public static Func<BindEntry, bool> <>9__66_1;

			public static Action<Vector2> <>9__69_0;

			public static UnityAction <>9__70_0;

			public static UnityAction <>9__70_1;

			public static UnityAction <>9__70_2;

			public static UnityAction <>9__70_3;

			public static UnityAction<string> <>9__70_4;

			public static UnityAction <>9__70_5;

			public static Action<KeyCombo> <>9__70_11;

			public static UnityAction <>9__70_7;

			public static UnityAction <>9__70_8;

			public static UnityAction <>9__70_9;

			public static UnityAction <>9__70_10;

			public static Func<BindEntry, int> <>9__72_1;

			public static Func<BindEntry, string> <>9__72_2;

			public static Func<BindEntry, string> <>9__72_3;

			public static Func<Conflict, bool> <>9__73_0;

			public static Func<BindEntry, bool> <>9__73_1;

			public static Func<Conflict, bool> <>9__73_2;

			public static Func<Conflict, bool> <>9__73_3;

			public static Func<Conflict, bool> <>9__73_4;

			public static Func<Conflict, Severity> <>9__87_0;

			public static Func<Conflict, bool> <>9__92_0;

			public static UnityAction <>9__92_3;

			public static Func<BindEntry, string> <>9__97_2;

			public static Func<string, string> <>9__103_0;

			public static UnityAction <>9__112_0;

			public static UnityAction <>9__112_1;

			public static Func<BindEntry, bool> <>9__112_2;

			public static UnityAction <>9__114_0;

			public static UnityAction <>9__114_1;

			internal bool <Rescan>b__66_0(BindEntry b)
			{
				if (!b.Internal)
				{
					return b.Compared;
				}
				return false;
			}

			internal bool <Rescan>b__66_1(BindEntry b)
			{
				return b.Id == _selected.Id;
			}

			internal void <BuildResizeGrip>b__69_0(Vector2 size)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//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)
				_size = size;
				Plugin.PanelSize = size;
				Rebuild();
			}

			internal void <BuildHeader>b__70_0()
			{
				Close();
			}

			internal void <BuildHeader>b__70_1()
			{
				Refresh();
			}

			internal void <BuildHeader>b__70_2()
			{
				Show(DetailPage.Legend);
			}

			internal void <BuildHeader>b__70_3()
			{
				Show(DetailPage.Hints);
			}

			internal void <BuildHeader>b__70_4(string _)
			{
				RequestPopulate();
			}

			internal void <BuildHeader>b__70_5()
			{
				if ((Object)(object)_search != (Object)null)
				{
					_search.text = "";
				}
				Populate();
			}

			internal void <BuildHeader>b__70_11(KeyCombo combo)
			{
				if ((Object)(object)_search != (Object)null)
				{
					_search.text = "\"" + KeyLabels.Heading(combo) + "\"";
				}
				Populate();
			}

			internal void <BuildHeader>b__70_7()
			{
				_conflictsOnly = !_conflictsOnly;
				Populate();
			}

			internal void <BuildHeader>b__70_8()
			{
				_yoursOnly = !_yoursOnly;
				Populate();
			}

			internal void <BuildHeader>b__70_9()
			{
				_mutedOnly = !_mutedOnly;
				Populate();
			}

			internal void <BuildHeader>b__70_10()
			{
				_groupByKey = !_groupByKey;
				Populate();
			}

			internal int <Populate>b__72_1(BindEntry b)
			{
				return (!b.Combo.IsBound) ? 1 : 0;
			}

			internal string <Populate>b__72_2(BindEntry b)
			{
				return b.Combo.MainToken;
			}

			internal string <Populate>b__72_3(BindEntry b)
			{
				return b.OwnerName;
			}

			internal bool <UpdateHeaderLabels>b__73_0(Conflict c)
			{
				return !MuteStore.IsMuted(c);
			}

			internal bool <UpdateHeaderLabels>b__73_1(BindEntry b)
			{
				if (b.Internal)
				{
					return _internalShown;
				}
				return true;
			}

			internal bool <UpdateHeaderLabels>b__73_2(Conflict c)
			{
				return c.Severity == Severity.Hard;
			}

			internal bool <UpdateHeaderLabels>b__73_3(Conflict c)
			{
				return c.Severity == Severity.Soft;
			}

			internal bool <UpdateHeaderLabels>b__73_4(Conflict c)
			{
				return c.Severity == Severity.Note;
			}

			internal Severity <ShowDetail>b__87_0(Conflict c)
			{
				return c.Severity;
			}

			internal bool <ShowPendingKey>b__92_0(Conflict c)
			{
				return c.Severity != Severity.Note;
			}

			internal void <ShowPendingKey>b__92_3()
			{
				_pendingFor = null;
				Refresh(rescan: false);
			}

			internal string <ShowOnScreen>b__97_2(BindEntry b)
			{
				return b.Id;
			}

			internal string <ShowSituations>b__103_0(string d)
			{
				return d;
			}

			internal void <ShowHintsPage>b__112_0()
			{
				HintOverlay.Toggle();
				Refresh(rescan: false);
			}

			internal void <ShowHintsPage>b__112_1()
			{
				Plugin.HintModNames = !Plugin.HintModNames;
				HintOverlay.Invalidate();
				Refresh(rescan: false);
			}

			internal bool <ShowHintsPage>b__112_2(BindEntry b)
			{
				return HintChoice.Shows(b.Id);
			}

			internal void <LegendAdvanced>b__114_0()
			{
				_internalShown = !_internalShown;
				Refresh(rescan: false);
			}

			internal void <LegendAdvanced>b__114_1()
			{
				_storedNamesShown = !_storedNamesShown;
				Refresh(rescan: false);
			}
		}

		private const float RowHeight = 26f;

		private const float TopChrome = 124f;

		private const float FooterHeight = 38f;

		private const float Margin = 30f;

		private const float Gap = 18f;

		private const float DetailWidth = 470f;

		private static Vector2 _size;

		private const float MarkWidth = 96f;

		private const float KeyWidth = 200f;

		private const float ProfileKeyWidth = 150f;

		private static GameObject _root;

		private static InputField _search;

		private static string _searchText = "";

		private static float _scrollAt = 1f;

		private static RectTransform _content;

		private static RectTransform _detail;

		private static Text _summary;

		private static bool _groupByKey;

		private static bool _mutedOnly;

		private static float _repopulateAt;

		private static string _rendered;

		private static Text _groupButtonLabel;

		private static Text _mutedButtonLabel;

		private static Text _pressKeyLabel;

		private static bool _yoursOnly;

		private static bool _conflictsOnly;

		private static bool _internalShown;

		private static bool _storedNamesShown;

		private static Text _yoursButtonLabel;

		private static Text _conflictsButtonLabel;

		private static readonly HashSet<string> _collapsed = new HashSet<string> { "about", "situations" };

		private static DetailPage _page = DetailPage.Bind;

		private static Text _legendButtonLabel;

		private static Text _hintsButtonLabel;

		private static BindEntry _selected;

		private static string _pendingFor;

		private static KeyCombo _pending;

		private static string _note;

		private static readonly Dictionary<string, Image> _rowBackgrounds = new Dictionary<string, Image>();

		private static float PanelWidth => Size.x;

		private static float PanelHeight => Size.y;

		private static Vector2 Size
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				if (_size == Vector2.zero)
				{
					_size = new Vector2(Mathf.Min(Plugin.PanelSize.x, (float)Screen.width * 0.95f), Mathf.Min(Plugin.PanelSize.y, (float)Screen.height * 0.95f));
				}
				return _size;
			}
		}

		private static float BodyHeight => PanelHeight - 124f - 38f;

		private static float ListWidth => PanelWidth - 60f - 18f - 470f;

		private static float RowWidth => ListWidth - 24f;

		public static bool IsOpen => (Object)(object)_root != (Object)null;

		public static bool Typing
		{
			get
			{
				if ((Object)(object)_search != (Object)null)
				{
					return _search.isFocused;
				}
				return false;
			}
		}

		private static RowColumns Columns()
		{
			float num = 96f;
			float num2 = 200f;
			float num3 = 150f;
			float num4 = LabelFor(num, num2, num3);
			if (num4 < 240f)
			{
				num3 = 0f;
				num4 = LabelFor(num, num2, 0f);
			}
			if (num4 < 240f)
			{
				float num5 = Mathf.Min(num2 - 130f, 240f - num4);
				num2 -= num5;
				num4 += num5;
			}
			if (num4 < 240f)
			{
				float num6 = Mathf.Min(num - 62f, 240f - num4);
				num -= num6;
				num4 += num6;
			}
			return new RowColumns
			{
				Mark = num,
				Label = Mathf.Max(num4, 80f),
				Key = num2,
				Profile = num3
			};
			static float LabelFor(float b, float k, float p)
			{
				return RowWidth - 14f - b - k - ((p > 0f) ? (p + 8f) : 0f) - 16f;
			}
		}

		private static void Show(DetailPage page)
		{
			_page = ((_page != page || _selected == null) ? page : DetailPage.Bind);
			_note = null;
			Refresh(rescan: false);
		}

		public static void Toggle()
		{
			if (IsOpen)
			{
				Close();
			}
			else
			{
				Open();
			}
		}

		public static void Open()
		{
			if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Bindrune: GUI is not ready yet.");
				return;
			}
			Rescan();
			Build();
			RestorePlace();
			GUIManager.BlockInput(true);
			HintOverlay.Movable = true;
			if ((Object)(object)_root != (Object)null)
			{
				Sfx.Play("sfx_gui_inventory_open");
			}
		}

		public static void Close(bool quietly = false)
		{
			if ((Object)(object)_root != (Object)null && !quietly)
			{
				Sfx.Play("sfx_gui_inventory_close");
			}
			KeyCapture.Changed = null;
			KeyCapture.Cancel();
			_pendingFor = null;
			_note = null;
			RememberPlace();
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			_content = null;
			_detail = null;
			GUIManager.BlockInput(false);
			HintOverlay.Movable = false;
		}

		public static void Tick()
		{
			KeyCapture.Tick();
			if (_repopulateAt > 0f && Time.realtimeSinceStartup >= _repopulateAt)
			{
				_repopulateAt = 0f;
				Populate();
			}
		}

		private static void RequestPopulate()
		{
			_repopulateAt = Time.realtimeSinceStartup + 0.15f;
		}

		private static void Refresh(bool rescan = true)
		{
			if (rescan)
			{
				Rescan();
			}
			Populate();
			ShowDetail();
			HintOverlay.Invalidate();
		}

		private static void RefreshCaptureState()
		{
			if (!((Object)(object)_root == (Object)null))
			{
				if ((Object)(object)_pressKeyLabel != (Object)null)
				{
					_pressKeyLabel.text = (KeyCapture.IsCapturingFor(CapturePurpose.Search) ? "press a key..." : "Press key");
				}
				ShowDetail();
			}
		}

		private static void Rescan()
		{
			SituationStore.Sync();
			PersonalStore.Sync();
			BindRegistry.Refresh();
			EquippedItems.Refresh();
			ConflictIndex.Rebuild(BindRegistry.All.Where((BindEntry b) => !b.Internal && b.Compared));
			if (_selected != null)
			{
				_selected = BindRegistry.All.FirstOrDefault((BindEntry b) => b.Id == _selected.Id);
			}
		}

		private static void Build()
		{
			//IL_0019: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			_root = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, PanelWidth, PanelHeight, true);
			((Object)_root).name = "BindrunePanel";
			((RectTransform)_root.transform).anchoredPosition = Vector2.zero;
			_rendered = null;
			KeyCapture.Changed = RefreshCaptureState;
			BuildHeader();
			if (!((Object)(object)MakeScrollView(ListWidth, BodyHeight, new Vector2(30f + ListWidth / 2f, 0f - (124f + BodyHeight / 2f)), out _content) == (Object)null))
			{
				MakeScrollView(470f, BodyHeight, new Vector2(30f + ListWidth + 18f + 235f, 0f - (124f + BodyHeight / 2f)), out _detail, 16);
				GameObject obj = Label("", _root.transform, PanelWidth - 120f, 22f, 14, Color.white);
				Anchor(obj, new Vector2(0.5f, 0f), new Vector2(0f, 19f));
				_summary = obj.GetComponent<Text>();
				_summary.alignment = (TextAnchor)4;
				BuildResizeGrip();
				Refresh(rescan: false);
			}
		}

		private static void Rebuild()
		{
			RememberPlace();
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			Build();
			RestorePlace();
		}

		private static void BuildResizeGrip()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0059: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("resize", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(ResizeGrip)
			});
			val.transform.SetParent(_root.transform, false);
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(1f, 0f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(1f, 0f);
			val2.sizeDelta = new Vector2(26f, 26f);
			val2.anchoredPosition = new Vector2(-6f, 6f);
			((Graphic)val.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0.22f);
			ResizeGrip component = val.GetComponent<ResizeGrip>();
			component.Target = (RectTransform)_root.transform;
			component.MinSize = new Vector2(1080f, 560f);
			component.Resized = delegate(Vector2 size)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//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)
				_size = size;
				Plugin.PanelSize = size;
				Rebuild();
			};
		}

		private static void BuildHeader()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_00b9: 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_00c4: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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)
			//IL_0167: Expected O, but got Unknown
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Expected O, but got Unknown
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Expected O, but got Unknown
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Expected O, but got Unknown
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Expected O, but got Unknown
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			AnchorLeft(Label("Bindrune", _root.transform, 200f, 32f, 26, GUIManager.Instance.ValheimOrange, bold: true), 30f, -36f);
			Transform transform = _root.transform;
			object obj = <>c.<>9__70_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					Close();
				};
				<>c.<>9__70_0 = val;
				obj = (object)val;
			}
			AnchorRight(Button("Close", transform, 110f, 32f, (UnityAction)obj), -30f, -36f);
			Transform transform2 = _root.transform;
			object obj2 = <>c.<>9__70_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					Refresh();
				};
				<>c.<>9__70_1 = val2;
				obj2 = (object)val2;
			}
			AnchorRight(Button("Rescan", transform2, 110f, 32f, (UnityAction)obj2), -150f, -36f);
			Transform transform3 = _root.transform;
			object obj3 = <>c.<>9__70_2;
			if (obj3 == null)
			{
				UnityAction val3 = delegate
				{
					Show(DetailPage.Legend);
				};
				<>c.<>9__70_2 = val3;
				obj3 = (object)val3;
			}
			GameObject obj4 = Button("?", transform3, 44f, 32f, (UnityAction)obj3);
			AnchorRight(obj4, -270f, -36f);
			_legendButtonLabel = obj4.GetComponentInChildren<Text>();
			Transform transform4 = _root.transform;
			object obj5 = <>c.<>9__70_3;
			if (obj5 == null)
			{
				UnityAction val4 = delegate
				{
					Show(DetailPage.Hints);
				};
				<>c.<>9__70_3 = val4;
				obj5 = (object)val4;
			}
			GameObject obj6 = Button("Hints", transform4, 100f, 32f, (UnityAction)obj5);
			AnchorRight(obj6, -324f, -36f);
			_hintsButtonLabel = obj6.GetComponentInChildren<Text>();
			GameObject obj7 = GUIManager.Instance.CreateInputField(_root.transform, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, (ContentType)0, "search mod, bind or \"key\"...", 16, 300f, 32f);
			AnchorLeft(obj7, 30f, -80f);
			_search = obj7.GetComponent<InputField>();
			((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				RequestPopulate();
			});
			Transform transform5 = _root.transform;
			object obj8 = <>c.<>9__70_5;
			if (obj8 == null)
			{
				UnityAction val5 = delegate
				{
					if ((Object)(object)_search != (Object)null)
					{
						_search.text = "";
					}
					Populate();
				};
				<>c.<>9__70_5 = val5;
				obj8 = (object)val5;
			}
			AnchorLeft(Button("x", transform5, 32f, 32f, (UnityAction)obj8), 336f, -80f);
			GameObject pressKey = null;
			pressKey = Button("Press key", _root.transform, 120f, 32f, (UnityAction)delegate
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Expected O, but got Unknown
				if (KeyCapture.IsCapturingFor(CapturePurpose.Search))
				{
					KeyCapture.Cancel();
				}
				else
				{
					KeyCapture.Begin(CapturePurpose.Search, delegate(KeyCombo combo)
					{
						if ((Object)(object)_search != (Object)null)
						{
							_search.text = "\"" + KeyLabels.Heading(combo) + "\"";
						}
						Populate();
					});
					KeyCapture.QuitsOver((RectTransform)pressKey.transform);
				}
			});
			AnchorLeft(pressKey, 378f, -80f);
			_pressKeyLabel = pressKey.GetComponentInChildren<Text>();
			float num = 516f;
			Transform transform6 = _root.transform;
			object obj9 = <>c.<>9__70_7;
			if (obj9 == null)
			{
				UnityAction val6 = delegate
				{
					_conflictsOnly = !_conflictsOnly;
					Populate();
				};
				<>c.<>9__70_7 = val6;
				obj9 = (object)val6;
			}
			GameObject obj10 = Button("Conflicts", transform6, 118f, 28f, (UnityAction)obj9);
			AnchorLeft(obj10, num, -80f);
			_conflictsButtonLabel = obj10.GetComponentInChildren<Text>();
			Transform transform7 = _root.transform;
			object obj11 = <>c.<>9__70_8;
			if (obj11 == null)
			{
				UnityAction val7 = delegate
				{
					_yoursOnly = !_yoursOnly;
					Populate();
				};
				<>c.<>9__70_8 = val7;
				obj11 = (object)val7;
			}
			GameObject obj12 = Button("Yours", transform7, 118f, 28f, (UnityAction)obj11);
			AnchorLeft(obj12, num + 118f + 8f, -80f);
			_yoursButtonLabel = obj12.GetComponentInChildren<Text>();
			Transform transform8 = _root.transform;
			object obj13 = <>c.<>9__70_9;
			if (obj13 == null)
			{
				UnityAction val8 = delegate
				{
					_mutedOnly = !_mutedOnly;
					Populate();
				};
				<>c.<>9__70_9 = val8;
				obj13 = (object)val8;
			}
			GameObject obj14 = Button("Muted", transform8, 118f, 28f, (UnityAction)obj13);
			AnchorLeft(obj14, num + 252f, -80f);
			_mutedButtonLabel = obj14.GetComponentInChildren<Text>();
			Transform transform9 = _root.transform;
			object obj15 = <>c.<>9__70_10;
			if (obj15 == null)
			{
				UnityAction val9 = delegate
				{
					_groupByKey = !_groupByKey;
					Populate();
				};
				<>c.<>9__70_10 = val9;
				obj15 = (object)val9;
			}
			GameObject obj16 = Button("Group: mod", transform9, 148f, 28f, (UnityAction)obj15);
			AnchorLeft(obj16, num + 378f, -80f);
			_groupButtonLabel = obj16.GetComponentInChildren<Text>();
			RowColumns rowColumns = Columns();
			float num2 = 50f;
			AnchorLeft(Label("conflict", _root.transform, rowColumns.Mark, 20f, 13, new Color(1f, 1f, 1f, 0.45f)), num2, -110f);
			num2 += rowColumns.Mark + 8f;
			AnchorLeft(Label("bind", _root.transform, rowColumns.Label, 20f, 13, new Color(1f, 1f, 1f, 0.45f)), num2, -110f);
			num2 += rowColumns.Label + 8f;
			AnchorLeft(Label("key", _root.transform, rowColumns.Key, 20f, 13, new Color(1f, 1f, 1f, 0.45f)), num2, -110f);
			num2 += rowColumns.Key + 8f;
			if (rowColumns.Profile > 0f)
			{
				AnchorLeft(Label("profile says", _root.transform, rowColumns.Profile, 20f, 13, new Color(1f, 1f, 1f, 0.35f)), num2, -110f);
			}
		}

		private static GameObject MakeScrollView(float width, float height, Vector2 position, out RectTransform content, int padding = 6)
		{
			//IL_0023: 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_0054: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			content = null;
			GameObject val = GUIManager.Instance.CreateScrollView(_root.transform, false, true, 8f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.25f), width, height);
			Anchor(val, new Vector2(0f, 1f), position);
			ScrollRect val2 = val.GetComponent<ScrollRect>() ?? val.GetComponentInChildren<ScrollRect>(true);
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogError((object)"Bindrune: scroll view has no ScrollRect.");
				return null;
			}
			val2.scrollSensitivity = Plugin.ScrollSpeed;
			content = val2.content;
			VerticalLayoutGroup obj = ((Component)content).GetComponent<VerticalLayoutGroup>() ?? ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((LayoutGroup)obj).padding = new RectOffset(padding, padding, padding, padding);
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f;
			(((Component)content).GetComponent<ContentSizeFitter>() ?? ((Component)content).gameObject.AddComponent<ContentSizeFitter>()).verticalFit = (FitMode)2;
			return val;
		}

		private static void Populate()
		{
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_content == (Object)null)
			{
				return;
			}
			string filter = (((Object)(object)_search != (Object)null) ? _search.text : "").Trim().ToLowerInvariant();
			bool conflictsOnly = _conflictsOnly;
			bool showInternal = _internalShown;
			List<BindEntry> list = BindRegistry.All.Where(delegate(BindEntry b)
			{
				if (b.Internal && !showInternal)
				{
					return false;
				}
				if (conflictsOnly && !ConflictIndex.Worst(b.Id).HasValue)
				{
					return false;
				}
				if (_mutedOnly && ConflictIndex.MutedCount(b.Id) == 0)
				{
					return false;
				}
				return (!_yoursOnly || PersonalKeys.IsPersonal(b.Id)) && Matches(b, filter);
			}).ToList();
			if (_groupByKey)
			{
				list = (from b in list
					orderby (!b.Combo.IsBound) ? 1 : 0, b.Combo.MainToken, b.OwnerName
					select b).ToList();
			}
			string text = Signature(list);
			if (text == _rendered)
			{
				UpdateHeaderLabels(list.Count);
				return;
			}
			_rendered = text;
			Clear((Transform)(object)_content);
			_rowBackgrounds.Clear();
			string text2 = null;
			foreach (BindEntry item in list)
			{
				string text3 = (_groupByKey ? KeyLabels.Heading(item.Combo) : item.OwnerName);
				if (text3 != text2)
				{
					text2 = text3;
					Fix(Label(text3, (Transform)(object)_content, RowWidth, 32f, 17, GUIManager.Instance.ValheimOrange, bold: true), RowWidth, 32f);
				}
				AddRow(item);
			}
			UpdateHeaderLabels(list.Count);
		}

		private static void UpdateHeaderLabels(int shownCount)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			List<Conflict> all = ConflictIndex.All;
			if ((Object)(object)_groupButtonLabel != (Object)null)
			{
				_groupButtonLabel.text = (_groupByKey ? "Grouped by key" : "Grouped by mod");
				_groupButtonLabel.fontSize = 15;
				((Graphic)_groupButtonLabel).color = new Color(1f, 1f, 1f, 0.8f);
			}
			SetFilter(_conflictsButtonLabel, "Conflicts", _conflictsOnly);
			SetFilter(_yoursButtonLabel, $"Yours ({PersonalKeys.Count})", _yoursOnly);
			SetFilter(_mutedButtonLabel, $"Muted ({all.Count(MuteStore.IsMuted)})", _mutedOnly);
			if ((Object)(object)_summary != (Object)null)
			{
				List<Conflict> source = all.Where((Conflict c) => !MuteStore.IsMuted(c)).ToList();
				int num = BindRegistry.All.Count((BindEntry b) => !b.Internal || _internalShown);
				string text = ((PersonalKeys.RestoredCount > 0) ? $"     {PersonalKeys.RestoredCount} put back - see ?" : "");
				_summary.text = $"{shownCount} of {num} binds shown     " + $"{source.Count((Conflict c) => c.Severity == Severity.Hard)} hard     " + $"{source.Count((Conflict c) => c.Severity == Severity.Soft)} soft     " + $"{source.Count((Conflict c) => c.Severity == Severity.Note)} notes     " + $"{PersonalKeys.Count} kept for you" + text;
			}
		}

		private static string Signature(List<BindEntry> shown)
		{
			StringBuilder stringBuilder = new StringBuilder(shown.Count * 48);
			stringBuilder.Append(_groupByKey ? "k|" : "m|").Append('|');
			foreach (BindEntry item in shown)
			{
				stringBuilder.Append(item.Id).Append('=').Append(item.Combo);
				if (PersonalKeys.IsPersonal(item.Id))
				{
					stringBuilder.Append('*').Append(ProfileKeyNote(item, yours: true));
				}
				Severity? severity = ConflictIndex.Worst(item.Id);
				if (severity.HasValue)
				{
					stringBuilder.Append('#').Append(severity).Append(ConflictIndex.Live(item.Id).Count);
				}
				stringBuilder.Append(';');
			}
			return stringBuilder.ToString();
		}

		private static bool Matches(BindEntry bind, string query)
		{
			if (query.Length == 0)
			{
				return true;
			}
			if (query.Length >= 3 && query[0] == '"' && query[query.Length - 1] == '"')
			{
				return UsesKey(bind, query.Substring(1, query.Length - 2));
			}
			if (IsKeyName(query))
			{
				return UsesKey(bind, query);
			}
			return (bind.OwnerName + " " + bind.Label + " " + KeyLabels.Of(bind.Combo)).ToLowerInvariant().Contains(query);
		}

		private unsafe static bool IsKeyName(string query)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.KeyboardLabels && query.Length == 1 && !char.IsWhiteSpace(query[0]))
			{
				return true;
			}
			if (Enum.TryParse<KeyCode>(query, ignoreCase: true, out KeyCode result) && Enum.IsDefined(typeof(KeyCode), result))
			{
				return string.Equals(((object)(*(KeyCode*)(&result))/*cast due to .constrained prefix*/).ToString(), query, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static bool UsesKey(BindEntry bind, string keyName)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0066: Unknown result type (might be due to invalid IL or missing references)
			if ((int)bind.Combo.Main == 0 && KeyLabels.Answers(bind.Combo.RawPath, keyName))
			{
				return true;
			}
			if (!Plugin.KeyboardLabels)
			{
				if (!Enum.TryParse<KeyCode>(keyName, ignoreCase: true, out KeyCode result))
				{
					return false;
				}
				if (bind.Combo.Main != result)
				{
					return bind.Combo.Modifiers.Contains(result);
				}
				return true;
			}
			if (!KeyLabels.Answers(bind.Combo.Main, keyName))
			{
				return bind.Combo.Modifiers.Any((KeyCode m) => KeyLabels.Answers(m, keyName));
			}
			return true;
		}

		private static void Reveal(BindEntry bind)
		{
			if (bind == null)
			{
				return;
			}
			if (!_rowBackgrounds.ContainsKey(bind.Id))
			{
				if ((Object)(object)_search != (Object)null)
				{
					_search.text = "";
				}
				_yoursOnly = false;
				_mutedOnly = false;
				Populate();
			}
			ScrollTo(bind.Id);
		}

		private static void RememberPlace()
		{
			if ((Object)(object)_search != (Object)null)
			{
				_searchText = _search.text;
			}
			ScrollRect val = ListScroll();
			if ((Object)(object)val != (Object)null)
			{
				_scrollAt = val.verticalNormalizedPosition;
			}
		}

		private static void RestorePlace()
		{
			if ((Object)(object)_search != (Object)null && _searchText.Length > 0)
			{
				_search.text = _searchText;
				Populate();
			}
			_repopulateAt = 0f;
			ScrollRect val = ListScroll();
			if (!((Object)(object)val == (Object)null))
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(_content);
				val.verticalNormalizedPosition = Mathf.Clamp01(_scrollAt);
			}
		}

		private static ScrollRect ListScroll()
		{
			if (!((Object)(object)_content == (Object)null))
			{
				return ((Component)_content).GetComponentInParent<ScrollRect>();
			}
			return null;
		}

		private static void ScrollTo(string bindId)
		{
			//IL_0058: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_content == (Object)null || !_rowBackgrounds.TryGetValue(bindId, out var value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			ScrollRect componentInParent = ((Component)_content).GetComponentInParent<ScrollRect>();
			if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.viewport == (Object)null))
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(_content);
				Rect rect = _content.rect;
				float height = ((Rect)(ref rect)).height;
				rect = componentInParent.viewport.rect;
				float num = height - ((Rect)(ref rect)).height;
				if (!(num <= 0f))
				{
					float num2 = 0f - ((RectTransform)((Component)value).transform).anchoredPosition.y;
					rect = componentInParent.viewport.rect;
					float num3 = num2 - ((Rect)(ref rect)).height / 2f;
					componentInParent.verticalNormalizedPosition = Mathf.Clamp01(1f - num3 / num);
				}
			}
		}

		private static void Select(BindEntry bind)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			KeyCapture.Cancel();
			if (_selected != null && _rowBackgrounds.TryGetValue(_selected.Id, out var value) && (Object)(object)value != (Object)null)
			{
				((Graphic)value).color = RowColour(selected: false);
			}
			_page = DetailPage.Bind;
			_pendingFor = null;
			_note = null;
			_selected = bind;
			if (bind != null && _rowBackgrounds.TryGetValue(bind.Id, out var value2) && (Object)(object)value2 != (Object)null)
			{
				((Graphic)value2).color = RowColour(selected: true);
			}
		}

		private static Color RowColour(bool selected)
		{
			//IL_0031: 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)
			if (!selected)
			{
				return new Color(0f, 0f, 0f, 0.01f);
			}
			return new Color(1f, 0.7f, 0.2f, 0.28f);
		}

		private static void AddRow(BindEntry bind)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: U