Decompiled source of PinnedChallenges v1.0.1

Mods/PinnedChallenges.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(PinnedChallengesMod), "Pinned Challenges", "1.0.1", "Relsev", null)]
[assembly: MelonGame("BoltBlasterGames", "TheSpellBrigade")]
[assembly: MelonOptionalDependencies(new string[] { "ModMenu" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PinnedChallenges")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+1856b18f4bf94ea33a9b586b39e9ee6f647e5453")]
[assembly: AssemblyProduct("PinnedChallenges")]
[assembly: AssemblyTitle("PinnedChallenges")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SpellBrigade.Shared
{
	internal static class Hooks
	{
		public static bool Patch(Harmony harmony, Instance log, Type target, string method, Type patchClass, string prefix = null, string postfix = null)
		{
			return Patch(harmony, log, AccessTools.Method(target, method, (Type[])null, (Type[])null), patchClass, prefix, postfix, target.Name + "." + method);
		}

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

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

		private readonly Func<Instance> _log;

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

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

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

		private string[] _current;

		private string _code;

		private TMP_Text _fontSample;

		private bool _subscribed;

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

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

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

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

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

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

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

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

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

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

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

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

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

		private const string PanelName = "SpellBrigade_MatchmakingLock";

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

		private static bool _owner;

		private static bool _wasBlocked;

		private static Instance _log;

		private static MatchmakingPreferencesModal _modal;

		private static TMP_Text _title;

		private static TMP_Text _body;

		private static float _pulse;

		private static float _nextCheck;

		private const string Title = "title";

		private const string Intro = "intro";

		private const string Footer = "footer";

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

		private static bool _prepareRestore;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			public float BlockedSensitivity;

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

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

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

		private static readonly State Own = new State();

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

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

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

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

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

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

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

		private static void BlockScroll(State state, ScrollRect scroll)
		{
			if (!((Object)(object)state.Blocked != (Object)null) || !((Object)(object)scroll != (Object)null) || !(((Il2CppObjectBase)state.Blocked).Pointer == ((Il2CppObjectBase)scroll).Pointer))
			{
				if ((Object)(object)state.Blocked != (Object)null)
				{
					state.Blocked.scrollSensitivity = state.BlockedSensitivity;
				}
				state.Blocked = scroll;
				if (!((Object)(object)scroll == (Object)null))
				{
					state.BlockedSensitivity = scroll.scrollSensitivity;
					scroll.scrollSensitivity = 0f;
				}
			}
		}
	}
}
namespace PinnedChallenges
{
	internal static class ChallengeMenu
	{
		private sealed class Card
		{
			public ChallengeProgressPanel Panel;

			public Image Pin;

			public ChallengeId Id;
		}

		private const string PinName = "PinnedChallenges_Pin";

		private const string HitName = "PinnedChallenges_Hit";

		private const float PinSize = 34f;

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

		private static readonly Dictionary<IntPtr, Card> Cards = new Dictionary<IntPtr, Card>();

		private static bool _subscribed;

		public static void ShowPostfix(ChallengeProgressPanel __instance, ChallengeConfiguration configuration)
		{
			//IL_00ba: 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)
			try
			{
				if ((Object)(object)__instance == (Object)null || (Object)(object)configuration == (Object)null)
				{
					return;
				}
				Transform parent = ((Component)__instance).transform.parent;
				if (!(((parent != null) ? ((Object)parent).name : null) == "PinnedChallenges_Source"))
				{
					if (!_subscribed)
					{
						_subscribed = true;
						Pins.Changed += RefreshAll;
					}
					if (!Cards.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out var value) || (Object)(object)value.Pin == (Object)null)
					{
						Dictionary<IntPtr, Card> cards = Cards;
						IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer;
						Card obj = new Card
						{
							Panel = __instance,
							Pin = CreatePin(__instance)
						};
						value = obj;
						cards[pointer] = obj;
					}
					value.Id = configuration.Id;
					Refresh(value);
				}
			}
			catch (Exception ex)
			{
				PinnedChallengesMod.Log.Warning("challenge card: " + ex.Message);
			}
		}

		private static Image CreatePin(ChallengeProgressPanel panel)
		{
			//IL_0066: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[2] { "PinnedChallenges_Pin", "PinnedChallenges_Hit" };
			foreach (string text in array)
			{
				Transform val = ((Component)panel).transform.Find(text);
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
				}
			}
			RectTransform obj = Ui.NewRect("PinnedChallenges_Hit", ((Component)panel).transform);
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			Vector2 offsetMin = (obj.offsetMax = Vector2.zero);
			obj.offsetMin = offsetMin;
			((Graphic)((Component)obj).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0f);
			Button obj2 = ((Component)obj).gameObject.AddComponent<Button>();
			((Selectable)obj2).transition = (Transition)0;
			Navigation navigation = ((Selectable)obj2).navigation;
			navigation.mode = (Mode)0;
			((Selectable)obj2).navigation = navigation;
			IntPtr key = ((Il2CppObjectBase)panel).Pointer;
			((UnityEvent)obj2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				//IL_0015: 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)
				try
				{
					if (Cards.TryGetValue(key, out var value) && !IsCompleted(value.Id))
					{
						Pins.Toggle(value.Id);
					}
				}
				catch (Exception ex)
				{
					PinnedChallengesMod.Log.Warning("pin: " + ex.Message);
				}
			}));
			Image obj3 = Ui.NewImage("PinnedChallenges_Pin", ((Component)panel).transform, Dim);
			obj3.sprite = Ui.Pin;
			obj3.preserveAspect = true;
			RectTransform rectTransform = ((Graphic)obj3).rectTransform;
			Vector2 val2 = (rectTransform.pivot = Vector2.one);
			offsetMin = (rectTransform.anchorMax = val2);
			rectTransform.anchorMin = offsetMin;
			rectTransform.sizeDelta = new Vector2(34f, 34f);
			rectTransform.anchoredPosition = new Vector2(-14f, -10f);
			return obj3;
		}

		private static void RefreshAll()
		{
			List<IntPtr> list = new List<IntPtr>();
			foreach (var (item, card2) in Cards)
			{
				if ((Object)(object)card2.Panel == (Object)null || (Object)(object)card2.Pin == (Object)null)
				{
					list.Add(item);
				}
				else
				{
					Refresh(card2);
				}
			}
			foreach (IntPtr item2 in list)
			{
				Cards.Remove(item2);
			}
		}

		private static void Refresh(Card card)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IsCompleted(card.Id);
			((Component)card.Pin).gameObject.SetActive(!flag);
			((Graphic)card.Pin).color = (Pins.IsPinned(card.Id) ? Ui.Gold : Dim);
		}

		internal static bool IsCompleted(ChallengeId id)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				LocalPlayer instance = SingletonPersistent<LocalPlayer>.Instance;
				bool? obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					ChallengeManager challengeManager = instance.GetChallengeManager();
					obj = ((challengeManager != null) ? new bool?(challengeManager.IsCompleted(id)) : ((bool?)null));
				}
				bool? flag = obj;
				return flag == true;
			}
			catch
			{
				return false;
			}
		}
	}
	internal static class LayoutEditor
	{
		private const string ModalKey = "SpellBrigade.Modal";

		private static readonly Color Dim = new Color(0f, 0f, 0f, 0.6f);

		private static readonly Color ButtonColor = new Color(0.1f, 0.08f, 0.16f, 0.95f);

		private static GameObject _overlay;

		private static RectTransform _canvas;

		private static RectTransform _block;

		private static Canvas _canvasComponent;

		private static Vector2 _fraction;

		private static Image _frame;

		private static Image _handle;

		private static TMP_Text _sizeLabel;

		private const float MinScale = 0.5f;

		private const float MaxScale = 2f;

		private const float HandleSize = 26f;

		private static readonly List<RunHud.Card> Cards = new List<RunHud.Card>();

		private static ChallengeManager _manager;

		private static GameObject _previousSelection;

		private static bool _dragging;

		private static bool _resizing;

		private static Vector2 _grab;

		private static float _nextUpdate;

		public static void Open()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_overlay != (Object)null)
			{
				return;
			}
			LocalPlayer instance = SingletonPersistent<LocalPlayer>.Instance;
			_manager = ((instance != null) ? instance.GetChallengeManager() : null);
			ChallengePanel val = RunHud.FindAnyTemplate();
			if (_manager == null || (Object)(object)val == (Object)null)
			{
				PinnedChallengesMod.Log.Warning("can't open the position editor yet: challenges aren't loaded");
				return;
			}
			_overlay = new GameObject("PinnedChallenges_Layout");
			Object.DontDestroyOnLoad((Object)(object)_overlay);
			Canvas obj = _overlay.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 32000;
			CanvasScaler obj2 = _overlay.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 0.5f;
			_overlay.AddComponent<GraphicRaycaster>();
			_canvas = _overlay.GetComponent<RectTransform>();
			_canvasComponent = obj;
			_fraction = RunHud.SavedPosition;
			Image obj3 = Ui.NewImage("Dim", (Transform)(object)_canvas, Dim);
			((Graphic)obj3).raycastTarget = true;
			Stretch(((Graphic)obj3).rectTransform);
			_block = RunHud.BuildBlock((Transform)(object)_canvas, val, _manager, PreviewIds(), Cards);
			_frame = Ui.NewImage("Frame", (Transform)(object)_block, new Color(Ui.Gold.r, Ui.Gold.g, Ui.Gold.b, 0.18f));
			RectTransform rectTransform = ((Graphic)_frame).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.offsetMin = new Vector2(-12f, -12f);
			rectTransform.offsetMax = new Vector2(12f, 12f);
			((Transform)rectTransform).SetAsFirstSibling();
			_handle = Ui.NewImage("Resize", (Transform)(object)_block, Ui.Gold);
			RectTransform rectTransform2 = ((Graphic)_handle).rectTransform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(1f, 0f);
			rectTransform2.anchorMax = val2;
			rectTransform2.anchorMin = val2;
			rectTransform2.pivot = new Vector2(0.5f, 0.5f);
			rectTransform2.sizeDelta = new Vector2(26f, 26f);
			rectTransform2.anchoredPosition = new Vector2(6f, -6f);
			TMP_Text val3 = ((Cards.Count > 0) ? Cards[0].Description : null);
			if ((Object)(object)val3 != (Object)null)
			{
				PlaceTop(Text(val3, "Hint", "drag", 34f, Color.white, (FontStyles)1).rectTransform, -70f, 60f);
				PlaceTop(Text(val3, "Size", "size_hint", 22f, new Color(1f, 1f, 1f, 0.6f), (FontStyles)0).rectTransform, -125f, 36f);
				PlaceTop(Text(val3, "Keys", "keys", 22f, new Color(1f, 1f, 1f, 0.6f), (FontStyles)0).rectTransform, -160f, 36f);
				_sizeLabel = Ui.CloneText(val3, (Transform)(object)_canvas, "Scale");
				_sizeLabel.fontSize = 20f;
				_sizeLabel.fontStyle = (FontStyles)1;
				((Graphic)_sizeLabel).color = Ui.Gold;
				_sizeLabel.alignment = (TextAlignmentOptions)1025;
				AddButton(val3, "default", -160f, ResetPosition);
				AddButton(val3, "done", 160f, Close);
			}
			_previousSelection = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
			EventSystem current = EventSystem.current;
			if (current != null)
			{
				current.SetSelectedGameObject((GameObject)null);
			}
			AppDomain.CurrentDomain.SetData("SpellBrigade.Modal", true);
			_dragging = (_resizing = false);
		}

		public static void Restyle()
		{
			if (!((Object)(object)_overlay == (Object)null))
			{
				RunHud.Restyle(Cards);
				SetScale(PinnedChallengesMod.HudScaleEntry.Value);
			}
		}

		public static void Tick()
		{
			//IL_002b: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_overlay == (Object)null)
			{
				return;
			}
			if ((Object)(object)_block == (Object)null)
			{
				Close();
				return;
			}
			RunHud.Place(_block, _canvasComponent, _fraction);
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				if (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame || ((ButtonControl)current.escapeKey).wasPressedThisFrame)
				{
					Close();
					return;
				}
				if (((ButtonControl)current.rKey).wasPressedThisFrame)
				{
					ResetPosition();
				}
			}
			Mouse current2 = Mouse.current;
			if (current2 != null)
			{
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current2).position).ReadValue();
				bool flag = RectTransformUtility.RectangleContainsScreenPoint(((Graphic)_handle).rectTransform, val, (Camera)null);
				bool flag2 = flag || RectTransformUtility.RectangleContainsScreenPoint(_block, val, (Camera)null);
				if (current2.rightButton.wasPressedThisFrame)
				{
					Close();
					return;
				}
				if (current2.leftButton.wasPressedThisFrame)
				{
					if (flag)
					{
						_resizing = true;
					}
					else if (flag2)
					{
						_dragging = true;
						_grab = RunHud.TopLeft(_block, _fraction) - val;
					}
				}
				if (!current2.leftButton.isPressed)
				{
					_dragging = (_resizing = false);
				}
				if (_dragging)
				{
					MoveTo(val + _grab);
				}
				if (_resizing)
				{
					ResizeTo(val);
				}
				float y = ((InputControl<Vector2>)(object)current2.scroll).ReadValue().y;
				if (flag2 && Mathf.Abs(y) > 0.01f)
				{
					SetScale(PinnedChallengesMod.HudScaleEntry.Value + ((y > 0f) ? 0.05f : (-0.05f)));
				}
				bool flag3 = _dragging || _resizing;
				((Graphic)_frame).color = new Color(Ui.Gold.r, Ui.Gold.g, Ui.Gold.b, flag3 ? 0.45f : (flag2 ? 0.3f : 0.18f));
				((Graphic)_handle).color = new Color(Ui.Gold.r, Ui.Gold.g, Ui.Gold.b, (_resizing || flag) ? 1f : 0.7f);
			}
			if ((Object)(object)_sizeLabel != (Object)null)
			{
				Il2CppStructArray<Vector3> val2 = new Il2CppStructArray<Vector3>(4L);
				_block.GetWorldCorners(val2);
				((Transform)_sizeLabel.rectTransform).position = ((Il2CppArrayBase<Vector3>)(object)val2)[1] + new Vector3(0f, 8f, 0f);
				_sizeLabel.rectTransform.sizeDelta = new Vector2(200f, 30f);
				_sizeLabel.rectTransform.pivot = Vector2.zero;
				_sizeLabel.text = $"{PinnedChallengesMod.HudScaleEntry.Value * 100f:0}%";
			}
			if (!(Time.unscaledTime >= _nextUpdate))
			{
				return;
			}
			_nextUpdate = Time.unscaledTime + 0.25f;
			foreach (RunHud.Card card in Cards)
			{
				RunHud.Update(card, _manager);
			}
		}

		private static void MoveTo(Vector2 screenPoint)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0033: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			_fraction = new Vector2(screenPoint.x / (float)Screen.width, screenPoint.y / (float)Screen.height);
			Vector2 val = RunHud.TopLeft(_block, _fraction);
			_fraction = new Vector2(val.x / (float)Screen.width, val.y / (float)Screen.height);
			RunHud.Place(_block, _canvasComponent, _fraction);
		}

		private static void ResizeTo(Vector2 pointer)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			SetScale((pointer.x - RunHud.TopLeft(_block, _fraction).x) / (400f * (float)Screen.height / 1080f));
		}

		private static void SetScale(float scale)
		{
			//IL_0040: 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)
			scale = Mathf.Clamp(Mathf.Round(scale * 100f) / 100f, 0.5f, 2f);
			PinnedChallengesMod.HudScaleEntry.Value = scale;
			if ((Object)(object)_block != (Object)null)
			{
				MoveTo(RunHud.TopLeft(_block, _fraction));
			}
		}

		private static void ResetPosition()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			_fraction = new Vector2(0.7354167f, 71f / 72f);
			SetScale(PinnedChallengesMod.HudScaleEntry.DefaultValue);
		}

		private static void Close()
		{
			if ((Object)(object)_overlay == (Object)null)
			{
				return;
			}
			PinnedChallengesMod.HudXEntry.Value = Mathf.Clamp01(_fraction.x);
			PinnedChallengesMod.HudYEntry.Value = Mathf.Clamp01(_fraction.y);
			PinnedChallengesMod.Save();
			Object.Destroy((Object)(object)_overlay);
			_overlay = null;
			Cards.Clear();
			AppDomain.CurrentDomain.SetData("SpellBrigade.Modal", false);
			if ((Object)(object)_previousSelection != (Object)null)
			{
				EventSystem current = EventSystem.current;
				if (current != null)
				{
					current.SetSelectedGameObject(_previousSelection);
				}
			}
			RunHud.Rescale();
			MenuPage.Refresh();
			PinnedChallengesMod.Log.Msg($"cards position: {PinnedChallengesMod.HudXEntry.Value:0.###}, {PinnedChallengesMod.HudYEntry.Value:0.###}");
		}

		private static List<ChallengeId> PreviewIds()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			List<ChallengeId> list = new List<ChallengeId>(Pins.All);
			if (list.Count > 0)
			{
				return list;
			}
			Dictionary<ChallengeId, ChallengeConfiguration> configurationForChallenges = _manager.ConfigurationForChallenges;
			foreach (ChallengeId value in Enum.GetValues(typeof(ChallengeId)))
			{
				if (configurationForChallenges != null && configurationForChallenges.ContainsKey(value))
				{
					ChallengeConfiguration val2 = configurationForChallenges[value];
					if (!((Object)(object)val2 == (Object)null) && !val2.Disabled && !val2.IsComingSoon && !_manager.IsCompleted(value))
					{
						list.Add(value);
						break;
					}
				}
			}
			return list;
		}

		private static TMP_Text Text(TMP_Text font, string name, string key, float fontSize, Color color, FontStyles style)
		{
			//IL_0014: 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)
			TMP_Text obj = Ui.CloneText(font, (Transform)(object)_canvas, name);
			obj.fontSize = fontSize;
			((Graphic)obj).color = color;
			obj.fontStyle = style;
			obj.alignment = (TextAlignmentOptions)514;
			Strings.Bind(obj, key);
			return obj;
		}

		private static void PlaceTop(RectTransform rect, float y, float height)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 1f);
			rect.pivot = val;
			Vector2 anchorMin = (rect.anchorMax = val);
			rect.anchorMin = anchorMin;
			rect.anchoredPosition = new Vector2(0f, y);
			rect.sizeDelta = new Vector2(1600f, height);
		}

		private static void AddButton(TMP_Text font, string key, float x, Action onClick)
		{
			//IL_002d: 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_0036: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.NewRect(key, (Transform)(object)_canvas);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0f);
			val.pivot = val2;
			Vector2 anchorMin = (val.anchorMax = val2);
			val.anchorMin = anchorMin;
			val.anchoredPosition = new Vector2(x, 70f);
			val.sizeDelta = new Vector2(280f, 72f);
			Image val4 = ((Component)val).gameObject.AddComponent<Image>();
			((Graphic)val4).color = ButtonColor;
			Button obj = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val4;
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.85f, 0.45f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.65f, 0.3f);
			((Selectable)obj).colors = colors;
			Navigation navigation = ((Selectable)obj).navigation;
			navigation.mode = (Mode)0;
			((Selectable)obj).navigation = navigation;
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				try
				{
					onClick();
				}
				catch (Exception ex)
				{
					PinnedChallengesMod.Log.Warning("position editor: " + ex.Message);
				}
			}));
			TMP_Text obj2 = Ui.CloneText(font, (Transform)(object)val, "Label");
			obj2.fontSize = 26f;
			obj2.fontStyle = (FontStyles)1;
			((Graphic)obj2).color = Color.white;
			obj2.alignment = (TextAlignmentOptions)514;
			Stretch(obj2.rectTransform);
			Strings.Bind(obj2, key);
		}

		private static void Stretch(RectTransform rect)
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			Vector2 offsetMin = (rect.offsetMax = Vector2.zero);
			rect.offsetMin = offsetMin;
		}
	}
	internal static class MenuPage
	{
		private static bool _registered;

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void Register()
		{
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			_registered = true;
			Menu.AddPage("PinnedChallenges", "Pinned Challenges").Number((Func<string>)(() => Strings.Get("hud_scale")), 0.5f, 2f, 0.05f, (Func<float>)(() => PinnedChallengesMod.HudScaleEntry.Value), (Action<float>)delegate(float v)
			{
				Set(PinnedChallengesMod.HudScaleEntry, v);
			}, (Func<float, string>)Percent, (float?)PinnedChallengesMod.HudScaleEntry.DefaultValue).Toggle((Func<string>)(() => Strings.Get("game_style")), (Func<bool>)(() => PinnedChallengesMod.GameStyleEntry.Value), (Action<bool>)delegate(bool v)
			{
				PinnedChallengesMod.GameStyleEntry.Value = v;
				PinnedChallengesMod.Save();
				RunHud.Rescale();
				LayoutEditor.Restyle();
			}, (bool?)PinnedChallengesMod.GameStyleEntry.DefaultValue)
				.Number((Func<string>)(() => Strings.Get("opacity")), 0f, 1f, 0.05f, (Func<float>)(() => PinnedChallengesMod.OpacityEntry.Value), (Action<float>)delegate(float v)
				{
					Set(PinnedChallengesMod.OpacityEntry, v);
				}, (Func<float, string>)Percent, (float?)PinnedChallengesMod.OpacityEntry.DefaultValue)
				.Number((Func<string>)(() => Strings.Get("text_opacity")), 0.1f, 1f, 0.05f, (Func<float>)(() => PinnedChallengesMod.TextOpacityEntry.Value), (Action<float>)delegate(float v)
				{
					Set(PinnedChallengesMod.TextOpacityEntry, v);
				}, (Func<float, string>)Percent, (float?)PinnedChallengesMod.TextOpacityEntry.DefaultValue)
				.Number((Func<string>)(() => Strings.Get("max_pinned")), 1f, 5f, 1f, (Func<float>)(() => PinnedChallengesMod.MaxPinsEntry.Value), (Action<float>)delegate(float v)
				{
					PinnedChallengesMod.MaxPinsEntry.Value = (int)v;
					PinnedChallengesMod.Save();
					Pins.Trim();
				}, (Func<float, string>)((float v) => v.ToString("0")), (float?)PinnedChallengesMod.MaxPinsEntry.DefaultValue)
				.Buttons((MenuButton[])(object)new MenuButton[2]
				{
					new MenuButton((Func<string>)(() => Strings.Get("position")), (Action)LayoutEditor.Open),
					new MenuButton((Func<string>)(() => Strings.Get("unpin_all")), (Action)Pins.Clear)
				});
		}

		public static void Refresh()
		{
			if (_registered)
			{
				RefreshMenu();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void RefreshMenu()
		{
			Menu.Refresh();
		}

		private static string Percent(float v)
		{
			return $"{v * 100f:0}%";
		}

		private static void Set(MelonPreferences_Entry<float> entry, float value)
		{
			if (entry.Value != value)
			{
				entry.Value = value;
				PinnedChallengesMod.Save();
				RunHud.Rescale();
				LayoutEditor.Restyle();
			}
		}
	}
	public class PinnedChallengesMod : MelonMod
	{
		public static Instance Log;

		private static MelonPreferences_Category _category;

		internal static MelonPreferences_Entry<string> PinnedEntry;

		internal static MelonPreferences_Entry<float> HudScaleEntry;

		internal static MelonPreferences_Entry<float> HudXEntry;

		internal static MelonPreferences_Entry<float> HudYEntry;

		internal static MelonPreferences_Entry<float> OpacityEntry;

		internal static MelonPreferences_Entry<float> TextOpacityEntry;

		internal static MelonPreferences_Entry<int> MaxPinsEntry;

		internal static MelonPreferences_Entry<bool> GameStyleEntry;

		internal const float DefaultX = 0.7354167f;

		internal const float DefaultY = 71f / 72f;

		public override void OnInitializeMelon()
		{
			Log = ((MelonBase)this).LoggerInstance;
			_category = MelonPreferences.CreateCategory("PinnedChallenges", "Pinned Challenges");
			PinnedEntry = _category.CreateEntry<string>("Pinned", "", "Pinned", "Закреплённые испытания через запятую (ChallengeId). Удобнее закреплять кликом в меню испытаний", false, false, (ValueValidator)null, (string)null);
			HudScaleEntry = _category.CreateEntry<float>("HudScale", 1f, "HUD Scale", "Размер строк с испытаниями в забеге", false, false, (ValueValidator)(object)new ValueRange<float>(0.3f, 2f), (string)null);
			OpacityEntry = _category.CreateEntry<float>("Opacity", 0.6f, "Card Background", "Непрозрачность фона карточек (0 — без фона, 1 — сплошной)", false, false, (ValueValidator)(object)new ValueRange<float>(0f, 1f), (string)null);
			TextOpacityEntry = _category.CreateEntry<float>("TextOpacity", 1f, "Text and Icons", "Непрозрачность текста, значков и полоски прогресса", false, false, (ValueValidator)(object)new ValueRange<float>(0.1f, 1f), (string)null);
			GameStyleEntry = _category.CreateEntry<bool>("GameStyle", true, "Game-style Background", "Фон карточек как у уведомлений игры (false — простая тёмная плашка)", false, false, (ValueValidator)null, (string)null);
			MaxPinsEntry = _category.CreateEntry<int>("MaxPinned", 3, "Max Pinned", "Сколько испытаний можно закрепить (1–5)", false, false, (ValueValidator)(object)new ValueRange<int>(1, 5), (string)null);
			HudXEntry = _category.CreateEntry<float>("HudX", 0.7354167f, "HUD X", "Левый край карточек, доля ширины экрана (0 — слева, 1 — справа)", false, false, (ValueValidator)(object)new ValueRange<float>(0f, 1f), (string)null);
			HudYEntry = _category.CreateEntry<float>("HudY", 71f / 72f, "HUD Y", "Верх карточек, доля высоты экрана (0 — снизу, 1 — сверху)", false, false, (ValueValidator)(object)new ValueRange<float>(0f, 1f), (string)null);
			_category.SaveToFile(false);
			Pins.Load();
			bool flag = Hooks.Patch(((MelonBase)this).HarmonyInstance, Log, typeof(ChallengeProgressPanel), "Show", typeof(ChallengeMenu), null, "ShowPostfix");
			bool flag2 = Hooks.Patch(((MelonBase)this).HarmonyInstance, Log, typeof(GameplayChallengeTrackerController), "Start", typeof(RunHud), null, "RunStarted");
			bool flag3 = Hooks.Patch(((MelonBase)this).HarmonyInstance, Log, typeof(GameplayChallengeTrackerController), "OnDestroy", typeof(RunHud), "RunEnded");
			if (flag && flag2 && flag3)
			{
				Log.Msg($"ready — {Pins.All.Count} pinned. Click a challenge card to pin it");
			}
			else
			{
				Log.Warning("partially loaded: pinning " + (flag ? "ok" : "unavailable") + ", in-run cards " + ((flag2 && flag3) ? "ok" : "unavailable"));
			}
			if (MelonBase.FindMelon("Mod Menu", "Relsev") != null)
			{
				try
				{
					MenuPage.Register();
				}
				catch (Exception ex)
				{
					Log.Warning("Mod Menu page: " + ex.Message);
				}
			}
		}

		internal static void Save()
		{
			_category.SaveToFile(false);
		}

		public override void OnUpdate()
		{
			WheelSelect.Tick();
			try
			{
				RunHud.Tick();
			}
			catch (Exception value)
			{
				Log.Error($"in-run cards: {value}");
				RunHud.RunEnded();
			}
			try
			{
				LayoutEditor.Tick();
			}
			catch (Exception value2)
			{
				Log.Error($"position editor: {value2}");
			}
		}
	}
	internal static class Pins
	{
		private static readonly List<ChallengeId> Ids = new List<ChallengeId>();

		public static int Max => Math.Clamp(PinnedChallengesMod.MaxPinsEntry?.Value ?? 3, 1, 5);

		public static IReadOnlyList<ChallengeId> All => Ids;

		public static event Action Changed;

		public static bool IsPinned(ChallengeId id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Ids.Contains(id);
		}

		public static void Toggle(ChallengeId id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!Ids.Remove(id))
			{
				Ids.Add(id);
				while (Ids.Count > Max)
				{
					Ids.RemoveAt(0);
				}
			}
			Save();
			PinnedChallengesMod.Log.Msg("pinned: " + ((Ids.Count > 0) ? string.Join(", ", Ids) : "none"));
		}

		public static void Trim()
		{
			if (Ids.Count > Max)
			{
				while (Ids.Count > Max)
				{
					Ids.RemoveAt(0);
				}
				Save();
			}
		}

		public static void Clear()
		{
			if (Ids.Count != 0)
			{
				Ids.Clear();
				Save();
			}
		}

		public static void Remove(ChallengeId id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Ids.Remove(id))
			{
				Save();
			}
		}

		public static void Load()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Ids.Clear();
			string[] array = (PinnedChallengesMod.PinnedEntry.Value ?? "").Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
			foreach (string text in array)
			{
				if (Enum.TryParse<ChallengeId>(text, out ChallengeId result) && !Ids.Contains(result) && Ids.Count < Max)
				{
					Ids.Add(result);
				}
				else
				{
					PinnedChallengesMod.Log.Warning("ignored pinned challenge '" + text + "'");
				}
			}
		}

		private static void Save()
		{
			PinnedChallengesMod.PinnedEntry.Value = string.Join(",", Ids);
			PinnedChallengesMod.Save();
			try
			{
				Pins.Changed?.Invoke();
			}
			catch (Exception ex)
			{
				PinnedChallengesMod.Log.Warning("pins changed: " + ex.Message);
			}
		}
	}
	internal static class RunHud
	{
		internal sealed class Card
		{
			public ChallengeId Id;

			public ChallengeConfiguration Config;

			public TMP_Text Source;

			public TMP_Text Description;

			public TMP_Text Progress;

			public GameObject Bar;

			public RectTransform Fill;

			public Image Background;

			public Image Icon;

			public Image BarBack;

			public Image FillImage;

			public Image GameBackground;

			public bool Done;
		}

		public const string RootName = "PinnedChallenges_Hud";

		public const string HiddenName = "PinnedChallenges_Source";

		public const float Width = 400f;

		public const float RowHeight = 64f;

		public const float Spacing = 8f;

		private const float Pad = 8f;

		private const float IconSize = 46f;

		private static readonly Color Plain = new Color(0.05f, 0.04f, 0.09f);

		private static readonly List<Card> Cards = new List<Card>();

		private static RectTransform _root;

		private static Canvas _canvas;

		private static CanvasGroup _group;

		private static bool _inRun;

		private static bool _built;

		private static bool _warned;

		private static bool _subscribed;

		private static float _nextTick;

		private static float BackgroundAlpha => PinnedChallengesMod.OpacityEntry?.Value ?? 0.6f;

		private static float TextAlpha => PinnedChallengesMod.TextOpacityEntry?.Value ?? 1f;

		private static bool GameStyle => PinnedChallengesMod.GameStyleEntry?.Value ?? true;

		public static Vector2 SavedPosition => new Vector2(PinnedChallengesMod.HudXEntry.Value, PinnedChallengesMod.HudYEntry.Value);

		public static float PixelsPerUnit => PinnedChallengesMod.HudScaleEntry.Value * (float)Screen.height / 1080f;

		public static void RunStarted()
		{
			if (!_subscribed)
			{
				_subscribed = true;
				Pins.Changed += Rebuild;
			}
			_inRun = true;
			_built = (_warned = false);
			_nextTick = 0f;
		}

		public static void RunEnded()
		{
			_inRun = (_built = false);
			Cards.Clear();
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_root).gameObject);
			}
			_root = null;
			_group = null;
		}

		private static void Rebuild()
		{
			if (_inRun)
			{
				RunEnded();
				RunStarted();
			}
		}

		public static void Rescale()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_root == (Object)null) && !((Object)(object)_canvas == (Object)null))
			{
				Place(_root, _canvas, SavedPosition);
				Restyle(Cards);
			}
		}

		public static void Restyle(List<Card> cards)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			foreach (Card card in cards)
			{
				if (!((Object)(object)card.Background == (Object)null))
				{
					Image val = (GameStyle ? card.GameBackground : null);
					if ((Object)(object)val != (Object)null && (Object)(object)val.sprite != (Object)null)
					{
						card.Background.sprite = val.sprite;
						card.Background.type = val.type;
						card.Background.pixelsPerUnitMultiplier = val.pixelsPerUnitMultiplier;
						Color color = ((Graphic)val).color;
						((Graphic)card.Background).color = new Color(color.r, color.g, color.b, BackgroundAlpha);
					}
					else
					{
						card.Background.sprite = null;
						card.Background.type = (Type)0;
						((Graphic)card.Background).color = new Color(Plain.r, Plain.g, Plain.b, BackgroundAlpha);
					}
					Recolor(card);
				}
			}
		}

		private static void Recolor(Card card)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			float textAlpha = TextAlpha;
			if ((Object)(object)card.Description != (Object)null)
			{
				((Graphic)card.Description).color = WithAlpha(card.Done ? Ui.Gold : Color.white, textAlpha);
			}
			if ((Object)(object)card.Progress != (Object)null)
			{
				((Graphic)card.Progress).color = WithAlpha(Ui.Gold, textAlpha);
			}
			if ((Object)(object)card.Icon != (Object)null)
			{
				((Graphic)card.Icon).color = WithAlpha(Color.white, textAlpha);
			}
			if ((Object)(object)card.BarBack != (Object)null)
			{
				((Graphic)card.BarBack).color = new Color(1f, 1f, 1f, 0.15f * textAlpha);
			}
			if ((Object)(object)card.FillImage != (Object)null)
			{
				((Graphic)card.FillImage).color = WithAlpha(Ui.Gold, textAlpha);
			}
		}

		private static Color WithAlpha(Color c, float a)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return new Color(c.r, c.g, c.b, a);
		}

		public static void Tick()
		{
			HideUnderStore();
			if (!_inRun || Time.unscaledTime < _nextTick)
			{
				return;
			}
			_nextTick = Time.unscaledTime + 0.5f;
			LocalPlayer instance = SingletonPersistent<LocalPlayer>.Instance;
			ChallengeManager val = ((instance != null) ? instance.GetChallengeManager() : null);
			if (val == null)
			{
				return;
			}
			if (!_built)
			{
				_built = TryBuild(val);
				return;
			}
			if ((Object)(object)_root == (Object)null)
			{
				RunEnded();
				return;
			}
			foreach (Card card in Cards)
			{
				Update(card, val);
			}
		}

		private static bool TryBuild(ChallengeManager manager)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			foreach (ChallengeId item in new List<ChallengeId>(Pins.All))
			{
				if (manager.IsCompleted(item))
				{
					Pins.Remove(item);
				}
			}
			if (Pins.All.Count == 0)
			{
				return true;
			}
			ChallengePanel val = FindTemplate();
			Canvas val2 = (((Object)(object)val != (Object)null) ? RootCanvas(((Component)val).transform) : null);
			if ((Object)(object)val2 == (Object)null)
			{
				if (!_warned)
				{
					PinnedChallengesMod.Log.Warning("challenge card template not found yet, retrying");
				}
				_warned = true;
				return false;
			}
			_canvas = val2;
			_root = BuildBlock(((Component)val2).transform, val, manager, Pins.All, Cards);
			((Transform)_root).SetAsFirstSibling();
			_group = ((Component)_root).gameObject.AddComponent<CanvasGroup>();
			CanvasGroup obj = _group;
			bool blocksRaycasts = (_group.interactable = false);
			obj.blocksRaycasts = blocksRaycasts;
			Place(_root, val2, SavedPosition);
			PinnedChallengesMod.Log.Msg($"showing {Cards.Count} pinned challenge(s)");
			return true;
		}

		private static void HideUnderStore()
		{
			if ((Object)(object)_group == (Object)null)
			{
				return;
			}
			float num = 0f;
			try
			{
				StorePanel instance = Singleton<StorePanel>.Instance;
				if ((Object)(object)instance != (Object)null && instance.isOpen)
				{
					num = (((Object)(object)instance.group != (Object)null) ? instance.group.alpha : 1f);
				}
			}
			catch
			{
			}
			_group.alpha = 1f - Mathf.Clamp01(num);
		}

		public static void Place(RectTransform block, Canvas canvas, Vector2 fraction)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			float num = ((canvas.scaleFactor > 0f) ? canvas.scaleFactor : 1f);
			((Transform)block).localScale = Vector3.one * (PixelsPerUnit / num);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			block.anchorMax = val;
			block.anchorMin = val;
			block.pivot = new Vector2(0f, 1f);
			Camera val2 = (((int)canvas.renderMode == 0) ? null : canvas.worldCamera);
			Vector2 val3 = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(((Component)canvas).GetComponent<RectTransform>(), TopLeft(block, fraction), val2, ref val3))
			{
				((Transform)block).localPosition = new Vector3(val3.x, val3.y, 0f);
			}
		}

		public static Vector2 TopLeft(RectTransform block, Vector2 fraction)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = block.sizeDelta * PixelsPerUnit;
			float num = Mathf.Clamp(fraction.x * (float)Screen.width, 0f, Mathf.Max(0f, (float)Screen.width - val.x));
			float num2 = Mathf.Clamp(fraction.y * (float)Screen.height, Mathf.Min((float)Screen.height, val.y), (float)Screen.height);
			return new Vector2(num, num2);
		}

		public static RectTransform BuildBlock(Transform parent, ChallengePanel template, ChallengeManager manager, IEnumerable<ChallengeId> ids, List<Card> cards)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_002d: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.NewRect("PinnedChallenges_Hud", parent);
			Vector2 anchorMin = (val.anchorMax = Vector2.zero);
			val.anchorMin = anchorMin;
			val.pivot = new Vector2(0f, 1f);
			RectTransform val2 = Ui.NewRect("PinnedChallenges_Source", (Transform)(object)val);
			((Component)val2).gameObject.AddComponent<CanvasGroup>().alpha = 0f;
			Dictionary<ChallengeId, ChallengeConfiguration> configurationForChallenges = manager.ConfigurationForChallenges;
			float num = 0f;
			foreach (ChallengeId id in ids)
			{
				if (configurationForChallenges != null && configurationForChallenges.ContainsKey(id))
				{
					Card card = CreateCard(template, val, val2, configurationForChallenges[id], num);
					cards.Add(card);
					Update(card, manager);
					num += 72f;
				}
			}
			val.sizeDelta = new Vector2(400f, Mathf.Max(64f, num - 8f));
			return val;
		}

		public static ChallengePanel FindTemplate()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			ChallengeNotification instance = Singleton<ChallengeNotification>.Instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.challengeUI != (Object)null)
			{
				return instance.challengeUI;
			}
			foreach (ChallengeNotification item in Resources.FindObjectsOfTypeAll<ChallengeNotification>())
			{
				if ((Object)(object)item != (Object)null)
				{
					Scene scene = ((Component)item).gameObject.scene;
					if (((Scene)(ref scene)).name != null && (Object)(object)item.challengeUI != (Object)null)
					{
						return item.challengeUI;
					}
				}
			}
			return null;
		}

		public static ChallengePanel FindAnyTemplate()
		{
			ChallengePanel val = FindTemplate();
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			foreach (ChallengePanel item in Resources.FindObjectsOfTypeAll<ChallengePanel>())
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item.descriptionLocalizer != (Object)null)
				{
					return item;
				}
			}
			return null;
		}

		private static Canvas RootCanvas(Transform t)
		{
			Canvas result = null;
			while ((Object)(object)t != (Object)null)
			{
				Canvas component = ((Component)t).GetComponent<Canvas>();
				if ((Object)(object)component != (Object)null)
				{
					result = component;
				}
				t = t.parent;
			}
			return result;
		}

		private static Card CreateCard(ChallengePanel template, RectTransform root, RectTransform hidden, ChallengeConfiguration config, float y)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: 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_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, (Transform)(object)hidden);
			val.SetActive(true);
			foreach (Animator componentsInChild in val.GetComponentsInChildren<Animator>(true))
			{
				((Behaviour)componentsInChild).enabled = false;
			}
			ChallengePanel component = val.GetComponent<ChallengePanel>();
			component.Show(config);
			Image gameBackground = LargestImage(val, component.iconImage);
			TMP_Text val2 = (((Object)(object)component.descriptionLocalizer != (Object)null) ? ((Component)component.descriptionLocalizer).GetComponent<TMP_Text>() : null);
			if (val2 == null)
			{
				val2 = val.GetComponentInChildren<TMP_Text>(true);
			}
			RectTransform val3 = Ui.NewRect($"Challenge_{config.Id}", (Transform)(object)root);
			Ui.Place(val3, 0f, y, 400f, 64f);
			Image val4 = ((Component)val3).gameObject.AddComponent<Image>();
			((Graphic)val4).raycastTarget = false;
			Image val5 = Ui.NewImage("Icon", (Transform)(object)val3, Color.white);
			val5.sprite = config.Icon;
			val5.preserveAspect = true;
			Ui.Place(((Graphic)val5).rectTransform, 8f, 9f, 46f, 46f);
			float num = 64f;
			float num2 = 400f - num - 8f;
			TMP_Text val6 = Ui.CloneText(val2, (Transform)(object)val3, "Description");
			val6.fontSize = 19f;
			((Graphic)val6).color = Color.white;
			val6.alignment = (TextAlignmentOptions)257;
			val6.textWrappingMode = (TextWrappingModes)1;
			val6.overflowMode = (TextOverflowModes)1;
			val6.maxVisibleLines = 2;
			Ui.Place(val6.rectTransform, num, 5f, num2, 42f);
			Image val7 = Ui.NewImage("Bar", (Transform)(object)val3, new Color(1f, 1f, 1f, 0.15f));
			Ui.Place(((Graphic)val7).rectTransform, num, 53f, num2 - 118f, 4f);
			RectTransform rectTransform = ((Graphic)Ui.NewImage("Fill", ((Component)val7).transform, Ui.Gold)).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = new Vector2(0f, 1f);
			Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero);
			rectTransform.offsetMin = offsetMin;
			TMP_Text val8 = Ui.CloneText(val2, (Transform)(object)val3, "Progress");
			val8.fontSize = 16f;
			val8.fontStyle = (FontStyles)1;
			((Graphic)val8).color = Ui.Gold;
			val8.alignment = (TextAlignmentOptions)516;
			Ui.Place(val8.rectTransform, 282f, 45f, 110f, 16f);
			Card card = new Card
			{
				Id = config.Id,
				Config = config,
				Source = val2,
				Description = val6,
				Progress = val8,
				Bar = ((Component)val7).gameObject,
				Fill = rectTransform,
				Background = val4,
				Icon = val5,
				BarBack = val7,
				FillImage = ((Component)rectTransform).GetComponent<Image>(),
				GameBackground = gameBackground
			};
			Restyle(new List<Card> { card });
			return card;
		}

		private static Image LargestImage(GameObject root, Image exclude)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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)
			Image result = null;
			float num = 0f;
			foreach (Image componentsInChild in root.GetComponentsInChildren<Image>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null) && !((Object)(object)componentsInChild.sprite == (Object)null) && (!((Object)(object)exclude != (Object)null) || (!(((Il2CppObjectBase)componentsInChild).Pointer == ((Il2CppObjectBase)exclude).Pointer) && !((Component)componentsInChild).transform.IsChildOf(((Component)exclude).transform))))
				{
					Rect rect = ((Graphic)componentsInChild).rectTransform.rect;
					Vector2 size = ((Rect)(ref rect)).size;
					float num2 = size.x * size.y;
					if (num2 > num)
					{
						num = num2;
						result = componentsInChild;
					}
				}
			}
			return result;
		}

		public static void Update(Card card, ChallengeManager manager)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)card.Description == (Object)null))
			{
				string text = (((Object)(object)card.Source != (Object)null) ? card.Source.text : "");
				if (card.Description.text != text)
				{
					card.Description.text = text;
				}
				bool flag = manager.IsCompleted(card.Id);
				bool flag2 = card.Config.IsBinaryChallenge();
				Dictionary<ChallengeId, ChallengeProgress> progressForChallenges = manager.ProgressForChallenges;
				int num = ((progressForChallenges != null && progressForChallenges.ContainsKey(card.Id)) ? progressForChallenges[card.Id].Value : 0);
				int num2 = Math.Max(1, card.Config.TargetValue);
				float num3 = (flag ? 1f : Mathf.Clamp01((float)num / (float)num2));
				card.Bar.SetActive(!flag2 || flag);
				card.Fill.anchorMax = new Vector2(num3, 1f);
				if (card.Done != flag)
				{
					card.Done = flag;
					Recolor(card);
				}
				string text2 = ((flag || flag2) ? "" : (Format(Math.Min(num, num2)) + " / " + Format(num2)));
				if (card.Progress.text != text2)
				{
					card.Progress.text = text2;
				}
			}
		}

		private static string Format(int n)
		{
			return n.ToString("N0", CultureInfo.InvariantCulture).Replace(',', ' ');
		}
	}
	internal static class Strings
	{
		public const string HudScale = "hud_scale";

		public const string UnpinAll = "unpin_all";

		public const string Position = "position";

		public const string DragHint = "drag";

		public const string KeysHint = "keys";

		public const string Done = "done";

		public const string Default = "default";

		public const string Opacity = "opacity";

		public const string MaxPinned = "max_pinned";

		public const string SizeHint = "size_hint";

		public const string TextOpacity = "text_opacity";

		public const string GameStyle = "game_style";

		private static readonly string[] Keys = new string[12]
		{
			"hud_scale", "unpin_all", "position", "drag", "keys", "done", "default", "opacity", "max_pinned", "size_hint",
			"text_opacity", "game_style"
		};

		private static readonly Dictionary<string, string[]> Table = new Dictionary<string, string[]>
		{
			["en"] = new string[12]
			{
				"Card size in runs", "Unpin all", "Card position", "Drag the cards with the mouse", "Enter or right click — done · R — default position", "Done", "Default", "Card background", "Max pinned", "Mouse wheel or the corner — size",
				"Text and icons", "Game-style background"
			},
			["ru"] = new string[12]
			{
				"Размер карточек в забеге", "Открепить всё", "Положение карточек", "Перетащите карточки мышью", "Enter или ПКМ — готово · R — на место по умолчанию", "Готово", "По умолчанию", "Фон карточек", "Сколько можно закрепить", "Колесо мыши или уголок — размер",
				"Текст и значки", "Фон в стиле игры"
			},
			["uk"] = new string[12]
			{
				"Розмір карток у забігу", "Відкріпити все", "Положення карток", "Перетягніть картки мишею", "Enter або ПКМ — готово · R — типове місце", "Готово", "Типово", "Фон карток", "Скільки можна закріпити", "Коліщатко миші або куточок — розмір",
				"Текст і значки", "Фон у стилі гри"
			},
			["de"] = new string[12]
			{
				"Kartengröße im Lauf", "Alle lösen", "Kartenposition", "Ziehe die Karten mit der Maus", "Enter oder Rechtsklick — fertig · R — Standardposition", "Fertig", "Standard", "Kartenhintergrund", "Maximal angeheftet", "Mausrad oder Ecke — Größe",
				"Text und Symbole", "Hintergrund im Spielstil"
			},
			["fr"] = new string[12]
			{
				"Taille des cartes en partie", "Tout désépingler", "Position des cartes", "Faites glisser les cartes avec la souris", "Entrée ou clic droit — terminé · R — position par défaut", "Terminé", "Par défaut", "Fond des cartes", "Épingles max.", "Molette ou coin — taille",
				"Texte et icônes", "Fond style jeu"
			},
			["it"] = new string[12]
			{
				"Dimensione schede in partita", "Rimuovi tutti", "Posizione schede", "Trascina le schede con il mouse", "Invio o clic destro — fatto · R — posizione predefinita", "Fatto", "Predefinita", "Sfondo schede", "Massimo fissati", "Rotellina o angolo — dimensione",
				"Testo e icone", "Sfondo in stile gioco"
			},
			["nl"] = new string[12]
			{
				"Kaartgrootte tijdens run", "Alles losmaken", "Kaartpositie", "Sleep de kaarten met de muis", "Enter of rechtsklik — klaar · R — standaardpositie", "Klaar", "Standaard", "Kaartachtergrond", "Max. vastgezet", "Muiswiel of hoek — grootte",
				"Tekst en pictogrammen", "Achtergrond in spelstijl"
			},
			["pl"] = new string[12]
			{
				"Rozmiar kart w wyprawie", "Odepnij wszystko", "Położenie kart", "Przeciągnij karty myszą", "Enter lub PPM — gotowe · R — domyślne położenie", "Gotowe", "Domyślne", "Tło kart", "Maks. przypiętych", "Kółko myszy lub róg — rozmiar",
				"Tekst i ikony", "Tło w stylu gry"
			},
			["pt-br"] = new string[12]
			{
				"Tamanho dos cartões na partida", "Desafixar tudo", "Posição dos cartões", "Arraste os cartões com o mouse", "Enter ou clique direito — pronto · R — posição padrão", "Pronto", "Padrão", "Fundo dos cartões", "Máximo fixados", "Roda do mouse ou canto — tamanho",
				"Texto e ícones", "Fundo no estilo do jogo"
			},
			["pt"] = new string[12]
			{
				"Tamanho dos cartões na partida", "Desafixar tudo", "Posição dos cartões", "Arraste os cartões com o rato", "Enter ou clique direito — concluído · R — posição predefinida", "Concluído", "Predefinição", "Fundo dos cartões", "Máximo afixados", "Roda do rato ou canto — tamanho",
				"Texto e ícones", "Fundo ao estilo do jogo"
			},
			["es"] = new string[12]
			{
				"Tamaño de tarjetas en partida", "Desfijar todo", "Posición de tarjetas", "Arrastra las tarjetas con el ratón", "Enter o clic derecho — listo · R — posición predeterminada", "Listo", "Predeterminado", "Fondo de tarjetas", "Máximo fijados", "Rueda del ratón o esquina — tamaño",
				"Texto e iconos", "Fondo al estilo del juego"
			},
			["es-mx"] = new string[12]
			{
				"Tamaño de tarjetas en partida", "Desfijar todo", "Posición de tarjetas", "Arrastra las tarjetas con el mouse", "Enter o clic derecho — listo · R — posición predeterminada", "Listo", "Predeterminado", "Fondo de tarjetas", "Máximo fijados", "Rueda del mouse o esquina — tamaño",
				"Texto e iconos", "Fondo al estilo del juego"
			},
			["ja"] = new string[12]
			{
				"ラン中のカードサイズ", "すべて追跡解除", "カードの位置", "マウスでカードをドラッグ", "Enter または右クリックで完了 · R で初期位置", "完了", "初期位置", "カードの背景", "追跡できる最大数", "ホイールまたは角 — サイズ",
				"テキストとアイコン", "ゲーム風の背景"
			},
			["ko"] = new string[12]
			{
				"런 중 카드 크기", "모두 추적 해제", "카드 위치", "마우스로 카드를 끌어 옮기세요", "Enter 또는 우클릭 — 완료 · R — 기본 위치", "완료", "기본값", "카드 배경", "최대 추적 수", "마우스 휠 또는 모서리 — 크기",
				"텍스트와 아이콘", "게임 스타일 배경"
			},