Decompiled source of ModSettingsMenu v1.3.0

BepInEx/plugins/ModSettingsMenu/ModSettingsMenu.dll

Decompiled 5 days 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.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ModSettingsMenu.Api;
using ModSettingsMenu.Configuration;
using ModSettingsMenu.Localization;
using ModSettingsMenu.Runtime;
using SunkenlandLocalizationAPI.Api;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ModSettingsMenu")]
[assembly: AssemblyDescription("Mod Settings Menu mod for Sunkenland by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("ModSettingsMenu")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: ComVisible(false)]
[assembly: Guid("6d512f55-e9ee-445c-9fb4-93ed6c1ef50a")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.3.0.0")]
namespace ModSettingsMenu
{
	[BepInPlugin("IceBoxStudio.Sunkenland.ModSettingsMenu", "ModSettingsMenu", "1.3.0")]
	[BepInDependency("IceBoxStudio.Sunkenland.LocalizationAPI", "1.2.0")]
	public sealed class ModSettingsMenu : BaseUnityPlugin
	{
		private Harmony _harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModSettingsRegistry.RefreshRequested += RefreshMenus;
			LocalizationApi.LanguageChanged += RefreshLocalizedText;
			try
			{
				Log.LogInfo((object)"=============================================");
				Log.LogInfo((object)("ModSettingsMenu " + I18n.Text("plugin.initializing")));
				Log.LogInfo((object)(I18n.Text("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
				_harmony = new Harmony("IceBoxStudio.Sunkenland.ModSettingsMenu");
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				Log.LogInfo((object)("ModSettingsMenu " + I18n.Text("plugin.initialized")));
				Log.LogInfo((object)"=============================================");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to initialize Mod Settings Menu: {arg}");
			}
		}

		private static void RefreshMenus()
		{
			ModSettingsMenuController.Refresh();
		}

		private static void RefreshLocalizedText(string language)
		{
			ModSettingsMenuController.RefreshLocalizedText();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.Sunkenland.ModSettingsMenu";

		public const string PLUGIN_NAME = "ModSettingsMenu";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace ModSettingsMenu.Runtime
{
	internal sealed class ConfigRows
	{
		private readonly Transform _content;

		private readonly GameObject _row;

		private readonly GameObject _heading;

		private readonly GameObject _toggle;

		private readonly GameObject _dropdown;

		private readonly KeybindCapture _keybindCapture;

		private readonly ModInfoRow _info;

		private readonly List<GameObject> _createdRows = new List<GameObject>();

		public ConfigRows(Transform content, GameObject row, GameObject heading, GameObject toggle, GameObject dropdown, KeybindCapture keybindCapture, ModInfoRow info)
		{
			_content = content;
			_row = row;
			_heading = heading;
			_toggle = toggle;
			_dropdown = dropdown;
			_keybindCapture = keybindCapture;
			_info = info;
		}

		public void Build(ModConfig mod)
		{
			ClearRows();
			if (mod == null)
			{
				CreateHeading(I18n.Text("menu.no_configurable_mods"));
			}
			else
			{
				GameObject val = _info?.Create(mod);
				if ((Object)(object)val != (Object)null)
				{
					CompleteRow(val);
				}
				List<ConfigEntryBase> list = (from entry in mod.ConfigFile.GetConfigEntries()
					orderby ModSettingsOrder.GetSectionOrder(mod, entry.Definition.Section)
					select entry).ThenBy<ConfigEntryBase, string>((ConfigEntryBase entry) => entry.Definition.Section, StringComparer.OrdinalIgnoreCase).ThenBy((ConfigEntryBase entry) => ModSettingsOrder.GetEntryOrder(mod, entry)).ThenBy<ConfigEntryBase, string>((ConfigEntryBase entry) => entry.Definition.Key, StringComparer.OrdinalIgnoreCase)
					.ToList();
				string text = null;
				foreach (ConfigEntryBase item in list)
				{
					if (!string.Equals(text, item.Definition.Section, StringComparison.OrdinalIgnoreCase))
					{
						text = item.Definition.Section;
						CreateHeading(SplitName(LocalizationApi.GetConfigSection(text, mod.ConfigFile)));
					}
					CreateEntryRow(mod, item);
				}
			}
			LayoutRebuild();
		}

		public void Reset(ModConfig mod)
		{
			if (mod != null)
			{
				ConfigEntryBase[] configEntries = mod.ConfigFile.GetConfigEntries();
				foreach (ConfigEntryBase obj in configEntries)
				{
					ConfigValues.TrySetValue(obj, obj.DefaultValue);
				}
				Build(mod);
			}
		}

		private void ClearRows()
		{
			foreach (GameObject createdRow in _createdRows)
			{
				if ((Object)(object)createdRow != (Object)null)
				{
					Object.Destroy((Object)(object)createdRow);
				}
			}
			_createdRows.Clear();
		}

		private void CreateHeading(string text)
		{
			GameObject val = Object.Instantiate<GameObject>(_heading, _content);
			((Object)val).name = "Mod Settings Section - " + text;
			val.SetActive(false);
			NativeUi.DisableLocalization(val);
			NativeUi.SetText(val, text);
			CompleteRow(val);
		}

		private void CreateEntryRow(ModConfig mod, ConfigEntryBase entry)
		{
			Type settingType = entry.SettingType;
			ConfigDescription description = entry.Description;
			AcceptableValueBase acceptable = ((description != null) ? description.AcceptableValues : null);
			IReadOnlyList<object> values;
			float min;
			float max;
			if (settingType == typeof(bool))
			{
				CreateBoolRow(entry);
			}
			else if (settingType == typeof(KeyCode))
			{
				CreateKeybindRow(entry);
			}
			else if (settingType.IsEnum)
			{
				CreateDropdownRow(entry, Enum.GetValues(settingType).Cast<object>().ToList());
			}
			else if (ConfigValues.TryGetAcceptableValues(acceptable, out values))
			{
				CreateDropdownRow(entry, values);
			}
			else if (ConfigValues.TryGetNumericRange(acceptable, out min, out max) && ConfigValues.IsSliderType(settingType))
			{
				CreateSliderRow(mod, entry, min, max);
			}
			else
			{
				CreateInputRow(entry);
			}
		}

		private void CreateBoolRow(ConfigEntryBase entry)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(_toggle, _content);
			((Object)val).name = GetRowName(entry);
			val.SetActive(false);
			NativeUi.DisableLocalization(val);
			Toggle toggle = val.GetComponent<Toggle>();
			if ((Object)(object)toggle == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			toggle.onValueChanged = new ToggleEvent();
			toggle.SetIsOnWithoutNotify((bool)entry.BoxedValue);
			((UnityEvent<bool>)(object)toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				if (!ConfigValues.TrySetValue(entry, value))
				{
					toggle.SetIsOnWithoutNotify((bool)entry.BoxedValue);
				}
			});
			NativeUi.SetText(val, GetSettingText(entry));
			CompleteRow(val);
		}

		private void CreateKeybindRow(ConfigEntryBase entry)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			GameObject val = NewRow(GetRowName(entry));
			HideSlider(val);
			Transform val2 = NativeUi.FindValueBackground(val);
			SetValueLayout(val, val2, 0.65f, 20f);
			TMP_Text buttonText = NativeUi.FindValueText(val);
			Button button = (((Object)(object)val2 == (Object)null) ? null : (((Component)val2).GetComponent<Button>() ?? ((Component)val2).gameObject.AddComponent<Button>()));
			if ((Object)(object)button == (Object)null || (Object)(object)buttonText == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			button.onClick = new ButtonClickedEvent();
			((UnityEvent)button.onClick).AddListener((UnityAction)delegate
			{
				_keybindCapture.Begin(entry, button, buttonText);
			});
			NativeUi.SetRowTitle(val, GetSettingText(entry));
			buttonText.text = KeybindCapture.FormatKeyCode(entry.BoxedValue);
			CompleteRow(val);
		}

		private void CreateSliderRow(ModConfig mod, ConfigEntryBase entry, float min, float max)
		{
			GameObject val = NewRow(GetRowName(entry));
			Slider slider = val.GetComponentInChildren<Slider>(true);
			if ((Object)(object)slider == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			SetValueLayout(val, NativeUi.FindValueBackground(val), 0.75f, 20f);
			Image sliderFill = (((Object)(object)slider.fillRect == (Object)null) ? null : ((Component)slider.fillRect).GetComponent<Image>());
			double? sliderStep = ModSettingsMetadata.GetSliderStep(mod, entry);
			double step = ConfigValues.GetSliderStep(min, max, entry.SettingType, sliderStep);
			float num = ConfigValues.SnapSliderValue(Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture), min, max, entry.SettingType, step);
			slider.minValue = min;
			slider.maxValue = max;
			slider.wholeNumbers = ConfigValues.IsIntegralType(entry.SettingType);
			slider.SetValueWithoutNotify(num);
			TMP_Text valueText = NativeUi.FindValueText(val);
			((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float sliderValue)
			{
				float num2 = ConfigValues.SnapSliderValue(sliderValue, min, max, entry.SettingType, step);
				if (Math.Abs(sliderValue - num2) > 0.0001f)
				{
					slider.SetValueWithoutNotify(num2);
				}
				object value = ConfigValues.ConvertSliderValue(num2, entry.SettingType);
				if (!ConfigValues.TrySetValue(entry, value))
				{
					float valueWithoutNotify = Convert.ToSingle(entry.BoxedValue, CultureInfo.InvariantCulture);
					slider.SetValueWithoutNotify(valueWithoutNotify);
				}
				if ((Object)(object)valueText != (Object)null)
				{
					valueText.text = ConfigValues.FormatValue(entry.BoxedValue);
				}
				UpdateSliderFill(sliderFill, slider);
			});
			NativeUi.SetRowTitle(val, GetSettingText(entry));
			if ((Object)(object)valueText != (Object)null)
			{
				valueText.text = ConfigValues.FormatValue(ConfigValues.ConvertSliderValue(num, entry.SettingType));
			}
			CompleteRow(val);
		}

		private void CreateDropdownRow(ConfigEntryBase entry, IReadOnlyList<object> values)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			GameObject val = NewRow(GetRowName(entry));
			HideSlider(val);
			SetValueLayout(val, NativeUi.FindValueBackground(val), 0.65f, 20f);
			TMP_Dropdown dropdown = AddControl<TMP_Dropdown>(val, _dropdown);
			if ((Object)(object)dropdown == (Object)null || values.Count == 0)
			{
				Object.Destroy((Object)(object)val);
				CreateInputRow(entry);
				return;
			}
			dropdown.ClearOptions();
			foreach (object value in values)
			{
				dropdown.options.Add(new OptionData(GetConfigValueText(entry, value)));
			}
			int valueWithoutNotify = values.Select((object value, int index) => new { value, index }).FirstOrDefault(item => object.Equals(item.value, entry.BoxedValue))?.index ?? 0;
			dropdown.onValueChanged = new DropdownEvent();
			dropdown.SetValueWithoutNotify(valueWithoutNotify);
			dropdown.RefreshShownValue();
			((UnityEvent<int>)(object)dropdown.onValueChanged).AddListener((UnityAction<int>)delegate(int index)
			{
				if (index >= 0 && index < values.Count && !ConfigValues.TrySetValue(entry, values[index]))
				{
					int valueWithoutNotify2 = values.Select((object value, int valueIndex) => new { value, valueIndex }).FirstOrDefault(item => object.Equals(item.value, entry.BoxedValue))?.valueIndex ?? 0;
					dropdown.SetValueWithoutNotify(valueWithoutNotify2);
					dropdown.RefreshShownValue();
				}
			});
			NativeUi.SetRowTitle(val, GetSettingText(entry));
			CompleteRow(val);
		}

		private void CreateInputRow(ConfigEntryBase entry)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NewRow(GetRowName(entry));
			HideSlider(val);
			Transform val2 = NativeUi.FindValueBackground(val);
			TMP_Text val3 = NativeUi.FindValueText(val);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			SetValueLayout(val, val2, 0.3f, 20f);
			GameObject val4 = new GameObject("Input", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(TMP_InputField)
			});
			val4.transform.SetParent(val2, false);
			RectTransform component = val4.GetComponent<RectTransform>();
			NativeUi.Stretch(component);
			component.offsetMin = new Vector2(0f, 10f);
			component.offsetMax = new Vector2(0f, -10f);
			Image component2 = val4.GetComponent<Image>();
			((Graphic)component2).color = Color.white;
			Button component3 = ((Component)val2).GetComponent<Button>();
			PrepareBackground(component3);
			if ((Object)(object)component3 != (Object)null && (Object)(object)((Selectable)component3).targetGraphic != (Object)null)
			{
				((Selectable)component3).targetGraphic.color = Color.clear;
			}
			GameObject val5 = new GameObject("Text Viewport", new Type[2]
			{
				typeof(RectTransform),
				typeof(RectMask2D)
			});
			val5.transform.SetParent(val4.transform, false);
			RectTransform component4 = val5.GetComponent<RectTransform>();
			NativeUi.Stretch(component4);
			component4.offsetMin = new Vector2(12f, 2f);
			component4.offsetMax = new Vector2(-12f, -2f);
			TMP_InputField input = val4.GetComponent<TMP_InputField>();
			val3.transform.SetParent(val5.transform, false);
			((Graphic)val3).color = Color.black;
			val3.alignment = (TextAlignmentOptions)4097;
			((Graphic)val3).raycastTarget = false;
			((Selectable)input).targetGraphic = (Graphic)(object)component2;
			input.textViewport = component4;
			input.textComponent = val3;
			input.lineType = (LineType)0;
			input.richText = false;
			input.onEndEdit = new SubmitEvent();
			input.SetTextWithoutNotify(entry.GetSerializedValue());
			((UnityEvent<string>)(object)input.onEndEdit).AddListener((UnityAction<string>)delegate(string value)
			{
				if (!ConfigValues.TrySetSerializedValue(entry, value))
				{
					input.SetTextWithoutNotify(entry.GetSerializedValue());
				}
			});
			NativeUi.SetRowTitle(val, GetSettingText(entry));
			CompleteRow(val);
		}

		private void CompleteRow(GameObject row)
		{
			row.SetActive(true);
			_createdRows.Add(row);
		}

		private GameObject NewRow(string name)
		{
			GameObject obj = Object.Instantiate<GameObject>(_row, _content);
			((Object)obj).name = name;
			obj.SetActive(false);
			NativeUi.DisableLocalization(obj);
			return obj;
		}

		private T AddControl<T>(GameObject row, GameObject source) where T : Component
		{
			Transform val = NativeUi.FindValueBackground(row);
			if ((Object)(object)val == (Object)null || (Object)(object)source == (Object)null)
			{
				return default(T);
			}
			TMP_Text val2 = NativeUi.FindValueText(row);
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			PrepareBackground(((Component)val).GetComponent<Button>());
			GameObject obj = Object.Instantiate<GameObject>(source, val);
			((Object)obj).name = ((Object)source).name;
			NativeUi.DisableLocalization(obj);
			NativeUi.Stretch(obj.GetComponent<RectTransform>());
			return obj.GetComponentInChildren<T>(true);
		}

		private static void SetValueLayout(GameObject row, Transform valueBackground, float titleWidth, float rightInset)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Transform obj = row.transform.Find("TitleAndSlider");
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			RectTransform val2 = (RectTransform)(object)((valueBackground is RectTransform) ? valueBackground : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				HorizontalLayoutGroup component = row.GetComponent<HorizontalLayoutGroup>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
				}
				val.anchorMin = Vector2.zero;
				val.anchorMax = new Vector2(titleWidth, 1f);
				val.offsetMin = new Vector2(10f, 0f);
				val.offsetMax = new Vector2(-10f, 0f);
				val2.anchorMin = new Vector2(titleWidth, 0f);
				val2.anchorMax = Vector2.one;
				val2.offsetMin = new Vector2(10f, 0f);
				val2.offsetMax = new Vector2(0f - rightInset, 0f);
			}
		}

		private void LayoutRebuild()
		{
			RectTransform component = ((Component)_content).GetComponent<RectTransform>();
			LayoutRebuilder.ForceRebuildLayoutImmediate(component);
			_info?.Repair();
			LayoutRebuilder.ForceRebuildLayoutImmediate(component);
			ScrollRect componentInParent = ((Component)_content).GetComponentInParent<ScrollRect>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				componentInParent.verticalNormalizedPosition = 1f;
			}
		}

		private static string GetRowName(ConfigEntryBase entry)
		{
			return "Mod Setting - " + entry.Definition.Key;
		}

		private static string GetSettingText(ConfigEntryBase entry)
		{
			return SplitName(LocalizationApi.GetConfigDisplayName(entry));
		}

		private static string GetConfigValueText(ConfigEntryBase entry, object value)
		{
			string result = default(string);
			if (!LocalizationApi.TryGetConfigDisplayValue(entry, value, ref result))
			{
				return ConfigValues.FormatValue(value);
			}
			return result;
		}

		private static string SplitName(string text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			StringBuilder stringBuilder = new StringBuilder(text.Length + 8);
			for (int i = 0; i < text.Length; i++)
			{
				char c = text[i];
				if (c == '_')
				{
					if (stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != ' ')
					{
						stringBuilder.Append(' ');
					}
					continue;
				}
				bool flag = i > 0 && !char.IsWhiteSpace(text[i - 1]);
				if (char.IsUpper(c) && flag && (char.IsLower(text[i - 1]) || (i + 1 < text.Length && char.IsLower(text[i + 1]))) && stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != ' ')
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString().Trim();
		}

		private static void PrepareBackground(Button button)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0048: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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 (!((Object)(object)button == (Object)null))
			{
				Graphic targetGraphic = ((Selectable)button).targetGraphic;
				if ((Object)(object)targetGraphic != (Object)null)
				{
					ColorBlock colors = ((Selectable)button).colors;
					targetGraphic.color = ((ColorBlock)(ref colors)).normalColor;
					targetGraphic.raycastTarget = false;
				}
				button.onClick = new ButtonClickedEvent();
				((Selectable)button).transition = (Transition)0;
				Navigation navigation = ((Selectable)button).navigation;
				((Navigation)(ref navigation)).mode = (Mode)0;
				((Selectable)button).navigation = navigation;
			}
		}

		private static void HideSlider(GameObject row)
		{
			Slider componentInChildren = row.GetComponentInChildren<Slider>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			CustomTMPSlider component = row.GetComponent<CustomTMPSlider>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
		}

		private static void UpdateSliderFill(Image fill, Slider slider)
		{
			if (!((Object)(object)fill == (Object)null) && !((Object)(object)slider == (Object)null))
			{
				float num = slider.maxValue - slider.minValue;
				fill.fillAmount = ((num <= 0f) ? 0f : Mathf.Clamp01((slider.value - slider.minValue) / num));
			}
		}
	}
	internal sealed class KeybindCapture
	{
		private ConfigEntryBase _entry;

		private TMP_Text _buttonText;

		private int _startFrame;

		public bool IsActive => _entry != null;

		public void Begin(ConfigEntryBase entry, Button button, TMP_Text buttonText)
		{
			_entry = entry;
			_buttonText = buttonText;
			_startFrame = Time.frameCount;
			_buttonText.text = I18n.Text("menu.press_a_key");
			NativeUi.SelectObject(((Component)button).gameObject);
		}

		public void CaptureInput()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (Time.frameCount <= _startFrame)
			{
				return;
			}
			foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
			{
				if ((int)value != 0 && Input.GetKeyDown(value))
				{
					if ((int)value == 27)
					{
						Finish(save: false, (KeyCode)0);
					}
					else
					{
						Finish(save: true, value);
					}
					break;
				}
			}
		}

		public void Cancel()
		{
			if (IsActive)
			{
				Finish(save: false, (KeyCode)0);
			}
		}

		public unsafe static string FormatKeyCode(object value)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!(value is KeyCode val))
			{
				return ConfigValues.FormatValue(value);
			}
			return ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString();
		}

		private void Finish(bool save, KeyCode keyCode)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (save && _entry != null && !ConfigValues.TrySetValue(_entry, keyCode))
			{
				keyCode = (KeyCode)_entry.BoxedValue;
			}
			else if (_entry != null)
			{
				keyCode = (KeyCode)_entry.BoxedValue;
			}
			if ((Object)(object)_buttonText != (Object)null)
			{
				_buttonText.text = FormatKeyCode(keyCode);
			}
			_entry = null;
			_buttonText = null;
		}
	}
	internal sealed class ModInfoRow
	{
		private sealed class MetadataPart
		{
			public string Text { get; }

			public string Name { get; }

			public string Url { get; }

			public MetadataPart(string text, string name = null, string url = null)
			{
				Text = text;
				Name = name;
				Url = url;
			}
		}

		private sealed class ModLink
		{
			public string Name { get; }

			public string Url { get; }

			public int Start { get; }

			public int Length { get; }

			public ModLink(string name, string url, int start, int length)
			{
				Name = name;
				Url = url;
				Start = start;
				Length = length;
			}
		}

		private readonly Transform _content;

		private readonly GameObject _slider;

		private readonly GameObject _divider;

		private readonly GameObject _linkButton;

		private readonly GameObject _description;

		private readonly TMP_Text _descriptionFont;

		private GameObject _row;

		private IReadOnlyList<ModLink> _links = Array.Empty<ModLink>();

		private bool _linksCreated;

		public ModInfoRow(Transform content, GameObject slider, GameObject divider, GameObject linkButton, GameObject description, TMP_Text descriptionFont)
		{
			_content = content;
			_slider = slider;
			_divider = divider;
			_linkButton = linkButton;
			_description = description;
			_descriptionFont = descriptionFont;
		}

		public GameObject Create(ModConfig mod)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			_row = null;
			_links = Array.Empty<ModLink>();
			_linksCreated = false;
			ModSettingsRegistration modSettingsRegistration = mod?.Registration;
			if (modSettingsRegistration == null)
			{
				return null;
			}
			List<ModLink> links;
			string text = BuildText(modSettingsRegistration, out links);
			if (string.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			GameObject val = NewRow();
			HideRowContents(val);
			RectTransform component = val.GetComponent<RectTransform>();
			RectTransform component2 = _slider.GetComponent<RectTransform>();
			RectTransform component3 = _description.GetComponent<RectTransform>();
			RectTransform component4 = _divider.GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null || (Object)(object)component4 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			float num = Mathf.Max(765f, component2.sizeDelta.x);
			float width = Mathf.Max(1f, num - 20f);
			RectTransform infoRect;
			TMP_Text infoLabel;
			float height;
			GameObject val2 = CreateText(val, text, width, out infoRect, out infoLabel, out height);
			if ((Object)(object)val2 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			float num2 = height + 2f + 12f + 6f;
			component.sizeDelta = new Vector2(num, num2);
			SetTextRect(infoRect, component3, height, num2, 6f, 10f);
			val2.SetActive(true);
			GameObject val3 = Object.Instantiate<GameObject>(_divider, val.transform);
			((Object)val3).name = "Information Divider";
			val3.SetActive(false);
			HideChildren(val3);
			Image component5 = val3.GetComponent<Image>();
			RectTransform component6 = val3.GetComponent<RectTransform>();
			if ((Object)(object)component5 == (Object)null || (Object)(object)component6 == (Object)null)
			{
				Object.Destroy((Object)(object)val3);
				Object.Destroy((Object)(object)val);
				return null;
			}
			((Graphic)component5).raycastTarget = false;
			DisableLayoutDrivers(val3);
			component6.anchorMin = new Vector2(0f, 0.5f);
			component6.anchorMax = new Vector2(1f, 0.5f);
			component6.pivot = new Vector2(0.5f, 0.5f);
			component6.sizeDelta = new Vector2(0f, 2f);
			component6.anchoredPosition = new Vector2(0f, (0f - num2) * 0.5f + 6f + 1f);
			((Transform)component6).localScale = ((Transform)component4).localScale;
			((Transform)component6).localRotation = ((Transform)component4).localRotation;
			val3.SetActive(true);
			_row = val;
			_links = links;
			return val;
		}

		public void Repair()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00a0: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_row == (Object)null)
			{
				return;
			}
			Transform transform = _row.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			Transform obj = transform.Find("Information Text");
			RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			Transform obj2 = transform.Find("Information Divider");
			RectTransform val3 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				return;
			}
			TMP_Text val4 = ((Component)val2).GetComponent<TMP_Text>() ?? ((Component)val2).GetComponentInChildren<TMP_Text>(true);
			if (!((Object)(object)val4 == (Object)null))
			{
				Rect rect = val.rect;
				StretchRow(val, 765f, ((Rect)(ref rect)).height);
				((Transform)val).localScale = Vector3.one;
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = new Vector2(10f, val2.offsetMin.y);
				val2.offsetMax = new Vector2(-10f, val2.offsetMax.y);
				((Transform)val2).localScale = Vector3.one;
				Canvas.ForceUpdateCanvases();
				val4.ForceMeshUpdate(true, true);
				float num = Mathf.Max(_descriptionFont.fontSize, val4.renderedHeight);
				float num2 = num + 2f + 12f + 6f;
				StretchRow(val, 765f, num2);
				SetTextRect(val2, null, num, num2, 6f, 10f);
				val3.anchorMin = new Vector2(0f, 0.5f);
				val3.anchorMax = new Vector2(1f, 0.5f);
				val3.sizeDelta = new Vector2(0f, 2f);
				val3.anchoredPosition = new Vector2(0f, (0f - num2) * 0.5f + 6f + 1f);
				((Transform)val3).localScale = Vector3.one;
				if (!_linksCreated && _links.Count > 0)
				{
					Canvas.ForceUpdateCanvases();
					val4.ForceMeshUpdate(true, true);
					CreateLinkButtons(_row, val2, val4, _links);
				}
				_linksCreated = true;
			}
		}

		private GameObject CreateText(GameObject row, string text, float width, out RectTransform infoRect, out TMP_Text infoLabel, out float height)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			infoRect = null;
			infoLabel = null;
			height = 0f;
			GameObject val = Object.Instantiate<GameObject>(_description, row.transform);
			((Object)val).name = "Information Text";
			val.SetActive(false);
			NativeUi.DisableLocalization(val);
			infoRect = val.GetComponent<RectTransform>();
			infoLabel = val.GetComponent<TMP_Text>() ?? val.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)infoRect == (Object)null || (Object)(object)infoLabel == (Object)null || (Object)(object)_descriptionFont == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				infoRect = null;
				infoLabel = null;
				return null;
			}
			infoLabel.enableAutoSizing = false;
			infoLabel.enableWordWrapping = true;
			infoLabel.richText = true;
			infoLabel.overflowMode = (TextOverflowModes)0;
			infoLabel.alignment = (TextAlignmentOptions)257;
			infoLabel.fontSize = _descriptionFont.fontSize;
			infoLabel.text = text.Trim();
			DisableLayoutDrivers(val);
			height = Mathf.Max(_descriptionFont.fontSize, infoLabel.GetPreferredValues(infoLabel.text, width, 0f).y);
			return val;
		}

		private void CreateLinkButtons(GameObject row, RectTransform infoRect, TMP_Text infoText, IReadOnlyList<ModLink> links)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)infoRect == (Object)null || (Object)(object)infoText == (Object)null)
			{
				return;
			}
			infoText.ForceMeshUpdate(true, true);
			for (int i = 0; i < links.Count; i++)
			{
				ModLink link = links[i];
				List<Rect> linkBounds = GetLinkBounds(infoText, link);
				for (int j = 0; j < linkBounds.Count; j++)
				{
					CreateLinkButton(row, infoRect, infoText, link, linkBounds[j], j);
				}
			}
		}

		private void CreateLinkButton(GameObject row, RectTransform infoRect, TMP_Text infoText, ModLink link, Rect bounds, int segment)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(_linkButton, row.transform);
			((Object)val).name = link.Name + " Link " + segment;
			val.SetActive(false);
			NativeUi.DisableLocalization(val);
			NativeUi.SetText(val, string.Empty);
			Button component = val.GetComponent<Button>();
			Image component2 = val.GetComponent<Image>();
			if ((Object)(object)component2 == (Object)null)
			{
				GameObject val2 = new GameObject("Link Hit Area", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val2.transform.SetParent(val.transform, false);
				RectTransform component3 = val2.GetComponent<RectTransform>();
				component3.anchorMin = Vector2.zero;
				component3.anchorMax = Vector2.one;
				component3.offsetMin = Vector2.zero;
				component3.offsetMax = Vector2.zero;
				component2 = val2.GetComponent<Image>();
			}
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			Graphic[] componentsInChildren = val.GetComponentsInChildren<Graphic>(true);
			foreach (Graphic val3 in componentsInChildren)
			{
				if (!((Object)(object)val3 == (Object)(object)component2))
				{
					Color color = val3.color;
					color.a = 0f;
					val3.color = color;
					val3.raycastTarget = false;
				}
			}
			((Graphic)component2).color = Color.clear;
			((Graphic)component2).raycastTarget = true;
			((Selectable)component).targetGraphic = (Graphic)(object)component2;
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				Application.OpenURL(link.Url);
			});
			((Selectable)component).transition = (Transition)0;
			((Selectable)component).interactable = true;
			Navigation navigation = ((Selectable)component).navigation;
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)component).navigation = navigation;
			RectTransform component4 = val.GetComponent<RectTransform>();
			if ((Object)(object)component4 == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			component4.anchorMin = new Vector2(0.5f, 0.5f);
			component4.anchorMax = new Vector2(0.5f, 0.5f);
			component4.pivot = new Vector2(0.5f, 0.5f);
			component4.sizeDelta = ((Rect)(ref bounds)).size + new Vector2(4f, 4f);
			((Transform)component4).localScale = ((Transform)infoRect).localScale;
			((Transform)component4).localRotation = ((Transform)infoRect).localRotation;
			((Transform)component4).localPosition = row.transform.InverseTransformPoint(((Transform)infoRect).TransformPoint(new Vector3(((Rect)(ref bounds)).center.x, ((Rect)(ref bounds)).center.y, 0f)));
			ConfigureHover(val, infoText, link);
			val.SetActive(true);
		}

		private static void ConfigureHover(GameObject buttonObject, TMP_Text infoText, ModLink link)
		{
			//IL_00e4: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			if (!((Object)(object)buttonObject == (Object)null) && !((Object)(object)infoText == (Object)null) && link.Start >= 0 && link.Start + link.Length <= infoText.text.Length)
			{
				string normalText = infoText.text;
				string hoverText = normalText.Substring(0, link.Start) + "<u>" + normalText.Substring(link.Start, link.Length) + "</u>" + normalText.Substring(link.Start + link.Length);
				EventTrigger obj = buttonObject.GetComponent<EventTrigger>() ?? buttonObject.AddComponent<EventTrigger>();
				obj.triggers.Clear();
				Entry val = new Entry
				{
					eventID = (EventTriggerType)0
				};
				((UnityEvent<BaseEventData>)(object)val.callback).AddListener((UnityAction<BaseEventData>)delegate
				{
					infoText.text = hoverText;
				});
				obj.triggers.Add(val);
				Entry val2 = new Entry
				{
					eventID = (EventTriggerType)1
				};
				((UnityEvent<BaseEventData>)(object)val2.callback).AddListener((UnityAction<BaseEventData>)delegate
				{
					infoText.text = normalText;
				});
				obj.triggers.Add(val2);
			}
		}

		private static List<Rect> GetLinkBounds(TMP_Text text, ModLink link)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			List<Rect> list = new List<Rect>();
			TMP_TextInfo textInfo = text.textInfo;
			int num = Math.Min(link.Start + link.Length, textInfo.characterCount);
			int num2 = -1;
			float num3 = 0f;
			float num4 = 0f;
			float num5 = 0f;
			float num6 = 0f;
			for (int i = link.Start; i < num; i++)
			{
				TMP_CharacterInfo val = textInfo.characterInfo[i];
				if (!val.isVisible)
				{
					continue;
				}
				if (num2 != val.lineNumber)
				{
					if (num2 >= 0)
					{
						list.Add(Rect.MinMaxRect(num3, num4, num5, num6));
					}
					num2 = val.lineNumber;
					num3 = val.bottomLeft.x;
					num4 = val.bottomLeft.y;
					num5 = val.topRight.x;
					num6 = val.topRight.y;
				}
				else
				{
					num3 = Mathf.Min(num3, val.bottomLeft.x);
					num4 = Mathf.Min(num4, val.bottomLeft.y);
					num5 = Mathf.Max(num5, val.topRight.x);
					num6 = Mathf.Max(num6, val.topRight.y);
				}
			}
			if (num2 >= 0)
			{
				list.Add(Rect.MinMaxRect(num3, num4, num5, num6));
			}
			return list;
		}

		private static string BuildText(ModSettingsRegistration registration, out List<ModLink> links)
		{
			List<MetadataPart> list = new List<MetadataPart>();
			bool hasValue = registration.NexusModsId.HasValue;
			bool flag = !string.IsNullOrWhiteSpace(registration.ThunderstoreTeam);
			bool flag2 = hasValue && flag;
			if (!string.IsNullOrWhiteSpace(registration.Version))
			{
				list.Add(new MetadataPart("V" + registration.Version.Trim()));
			}
			if (!string.IsNullOrWhiteSpace(registration.Author))
			{
				list.Add(new MetadataPart(registration.Author.Trim()));
			}
			if (hasValue)
			{
				list.Add(new MetadataPart(flag2 ? "Nexus" : I18n.Text("menu.open_nexus_page"), "Nexus Mods", ModSettingsRegistry.GetNexusModsUrl(registration.NexusModsId.Value)));
			}
			if (flag)
			{
				list.Add(new MetadataPart(flag2 ? "Thunderstore" : I18n.Text("menu.open_thunderstore_page"), "Thunderstore", ModSettingsRegistry.GetThunderstoreUrl(registration.ThunderstoreTeam, registration.ThunderstoreModName)));
			}
			links = new List<ModLink>();
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < list.Count; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append(" · ");
				}
				MetadataPart metadataPart = list[i];
				int length = stringBuilder.Length;
				stringBuilder.Append(metadataPart.Text);
				if (!string.IsNullOrWhiteSpace(metadataPart.Url))
				{
					links.Add(new ModLink(metadataPart.Name, metadataPart.Url, length, metadataPart.Text.Length));
				}
			}
			if (!string.IsNullOrWhiteSpace(registration.Description))
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("\n\n");
				}
				stringBuilder.Append(registration.Description.Trim());
			}
			return stringBuilder.ToString();
		}

		private GameObject NewRow()
		{
			GameObject obj = Object.Instantiate<GameObject>(_slider, _content);
			((Object)obj).name = "Mod Settings Information";
			obj.SetActive(false);
			NativeUi.DisableLocalization(obj);
			HorizontalLayoutGroup component = obj.GetComponent<HorizontalLayoutGroup>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			return obj;
		}

		private static void HideRowContents(GameObject row)
		{
			HideChildren(row);
			Slider componentInChildren = row.GetComponentInChildren<Slider>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.SetActive(false);
			}
			CustomTMPSlider component = row.GetComponent<CustomTMPSlider>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
		}

		private static void HideChildren(GameObject root)
		{
			for (int i = 0; i < root.transform.childCount; i++)
			{
				((Component)root.transform.GetChild(i)).gameObject.SetActive(false);
			}
		}

		private static void SetTextRect(RectTransform rect, RectTransform source, float height, float rowHeight, float verticalPadding, float horizontalPadding)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.pivot = new Vector2(0.5f, 0.5f);
			rect.offsetMin = new Vector2(horizontalPadding, rowHeight - verticalPadding - height);
			rect.offsetMax = new Vector2(0f - horizontalPadding, 0f - verticalPadding);
			((Transform)rect).localScale = (((Object)(object)source == (Object)null) ? Vector3.one : ((Transform)source).localScale);
			((Transform)rect).localRotation = (((Object)(object)source == (Object)null) ? Quaternion.identity : ((Transform)source).localRotation);
		}

		private static void StretchRow(RectTransform rect, float nativeWidth, float height)
		{
			//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)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = new Vector2(0f, rect.anchorMin.y);
			rect.anchorMax = new Vector2(1f, rect.anchorMax.y);
			Vector2 sizeDelta = rect.sizeDelta;
			sizeDelta.x = 0f;
			sizeDelta.y = height;
			rect.sizeDelta = sizeDelta;
			rect.offsetMin = new Vector2(0f, rect.offsetMin.y);
			rect.offsetMax = new Vector2(0f, rect.offsetMax.y);
			Rect rect2 = rect.rect;
			if (((Rect)(ref rect2)).width < 1f)
			{
				rect.sizeDelta = new Vector2(nativeWidth, height);
			}
		}

		private static void DisableLayoutDrivers(GameObject root)
		{
			if (!((Object)(object)root == (Object)null))
			{
				LayoutGroup[] componentsInChildren = root.GetComponentsInChildren<LayoutGroup>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Behaviour)componentsInChildren[i]).enabled = false;
				}
				ContentSizeFitter[] componentsInChildren2 = root.GetComponentsInChildren<ContentSizeFitter>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					((Behaviour)componentsInChildren2[i]).enabled = false;
				}
				AspectRatioFitter[] componentsInChildren3 = root.GetComponentsInChildren<AspectRatioFitter>(true);
				for (int i = 0; i < componentsInChildren3.Length; i++)
				{
					((Behaviour)componentsInChildren3[i]).enabled = false;
				}
				LayoutElement[] componentsInChildren4 = root.GetComponentsInChildren<LayoutElement>(true);
				for (int i = 0; i < componentsInChildren4.Length; i++)
				{
					((Behaviour)componentsInChildren4[i]).enabled = false;
				}
			}
		}
	}
	public static class ModSettingsMenuController
	{
		private static Button _titleSource;

		private static Button _pauseSource;

		private static GameObject _titleButton;

		private static GameObject _pauseButton;

		private static ModSettingsPanel _panel;

		private static readonly FieldInfo TitleSettingsButtonField = AccessTools.Field(typeof(UIMenu), "btnOpenSettings");

		private static readonly FieldInfo PauseSettingsButtonField = AccessTools.Field(typeof(UIGameMenu), "btnSettings");

		public static void AddTitleButton(Button source)
		{
			_titleButton = AddButton(_titleButton, ref _titleSource, source, inTitleMenu: true);
		}

		public static void AddTitleButton(UIMenu menu)
		{
			if ((Object)(object)menu == (Object)null)
			{
				ManualLogSource log = ModSettingsMenu.Log;
				if (log != null)
				{
					log.LogInfo((object)"Mainframe title menu is null.");
				}
				return;
			}
			if (TitleSettingsButtonField == null)
			{
				ManualLogSource log2 = ModSettingsMenu.Log;
				if (log2 != null)
				{
					log2.LogError((object)"Mainframe title settings field is missing.");
				}
				return;
			}
			Button button = GetButton(menu, TitleSettingsButtonField);
			if ((Object)(object)button == (Object)null)
			{
				ManualLogSource log3 = ModSettingsMenu.Log;
				if (log3 != null)
				{
					log3.LogError((object)"Mainframe title settings button is null.");
				}
				return;
			}
			ManualLogSource log4 = ModSettingsMenu.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)"Mainframe title settings button found.");
			}
			AddTitleButton(button);
		}

		public static void AddPauseButton(Button source)
		{
			_pauseButton = AddButton(_pauseButton, ref _pauseSource, source, inTitleMenu: false);
		}

		public static void CaptureInput(UISettings settings)
		{
			if (_panel != null && _panel.IsHost(settings))
			{
				_panel.RepairTabLabels();
				_panel.CaptureInput();
			}
		}

		public static void Refresh()
		{
			_panel?.Refresh();
		}

		public static void RefreshLocalizedText()
		{
			NativeUi.SetText(_titleButton, I18n.Text("menu.mod_settings"));
			NativeUi.SetText(_pauseButton, I18n.Text("menu.mod_settings"));
			_panel?.Refresh();
		}

		public static void Close(UISettings settings)
		{
			if (_panel != null && _panel.IsHost(settings))
			{
				_panel.Close();
			}
		}

		public static bool HandleEscape()
		{
			if (_panel == null || !_panel.IsCapturingKeybind)
			{
				return false;
			}
			_panel.CancelKeybind();
			return true;
		}

		private static GameObject AddButton(GameObject current, ref Button currentSource, Button source, bool inTitleMenu)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)source == (Object)null)
			{
				return current;
			}
			if ((Object)(object)current != (Object)null && (Object)(object)currentSource == (Object)(object)source)
			{
				return current;
			}
			if ((Object)(object)current != (Object)null)
			{
				Object.Destroy((Object)(object)current);
			}
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, ((Component)source).transform.parent);
			((Object)val).name = "Mod Settings Button";
			val.transform.SetSiblingIndex(((Component)source).transform.GetSiblingIndex() + 1);
			NativeUi.DisableLocalization(val);
			Button component = val.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Cloned settings button is missing Button.");
			}
			Navigation navigation = ((Selectable)source).navigation;
			Selectable selectOnDown = ((Navigation)(ref navigation)).selectOnDown;
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				Open(inTitleMenu);
			});
			NativeUi.SetText(val, I18n.Text("menu.mod_settings"));
			((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)component;
			((Selectable)source).navigation = navigation;
			Navigation navigation2 = ((Selectable)component).navigation;
			((Navigation)(ref navigation2)).selectOnUp = (Selectable)(object)source;
			((Navigation)(ref navigation2)).selectOnDown = selectOnDown;
			((Selectable)component).navigation = navigation2;
			if ((Object)(object)selectOnDown != (Object)null)
			{
				Navigation navigation3 = selectOnDown.navigation;
				((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)component;
				selectOnDown.navigation = navigation3;
			}
			currentSource = source;
			ManualLogSource log = ModSettingsMenu.Log;
			if (log != null)
			{
				log.LogInfo((object)(inTitleMenu ? "Added title mod settings button." : "Added pause mod settings button."));
			}
			return val;
		}

		private static Button GetButton(object menu, FieldInfo field)
		{
			if (menu != null && !(field == null))
			{
				object? value = field.GetValue(menu);
				return (Button)((value is Button) ? value : null);
			}
			return null;
		}

		private static void Open(bool inTitleMenu)
		{
			try
			{
				UISettings val = (((Object)(object)Mainframe.code == (Object)null) ? null : Mainframe.code.uiSettings);
				if (!((Object)(object)val == (Object)null))
				{
					val.Open(inTitleMenu);
					if (inTitleMenu)
					{
						Mainframe.code.UIMenu.Close();
					}
					else if ((Object)(object)Global.code != (Object)null)
					{
						Global.code.uiGameMenu.Close();
					}
					if (_panel == null || !_panel.IsHost(val))
					{
						_panel?.Destroy();
						_panel = ModSettingsPanel.Create(val);
					}
					_panel.Show();
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = ModSettingsMenu.Log;
				if (log != null)
				{
					log.LogError((object)$"Failed to open mod settings: {arg}");
				}
			}
		}
	}
	internal sealed class ModSettingsPanel
	{
		private static readonly string[] ToggleFields = new string[5] { "togglePanelGeneral", "togglePanelKeybinding", "togglePanelGraphics", "togglePanelAudio", "togglePanelControllers" };

		private readonly UISettings _settings;

		private readonly GameObject _panel;

		private readonly GameObject _tabTemplate;

		private readonly GameObject _tabScrollObject;

		private readonly ScrollRect _tabScroll;

		private readonly RectTransform _tabContent;

		private readonly GameObject _nativeContent;

		private readonly List<GameObject> _nativeTabs;

		private readonly Button _resetButton;

		private readonly Button _closeButton;

		private readonly Button _modResetButton;

		private readonly Button _modCloseButton;

		private readonly ConfigRows _rows;

		private readonly KeybindCapture _keybindCapture;

		private readonly List<GameObject> _tabs = new List<GameObject>();

		private readonly List<TMP_Text[]> _tabLabels = new List<TMP_Text[]>();

		private readonly List<string> _tabNames = new List<string>();

		private readonly List<int> _tabDiagnosticFrames = new List<int>();

		private IReadOnlyList<ModConfig> _mods = Array.Empty<ModConfig>();

		private string _selectedGuid;

		private bool _savedNativeState;

		private bool _contentState;

		private List<bool> _tabStates;

		private bool _resetState;

		private bool _closeState;

		public bool IsCapturingKeybind => _keybindCapture.IsActive;

		private ModSettingsPanel(UISettings settings, GameObject panel, GameObject tabTemplate, GameObject tabScrollObject, ScrollRect tabScroll, RectTransform tabContent, GameObject nativeContent, List<GameObject> nativeTabs, Button resetButton, Button closeButton, Button modResetButton, Button modCloseButton, ConfigRows rows, KeybindCapture keybindCapture)
		{
			_settings = settings;
			_panel = panel;
			_tabTemplate = tabTemplate;
			_tabScrollObject = tabScrollObject;
			_tabScroll = tabScroll;
			_tabContent = tabContent;
			_nativeContent = nativeContent;
			_nativeTabs = nativeTabs;
			_resetButton = resetButton;
			_closeButton = closeButton;
			_modResetButton = modResetButton;
			_modCloseButton = modCloseButton;
			_rows = rows;
			_keybindCapture = keybindCapture;
		}

		public static ModSettingsPanel Create(UISettings settings)
		{
			GameObject obj = GetPrivate<GameObject>(settings, "panelKeybinding");
			Slider val = GetPrivate<Slider>(settings, "sliderMouseSensitivity");
			Toggle val2 = GetPrivate<Toggle>(settings, "toggleCameraShake");
			TMP_Dropdown val3 = GetPrivate<TMP_Dropdown>(settings, "dropdownLanguage");
			Toggle val4 = GetPrivate<Toggle>(settings, "togglePanelGeneral");
			Button val5 = GetPrivate<Button>(settings, "btnResetToDefaultSettings");
			Button val6 = GetPrivate<Button>(settings, "btnClose");
			if ((Object)(object)obj == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null)
			{
				throw new InvalidOperationException("UISettings is missing a required native template.");
			}
			Transform parent = obj.transform.parent;
			if ((Object)(object)parent == (Object)null || (Object)(object)parent.parent == (Object)null)
			{
				throw new InvalidOperationException("Native keybinding panel is missing its content container.");
			}
			GameObject val7 = Object.Instantiate<GameObject>(obj, parent.parent);
			((Object)val7).name = "Mod Settings Panel";
			val7.transform.SetSiblingIndex(parent.GetSiblingIndex());
			CopyRectTransform(((Component)parent).GetComponent<RectTransform>(), val7.GetComponent<RectTransform>());
			val7.SetActive(false);
			NativeUi.DisableLocalization(val7);
			LocalizedKeybindingButton[] componentsInChildren = val7.GetComponentsInChildren<LocalizedKeybindingButton>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			ScrollRect[] componentsInChildren2 = val7.GetComponentsInChildren<ScrollRect>(true);
			if (componentsInChildren2.Length == 0 || componentsInChildren2.Any((ScrollRect item) => (Object)(object)item.content == (Object)null))
			{
				Object.Destroy((Object)(object)val7);
				throw new InvalidOperationException("Native keybinding panel is missing a scroll content area.");
			}
			ScrollRect[] array = componentsInChildren2;
			for (int i = 0; i < array.Length; i++)
			{
				NativeUi.ClearLayout((Transform)(object)array[i].content);
			}
			for (int num = 1; num < componentsInChildren2.Length; num++)
			{
				Transform parent2 = ((Component)componentsInChildren2[num]).transform.parent;
				if ((Object)(object)parent2 != (Object)null)
				{
					((Component)parent2).gameObject.SetActive(false);
				}
			}
			ScrollRect obj2 = componentsInChildren2[0];
			Scrollbar verticalScrollbar = obj2.verticalScrollbar;
			if ((Object)(object)verticalScrollbar == (Object)null)
			{
				Object.Destroy((Object)(object)val7);
				throw new InvalidOperationException("Native keybinding scroll is missing a vertical scrollbar.");
			}
			Transform parent3 = ((Component)obj2).transform.parent;
			StretchWidth((RectTransform)(object)((parent3 is RectTransform) ? parent3 : null));
			Transform transform = ((Component)obj2).transform;
			BalanceScrollMargins((RectTransform)(object)((transform is RectTransform) ? transform : null));
			obj2.scrollSensitivity = 50f;
			Button modResetButton = CloneButton(val5, parent.parent, "Mod Settings Reset Button");
			Button modCloseButton = CloneButton(val6, parent.parent, "Mod Settings Close Button");
			Transform val8 = FindRow(val);
			GameObject divider = FindTemplate(val8, "TitleAndSlider/Slider mouse sensitivity/Background");
			GameObject val9 = FindTemplate(((Component)val3).transform, "Label");
			TMP_Text component = val9.GetComponent<TMP_Text>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val7);
				throw new InvalidOperationException("Native dropdown label is missing TextMeshProUGUI.");
			}
			KeybindCapture keybindCapture = new KeybindCapture();
			ConfigRows rows = new ConfigRows(info: new ModInfoRow((Transform)(object)obj2.content, ((Component)val8).gameObject, divider, ((Component)val6).gameObject, val9, component), content: (Transform)(object)obj2.content, row: ((Component)val8).gameObject, heading: FindGroupHeading(val8), toggle: ((Component)val2).gameObject, dropdown: ((Component)val3).gameObject, keybindCapture: keybindCapture);
			ScrollRect scroll;
			RectTransform content;
			GameObject tabScrollObject = CreateTabScroll(((Component)val4).transform.parent, verticalScrollbar, out scroll, out content);
			return new ModSettingsPanel(settings, val7, ((Component)val4).gameObject, tabScrollObject, scroll, content, ((Component)parent).gameObject, GetPrivateToggleGameObjects(settings, ToggleFields), val5, val6, modResetButton, modCloseButton, rows, keybindCapture);
		}

		public bool IsHost(UISettings settings)
		{
			return (Object)(object)_settings == (Object)(object)settings;
		}

		public void Show()
		{
			SaveNativeState();
			HideNative();
			if ((Object)(object)_tabScrollObject != (Object)null)
			{
				_tabScrollObject.SetActive(true);
			}
			_panel.SetActive(true);
			BuildTabs();
			SetupButtons();
			SelectMod(_selectedGuid);
		}

		public void CaptureInput()
		{
			if (_panel.activeSelf && _keybindCapture.IsActive)
			{
				_keybindCapture.CaptureInput();
			}
		}

		public void RepairTabLabels()
		{
			if ((Object)(object)_panel == (Object)null || !_panel.activeSelf)
			{
				return;
			}
			for (int i = 0; i < _tabs.Count && i < _mods.Count && i < _tabLabels.Count && i < _tabNames.Count; i++)
			{
				GameObject val = _tabs[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = _tabNames[i];
				TMP_Text[] array = _tabLabels[i];
				string gUID = _mods[i].Info.Metadata.GUID;
				PrepareTabFont(array, text, gUID, logDiagnostics: false);
				TMP_Text component = val.GetComponent<TMP_Text>();
				foreach (TMP_Text val2 in array)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						if (!string.Equals(val2.text, text, StringComparison.Ordinal))
						{
							val2.text = text;
						}
						if ((Object)(object)val2 == (Object)(object)component)
						{
							((Behaviour)val2).enabled = true;
						}
					}
				}
				if (i < _tabDiagnosticFrames.Count && _tabDiagnosticFrames[i] >= 0)
				{
					int num = _tabDiagnosticFrames[i] + 1;
					_tabDiagnosticFrames[i] = (LogTabMesh(array, text, gUID, num) ? (-1) : num);
				}
			}
		}

		public void Refresh()
		{
			if (_panel.activeSelf)
			{
				BuildTabs();
				SetupButtons();
				SelectMod(_selectedGuid);
			}
		}

		public void CancelKeybind()
		{
			_keybindCapture.Cancel();
		}

		public void Close()
		{
			_keybindCapture.Cancel();
			if ((Object)(object)_panel != (Object)null)
			{
				_panel.SetActive(false);
			}
			if ((Object)(object)_tabScrollObject != (Object)null)
			{
				_tabScrollObject.SetActive(false);
			}
			ClearTabs();
			RestoreNative();
		}

		public void Destroy()
		{
			Close();
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
			}
			if ((Object)(object)_tabScrollObject != (Object)null)
			{
				Object.Destroy((Object)(object)_tabScrollObject);
			}
			if ((Object)(object)_modResetButton != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_modResetButton).gameObject);
			}
			if ((Object)(object)_modCloseButton != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_modCloseButton).gameObject);
			}
		}

		private void BuildTabs()
		{
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			ClearTabs();
			_mods = ModConfigs.Load();
			if (!_mods.Any((ModConfig mod) => string.Equals(mod.Info.Metadata.GUID, _selectedGuid, StringComparison.OrdinalIgnoreCase)))
			{
				ModConfig? modConfig = _mods.FirstOrDefault();
				_selectedGuid = ((modConfig != null) ? modConfig.Info.Metadata.GUID : null);
			}
			for (int num = 0; num < _mods.Count; num++)
			{
				ModConfig modConfig2 = _mods[num];
				GameObject val = Object.Instantiate<GameObject>(_tabTemplate, (Transform)(object)_tabContent);
				((Object)val).name = "Mod Settings Tab - " + modConfig2.Info.Metadata.GUID;
				val.SetActive(false);
				NativeUi.DisableLocalization(val);
				Toggle tab = val.GetComponent<Toggle>();
				if ((Object)(object)tab == (Object)null)
				{
					Object.Destroy((Object)(object)val);
					throw new InvalidOperationException("Cloned mod settings tab is missing Toggle.");
				}
				CopyTabLayout(val, num);
				tab.group = null;
				string guid = modConfig2.Info.Metadata.GUID;
				string modName = GetModName(modConfig2);
				TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true);
				val.SetActive(true);
				PrepareTabFont(componentsInChildren, modName, guid, logDiagnostics: true);
				NativeUi.SetText(val, modName);
				tab.onValueChanged = new ToggleEvent();
				((UnityEvent<bool>)(object)tab.onValueChanged).AddListener((UnityAction<bool>)delegate(bool isOn)
				{
					if (isOn)
					{
						SelectMod(guid);
					}
					else if (string.Equals(_selectedGuid, guid, StringComparison.OrdinalIgnoreCase))
					{
						SetTabVisual(tab, isOn: true);
					}
				});
				SetTabVisual(tab, isOn: false);
				_tabs.Add(val);
				_tabLabels.Add(componentsInChildren);
				_tabNames.Add(modName);
				_tabDiagnosticFrames.Add(0);
			}
			ResizeTabContent();
		}

		private void SelectMod(string guid)
		{
			_selectedGuid = guid;
			for (int i = 0; i < _tabs.Count; i++)
			{
				Toggle component = _tabs[i].GetComponent<Toggle>();
				if ((Object)(object)component != (Object)null)
				{
					SetTabVisual(component, string.Equals(_mods[i].Info.Metadata.GUID, guid, StringComparison.OrdinalIgnoreCase));
				}
			}
			ModConfig modConfig = _mods.FirstOrDefault((ModConfig mod) => string.Equals(mod.Info.Metadata.GUID, guid, StringComparison.OrdinalIgnoreCase));
			_rows.Build(modConfig);
			if ((Object)(object)_modResetButton != (Object)null)
			{
				((Selectable)_modResetButton).interactable = modConfig != null;
			}
			for (int num = 0; num < _mods.Count; num++)
			{
				if (_mods[num] == modConfig)
				{
					ScrollToTab(num);
					break;
				}
			}
		}

		private void SaveNativeState()
		{
			if (!_savedNativeState)
			{
				_contentState = (Object)(object)_nativeContent != (Object)null && _nativeContent.activeSelf;
				_tabStates = _nativeTabs.Select((GameObject tab) => (Object)(object)tab != (Object)null && tab.activeSelf).ToList();
				_resetState = (Object)(object)_resetButton != (Object)null && ((Component)_resetButton).gameObject.activeSelf;
				_closeState = (Object)(object)_closeButton != (Object)null && ((Component)_closeButton).gameObject.activeSelf;
				_savedNativeState = true;
			}
		}

		private void HideNative()
		{
			if ((Object)(object)_nativeContent != (Object)null)
			{
				_nativeContent.SetActive(false);
			}
			foreach (GameObject nativeTab in _nativeTabs)
			{
				if ((Object)(object)nativeTab != (Object)null)
				{
					nativeTab.SetActive(false);
				}
			}
			if ((Object)(object)_resetButton != (Object)null)
			{
				((Component)_resetButton).gameObject.SetActive(false);
			}
			if ((Object)(object)_closeButton != (Object)null)
			{
				((Component)_closeButton).gameObject.SetActive(false);
			}
		}

		private void RestoreNative()
		{
			if (!_savedNativeState)
			{
				return;
			}
			if ((Object)(object)_nativeContent != (Object)null)
			{
				_nativeContent.SetActive(_contentState);
			}
			for (int i = 0; i < _nativeTabs.Count; i++)
			{
				if ((Object)(object)_nativeTabs[i] != (Object)null)
				{
					_nativeTabs[i].SetActive(_tabStates[i]);
				}
			}
			if ((Object)(object)_resetButton != (Object)null)
			{
				((Component)_resetButton).gameObject.SetActive(_resetState);
			}
			if ((Object)(object)_closeButton != (Object)null)
			{
				((Component)_closeButton).gameObject.SetActive(_closeState);
			}
			if ((Object)(object)_modResetButton != (Object)null)
			{
				((Component)_modResetButton).gameObject.SetActive(false);
			}
			if ((Object)(object)_modCloseButton != (Object)null)
			{
				((Component)_modCloseButton).gameObject.SetActive(false);
			}
			_savedNativeState = false;
		}

		private void SetupButtons()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			if ((Object)(object)_modResetButton != (Object)null)
			{
				((Component)_modResetButton).gameObject.SetActive(true);
				((Component)_modResetButton).transform.SetAsLastSibling();
				_modResetButton.onClick = new ButtonClickedEvent();
				((UnityEvent)_modResetButton.onClick).AddListener(new UnityAction(ResetSelectedMod));
			}
			if ((Object)(object)_modCloseButton != (Object)null)
			{
				((Component)_modCloseButton).gameObject.SetActive(true);
				((Component)_modCloseButton).transform.SetAsLastSibling();
				_modCloseButton.onClick = new ButtonClickedEvent();
				((UnityEvent)_modCloseButton.onClick).AddListener(new UnityAction(_settings.Close));
			}
		}

		private void ResetSelectedMod()
		{
			ModConfig mod = _mods.FirstOrDefault((ModConfig modConfig) => string.Equals(modConfig.Info.Metadata.GUID, _selectedGuid, StringComparison.OrdinalIgnoreCase));
			_rows.Reset(mod);
		}

		private void ClearTabs()
		{
			foreach (GameObject tab in _tabs)
			{
				if ((Object)(object)tab != (Object)null)
				{
					Object.Destroy((Object)(object)tab);
				}
			}
			_tabs.Clear();
			_tabLabels.Clear();
			_tabNames.Clear();
			_tabDiagnosticFrames.Clear();
		}

		private void CopyTabLayout(GameObject tabObject, int index)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = _nativeTabs[Mathf.Min(index, _nativeTabs.Count - 1)].GetComponent<RectTransform>();
			RectTransform component2 = tabObject.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				CopyRectTransform(component, component2);
				if (index >= _nativeTabs.Count)
				{
					float tabStep = GetTabStep(component);
					component2.anchoredPosition += new Vector2(tabStep * (float)(index - _nativeTabs.Count + 1), 0f);
				}
			}
		}

		private void ResizeTabContent()
		{
			//IL_004f: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_tabContent == (Object)null) && !((Object)(object)_tabScroll == (Object)null) && !((Object)(object)_tabScroll.viewport == (Object)null))
			{
				RectTransform component = _tabTemplate.GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null))
				{
					float tabStep = GetTabStep(component);
					float num = component.anchoredPosition.x + tabStep * (float)Mathf.Max(0, _tabs.Count - 1);
					Rect rect = component.rect;
					float num2 = num + ((Rect)(ref rect)).width * (1f - component.pivot.x) + 20f;
					RectTransform tabContent = _tabContent;
					rect = _tabScroll.viewport.rect;
					tabContent.sizeDelta = new Vector2(Mathf.Max(((Rect)(ref rect)).width, num2), 0f);
					_tabScroll.horizontalNormalizedPosition = 0f;
				}
			}
		}

		private void ScrollToTab(int index)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (index < 0 || index >= _tabs.Count || (Object)(object)_tabScroll == (Object)null || (Object)(object)_tabScroll.viewport == (Object)null || (Object)(object)_tabContent == (Object)null)
			{
				return;
			}
			Rect rect = _tabScroll.viewport.rect;
			float width = ((Rect)(ref rect)).width;
			rect = _tabContent.rect;
			float num = ((Rect)(ref rect)).width - width;
			if (num <= 0f)
			{
				_tabScroll.horizontalNormalizedPosition = 0f;
				return;
			}
			RectTransform component = _tabs[index].GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				float num2 = component.anchoredPosition.x - width * 0.5f;
				_tabScroll.horizontalNormalizedPosition = Mathf.Clamp01(num2 / num);
			}
		}

		private float GetTabStep(RectTransform source)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (_nativeTabs.Count > 1)
			{
				GameObject obj = _nativeTabs[0];
				RectTransform val = ((obj != null) ? obj.GetComponent<RectTransform>() : null);
				GameObject obj2 = _nativeTabs[1];
				RectTransform val2 = ((obj2 != null) ? obj2.GetComponent<RectTransform>() : null);
				float num = (((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) ? 0f : (val2.anchoredPosition.x - val.anchoredPosition.x));
				if (num > 0f)
				{
					return num;
				}
			}
			Rect rect = source.rect;
			return ((Rect)(ref rect)).width;
		}

		private static void SetTabVisual(Toggle tab, bool isOn)
		{
			tab.SetIsOnWithoutNotify(isOn);
			TMP_Text component = ((Component)tab).GetComponent<TMP_Text>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = true;
			}
		}

		private static void PrepareTabFont(TMP_Text[] labels, string text, string guid, bool logDiagnostics)
		{
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Invalid comparison between Unknown and I4
			string fontName;
			switch (LocalizationApi.CurrentLanguage)
			{
			case "zh-Hans":
				fontName = "NotoSansSC-Regular SDF";
				break;
			case "ja":
				fontName = "NotoSansJP-Regular SDF";
				break;
			case "ko":
				fontName = "NotoSansKR-Regular SDF";
				break;
			default:
				if (logDiagnostics)
				{
					ManualLogSource log = ModSettingsMenu.Log;
					if (log != null)
					{
						log.LogInfo((object)("[TabFont] skip guid=" + guid + " text=\"" + EscapeLogText(text) + "\" language=" + LocalizationApi.CurrentLanguage));
					}
				}
				return;
			}
			if (labels == null)
			{
				if (logDiagnostics)
				{
					ManualLogSource log2 = ModSettingsMenu.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[TabFont] no labels guid=" + guid + " text=\"" + EscapeLogText(text) + "\""));
					}
				}
				return;
			}
			TMP_FontAsset val = null;
			string text2 = null;
			foreach (TMP_Text val2 in labels)
			{
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2.font == (Object)null)
				{
					continue;
				}
				val = FindFont(val2.font, fontName);
				if ((Object)(object)val != (Object)null)
				{
					text2 = "label:" + ((Object)((Component)val2).gameObject).name;
					break;
				}
				List<TMP_FontAsset> fallbackFontAssetTable = val2.font.fallbackFontAssetTable;
				if (fallbackFontAssetTable == null)
				{
					continue;
				}
				for (int j = 0; j < fallbackFontAssetTable.Count; j++)
				{
					val = FindFont(fallbackFontAssetTable[j], fontName);
					if ((Object)(object)val != (Object)null)
					{
						text2 = "fallback:" + ((Object)((Component)val2).gameObject).name + "[" + j + "]";
						break;
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset item) => (Object)(object)FindFont(item, fontName) != (Object)null));
				if ((Object)(object)val != (Object)null)
				{
					text2 = "resources";
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				if (logDiagnostics)
				{
					ManualLogSource log3 = ModSettingsMenu.Log;
					if (log3 != null)
					{
						log3.LogWarning((object)("[TabFont] font not found guid=" + guid + " text=\"" + EscapeLogText(text) + "\" language=" + LocalizationApi.CurrentLanguage + " requested=" + fontName + " labels=" + DescribeLabels(labels)));
					}
				}
				return;
			}
			if ((int)val.atlasPopulationMode != 1 || (Object)(object)val.sourceFontFile == (Object)null)
			{
				if (logDiagnostics)
				{
					ManualLogSource log4 = ModSettingsMenu.Log;
					if (log4 != null)
					{
						log4.LogWarning((object)("[TabFont] unusable font guid=" + guid + " text=\"" + EscapeLogText(text) + "\" match=" + text2 + " " + DescribeFont(val) + " labels=" + DescribeLabels(labels)));
					}
				}
				return;
			}
			int num = ((val.characterTable == null) ? (-1) : val.characterTable.Count);
			int num2 = ((val.glyphTable == null) ? (-1) : val.glyphTable.Count);
			string text3 = default(string);
			bool flag = val.TryAddCharacters(text, ref text3, false);
			uint[] codes = default(uint[]);
			bool flag2 = val.HasCharacters(text, ref codes, false, false);
			if (logDiagnostics)
			{
				ManualLogSource log5 = ModSettingsMenu.Log;
				if (log5 != null)
				{
					log5.LogInfo((object)("[TabFont] prepare guid=" + guid + " text=\"" + EscapeLogText(text) + "\" codes=" + FormatTextCodes(text) + " language=" + LocalizationApi.CurrentLanguage + " " + $"match={text2} added={flag} reportedMissing={FormatTextCodes(text3)} " + $"hasAll={flag2} actualMissing={FormatCodes(codes)} " + $"characters={num}->{GetCharacterCount(val)} " + $"glyphs={num2}->{GetGlyphCount(val)} {DescribeFont(val)} " + "labelsBefore=" + DescribeLabels(labels)));
				}
			}
			foreach (TMP_Text val3 in labels)
			{
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3.font != (Object)(object)val)
				{
					val3.font = val;
				}
			}
			if (logDiagnostics)
			{
				ManualLogSource log6 = ModSettingsMenu.Log;
				if (log6 != null)
				{
					log6.LogInfo((object)("[TabFont] bound guid=" + guid + " text=\"" + EscapeLogText(text) + "\" labelsAfter=" + DescribeLabels(labels)));
				}
			}
		}

		private static bool LogTabMesh(TMP_Text[] labels, string text, string guid, int frame)
		{
			//IL_00b0: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			bool flag = labels?.Any((TMP_Text label) => (Object)(object)label != (Object)null && label.textInfo != null && label.textInfo.characterCount >= text.Length) ?? false;
			if (!flag && frame < 120)
			{
				return false;
			}
			if (!flag)
			{
				ManualLogSource log = ModSettingsMenu.Log;
				if (log != null)
				{
					log.LogWarning((object)("[TabFont] mesh not ready guid=" + guid + " text=\"" + EscapeLogText(text) + "\" " + $"frames={frame} labels={DescribeLabels(labels)}"));
				}
				return true;
			}
			foreach (TMP_Text val in labels)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Rect rect = val.rectTransform.rect;
					TMP_TextInfo textInfo = val.textInfo;
					List<string> list = new List<string>();
					for (int num2 = 0; num2 < textInfo.characterCount; num2++)
					{
						TMP_CharacterInfo val2 = textInfo.characterInfo[num2];
						uint code = ((val2.textElement != null) ? val2.textElement.unicode : 0u);
						uint num3 = ((val2.textElement != null) ? val2.textElement.glyphIndex : 0u);
						TMP_TextElement textElement = val2.textElement;
						int num4 = ((((textElement != null) ? textElement.glyph : null) == null) ? (-1) : val2.textElement.glyph.atlasIndex);
						list.Add(FormatCode(val2.character) + "=>" + FormatCode(code) + $"/glyph={num3}/atlas={num4}" + "/font=" + DescribeFontName(val2.fontAsset) + $"/visible={val2.isVisible}/material={val2.materialReferenceIndex}");
					}
					ManualLogSource log2 = ModSettingsMenu.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("[TabFont] mesh guid=" + guid + " text=\"" + EscapeLogText(text) + "\" " + $"label={((Object)((Component)val).gameObject).name}#{((Object)val).GetInstanceID()} " + $"active={((Component)val).gameObject.activeInHierarchy} enabled={((Behaviour)val).enabled} " + $"rect={((Rect)(ref rect)).width:0.##}x{((Rect)(ref rect)).height:0.##} overflow={val.overflowMode} " + $"font={DescribeFontName(val.font)} characters={textInfo.characterCount} " + string.Format("materials={0} data=[{1}]", textInfo.materialCount, string.Join(", ", list))));
					}
				}
			}
			return true;
		}

		private static string DescribeLabels(TMP_Text[] labels)
		{
			if (labels == null)
			{
				return "null";
			}
			return "[" + string.Join(", ", labels.Select((TMP_Text label) => (!((Object)(object)label == (Object)null)) ? (((Object)((Component)label).gameObject).name + "#" + ((Object)label).GetInstanceID() + "=" + DescribeFontName(label.font)) : "null")) + "]";
		}

		private static string DescribeFont(TMP_FontAsset font)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)font == (Object)null)
			{
				return "font=null";
			}
			string arg = (((Object)(object)font.sourceFontFile == (Object)null) ? "null" : (((Object)font.sourceFontFile).name + "#" + ((Object)font.sourceFontFile).GetInstanceID()));
			Texture2D[] atlasTextures = font.atlasTextures;
			string text = ((atlasTextures == null) ? "null" : ("[" + string.Join(", ", atlasTextures.Select((Texture2D texture, int index) => (!((Object)(object)texture == (Object)null)) ? (index + ":" + ((Texture)texture).width + "x" + ((Texture)texture).height + "#" + ((Object)texture).GetInstanceID()) : (index + ":null"))) + "]"));
			return $"font={DescribeFontName(font)} mode={font.atlasPopulationMode} " + $"source={arg} atlasSize={font.atlasWidth}x{font.atlasHeight} " + $"atlasCount={font.atlasTextureCount} multiAtlas={font.isMultiAtlasTexturesEnabled} " + "atlasTextures=" + text;
		}

		private static string DescribeFontName(TMP_FontAsset font)
		{
			if (!((Object)(object)font == (Object)null))
			{
				return ((Object)font).name + "#" + ((Object)font).GetInstanceID();
			}
			return "null";
		}

		private static int GetCharacterCount(TMP_FontAsset font)
		{
			if (font.characterTable != null)
			{
				return font.characterTable.Count;
			}
			return -1;
		}

		private static int GetGlyphCount(TMP_FontAsset font)
		{
			if (font.glyphTable != null)
			{
				return font.glyphTable.Count;
			}
			return -1;
		}

		private static string FormatTextCodes(string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				return "[" + string.Join(" ", text.Select((char character) => FormatCode(character))) + "]";
			}
			return "[]";
		}

		private static string FormatCodes(uint[] codes)
		{
			if (codes != null && codes.Length != 0)
			{
				return "[" + string.Join(" ", codes.Select(FormatCode)) + "]";
			}
			return "[]";
		}

		private static string FormatCode(uint code)
		{
			return "U+" + code.ToString((code > 65535) ? "X8" : "X4");
		}

		private static string EscapeLogText(string text)
		{
			if (text != null)
			{
				return text.Replace("\r", "\\r").Replace("\n", "\\n");
			}
			return "null";
		}

		private static TMP_FontAsset FindFont(TMP_FontAsset font, string fontName)
		{
			if ((Object)(object)font == (Object)null)
			{
				return null;
			}
			if (!string.Equals(((Object)font).name, fontName, StringComparison.Ordinal) && !((Object)font).name.StartsWith(fontName + "(", StringComparison.OrdinalIgnoreCase) && !((Object)font).name.StartsWith(fontName + " ", StringComparison.OrdinalIgnoreCase))
			{
				return null;
			}
			return font;
		}

		private static void CopyRectTransform(RectTransform source, RectTransform target)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null))
			{
				target.anchorMin = source.anchorMin;
				target.anchorMax = source.anchorMax;
				target.pivot = source.pivot;
				target.sizeDelta = source.sizeDelta;
				target.anchoredPosition = source.anchoredPosition;
				((Transform)target).localScale = ((Transform)source).localScale;
				((Transform)target).localRotation = ((Transform)source).localRotation;
			}
		}

		private static void StretchWidth(RectTransform rect)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rect == (Object)null))
			{
				rect.anchorMin = new Vector2(0f, rect.anchorMin.y);
				rect.anchorMax = new Vector2(1f, rect.anchorMax.y);
				rect.offsetMin = new Vector2(0f, rect.offsetMin.y);
				rect.offsetMax = new Vector2(0f, rect.offsetMax.y);
				((Transform)rect).localScale = Vector3.one;
			}
		}

		private static void BalanceScrollMargins(RectTransform rect)
		{
			//IL_0010: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rect == (Object)null))
			{
				float num = Mathf.Max(0f, 0f - rect.offsetMax.x);
				rect.offsetMin = new Vector2(num, rect.offsetMin.y);
			}
		}

		private static GameObject CreateTabScroll(Transform tabGroup, Scrollbar scrollbarTemplate, out ScrollRect scroll, out RectTransform content)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tabGroup == (Object)null || (Object)(object)tabGroup.parent == (Object)null)
			{
				throw new InvalidOperationException("Native tab group is missing its parent.");
			}
			GameObject val = new GameObject("Mod Settings Tab Scroll", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(ScrollRect)
			});
			val.transform.SetParent(tabGroup.parent, false);
			CopyRectTransform(((Component)tabGroup).GetComponent<RectTransform>(), val.GetComponent<RectTransform>());
			val.transform.SetSiblingIndex(tabGroup.GetSiblingIndex() + 1);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = Color.clear;
			((Graphic)component).raycastTarget = true;
			GameObject val2 = new GameObject("Viewport", new Type[2]
			{
				typeof(RectTransform),
				typeof(RectMask2D)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform component2 = val2.GetComponent<RectTransform>();
			NativeUi.Stretch(component2);
			component2.offsetMin = new Vector2(0f, 20f);
			GameObject val3 = new GameObject("Content", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val2.transform, false);
			content = val3.GetComponent<RectTransform>();
			content.anchorMin = new Vector2(0f, 0f);
			content.anchorMax = new Vector2(0f, 1f);
			content.pivot = new Vector2(0f, 0.5f);
			content.anchoredPosition = Vector2.zero;
			content.sizeDelta = Vector2.zero;
			scroll = val.GetComponent<ScrollRect>();
			scroll.content = content;
			scroll.viewport = component2;
			scroll.horizontal = true;
			scroll.vertical = false;
			scroll.movementType = (MovementType)2;
			scroll.inertia = true;
			scroll.scrollSensitivity = 30f;
			Scrollbar horizontalScrollbar = CloneHorizontalScrollbar(scrollbarTemplate, val.transform);
			scroll.horizontalScrollbar = horizontalScrollbar;
			scroll.horizontalScrollbarVisibility = (ScrollbarVisibility)0;
			scroll.horizontalScrollbarSpacing = 0f;
			val.SetActive(false);
			return val;
		}

		private static Scrollbar CloneHorizontalScrollbar(Scrollbar source, Transform parent)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_005c: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, parent);
			((Object)val).name = "Horizontal Scrollbar";
			Scrollbar component = val.GetComponent<Scrollbar>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Cloned native scrollbar is missing Scrollbar.");
			}
			component.onValueChanged = new ScrollEvent();
			component.SetDirection((Direction)0, true);
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 0f);
			component2.pivot = new Vector2(0.5f, 0f);
			component2.sizeDelta = new Vector2(-40f, 14f);
			component2.anchoredPosition = new Vector2(0f, 3f);
			return component;
		}

		private static Button CloneButton(Button source, Transform parent, string name)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, parent);
			((Object)val).name = name;
			CopyRectTransform(((Component)source).GetComponent<RectTransform>(), val.GetComponent<RectTransform>());
			val.SetActive(false);
			Button component = val.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Cloned native settings button is missing Button.");
			}
			return component;
		}

		private static Transform FindRow(Slider slider)
		{
			Transform val = ((Component)slider).transform;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val.Find("ValueBackground") != (Object)null)
				{
					return val;
				}
				val = val.parent;
			}
			throw new InvalidOperationException("Native slider row is missing ValueBackground.");
		}

		private static GameObject FindTemplate(Transform root, string path)
		{
			Transform obj = (((Object)(object)root == (Object)null) ? null : root.Find(path));
			if ((Object)(object)obj == (Object)null)
			{
				throw new InvalidOperationException("Native settings resource path is missing: " + path);
			}
			return ((Component)obj).gameObject;
		}

		private static GameObject FindGroupHeading(Transform row)
		{
			Transform parent = row.parent;
			if ((Object)(object)parent != (Object)null)
			{
				for (int i = 0; i < parent.childCount; i++)
				{
					Transform child = parent.GetChild(i);
					if ((Object)(object)child != (Object)(object)row && (Object)(object)((Component)child).GetComponent<TMP_Text>() != (Object)null)
					{
						return ((Component)child).gameObject;
					}
				}
			}
			throw new InvalidOperationException("Native settings group is missing its heading.");
		}

		private static List<GameObject> GetPrivateToggleGameObjects(UISettings settings, IEnumerable<string> names)
		{
			return names.Select(delegate(string name)
			{
				Toggle obj = GetPrivate<Toggle>(settings, name);
				return (obj == null) ? null : ((Component)obj).gameObject;
			}).ToList();
		}

		private static T GetPrivate<T>(UISettings settings, string name) where T : class
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(UISettings), name);
			if (!(fieldInfo == null))
			{
				return fieldInfo.GetValue(settings) as T;
			}
			return null;
		}

		private static string GetModName(ModConfig mod)
		{
			string text = mod.Registration?.GetName();
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return mod.Info.Metadata.Name;
		}
	}
	internal static class NativeUi
	{
		public static void DisableLocalization(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().Name.StartsWith("Localize", StringComparison.Ordinal))
				{
					((Behaviour)val).ena