Decompiled source of MapMenuPlus v1.0.0

Mods\MapMenuPlus.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MapMenuPlus;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(MapMenuPlusMod), "MapMenuPlus", "1.0.0", "community", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace MapMenuPlus
{
	internal sealed class CursorArea
	{
		private const float RefindEvery = 3f;

		private GameObject _go;

		private readonly List<LaserCursor> _cursors = new List<LaserCursor>();

		private float _nextFind;

		private Vector3 _size;

		private bool _attached;

		private int _logs;

		internal void Show(float now, Transform frame, Vector2 centre, Vector2 size, float depth)
		{
			//IL_0039: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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)
			if ((Object)(object)frame == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_go == (Object)null)
				{
					_go = new GameObject("MMP_CursorArea");
				}
				Vector3 val = frame.TransformPoint(new Vector3(1f, 0f, 0f)) - frame.TransformPoint(Vector3.zero);
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (!(magnitude < 1E-07f))
				{
					Transform transform = _go.transform;
					transform.position = frame.TransformPoint(new Vector3(centre.x, centre.y, 0f));
					transform.rotation = frame.rotation;
					Vector3 val2 = default(Vector3);
					((Vector3)(ref val2))..ctor(size.x * magnitude, size.y * magnitude, depth * magnitude);
					val = val2 - _size;
					if (((Vector3)(ref val)).sqrMagnitude > 1E-06f || !_attached || now >= _nextFind)
					{
						_size = val2;
						_nextFind = now + 3f;
						Attach();
					}
				}
			}
			catch (Exception e)
			{
				if (_logs++ < 5)
				{
					Log.Error("Cursor area update failed", e);
				}
			}
		}

		internal void Hide()
		{
			if (!_attached)
			{
				return;
			}
			_attached = false;
			foreach (LaserCursor cursor in _cursors)
			{
				try
				{
					if ((Object)(object)cursor != (Object)null)
					{
						SetRegions(cursor, add: false);
					}
				}
				catch
				{
				}
			}
			_cursors.Clear();
		}

		internal void Reset()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Hide();
			try
			{
				if ((Object)(object)_go != (Object)null)
				{
					Object.Destroy((Object)(object)_go);
				}
			}
			catch
			{
			}
			_go = null;
			_size = Vector3.zero;
		}

		private void Attach()
		{
			_cursors.Clear();
			foreach (LaserCursor item in Object.FindObjectsOfType<LaserCursor>(true))
			{
				if ((Object)(object)item != (Object)null)
				{
					_cursors.Add(item);
				}
			}
			int num = 0;
			foreach (LaserCursor cursor in _cursors)
			{
				try
				{
					if (SetRegions(cursor, add: true))
					{
						num++;
					}
				}
				catch (Exception ex)
				{
					if (_logs++ < 5)
					{
						Log.Warn("Adding the cursor area failed: " + ex.Message);
					}
				}
			}
			if (!_attached && _logs++ < 5)
			{
				Log.Info("Laser cursor area added to " + num + " of " + _cursors.Count + " laser cursor(s) (" + (_size.x * 100f).ToString("0") + " x " + (_size.y * 100f).ToString("0") + " cm).");
			}
			_attached = true;
		}

		private bool SetRegions(LaserCursor lc, bool add)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			Il2CppReferenceArray<CursorRegion> regions = lc.regions;
			List<CursorRegion> list = new List<CursorRegion>();
			int num = 0;
			if (regions != null)
			{
				for (int i = 0; i < ((Il2CppArrayBase<CursorRegion>)(object)regions).Length; i++)
				{
					CursorRegion val = ((Il2CppArrayBase<CursorRegion>)(object)regions)[i];
					Transform val2 = null;
					try
					{
						val2 = val.center;
					}
					catch
					{
					}
					if ((Object)(object)val2 != (Object)null && (Object)(object)_go != (Object)null && ((Object)val2).GetInstanceID() == ((Object)_go.transform).GetInstanceID())
					{
						num++;
					}
					else
					{
						list.Add(val);
					}
				}
			}
			if (!add && num == 0)
			{
				return false;
			}
			if (add && (Object)(object)_go != (Object)null)
			{
				list.Add(new CursorRegion
				{
					bounds = new Bounds(Vector3.zero, _size),
					center = _go.transform
				});
			}
			lc.regions = Il2CppReferenceArray<CursorRegion>.op_Implicit(list.ToArray());
			return add;
		}
	}
	internal sealed class JNode
	{
		internal enum Kind
		{
			Null,
			Bool,
			Num,
			Str,
			Arr,
			Obj
		}

		internal Kind K;

		internal string S;

		internal double N;

		internal bool B;

		internal List<JNode> A;

		internal Dictionary<string, JNode> O;

		internal int Start;

		internal int End;

		internal static readonly JNode Missing = new JNode
		{
			K = Kind.Null
		};

		internal bool Exists
		{
			get
			{
				if (this != Missing)
				{
					return K != Kind.Null;
				}
				return false;
			}
		}

		internal bool IsObj => K == Kind.Obj;

		internal bool IsArr => K == Kind.Arr;

		internal JNode this[string key]
		{
			get
			{
				if (K != Kind.Obj || key == null || !O.TryGetValue(key, out var value))
				{
					return Missing;
				}
				return value;
			}
		}

		internal JNode this[int i]
		{
			get
			{
				if (K != Kind.Arr || i < 0 || i >= A.Count)
				{
					return Missing;
				}
				return A[i];
			}
		}

		internal int Count
		{
			get
			{
				if (K != Kind.Arr)
				{
					if (K != Kind.Obj)
					{
						return 0;
					}
					return O.Count;
				}
				return A.Count;
			}
		}

		internal IEnumerable<JNode> Items
		{
			get
			{
				if (K != Kind.Arr)
				{
					return Array.Empty<JNode>();
				}
				return A;
			}
		}

		internal IEnumerable<KeyValuePair<string, JNode>> Props
		{
			get
			{
				if (K != Kind.Obj)
				{
					return Array.Empty<KeyValuePair<string, JNode>>();
				}
				return O;
			}
		}

		internal string Str
		{
			get
			{
				switch (K)
				{
				case Kind.Str:
					return S;
				case Kind.Num:
					return N.ToString("R", CultureInfo.InvariantCulture);
				case Kind.Bool:
					if (!B)
					{
						return "false";
					}
					return "true";
				default:
					return null;
				}
			}
		}

		internal double Num
		{
			get
			{
				if (K == Kind.Num)
				{
					return N;
				}
				if (K == Kind.Str && double.TryParse(S, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					return result;
				}
				if (K == Kind.Bool)
				{
					return B ? 1 : 0;
				}
				return 0.0;
			}
		}

		internal long Long
		{
			get
			{
				double num = Num;
				if (!(num > 9.223372036854776E+18))
				{
					if (!(num < -9.223372036854776E+18))
					{
						return (long)num;
					}
					return long.MinValue;
				}
				return long.MaxValue;
			}
		}

		internal int Int
		{
			get
			{
				double num = Num;
				if (!(num > 2147483647.0))
				{
					if (!(num < -2147483648.0))
					{
						return (int)num;
					}
					return int.MinValue;
				}
				return int.MaxValue;
			}
		}

		internal bool Bool
		{
			get
			{
				if (K != Kind.Bool)
				{
					return Num != 0.0;
				}
				return B;
			}
		}
	}
	internal static class Json
	{
		private const int MaxDepth = 64;

		internal static JNode Parse(string text)
		{
			if (text == null)
			{
				throw new FormatException("no text");
			}
			int i = 0;
			JNode result = Value(text, ref i, 0);
			Skip(text, ref i);
			if (i != text.Length)
			{
				throw new FormatException("text after the JSON value at " + i);
			}
			return result;
		}

		internal static bool TryParse(string text, out JNode node)
		{
			try
			{
				node = Parse(text);
				return true;
			}
			catch
			{
				node = JNode.Missing;
				return false;
			}
		}

		internal static string Raw(string text, JNode n)
		{
			if (n == null || n == JNode.Missing || n.End <= n.Start)
			{
				return null;
			}
			return text.Substring(n.Start, n.End - n.Start);
		}

		private static void Skip(string s, ref int i)
		{
			while (i < s.Length)
			{
				char c = s[i];
				if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
				{
					i++;
					continue;
				}
				break;
			}
		}

		private static JNode Value(string s, ref int i, int depth)
		{
			if (depth > 64)
			{
				throw new FormatException("too deep");
			}
			Skip(s, ref i);
			if (i >= s.Length)
			{
				throw new FormatException("unexpected end");
			}
			int start = i;
			char c = s[i];
			JNode jNode;
			if (c == '{')
			{
				jNode = Obj(s, ref i, depth);
			}
			else if (c == '[')
			{
				jNode = Arr(s, ref i, depth);
			}
			else if (c == '"')
			{
				jNode = new JNode
				{
					K = JNode.Kind.Str,
					S = Str(s, ref i)
				};
			}
			else if (c == 't' && Word(s, ref i, "true"))
			{
				jNode = new JNode
				{
					K = JNode.Kind.Bool,
					B = true
				};
			}
			else if (c == 'f' && Word(s, ref i, "false"))
			{
				jNode = new JNode
				{
					K = JNode.Kind.Bool,
					B = false
				};
			}
			else if (c == 'n' && Word(s, ref i, "null"))
			{
				jNode = new JNode
				{
					K = JNode.Kind.Null
				};
			}
			else
			{
				switch (c)
				{
				case '-':
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					break;
				default:
					throw new FormatException("unexpected '" + c + "' at " + i);
				}
				jNode = new JNode
				{
					K = JNode.Kind.Num,
					N = Number(s, ref i)
				};
			}
			jNode.Start = start;
			jNode.End = i;
			return jNode;
		}

		private static bool Word(string s, ref int i, string w)
		{
			if (string.CompareOrdinal(s, i, w, 0, w.Length) != 0)
			{
				return false;
			}
			i += w.Length;
			return true;
		}

		private static JNode Obj(string s, ref int i, int depth)
		{
			JNode jNode = new JNode
			{
				K = JNode.Kind.Obj,
				O = new Dictionary<string, JNode>(StringComparer.Ordinal)
			};
			i++;
			Skip(s, ref i);
			if (i < s.Length && s[i] == '}')
			{
				i++;
				return jNode;
			}
			while (true)
			{
				Skip(s, ref i);
				if (i >= s.Length || s[i] != '"')
				{
					throw new FormatException("expected a key at " + i);
				}
				string key = Str(s, ref i);
				Skip(s, ref i);
				if (i >= s.Length || s[i] != ':')
				{
					throw new FormatException("expected ':' at " + i);
				}
				i++;
				jNode.O[key] = Value(s, ref i, depth + 1);
				Skip(s, ref i);
				if (i >= s.Length)
				{
					throw new FormatException("unexpected end in an object");
				}
				if (s[i] != ',')
				{
					break;
				}
				i++;
			}
			if (s[i] == '}')
			{
				i++;
				return jNode;
			}
			throw new FormatException("expected ',' or '}' at " + i);
		}

		private static JNode Arr(string s, ref int i, int depth)
		{
			JNode jNode = new JNode
			{
				K = JNode.Kind.Arr,
				A = new List<JNode>()
			};
			i++;
			Skip(s, ref i);
			if (i < s.Length && s[i] == ']')
			{
				i++;
				return jNode;
			}
			while (true)
			{
				jNode.A.Add(Value(s, ref i, depth + 1));
				Skip(s, ref i);
				if (i >= s.Length)
				{
					throw new FormatException("unexpected end in a list");
				}
				if (s[i] != ',')
				{
					break;
				}
				i++;
			}
			if (s[i] == ']')
			{
				i++;
				return jNode;
			}
			throw new FormatException("expected ',' or ']' at " + i);
		}

		private static string Str(string s, ref int i)
		{
			i++;
			StringBuilder stringBuilder = null;
			int num = i;
			while (i < s.Length)
			{
				switch (s[i])
				{
				case '"':
				{
					string result = ((stringBuilder == null) ? s.Substring(num, i - num) : stringBuilder.Append(s, num, i - num).ToString());
					i++;
					return result;
				}
				case '\\':
					break;
				default:
					i++;
					continue;
				}
				if (stringBuilder == null)
				{
					stringBuilder = new StringBuilder();
				}
				stringBuilder.Append(s, num, i - num);
				i++;
				if (i >= s.Length)
				{
					break;
				}
				char c = s[i];
				switch (c)
				{
				case '"':
					stringBuilder.Append('"');
					break;
				case '\\':
					stringBuilder.Append('\\');
					break;
				case '/':
					stringBuilder.Append('/');
					break;
				case 'b':
					stringBuilder.Append('\b');
					break;
				case 'f':
					stringBuilder.Append('\f');
					break;
				case 'n':
					stringBuilder.Append('\n');
					break;
				case 'r':
					stringBuilder.Append('\r');
					break;
				case 't':
					stringBuilder.Append('\t');
					break;
				case 'u':
				{
					if (i + 4 >= s.Length)
					{
						throw new FormatException("broken \\u at " + i);
					}
					if (!int.TryParse(s.Substring(i + 1, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result2))
					{
						throw new FormatException("broken \\u at " + i);
					}
					stringBuilder.Append((char)result2);
					i += 4;
					break;
				}
				default:
					throw new FormatException("unknown escape \\" + c + " at " + i);
				}
				i++;
				num = i;
			}
			throw new FormatException("text without an end");
		}

		private static double Number(string s, ref int i)
		{
			int num = i;
			if (s[i] == '-')
			{
				i++;
			}
			while (i < s.Length)
			{
				char c = s[i];
				if ((c < '0' || c > '9') && c != '.' && c != 'e' && c != 'E' && c != '+' && c != '-')
				{
					break;
				}
				i++;
			}
			if (!double.TryParse(s.Substring(num, i - num), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				throw new FormatException("broken number at " + num);
			}
			return result;
		}
	}
	internal static class R
	{
		private const BindingFlags F = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly Dictionary<string, MemberInfo> Cache = new Dictionary<string, MemberInfo>();

		private static readonly Dictionary<Type, MethodInfo> Casts = new Dictionary<Type, MethodInfo>();

		private static readonly Dictionary<string, Type> Types = new Dictionary<string, Type>();

		private static MemberInfo Member(Type t, string name)
		{
			string key = t.FullName + "|" + name;
			if (Cache.TryGetValue(key, out var value))
			{
				return value;
			}
			value = null;
			Type type = t;
			while (type != null && value == null)
			{
				PropertyInfo property = type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.GetIndexParameters().Length == 0)
				{
					value = property;
					break;
				}
				FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					value = field;
				}
				type = type.BaseType;
			}
			Cache[key] = value;
			return value;
		}

		internal static bool Has(object o, string name)
		{
			if (o != null)
			{
				return Member(o.GetType(), name) != null;
			}
			return false;
		}

		internal static object Get(object o, string name)
		{
			if (o == null)
			{
				return null;
			}
			MemberInfo memberInfo = Member(o.GetType(), name);
			PropertyInfo propertyInfo = memberInfo as PropertyInfo;
			if (propertyInfo != null)
			{
				return propertyInfo.GetValue(propertyInfo.GetGetMethod(nonPublic: true).IsStatic ? null : o);
			}
			FieldInfo fieldInfo = memberInfo as FieldInfo;
			if (fieldInfo != null)
			{
				return fieldInfo.GetValue(fieldInfo.IsStatic ? null : o);
			}
			return null;
		}

		internal static bool Set(object o, string name, object value)
		{
			if (o == null)
			{
				return false;
			}
			MemberInfo memberInfo = Member(o.GetType(), name);
			PropertyInfo propertyInfo = memberInfo as PropertyInfo;
			if (propertyInfo != null && propertyInfo.CanWrite)
			{
				propertyInfo.SetValue(o, value);
				return true;
			}
			FieldInfo fieldInfo = memberInfo as FieldInfo;
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(o, value);
				return true;
			}
			return false;
		}

		internal static object Static(Type t, string name)
		{
			if (t == null)
			{
				return null;
			}
			MemberInfo memberInfo = Member(t, name);
			PropertyInfo propertyInfo = memberInfo as PropertyInfo;
			if (propertyInfo != null)
			{
				return propertyInfo.GetValue(null);
			}
			FieldInfo fieldInfo = memberInfo as FieldInfo;
			if (fieldInfo != null)
			{
				return fieldInfo.GetValue(null);
			}
			return null;
		}

		internal static string Str(object o, string name)
		{
			try
			{
				return Get(o, name) as string;
			}
			catch
			{
				return null;
			}
		}

		internal static object Call(object o, string name, params object[] args)
		{
			if (o == null)
			{
				return null;
			}
			MethodInfo[] methods = o.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == name && methodInfo.GetParameters().Length == args.Length)
				{
					return methodInfo.Invoke(o, args);
				}
			}
			throw new MissingMethodException(o.GetType().Name, name);
		}

		internal static object Cast(object o, Type t)
		{
			if (o == null || t == null)
			{
				return null;
			}
			if (t.IsInstanceOfType(o))
			{
				return o;
			}
			Il2CppObjectBase val = (Il2CppObjectBase)((o is Il2CppObjectBase) ? o : null);
			if (val == null)
			{
				return null;
			}
			if (!Casts.TryGetValue(t, out var value))
			{
				value = null;
				MethodInfo method = typeof(Il2CppObjectBase).GetMethod("TryCast", BindingFlags.Instance | BindingFlags.Public);
				if (method != null)
				{
					value = method.MakeGenericMethod(t);
				}
				Casts[t] = value;
			}
			if (!(value != null))
			{
				return null;
			}
			return value.Invoke(val, null);
		}

		internal static List<object> Items(object list)
		{
			List<object> list2 = new List<object>();
			if (list == null)
			{
				return list2;
			}
			Type type = list.GetType();
			PropertyInfo property = type.GetProperty("Count");
			MethodInfo method = type.GetMethod("get_Item", new Type[1] { typeof(int) });
			if (property != null && method != null)
			{
				int num = Convert.ToInt32(property.GetValue(list));
				for (int i = 0; i < num; i++)
				{
					list2.Add(method.Invoke(list, new object[1] { i }));
				}
				return list2;
			}
			MethodInfo method2 = type.GetMethod("GetEnumerator", Type.EmptyTypes);
			if (method2 == null)
			{
				return list2;
			}
			object obj = method2.Invoke(list, null);
			if (obj == null)
			{
				return list2;
			}
			MethodInfo method3 = obj.GetType().GetMethod("MoveNext", Type.EmptyTypes);
			PropertyInfo property2 = obj.GetType().GetProperty("Current");
			if (method3 == null || property2 == null)
			{
				return list2;
			}
			int num2 = 0;
			while ((bool)method3.Invoke(obj, null) && num2++ < 100000)
			{
				list2.Add(property2.GetValue(obj));
			}
			return list2;
		}

		internal static int Count(object list)
		{
			if (list == null)
			{
				return 0;
			}
			PropertyInfo property = list.GetType().GetProperty("Count");
			if (!(property != null))
			{
				return 0;
			}
			return Convert.ToInt32(property.GetValue(list));
		}

		internal static Type FindType(string fullName, string shortName = null, string asmHint = null, Assembly first = null)
		{
			string key = fullName + "|" + shortName + "|" + asmHint;
			if (Types.TryGetValue(key, out var value))
			{
				return value;
			}
			Type type = Search(fullName, shortName, asmHint, first);
			Types[key] = type;
			return type;
		}

		private static Type Search(string fullName, string shortName, string asmHint, Assembly first)
		{
			if (first != null)
			{
				try
				{
					Type type = first.GetType(fullName, throwOnError: false);
					if (type != null)
					{
						return type;
					}
				}
				catch
				{
				}
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type2 = assembly.GetType(fullName, throwOnError: false);
					if (type2 != null)
					{
						return type2;
					}
				}
				catch
				{
				}
			}
			if (shortName == null)
			{
				return null;
			}
			assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies)
			{
				string text = assembly2.GetName().Name ?? "";
				if (asmHint != null && text.IndexOf(asmHint, StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				try
				{
					Type[] types = assembly2.GetTypes();
					foreach (Type type3 in types)
					{
						if (type3.Name == shortName)
						{
							return type3;
						}
					}
				}
				catch (ReflectionTypeLoadException ex)
				{
					Type[] types = ex.Types;
					foreach (Type type4 in types)
					{
						if (type4 != null && type4.Name == shortName)
						{
							return type4;
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}
	}
	internal static class Levels
	{
		private static Type _panelType;

		private static Type _modIoTarget;

		private static bool _panelTypeSearched;

		private static bool _listingLogged;

		private static bool _fusionSearched;

		private static PropertyInfo _hasServer;

		private static PropertyInfo _isHost;

		private static MethodInfo _requestLevel;

		private static MethodInfo _isInMarrowGame;

		private static bool _marrowGameSearched;

		internal static Type PanelType
		{
			get
			{
				if (_panelTypeSearched)
				{
					return _panelType;
				}
				_panelTypeSearched = true;
				Assembly assembly = typeof(UIRig).Assembly;
				_panelType = R.FindType("Il2CppSLZ.Bonelab.LevelsPanelView", null, null, assembly) ?? R.FindType("Il2CppSLZ.UI.LevelsPanelView", "LevelsPanelView", "Assembly-CSharp", assembly);
				Log.Info("Levels page class: " + ((_panelType != null) ? _panelType.FullName : "NOT FOUND"));
				return _panelType;
			}
		}

		internal static bool FusionClient
		{
			get
			{
				FindFusion();
				try
				{
					if (_hasServer == null || _isHost == null)
					{
						return false;
					}
					return (bool)_hasServer.GetValue(null) && !(bool)_isHost.GetValue(null);
				}
				catch
				{
					return false;
				}
			}
		}

		internal static int GameCount(object panel)
		{
			try
			{
				return R.Count(R.Get(panel, "_levelCrates"));
			}
			catch
			{
				return -1;
			}
		}

		internal static List<MapEntry> Read(object panel, out List<PackKey> packs, out string how)
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			List<MapEntry> list = new List<MapEntry>();
			packs = new List<PackKey>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			List<Crate> list2 = new List<Crate>();
			bool flag = false;
			try
			{
				foreach (object item2 in R.Items(R.Get(panel, "_levelCrates")))
				{
					object obj = R.Cast(item2, typeof(Crate));
					Crate item = (Crate)((obj is Crate) ? obj : null);
					list2.Add(item);
				}
				flag = list2.Count > 0;
			}
			catch (Exception ex)
			{
				Log.Warn("Reading the Levels page's list failed: " + ex.Message);
			}
			if (!flag)
			{
				list2.Clear();
				list2.AddRange(WarehouseLevels());
			}
			Dictionary<string, PackKey> dictionary = new Dictionary<string, PackKey>(StringComparer.OrdinalIgnoreCase);
			int num = -1;
			foreach (Crate item3 in list2)
			{
				num++;
				if ((Object)(object)item3 == (Object)null)
				{
					continue;
				}
				try
				{
					string text = ((((Scannable)item3).Barcode != (Barcode)null) ? ((Scannable)item3).Barcode.ID : null);
					if (string.IsNullOrEmpty(text) || !hashSet.Add(text))
					{
						continue;
					}
					MapEntry mapEntry = new MapEntry
					{
						Barcode = text,
						Title = (Text.StripTags(((Scannable)item3).Title) ?? text),
						GameIndex = (flag ? num : (-1)),
						Crate = item3
					};
					if (string.IsNullOrWhiteSpace(mapEntry.Title))
					{
						mapEntry.Title = text;
					}
					Pallet val = null;
					try
					{
						val = item3.Pallet;
					}
					catch
					{
					}
					if ((Object)(object)val != (Object)null)
					{
						try
						{
							mapEntry.Pack = Text.StripTags(((Scannable)val).Title);
						}
						catch
						{
						}
						try
						{
							mapEntry.PackBarcode = ((((Scannable)val).Barcode != (Barcode)null) ? ((Scannable)val).Barcode.ID : null);
						}
						catch
						{
						}
						mapEntry.Author = Text.StripTags(R.Str(val, "Author"));
						mapEntry.Slz = IsSlz(val, mapEntry.PackBarcode, mapEntry.Author);
					}
					if (string.IsNullOrEmpty(mapEntry.Pack))
					{
						mapEntry.Pack = (mapEntry.Slz ? "BONELAB" : "");
					}
					list.Add(mapEntry);
					if (!mapEntry.Slz && (Object)(object)val != (Object)null && !string.IsNullOrEmpty(mapEntry.PackBarcode))
					{
						if (!dictionary.TryGetValue(mapEntry.PackBarcode, out var value))
						{
							value = new PackKey
							{
								Barcode = mapEntry.PackBarcode,
								Title = mapEntry.Pack,
								Author = mapEntry.Author
							};
							ReadListing(val, value);
							dictionary[mapEntry.PackBarcode] = value;
							packs.Add(value);
						}
						value.LevelTitles.Add(mapEntry.Title);
						mapEntry.ListingThumb = value.ListingThumb;
					}
				}
				catch (Exception ex2)
				{
					Log.Warn("Reading a map failed: " + ex2.Message);
				}
			}
			stopwatch.Stop();
			int num2 = 0;
			foreach (PackKey pack in packs)
			{
				if (pack.ListingModId > 0)
				{
					num2++;
				}
			}
			how = (flag ? "the Levels page" : "all installed packs (the page's list was empty)") + ": " + list.Count + " maps, " + packs.Count + " mod packs (" + num2 + " with a mod.io id from the game), " + stopwatch.Elapsed.TotalMilliseconds.ToString("0") + " ms";
			return list;
		}

		private static List<Crate> WarehouseLevels()
		{
			List<Crate> list = new List<Crate>();
			try
			{
				Type type = typeof(Crate).Assembly.GetType("Il2CppSLZ.Marrow.Warehouse.LevelCrate");
				AssetWarehouse instance = AssetWarehouse.Instance;
				if (instance == null || type == null)
				{
					return list;
				}
				Enumerator<Pallet> enumerator = instance.GetPallets().GetEnumerator();
				while (enumerator.MoveNext())
				{
					Pallet current = enumerator.Current;
					if ((Object)(object)current == (Object)null)
					{
						continue;
					}
					try
					{
						if (current.Crates == null)
						{
							continue;
						}
						Enumerator<Crate> enumerator2 = current.Crates.GetEnumerator();
						while (enumerator2.MoveNext())
						{
							Crate current2 = enumerator2.Current;
							if (!((Object)(object)current2 == (Object)null) && R.Cast(current2, type) != null)
							{
								object obj = null;
								try
								{
									obj = R.Get(current2, "Redacted");
								}
								catch
								{
								}
								if ((!(obj is bool) || !(bool)obj) && (((Scannable)current2).Title ?? "").IndexOf("loading", StringComparison.OrdinalIgnoreCase) < 0)
								{
									list.Add(current2);
								}
							}
						}
					}
					catch
					{
					}
				}
			}
			catch (Exception ex)
			{
				Log.Warn("Reading the installed levels failed: " + ex.Message);
			}
			return list;
		}

		private static bool IsSlz(Pallet p, string barcode, string author)
		{
			if (!_marrowGameSearched)
			{
				_marrowGameSearched = true;
				try
				{
					_isInMarrowGame = ((object)p).GetType().GetMethod("IsInMarrowGame", Type.EmptyTypes);
				}
				catch
				{
				}
			}
			if (_isInMarrowGame != null)
			{
				try
				{
					return (bool)_isInMarrowGame.Invoke(p, null);
				}
				catch
				{
				}
			}
			if (!string.IsNullOrEmpty(barcode) && barcode.StartsWith("SLZ.", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			string text = Text.Norm(author);
			if (!(text == "slz"))
			{
				return text == "stresslevelzero";
			}
			return true;
		}

		private static void ReadListing(Pallet p, PackKey k)
		{
			try
			{
				object obj = R.Get(AssetWarehouse.Instance, "palletManifests");
				if (obj == null)
				{
					return;
				}
				object barcode = ((Scannable)p).Barcode;
				Type type = obj.GetType();
				MethodInfo method = type.GetMethod("ContainsKey");
				MethodInfo method2 = type.GetMethod("get_Item");
				if (method == null || method2 == null || !(bool)method.Invoke(obj, new object[1] { barcode }))
				{
					return;
				}
				object obj2 = R.Get(method2.Invoke(obj, new object[1] { barcode }), "ModListing");
				if (obj2 == null)
				{
					return;
				}
				PropertyInfo[] properties;
				if (!_listingLogged)
				{
					_listingLogged = true;
					List<string> list = new List<string>();
					properties = obj2.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
					foreach (PropertyInfo propertyInfo in properties)
					{
						list.Add(propertyInfo.Name);
					}
					Log.Info("Mod listing members: " + string.Join(", ", list));
				}
				properties = obj2.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
				foreach (PropertyInfo propertyInfo2 in properties)
				{
					if (!(propertyInfo2.PropertyType != typeof(string)) && propertyInfo2.Name.IndexOf("thumb", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						string text = null;
						try
						{
							text = propertyInfo2.GetValue(obj2) as string;
						}
						catch
						{
						}
						if (text != null && text.StartsWith("http", StringComparison.OrdinalIgnoreCase))
						{
							k.ListingThumb = text;
							break;
						}
					}
				}
				object obj4 = R.Get(obj2, "Targets");
				if (obj4 == null)
				{
					return;
				}
				if (_modIoTarget == null)
				{
					_modIoTarget = obj2.GetType().Assembly.GetType("Il2CppSLZ.Marrow.Forklift.Model.ModIOModTarget") ?? R.FindType("Il2CppSLZ.Marrow.Forklift.Model.ModIOModTarget", "ModIOModTarget", "SLZ");
				}
				if (_modIoTarget == null)
				{
					return;
				}
				foreach (object item in R.Items(R.Get(obj4, "Values")))
				{
					object obj5 = R.Cast(item, _modIoTarget);
					if (obj5 == null)
					{
						continue;
					}
					object obj6 = R.Get(obj5, "ModId");
					if (obj6 != null)
					{
						long num = Convert.ToInt64(obj6);
						if (num > 0)
						{
							k.ListingModId = num;
							break;
						}
					}
				}
			}
			catch (Exception ex)
			{
				if (!_listingLogged)
				{
					_listingLogged = true;
					Log.Warn("Reading a pack's mod listing failed: " + ex.Message);
				}
			}
		}

		internal static string ReadToken(out string where)
		{
			where = "";
			List<string> list = new List<string>();
			try
			{
				string text = R.Static(R.FindType("Il2CppSLZ.Marrow.Forklift.ModDownloader", "ModDownloader", "SLZ", typeof(Crate).Assembly), "ModSettingsPath") as string;
				if (!string.IsNullOrEmpty(text))
				{
					list.Add(text);
				}
			}
			catch (Exception ex)
			{
				Log.Warn("Finding the mod settings file failed: " + ex.Message);
			}
			try
			{
				string persistentDataPath = Application.persistentDataPath;
				if (!string.IsNullOrEmpty(persistentDataPath) && Directory.Exists(persistentDataPath))
				{
					string[] files = Directory.GetFiles(persistentDataPath, "*.json", SearchOption.TopDirectoryOnly);
					foreach (string item in files)
					{
						if (!list.Contains(item))
						{
							list.Add(item);
						}
					}
				}
			}
			catch
			{
			}
			foreach (string item2 in list)
			{
				try
				{
					if (!File.Exists(item2) || new FileInfo(item2).Length > 524288)
					{
						continue;
					}
					string text2 = File.ReadAllText(item2);
					if (text2.IndexOf("mod.io.access_token", StringComparison.Ordinal) >= 0 && Json.TryParse(text2, out var node))
					{
						string str = node["mod.io.access_token"].Str;
						where = Path.GetFileName(item2);
						if (!string.IsNullOrWhiteSpace(str))
						{
							return str;
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}

		internal static string ModsFolder()
		{
			try
			{
				string text = Path.Combine(Application.persistentDataPath, "Mods");
				return Directory.Exists(text) ? text : null;
			}
			catch
			{
				return null;
			}
		}

		private static void FindFusion()
		{
			if (_fusionSearched)
			{
				return;
			}
			_fusionSearched = true;
			try
			{
				Type type = R.FindType("LabFusion.Network.NetworkInfo");
				if (type != null)
				{
					_hasServer = type.GetProperty("HasServer", BindingFlags.Static | BindingFlags.Public);
					_isHost = type.GetProperty("IsHost", BindingFlags.Static | BindingFlags.Public);
				}
				Type type2 = R.FindType("LabFusion.Senders.LoadSender");
				if (type2 != null)
				{
					MethodInfo[] methods = type2.GetMethods(BindingFlags.Static | BindingFlags.Public);
					foreach (MethodInfo methodInfo in methods)
					{
						if (methodInfo.Name == "SendLevelRequest" && methodInfo.GetParameters().Length == 1)
						{
							_requestLevel = methodInfo;
							break;
						}
					}
				}
				Log.Info("Fusion: " + ((type != null) ? ("found (lobby check " + (_hasServer != null && _isHost != null) + ", level request " + (_requestLevel != null) + ")") : "not installed"));
			}
			catch (Exception ex)
			{
				Log.Warn("Looking for Fusion failed: " + ex.Message);
			}
		}

		internal static bool Play(object panel, MapEntry e, out string how)
		{
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Expected O, but got Unknown
			how = "";
			if (e == null)
			{
				return false;
			}
			if (panel != null && e.Crate != null)
			{
				try
				{
					List<object> list = R.Items(R.Get(panel, "_levelCrates"));
					int num = -1;
					for (int i = 0; i < list.Count; i++)
					{
						object obj = R.Cast(list[i], typeof(Crate));
						Crate val = (Crate)((obj is Crate) ? obj : null);
						if ((Object)(object)val != (Object)null && ((Scannable)val).Barcode != (Barcode)null && string.Equals(((Scannable)val).Barcode.ID, e.Barcode, StringComparison.OrdinalIgnoreCase))
						{
							num = i;
							break;
						}
					}
					int num2 = R.Count(R.Get(panel, "items"));
					if (num >= 0 && num2 > 0)
					{
						R.Set(panel, "_currentPage", num / num2);
						R.Call(panel, "SelectItem", num % num2);
						how = "the game's Levels page (item " + num % num2 + " of page " + (num / num2 + 1) + ")";
						return true;
					}
					how = "not in the page's list (" + num + ", " + num2 + " per page)";
				}
				catch (Exception ex)
				{
					how = "page failed: " + ex.GetBaseException().Message;
					Log.Warn("Starting \"" + e.Title + "\" through the Levels page failed: " + ex);
				}
			}
			if (FusionClient && _requestLevel != null && e.Crate != null)
			{
				try
				{
					Type parameterType = _requestLevel.GetParameters()[0].ParameterType;
					_requestLevel.Invoke(null, new object[1] { R.Cast(e.Crate, parameterType) });
					how += "; Fusion level request";
					return true;
				}
				catch (Exception ex2)
				{
					how = how + "; Fusion request failed: " + ex2.GetBaseException().Message;
				}
			}
			try
			{
				Type type = R.FindType("Il2CppSLZ.Marrow.SceneStreaming.SceneStreamer", "SceneStreamer", "SLZ", typeof(Crate).Assembly);
				if (type == null)
				{
					how += "; no SceneStreamer";
					return false;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!(methodInfo.Name != "Load"))
					{
						ParameterInfo[] parameters = methodInfo.GetParameters();
						if (parameters.Length == 2 && !(parameters[0].ParameterType != typeof(Barcode)))
						{
							Barcode val2 = (Barcode)Activator.CreateInstance(typeof(Barcode), e.Barcode);
							methodInfo.Invoke(null, new object[2] { val2, null });
							how += "; SceneStreamer.Load";
							return true;
						}
					}
				}
				how += "; no Load(Barcode, Barcode)";
			}
			catch (Exception ex3)
			{
				how = how + "; SceneStreamer failed: " + ex3.GetBaseException().Message;
			}
			return false;
		}
	}
	internal static class Log
	{
		private const int MaxLines = 8000;

		private static string _path;

		private static int _lines;

		private static readonly object Gate = new object();

		internal static void Init()
		{
			try
			{
				string text = Path.Combine(MelonEnvironment.UserDataDirectory, "MapMenuPlus");
				Directory.CreateDirectory(text);
				_path = Path.Combine(text, "log.txt");
				File.WriteAllText(_path, "MapMenuPlus log, started " + DateTime.Now.ToString() + Environment.NewLine);
			}
			catch
			{
				_path = null;
			}
		}

		internal static void Info(string msg)
		{
			Write("INFO  ", msg);
		}

		internal static void Warn(string msg)
		{
			Write("WARN  ", msg);
		}

		internal static void Error(string msg, Exception e)
		{
			Write("ERROR ", msg + ((e != null) ? (" :: " + e) : ""));
		}

		private static void Write(string level, string msg)
		{
			if (_path == null)
			{
				return;
			}
			try
			{
				lock (Gate)
				{
					if (_lines++ < 8000)
					{
						File.AppendAllText(_path, DateTime.Now.ToString("HH:mm:ss.fff") + " " + level + msg + Environment.NewLine);
					}
				}
			}
			catch
			{
			}
		}
	}
	internal struct HudRect
	{
		internal float X;

		internal float Y;

		internal float W;

		internal float H;

		internal float Left => X - W / 2f;

		internal float Right => X + W / 2f;

		internal float Top => Y + H / 2f;

		internal float Bottom => Y - H / 2f;

		internal HudRect(float x, float y, float w, float h)
		{
			X = x;
			Y = y;
			W = w;
			H = h;
		}
	}
	internal static class MapLayout
	{
		internal static readonly HudRect Panel = new HudRect(0f, 0f, 980f, 720f);

		internal static readonly HudRect TitleBar = new HudRect(0f, 333f, 980f, 54f);

		internal static readonly HudRect TitleIcon = new HudRect(-464f, 333f, 28f, 28f);

		internal static readonly HudRect Title = new HudRect(-328f, 333f, 230f, 44f);

		internal static readonly HudRect TitleText = new HudRect(-328f, 341f, 230f, 26f);

		internal static readonly HudRect SubTitle = new HudRect(-328f, 318f, 230f, 14f);

		internal static readonly HudRect Status = new HudRect(80f, 333f, 340f, 34f);

		internal static readonly HudRect Classic = new HudRect(350f, 333f, 140f, 40f);

		internal static readonly HudRect Close = new HudRect(458f, 333f, 44f, 40f);

		internal static readonly HudRect Sidebar = new HudRect(-375f, -27f, 230f, 666f);

		internal static readonly HudRect SideTitle = new HudRect(-375f, 285f, 206f, 26f);

		internal const float CatTop = 266f;

		internal const float CatH = 40f;

		internal const float CatGap = 8f;

		internal const float CatW = 214f;

		internal const float CatX = -375f;

		internal static readonly HudRect CatIcon = new HudRect(-85f, 0f, 20f, 20f);

		internal static readonly HudRect CatCount = new HudRect(81f, 0f, 40f, 22f);

		internal static readonly HudRect CatBar = new HudRect(-105f, 0f, 4f, 24f);

		internal const float CatLabelLeft = 42f;

		internal static readonly HudRect Separator = new HudRect(-375f, -26f, 198f, 2f);

		internal static readonly HudRect Random = new HudRect(-375f, -58f, 214f, 42f);

		internal static readonly HudRect NowLabel = new HudRect(-375f, -102f, 206f, 18f);

		internal static readonly HudRect NowPic = new HudRect(-375f, -172f, 206f, 116f);

		internal static readonly HudRect NowTitle = new HudRect(-375f, -244f, 206f, 22f);

		internal static readonly HudRect NowSub = new HudRect(-375f, -265f, 206f, 16f);

		internal static readonly HudRect Tip = new HudRect(-375f, -318f, 206f, 56f);

		internal static readonly HudRect Main = new HudRect(120f, -27f, 740f, 666f);

		internal static readonly HudRect Search = new HudRect(-125f, 272f, 230f, 46f);

		internal static readonly HudRect Sort = new HudRect(110f, 272f, 220f, 46f);

		internal static readonly HudRect Prev = new HudRect(322f, 272f, 46f, 46f);

		internal static readonly HudRect PageText = new HudRect(387f, 272f, 72f, 46f);

		internal static readonly HudRect Next = new HudRect(452f, 272f, 46f, 46f);

		internal const float GridLeft = -240f;

		internal const float GridRight = 480f;

		internal const float GridTop = 238f;

		internal const float GridBottom = -350f;

		internal const float Gap = 12f;

		internal const float CardPad = 4f;

		internal static readonly HudRect Back = new HudRect(-178f, 272f, 124f, 46f);

		internal static readonly HudRect Crumb = new HudRect(93f, 272f, 380f, 30f);

		internal static readonly HudRect BigPic = new HudRect(120f, 76f, 576f, 324f);

		internal static readonly HudRect GalPrev = new HudRect(-209f, 76f, 44f, 88f);

		internal static readonly HudRect GalNext = new HudRect(449f, 76f, 44f, 88f);

		internal static readonly HudRect Dots = new HudRect(120f, -100f, 300f, 10f);

		internal static readonly HudRect DTitle = new HudRect(120f, -132f, 700f, 36f);

		internal static readonly HudRect DInfo = new HudRect(120f, -164f, 700f, 22f);

		internal static readonly HudRect DStats = new HudRect(120f, -192f, 700f, 24f);

		internal static readonly HudRect DSummary = new HudRect(120f, -240f, 700f, 62f);

		internal static readonly HudRect Play = new HudRect(-80f, -316f, 300f, 58f);

		internal static readonly HudRect Fav = new HudRect(170f, -316f, 176f, 58f);

		internal static readonly HudRect Played = new HudRect(372f, -316f, 196f, 40f);

		internal const float ShadowOffset = 12f;

		internal const float ShadowGrow = 24f;

		internal const float KeyboardTopY = -410f;

		internal static float CardW => 232f;

		internal static float CardH => 188f;

		internal static float GridX => 120f;

		internal static float GridY => -56f;

		internal static float GridW => 720f;

		internal static HudRect CardPhoto => new HudRect(0f, CardH / 2f - 4f - 63f, CardW - 8f, 126f);

		internal static HudRect CardTitle => new HudRect(0f, CardPhoto.Bottom - 15f, CardW - 18f, 22f);

		internal static HudRect CardSub => new HudRect(0f, CardPhoto.Bottom - 38f, CardW - 18f, 16f);

		internal static HudRect CardShade
		{
			get
			{
				HudRect cardPhoto = CardPhoto;
				return new HudRect(0f, cardPhoto.Bottom + 20f, cardPhoto.W, 40f);
			}
		}

		internal static HudRect CardDlIcon
		{
			get
			{
				HudRect cardPhoto = CardPhoto;
				return new HudRect(cardPhoto.Left + 14f, cardPhoto.Bottom + 12f, 14f, 14f);
			}
		}

		internal static HudRect CardDlText
		{
			get
			{
				HudRect cardPhoto = CardPhoto;
				return new HudRect(cardPhoto.Left + 62f, cardPhoto.Bottom + 12f, 80f, 18f);
			}
		}

		internal static HudRect CardRateText
		{
			get
			{
				HudRect cardPhoto = CardPhoto;
				return new HudRect(cardPhoto.Right - 28f, cardPhoto.Bottom + 12f, 44f, 18f);
			}
		}

		internal static HudRect CardRateIcon
		{
			get
			{
				HudRect cardPhoto = CardPhoto;
				return new HudRect(cardPhoto.Right - 58f, cardPhoto.Bottom + 12f, 14f, 14f);
			}
		}

		internal static HudRect CardBadge
		{
			get
			{
				HudRect cardPhoto = CardPhoto;
				return new HudRect(cardPhoto.Left + 48f, cardPhoto.Top - 15f, 84f, 20f);
			}
		}

		internal static HudRect CardFav
		{
			get
			{
				HudRect cardPhoto = CardPhoto;
				return new HudRect(cardPhoto.Right - 17f, cardPhoto.Top - 17f, 24f, 24f);
			}
		}

		internal static float KeyboardBottom => -730f;

		internal static float CatY(int i)
		{
			return 246f - (float)i * 48f;
		}

		internal static float CardX(int col)
		{
			return -240f + CardW / 2f + (float)col * (CardW + 12f);
		}

		internal static float CardY(int row)
		{
			return 238f - CardH / 2f - (float)row * (CardH + 12f);
		}

		internal static List<KeyValuePair<string, HudRect>> GridParts()
		{
			List<KeyValuePair<string, HudRect>> list = Common();
			list.Add(P("Search", Search));
			list.Add(P("Sort", Sort));
			list.Add(P("Prev", Prev));
			list.Add(P("PageText", PageText));
			list.Add(P("Next", Next));
			for (int i = 0; i < 3; i++)
			{
				for (int j = 0; j < 3; j++)
				{
					list.Add(P("Card" + i + j, new HudRect(CardX(j), CardY(i), CardW, CardH)));
				}
			}
			return list;
		}

		internal static List<KeyValuePair<string, HudRect>> DetailParts()
		{
			List<KeyValuePair<string, HudRect>> list = Common();
			list.Add(P("Back", Back));
			list.Add(P("Crumb", Crumb));
			list.Add(P("Prev", Prev));
			list.Add(P("PageText", PageText));
			list.Add(P("Next", Next));
			list.Add(P("BigPic", BigPic));
			list.Add(P("GalPrev", GalPrev));
			list.Add(P("GalNext", GalNext));
			list.Add(P("Dots", Dots));
			list.Add(P("DTitle", DTitle));
			list.Add(P("DInfo", DInfo));
			list.Add(P("DStats", DStats));
			list.Add(P("DSummary", DSummary));
			list.Add(P("Play", Play));
			list.Add(P("Fav", Fav));
			list.Add(P("Played", Played));
			return list;
		}

		internal static List<KeyValuePair<string, HudRect>> CardParts()
		{
			return new List<KeyValuePair<string, HudRect>>
			{
				P("Photo", CardPhoto),
				P("Title", CardTitle),
				P("Sub", CardSub)
			};
		}

		internal static List<KeyValuePair<string, HudRect>> PhotoParts()
		{
			return new List<KeyValuePair<string, HudRect>>
			{
				P("DlIcon", CardDlIcon),
				P("DlText", CardDlText),
				P("RateIcon", CardRateIcon),
				P("RateText", CardRateText),
				P("Badge", CardBadge),
				P("Fav", CardFav)
			};
		}

		private static List<KeyValuePair<string, HudRect>> Common()
		{
			List<KeyValuePair<string, HudRect>> list = new List<KeyValuePair<string, HudRect>>
			{
				P("TitleIcon", TitleIcon),
				P("Title", Title),
				P("Status", Status),
				P("Classic", Classic),
				P("Close", Close),
				P("SideTitle", SideTitle),
				P("Separator", Separator),
				P("Random", Random),
				P("NowLabel", NowLabel),
				P("NowPic", NowPic),
				P("NowTitle", NowTitle),
				P("NowSub", NowSub),
				P("Tip", Tip)
			};
			for (int i = 0; i < MapModel.Cats.Length; i++)
			{
				list.Add(P("Cat" + i, new HudRect(-375f, CatY(i), 214f, 40f)));
			}
			return list;
		}

		private static KeyValuePair<string, HudRect> P(string n, HudRect r)
		{
			return new KeyValuePair<string, HudRect>(n, r);
		}
	}
	internal sealed class MapMenu
	{
		private sealed class CardSlot
		{
			internal int Index;

			internal GameObject Go;

			internal Transform Visual;

			internal CanvasGroup Group;

			internal Button Btn;

			internal RawImage Bg;

			internal RawImage Outline;

			internal RawImage Art;

			internal RawImage Photo;

			internal RawImage Shimmer;

			internal RawImage Shade;

			internal RawImage DlIcon;

			internal RawImage RateIcon;

			internal RawImage BadgeBg;

			internal RawImage FavIcon;

			internal RawImage FavBack;

			internal TMP_Text ArtText;

			internal TMP_Text DlText;

			internal TMP_Text RateText;

			internal TMP_Text BadgeText;

			internal TMP_Text Title;

			internal TMP_Text Sub;

			internal List<RawImage> Caps;

			internal MapEntry Entry;

			internal string Url;

			internal bool PhotoShown;

			internal float PhotoAlpha;

			internal float Scale = 1f;

			internal float Hover;

			internal float Appear = 1f;

			internal float AppearStart;

			internal float Zoom = 1f;

			internal bool Hovered;
		}

		private sealed class CatSlot
		{
			internal GameObject Go;

			internal Button Btn;

			internal RawImage Icon;

			internal RawImage Bar;

			internal RawImage CountBg;

			internal TMP_Text Label;

			internal TMP_Text Count;

			internal MapCat Cat;

			internal int State = -1;
		}

		private sealed class Hidden
		{
			internal Transform T;

			internal Vector3 Scale;
		}

		private const float RootZ = -20f;

		private const float CatcherZ = 6f;

		private const float Tiny = 0.0001f;

		private const float UnitMetres = 0.0013f;

		private const float HoverScale = 1.045f;

		private const float OpenTime = 0.18f;

		private const float CapR = 8f;

		private static readonly Vector2 CursorCentre = new Vector2(0f, (MapLayout.Panel.Top + 30f + MapLayout.KeyboardBottom - 30f) / 2f);

		private static readonly Vector2 CursorSize = new Vector2(MapLayout.Panel.W + 60f, MapLayout.Panel.Top + 30f - (MapLayout.KeyboardBottom - 30f));

		private readonly MapModel _model = new MapModel();

		private readonly Pictures _pics = new Pictures();

		private readonly IdStore _favorites;

		private readonly PlayLog _played;

		private readonly Random _rng = new Random();

		private Component _panel;

		private Transform _page;

		private bool _built;

		private bool _broken;

		private bool _wasOpen;

		private bool _scaleChecked;

		private float _openedAt;

		private float _openT = 1f;

		private float _baseScale = 1f;

		private UiStyle _style;

		private GameObject _root;

		private GameObject _newMenu;

		private GameObject _gridView;

		private GameObject _detailView;

		private CanvasGroup _group;

		private readonly List<CardSlot> _cards = new List<CardSlot>();

		private readonly List<CatSlot> _cats = new List<CatSlot>();

		private readonly List<Hidden> _hidden = new List<Hidden>();

		private readonly CursorArea _cursorArea = new CursorArea();

		private Vector2 _newMenuPos;

		private Keyboard _keyboard;

		private TMP_Text _subTitle;

		private TMP_Text _statusText;

		private TMP_Text _searchText;

		private TMP_Text _sortText;

		private TMP_Text _pageText;

		private TMP_Text _emptyText;

		private TMP_Text _emptyHint;

		private TMP_Text _tip;

		private RawImage _statusDot;

		private RawImage _searchFrame;

		private Button _prev;

		private Button _next;

		private RawImage _nowArt;

		private RawImage _nowPic;

		private TMP_Text _nowTitle;

		private TMP_Text _nowSub;

		private TMP_Text _nowArtText;

		private TMP_Text _crumb;

		private TMP_Text _mapPos;

		private TMP_Text _dTitle;

		private TMP_Text _dInfo;

		private TMP_Text _dlText;

		private TMP_Text _rateText;

		private TMP_Text _tagText;

		private TMP_Text _dSummary;

		private TMP_Text _playText;

		private TMP_Text _favText;

		private TMP_Text _playedText;

		private TMP_Text _bigArtText;

		private TMP_Text _bigHidden;

		private RawImage _bigArt;

		private RawImage _bigA;

		private RawImage _bigB;

		private RawImage _bigShimmer;

		private RawImage _dlIcon;

		private RawImage _rateIcon;

		private RawImage _favIconD;

		private Button _mapPrev;

		private Button _mapNext;

		private Button _galPrev;

		private Button _galNext;

		private Button _play;

		private Button _favBtn;

		private readonly List<RawImage> _dots = new List<RawImage>();

		private MapEntry _detail;

		private List<string> _gal = new List<string>();

		private int _galIndex;

		private Texture _bigShown;

		private int _bigShownIndex = -1;

		private float _bigFade = 1f;

		private float _nextGalSwap;

		private float _playLockUntil;

		private string _playLockText;

		private int _dataCount = -2;

		private int _modVersion = -1;

		private int _imgVersion = -1;

		private int _dataLogs;

		private float _nextInfoApply;

		private float _nextTokenCheck;

		private float _nextCountCheck;

		private string _current;

		private string _flash;

		private float _flashUntil;

		private bool _caretOn;

		private float _nextCaret;

		private string _lastPageKey;

		private float _shimmerT;

		private float _nextNow;

		private readonly Stopwatch _work = new Stopwatch();

		private int _spikeLogs;

		private static readonly Dictionary<string, Texture2D> Outlines = new Dictionary<string, Texture2D>();

		internal bool IsOpen => _wasOpen;

		internal MapMenu(string dataDir)
		{
			_favorites = new IdStore((dataDir != null) ? Path.Combine(dataDir, "favorites.txt") : null, 5000);
			_played = new PlayLog((dataDir != null) ? Path.Combine(dataDir, "played.txt") : null);
			Log.Info("Map menu: " + (Settings.NewMenu ? "new menu on" : "off (CLASSIC)") + ", " + _favorites.Ids.Count + " favorites, " + _played.Count + " maps played before.");
		}

		internal void LevelLoaded(string barcode, string title)
		{
			_current = barcode;
			if (!string.IsNullOrEmpty(barcode))
			{
				_played.Played(barcode, DateTimeOffset.UtcNow.ToUnixTimeSeconds());
				_model.SetRecent(_played.Recent(), apply: false);
			}
		}

		internal void SettingsChanged()
		{
			if (_built)
			{
				_modVersion = -1;
				ApplyMode(fromButton: false);
			}
		}

		internal void ClearPictures()
		{
			_pics.Clear();
			foreach (CardSlot card in _cards)
			{
				card.PhotoShown = false;
				card.Url = null;
			}
			_bigShown = null;
			_bigShownIndex = -1;
			_modVersion = -1;
		}

		internal string StatusLine()
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			foreach (MapEntry item in _model.All)
			{
				if (!item.Slz)
				{
					num++;
					if (item.ModId > 0)
					{
						num2++;
					}
					if (item.Info != null)
					{
						num3++;
					}
				}
			}
			return StatusWords(plain: true) + "\n" + _model.AllCount + " maps (" + num + " from mods: " + num2 + " found on mod.io, " + num3 + " with info). " + _pics.Decoded + " pictures shown, " + ModIo.ImagesDownloaded + " downloaded this session.";
		}

		internal void Reset()
		{
			try
			{
				ShowGameParts();
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_root != (Object)null)
				{
					Object.Destroy((Object)(object)_root);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_newMenu != (Object)null)
				{
					Object.Destroy((Object)(object)_newMenu);
				}
			}
			catch
			{
			}
			_root = null;
			_newMenu = null;
			_keyboard = null;
			_group = null;
			_gridView = null;
			_detailView = null;
			_cards.Clear();
			_cats.Clear();
			_dots.Clear();
			_cursorArea.Reset();
			_built = false;
			_broken = false;
			_wasOpen = false;
			_scaleChecked = false;
			_baseScale = 1f;
			_page = null;
			_panel = null;
			_hidden.Clear();
			_detail = null;
			_bigShown = null;
			_bigShownIndex = -1;
			_dataCount = -2;
			_modVersion = -1;
			_lastPageKey = null;
		}

		internal void Update(float now, Component panel)
		{
			if ((Object)(object)panel == (Object)null)
			{
				return;
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			bool wasOpen = _wasOpen;
			_work.Restart();
			try
			{
				Step(now, unscaledDeltaTime, panel);
			}
			finally
			{
				_work.Stop();
				double totalMilliseconds = _work.Elapsed.TotalMilliseconds;
				if (totalMilliseconds > 15.0 && _spikeLogs < 40)
				{
					_spikeLogs++;
					Log.Info("Slow menu frame: this mod took " + totalMilliseconds.ToString("0.0") + " ms" + (wasOpen ? "" : " (menu closed)") + ".");
				}
			}
		}

		private void Step(float now, float dt, Component panel)
		{
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			try
			{
				val = panel.transform;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)val != (Object)(object)_page)
			{
				if ((Object)(object)_page != (Object)null || _built)
				{
					Reset();
				}
				_page = val;
				_panel = panel;
			}
			if (!((Component)val).gameObject.activeInHierarchy)
			{
				if (_wasOpen)
				{
					_wasOpen = false;
					if (_keyboard != null)
					{
						_keyboard.Hide();
					}
					ModIo.Want(null, null);
					Log.Info("Map menu closed.");
				}
				_cursorArea.Hide();
				if (!_built && !_broken)
				{
					Build();
				}
				if (_built && now >= _nextCountCheck)
				{
					_nextCountCheck = now + 2f;
					int num = Levels.GameCount(_panel);
					if (num > 0 && num != _dataCount)
					{
						ReadData();
					}
				}
				return;
			}
			if (!_built && !_broken)
			{
				Build();
			}
			if (!_built)
			{
				return;
			}
			if (!_wasOpen)
			{
				_wasOpen = true;
				_openedAt = now;
				_openT = 0f;
				_lastPageKey = null;
				if (Levels.GameCount(_panel) != _dataCount || _model.AllCount == 0)
				{
					ReadData();
				}
				if (now >= _nextTokenCheck && ModIo.Status != ModIo.State.Ready && ModIo.Status != ModIo.State.Working)
				{
					_nextTokenCheck = now + 10f;
					ModIo.SetToken(Levels.ReadToken(out var _));
				}
				Log.Info("Map menu opened (" + (Settings.NewMenu ? "new menu" : "classic") + ", " + _model.AllCount + " maps).");
				ApplyMode(fromButton: false);
			}
			if (!_scaleChecked && now - _openedAt > 0.6f)
			{
				CheckScale();
			}
			if (Settings.NewMenu && (Object)(object)_root != (Object)null)
			{
				_cursorArea.Show(now, _root.transform, CursorCentre, CursorSize, 60f);
			}
			else if ((Object)(object)_newMenu != (Object)null)
			{
				_cursorArea.Show(now, _page, _newMenuPos, new Vector2(320f, 90f), 40f);
			}
			if (!Settings.NewMenu)
			{
				return;
			}
			HideGameParts();
			if (ModIo.Version != _modVersion && (now >= _nextInfoApply || _modVersion < 0))
			{
				_nextInfoApply = now + 1.2f;
				if (ApplyInfo())
				{
					Render();
				}
				else
				{
					RenderStatus();
				}
			}
			_pics.Tick();
			ShowNewPhotos(now);
			HoverCheck(now);
			Animate(now, dt);
		}

		private void ReadData()
		{
			try
			{
				List<PackKey> packs;
				string how;
				List<MapEntry> all = Levels.Read(_panel, out packs, out how);
				_dataCount = Levels.GameCount(_panel);
				_model.SetData(all, _favorites.Ids, _played.Recent());
				ModIo.Register(packs);
				_modVersion = -1;
				ApplyInfo();
				if (_dataLogs++ < 6)
				{
					Log.Info("Maps read from " + how + ".");
				}
				if (_detail != null)
				{
					_detail = _model.Find(_detail.Barcode);
				}
				if (_built && _wasOpen && Settings.NewMenu)
				{
					Render();
				}
			}
			catch (Exception e)
			{
				Log.Error("Reading the maps failed", e);
				_dataCount = Levels.GameCount(_panel);
			}
		}

		private bool ApplyInfo()
		{
			_modVersion = ModIo.Version;
			bool flag = false;
			bool useModIo = Settings.UseModIo;
			List<string> list = new List<string>();
			foreach (MapEntry item in _model.All)
			{
				if (!item.Slz)
				{
					long num = (useModIo ? ModIo.ModIdOf(item.PackBarcode) : 0);
					ModInfo modInfo = ((useModIo && num > 0) ? ModIo.InfoOf(num) : null);
					if (num != item.ModId || modInfo != item.Info)
					{
						item.ModId = num;
						item.Info = modInfo;
						flag = true;
					}
					string text = CardUrl(item);
					if (text != null)
					{
						list.Add(text);
					}
				}
			}
			if (flag)
			{
				_model.InfoChanged();
			}
			if (useModIo && list.Count > 0)
			{
				ModIo.WantLater(list);
			}
			return flag;
		}

		private static string CardUrl(MapEntry e)
		{
			if (e == null || e.Slz || !Settings.UseModIo)
			{
				return null;
			}
			if (e.Info != null)
			{
				if (e.Info.Explicit && !Settings.ShowMature)
				{
					return null;
				}
				return e.Info.CardPicture ?? e.ListingThumb;
			}
			return e.ListingThumb;
		}

		private static bool HiddenMature(MapEntry e)
		{
			if (e != null && e.Info != null && e.Info.Explicit && !Settings.ShowMature)
			{
				return Settings.UseModIo;
			}
			return false;
		}

		private void Build()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_054b: Unknown result type (might be due to invalid IL or missing references)
			Stopwatch stopwatch = Stopwatch.StartNew();
			try
			{
				_style = new UiStyle();
				ReadStyle(_style);
				Paint.Style = _style;
				Paint.Layer = _style.Layer;
				UiStyle style = _style;
				_root = new GameObject("MMP_Menu");
				_root.layer = style.Layer;
				_root.transform.SetParent(_page, false);
				RectTransform obj = _root.AddComponent<RectTransform>();
				obj.anchorMin = new Vector2(0.5f, 0.5f);
				obj.anchorMax = new Vector2(0.5f, 0.5f);
				obj.sizeDelta = Vector2.zero;
				obj.anchoredPosition = Vector2.zero;
				_root.transform.localPosition = new Vector3(0f, 0f, -20f);
				_group = _root.AddComponent<CanvasGroup>();
				Transform transform = _root.transform;
				HudRect panel = MapLayout.Panel;
				for (int num = 3; num >= 1; num--)
				{
					float num2 = 24f * (float)num / 3f;
					Paint.Pic(transform, "Shadow" + num, new Vector2(panel.X + 7.2000003f, panel.Y - 12f), new Vector2(panel.W + num2, panel.H + num2), (Texture)(object)Bank.Get("panel"), new Color(0f, 0f, 0f, 0.1f + 0.07f * (float)(3 - num)));
				}
				Paint.Pic(transform, "Panel", panel, "panel", Theme.Panel);
				Paint.Pic(transform, "TitleBar", MapLayout.TitleBar, "titlebar", Theme.TitleBar);
				Paint.Pic(transform, "Sidebar", MapLayout.Sidebar, "sidebar", Theme.Sidebar);
				((Graphic)Paint.Solid(transform, "AccentLine", new Vector2(0f, MapLayout.TitleBar.Bottom), new Vector2(panel.W - 2f, 2f), Theme.A(Theme.Accent, 0.9f))).raycastTarget = false;
				UiKit.Catcher(transform, "Catcher", Paint.V(panel), Paint.S(panel), 6f, style);
				Paint.Icon(transform, "TitleIcon", MapLayout.TitleIcon, "map", Theme.Accent);
				Paint.Text(transform, "Title", "MAP MENU", MapLayout.TitleText, 26f, Theme.Text, (TextAlignmentOptions)513, bold: true).characterSpacing = 2f;
				_subTitle = Paint.Text(transform, "SubTitle", "", MapLayout.SubTitle, 12.5f, Theme.Text2, (TextAlignmentOptions)513);
				Paint.Rounded(transform, "StatusBg", MapLayout.Status, 17f, Theme.Input);
				HudRect status = MapLayout.Status;
				_statusDot = Paint.Pic(transform, "StatusDot", new HudRect(status.Left + 20f, status.Y, 10f, 10f), "dot", Theme.Muted);
				_statusText = Paint.Text(transform, "StatusText", "", new HudRect(status.X + 12f, status.Y, status.W - 52f, status.H), 13.5f, Theme.Text2, (TextAlignmentOptions)513);
				Paint.TextBtn(transform, "Classic", MapLayout.Classic, 10f, "CLASSIC", 16f, Theme.Button, Theme.ButtonHover, Theme.ButtonPress, Theme.Text2, OnClassic, out var text);
				Paint.Icon(((Component)Paint.Btn(transform, "Close", MapLayout.Close, 10f, Theme.Danger, Theme.DangerHover, Theme.DangerHover, OnClose, out var _)).transform, "X", new HudRect(0f, 0f, 20f, 20f), "close", Theme.Text);
				BuildSidebar(transform);
				_gridView = ((Component)Paint.Node(transform, "GridView", Vector2.zero, Vector2.zero)).gameObject;
				BuildGrid(_gridView.transform);
				_detailView = ((Component)Paint.Node(transform, "DetailView", Vector2.zero, Vector2.zero)).gameObject;
				BuildDetails(_detailView.transform);
				_detailView.SetActive(false);
				_keyboard = new Keyboard(transform, new Vector2(0f, -410f), style, OnChar, OnBackspace, OnSpace, OnClear);
				_root.transform.SetAsLastSibling();
				float num3 = 430f;
				try
				{
					RectTransform component = ((Component)_page).GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null)
					{
						Rect rect = component.rect;
						if (((Rect)(ref rect)).height > 100f)
						{
							rect = component.rect;
							num3 = ((Rect)(ref rect)).height * 0.5f + 32f;
						}
					}
				}
				catch
				{
				}
				_newMenuPos = new Vector2(0f, num3);
				Button val = Paint.TextBtn(_page, "NewMenu", new HudRect(0f, num3, 280f, 50f), 25f, "NEW MAP MENU", 18f, Theme.AccentDeep, Theme.Accent, Theme.ButtonPress, Theme.Text, OnNewMenu, out text, "map");
				_newMenu = ((Component)val).gameObject;
				_built = true;
				float num4 = Unit();
				stopwatch.Stop();
				Log.Info("Map menu built in " + stopwatch.Elapsed.TotalMilliseconds.ToString("0") + " ms" + (((Component)_page).gameObject.activeInHierarchy ? "" : " (ahead of time, menu closed)") + " (layer " + style.Layer + ", font " + ((Object)(object)style.Font != (Object)null) + ", 1 page unit = " + (num4 * 1000f).ToString("0.###") + " mm, NEW MAP MENU button at y=" + num3.ToString("0") + ", page \"" + ((Object)((Component)_page).gameObject).name + "\" with " + _page.childCount + " parts).");
			}
			catch (Exception e)
			{
				_broken = true;
				Log.Error("Building the map menu failed: the game's menu stays", e);
				try
				{
					if ((Object)(object)_root != (Object)null)
					{
						Object.Destroy((Object)(object)_root);
					}
				}
				catch
				{
				}
				try
				{
					if ((Object)(object)_newMenu != (Object)null)
					{
						Object.Destroy((Object)(object)_newMenu);
					}
				}
				catch
				{
				}
				_root = null;
				_newMenu = null;
				ShowGameParts();
			}
		}

		private void BuildSidebar(Transform r)
		{
			//IL_0015: 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_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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_0180: 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_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: 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_02c0: Unknown result type (might be due to invalid IL or missing references)
			Paint.Text(r, "SideTitle", "LIBRARY", MapLayout.SideTitle, 13f, Theme.Muted, (TextAlignmentOptions)513, bold: true).characterSpacing = 9f;
			for (int i = 0; i < MapModel.Cats.Length; i++)
			{
				_cats.Add(MakeCat(r, i, MapModel.Cats[i]));
			}
			Paint.Solid(r, "Separator", Paint.V(MapLayout.Separator), Paint.S(MapLayout.Separator), Theme.Outline);
			Paint.TextBtn(r, "Random", MapLayout.Random, 10f, "SURPRISE ME", 15f, Theme.Button, Theme.ButtonHover, Theme.ButtonPress, Theme.Text, OnRandom, out var _, "dice");
			Paint.Text(r, "NowLabel", "YOU ARE IN", MapLayout.NowLabel, 11.5f, Theme.Muted, (TextAlignmentOptions)513, bold: true).characterSpacing = 6f;
			HudRect nowPic = MapLayout.NowPic;
			RawImage graphic;
			Transform transform = ((Component)Paint.Btn(r, "NowPic", nowPic, 8f, Theme.Clear, Theme.Accent, Theme.AccentHover, OnNow, out graphic)).transform;
			HudRect r2 = new HudRect(0f, 0f, nowPic.W, nowPic.H);
			Paint.Solid(transform, "NowBg", Vector2.zero, Paint.S(r2), Theme.PhotoBg);
			_nowArt = Paint.Pic(transform, "NowArt", r2, "mapart", Theme.Muted);
			_nowArtText = Paint.Text(transform, "NowArtText", "", new HudRect(0f, 0f, r2.W - 16f, r2.H - 10f), 15f, new Color(1f, 1f, 1f, 0.92f), (TextAlignmentOptions)514, bold: true, wrap: true);
			_nowPic = Paint.Pic(transform, "NowPhoto", r2, null, Color.white);
			((Behaviour)_nowPic).enabled = false;
			Paint.Caps(transform, "Now", r2, 8f, Theme.Sidebar);
			graphic.texture = (Texture)(object)OutlineTex(nowPic.W, nowPic.H);
			((Component)graphic).transform.SetAsLastSibling();
			_nowTitle = Paint.Text(r, "NowTitle", "", MapLayout.NowTitle, 15f, Theme.Text, (TextAlignmentOptions)513, bold: true);
			_nowSub = Paint.Text(r, "NowSub", "", MapLayout.NowSub, 12f, Theme.Text2, (TextAlignmentOptions)513);
			_tip = Paint.Text(r, "Tip", "", MapLayout.Tip, 12f, Theme.Muted, (TextAlignmentOptions)257, bold: false, wrap: true);
		}

		private CatSlot MakeCat(Transform r, int i, MapCat cat)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			CatSlot c = new CatSlot
			{
				Cat = cat
			};
			HudRect r2 = new HudRect(-375f, MapLayout.CatY(i), 214f, 40f);
			c.Btn = Paint.Btn(r, "Cat" + i, r2, 9f, Theme.Clear, Theme.RowHover, Theme.AccentSoft, delegate
			{
				OnCat(c);
			}, out var _);
			c.Go = ((Component)c.Btn).gameObject;
			Transform transform = c.Go.transform;
			c.Bar = Paint.Rounded(transform, "Bar", MapLayout.CatBar, 2f, Theme.Accent);
			c.Icon = Paint.Icon(transform, "Icon", MapLayout.CatIcon, MapModel.CatIcon(cat), Theme.Text2);
			float num = -65f;
			float num2 = MapLayout.CatCount.Left - 6f;
			c.Label = Paint.Text(transform, "Label", MapModel.CatLabel(cat), new HudRect((num + num2) / 2f, 0f, num2 - num, 40f), 15.5f, Theme.Text2, (TextAlignmentOptions)513);
			c.CountBg = Paint.Rounded(transform, "CountBg", MapLayout.CatCount, 11f, Theme.Pill);
			c.Count = Paint.Text(transform, "Count", "", MapLayout.CatCount, 11.5f, Theme.Text2, (TextAlignmentOptions)514, bold: true);
			return c;
		}

		private void BuildGrid(Transform g)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_00c3: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			RawImage graphic;
			Button val = Paint.Btn(g, "Search", MapLayout.Search, 12f, Theme.Input, Theme.InputHover, Theme.Input, OnSearchBox, out graphic);
			HudRect search = MapLayout.Search;
			_searchFrame = Paint.Pic(((Component)val).transform, "SearchFrame", new HudRect(0f, 0f, search.W, search.H), null, Theme.Outline);
			_searchFrame.texture = (Texture)(object)OutlineTex(search.W, search.H);
			Paint.Icon(((Component)val).transform, "SearchIcon", new HudRect((0f - search.W) / 2f + 22f, 0f, 18f, 18f), "search", Theme.Muted);
			_searchText = Paint.Text(((Component)val).transform, "SearchText", "", new HudRect(14f, 0f, search.W - 60f, search.H), 15f, Theme.Muted, (TextAlignmentOptions)513);
			Paint.TextBtn(g, "Sort", MapLayout.Sort, 12f, "SORT: A - Z", 14f, Theme.Button, Theme.ButtonHover, Theme.ButtonPress, Theme.Text2, OnSort, out _sortText, "list");
			_prev = IconBtn(g, "Prev", MapLayout.Prev, "chevron_left", OnPrev);
			_pageText = Paint.Text(g, "Page", "1 / 1", MapLayout.PageText, 17f, Theme.Text, (TextAlignmentOptions)514, bold: true);
			_next = IconBtn(g, "Next", MapLayout.Next, "chevron_right", OnNext);
			for (int i = 0; i < 9; i++)
			{
				_cards.Add(MakeCard(g, i));
			}
			_emptyText = Paint.Text(g, "Empty", "", new HudRect(MapLayout.GridX, 40f, MapLayout.GridW - 40f, 40f), 24f, Theme.Text2, (TextAlignmentOptions)514, bold: true);
			_emptyHint = Paint.Text(g, "EmptyHint", "", new HudRect(MapLayout.GridX, 4f, MapLayout.GridW - 40f, 30f), 15f, Theme.Muted, (TextAlignmentOptions)514);
		}

		private static Texture2D OutlineTex(float w, float h)
		{
			string key = w + "x" + h;
			if (Outlines.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = Bank.ToTexture(Shapes.RoundRectOutline((int)(w * 2f), (int)(h * 2f), 24f, 3f, Rgba.White));
			Outlines[key] = value;
			return value;
		}

		private Button IconBtn(Transform parent, string name, HudRect r, string icon, Action onClick)
		{
			//IL_0008: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			RawImage graphic;
			Button obj = Paint.Btn(parent, name, r, 10f, Theme.Button, Theme.ButtonHover, Theme.ButtonPress, onClick, out graphic);
			Paint.Icon(((Component)obj).transform, "Icon", new HudRect(0f, 0f, r.H * 0.42f, r.H * 0.42f), icon, Theme.Text);
			return obj;
		}

		private CardSlot MakeCard(Transform g, int i)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			CardSlot c = new CardSlot
			{
				Index = i
			};
			int col = i % 3;
			int row = i / 3;
			float cardW = MapLayout.CardW;
			float cardH = MapLayout.CardH;
			UiStyle style = _style;
			c.Go = new GameObject("MMP_Card" + i);
			c.Go.layer = style.Layer;
			c.Go.transform.SetParent(g, false);
			RectTransform obj = c.Go.AddComponent<RectTransform>();
			obj.sizeDelta = new Vector2(cardW, cardH);
			obj.anchoredPosition = new Vector2(MapLayout.CardX(col), MapLayout.CardY(row));
			c.Go.AddComponent<CanvasRenderer>();
			c.Group = c.Go.AddComponent<CanvasGroup>();
			GameObject val = new GameObject("Collider")
			{
				layer = style.Layer
			};
			val.transform.SetParent(c.Go.transform, false);
			BoxCollider obj2 = val.AddComponent<BoxCollider>();
			obj2.size = new Vector3(cardW + 6f, cardH + 6f, 1f);
			((Collider)obj2).isTrigger = true;
			c.Visual = (Transform)(object)Paint.Node(c.Go.transform, "Visual", Vector2.zero, new Vector2(cardW, cardH));
			Transform visual = c.Visual;
			c.Bg = Paint.Pic(visual, "Card", new HudRect(0f, 0f, cardW, cardH), "card", Theme.Card);
			((Graphic)c.Bg).raycastTarget = true;
			HudRect cardPhoto = MapLayout.CardPhoto;
			Paint.Solid(visual, "PhotoBg", Paint.V(cardPhoto), Paint.S(cardPhoto), Theme.PhotoBg);
			c.Art = Paint.Pic(visual, "Art", cardPhoto, "mapart", Theme.Muted);
			c.ArtText = Paint.Text(visual, "ArtText", "", new HudRect(cardPhoto.X, cardPhoto.Y + 4f, cardPhoto.W - 28f, cardPhoto.H - 30f), 19f, new Color(1f, 1f, 1f, 0.93f), (TextAlignmentOptions)514, bold: true, wrap: true);
			c.ArtText.characterSpacing = 3f;
			c.Photo = Paint.Pic(visual, "Photo", cardPhoto, null, Color.white);
			((Behaviour)c.Photo).enabled = false;
			c.Shimmer = Paint.Pic(visual, "Shimmer", cardPhoto, "shimmer", Color.white);
			((Component)c.Shimmer).gameObject.SetActive(false);
			c.Shade = Paint.Pic(visual, "Shade", MapLayout.CardShade, "shade", Color.white);
			c.Caps = Paint.Caps(visual, "Photo", cardPhoto, 8f, Theme.Card);
			c.DlIcon = Paint.Icon(visual, "DlIcon", MapLayout.CardDlIcon, "download", Theme.Text);
			c.DlText = Paint.Text(visual, "DlText", "", MapLayout.CardDlText, 12.5f, Theme.Text, (TextAlignmentOptions)513, bold: true);
			c.RateIcon = Paint.Icon(visual, "RateIcon", MapLayout.CardRateIcon, "star", Theme.Gold);
			c.RateText = Paint.Text(visual, "RateText", "", MapLayout.CardRateText, 12.5f, Theme.Text, (TextAlignmentOptions)516, bold: true);
			c.BadgeBg = Paint.Rounded(visual, "BadgeBg", MapLayout.CardBadge, 10f, Theme.Slz);
			c.BadgeText = Paint.Text(visual, "BadgeText", "", MapLayout.CardBadge, 10.5f, Theme.TitleBar, (TextAlignmentOptions)514, bold: true);
			c.BadgeText.characterSpacing = 3f;
			HudRect cardFav = MapLayout.CardFav;
			c.FavBack = Paint.Pic(visual, "FavBack", new HudRect(cardFav.X, cardFav.Y, cardFav.W + 8f, cardFav.H + 8f), "dot", new Color(0f, 0f, 0f, 0.55f));
			c.FavIcon = Paint.Icon(visual, "FavIcon", cardFav, "star", Theme.Gold);
			c.Title = Paint.Text(visual, "Title", "", MapLayout.CardTitle, 16.5f, Theme.Text, (TextAlignmentOptions)513, bold: true);
			c.Sub = Paint.Text(visual, "Sub", "", MapLayout.CardSub, 12.5f, Theme.Text2, (TextAlignmentOptions)513);
			c.Outline = Paint.Pic(visual, "Outline", new HudRect(0f, 0f, cardW, cardH), "card_outline", Theme.Clear);
			c.Btn = c.Go.AddComponent<Button>();
			((UnityEvent)c.Btn.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				OnCard(c);
			}));
			((Selectable)c.Btn).transition = (Transition)0;
			((Selectable)c.Btn).targetGraphic = (Graphic)(object)c.Bg;
			c.Go.AddComponent<ButtonHoverClick>();
			c.Go.SetActive(false);
			return c;
		}

		private void BuildDetails(Transform d)
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Unknown result type (might be due to invalid IL or missing references)
			Paint.TextBtn(d, "Back", MapLayout.Back, 12f, "BACK", 15f, Theme.Button, Theme.ButtonHover, Theme.ButtonPress, Theme.Text, OnBack, out var _, "chevron_left");
			_crumb = Paint.Text(d, "Crumb", "", MapLayout.Crumb, 13f, Theme.Muted, (TextAlignmentOptions)513, bold: true);
			_crumb.characterSpacing = 3f;
			_mapPrev = IconBtn(d, "MapPrev", MapLayout.Prev, "chevron_left", OnMapPrev);
			_mapPos = Paint.Text(d, "MapPos", "", MapLayout.PageText, 15f, Theme.Text, (TextAlignmentOptions)514, bold: true);
			_mapNext = IconBtn(d, "MapNext", MapLayout.Next, "chevron_right", OnMapNext);
			HudRect bigPic = MapLayout.BigPic;
			Paint.Pic(d, "BigFrame", new HudRect(bigPic.X, bigPic.Y, bigPic.W + 8f, bigPic.H + 8f), "bigframe", Theme.Input);
			_bigArt = Paint.Pic(d, "BigArt", bigPic, "mapart", Theme.Muted);
			_bigArtText = Paint.Text(d, "BigArtText", "", new HudRect(bigPic.X, bigPic.Y, bigPic.W - 80f, bigPic.H - 80f), 40f, new Color(1f, 1f, 1f, 0.93f), (TextAlignmentOptions)514, bold: true, wrap: true);
			_bigArtText.characterSpacing = 6f;
			_bigA = Paint.Pic(d, "BigA", bigPic, null, Color.white);
			((Behaviour)_bigA).enabled = false;
			_bigB = Paint.Pic(d, "BigB", bigPic, null, Color.white);
			((Behaviour)_bigB).enabled = false;
			_bigShimmer = Paint.Pic(d, "BigShimmer", bigPic, "shimmer", Color.white);
			((Component)_bigShimmer).gameObject.SetActive(false);
			_bigHidden = Paint.Text(d, "BigHidden", "", new HudRect(bigPic.X, bigPic.Y - 60f, bigPic.W - 60f, 30f), 15f, Theme.Text2, (TextAlignmentOptions)514);
			Paint.Caps(d, "Big", bigPic, 10f, Theme.Input);
			_galPrev = IconBtn(d, "GalPrev", MapLayout.GalPrev, "chevron_left", OnGalPrev);
			_galNext = IconBtn(d, "GalNext", MapLayout.GalNext, "chevron_right", OnGalNext);
			for (int i = 0; i < 12; i++)
			{
				RawImage val = Paint.Pic(d, "Dot" + i, new HudRect(0f, MapLayout.Dots.Y, 8f, 8f), "dot", Theme.Muted);
				((Component)val).gameObject.SetActive(false);
				_dots.Add(val);
			}
			_dTitle = Paint.Text(d, "DTitle", "", MapLayout.DTitle, 30f, Theme.Text, (TextAlignmentOptions)513, bold: true);
			_dInfo = Paint.Text(d, "DInfo", "", MapLayout.DInfo, 15f, Theme.Text2, (TextAlignmentOptions)513);
			HudRect dStats = MapLayout.DStats;
			float left = dStats.Left;
			_dlIcon = Paint.Icon(d, "DDlIcon", new HudRect(left + 9f, dStats.Y, 16f, 16f), "download", Theme.Accent);
			_dlText = Paint.Text(d, "DDlText", "", new HudRect(left + 139f, dStats.Y, 230f, dStats.H), 14.5f, Theme.Text, (TextAlignmentOptions)513);
			_rateIcon = Paint.Icon(d, "DRateIcon", new HudRect(left + 268f, dStats.Y, 16f, 16f), "star", Theme.Gold);
			_rateText = Paint.Text(d, "DRateText", "", new HudRect(left + 407f, dStats.Y, 250f, dStats.H), 14.5f, Theme.Text, (TextAlignmentOptions)513);
			_tagText = Paint.Text(d, "DTags", "", new HudRect(left + 620f, dStats.Y, 160f, dStats.H), 12.5f, Theme.Muted, (TextAlignmentOptions)516);
			_dSummary = Paint.Text(d, "DSummary", "", MapLayout.DSummary, 14.5f, Theme.Text2, (TextAlignmentOptions)257, bold: false, wrap: true);
			_play = Paint.TextBtn(d, "Play", MapLayout.Play, 14f, "PLAY", 24f, Theme.Play, Theme.PlayHover, Theme.PlayPress, Theme.TitleBar, OnPlay, out _playText, "play");
			_favBtn = Paint.TextBtn(d, "Fav", MapLayout.Fav, 14f, "FAVORITE", 15f, Theme.Button, Theme.ButtonHover, Theme.ButtonPress, Theme.Text2, OnFav, out _favText, "star");
			Transform val2 = ((Component)_favBtn).transform.Find("MMP_Icon");
			_favIconD = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<RawImage>() : null);
			_playedText = Paint.Text(d, "Played", "", MapLayout.Played, 12.5f, Theme.Muted, (TextAlignmentOptions)516, bold: false, wrap: true);
		}

		private void ReadStyle(UiStyle s)
		{
			s.Layer = 5;
			try
			{
				foreach (TMP_Text componentsInChild in ((Component)_page).GetComponentsInChildren<TMP_Text>(true))
				{
					if (!((Object)(object)componentsInChild == (Object)null) && !((Object)(object)componentsInChild.font == (Object)null))
					{
						s.Font = componentsInChild.font;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Log.Warn("Reading the menu's font failed (default font used): " + ex.Message);
			}
		}

		private float Unit()
		{
			//IL_0015: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			try
			{
				Vector3 val = _page.TransformPoint(new Vector3(1f, 0f, 0f)) - _page.TransformPoint(Vector3.zero);
				return ((Vector3)(ref val)).magnitude;
			}
			catch
			{
				return 0f;
			}
		}

		private void CheckScale()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			_scaleChecked = true;
			float num = Unit();
			if (!(num < 1E-07f) && !((Object)(object)_root == (Object)null))
			{
				float num2 = 0.0013f / num;
				if (!(num2 > 0.6f) || !(num2 < 1.6f))
				{
					_baseScale = Mathf.Clamp(num2, 0.25f, 4f);
					_root.transform.localScale = new Vector3(_baseScale, _baseScale, _baseScale);
					Log.Info("Levels page has another size (1 unit = " + (num * 1000f).ToString("0.###") + " mm): menu scaled x" + _baseScale.ToString("0.##") + ".");
				}
			}
		}

		private void ApplyMode(bool fromButton)
		{
			if (!_built)
			{
				return;
			}
			if (Settings.NewMenu)
			{
				HideGameParts();
				_root.SetActive(true);
				if ((Object)(object)_newMenu != (Object)null)
				{
					_newMenu.SetActive(false);
				}
				ApplyInfo();
				Render();
			}
			else
			{
				if (_keyboard != null)
				{
					_keyboard.Hide();
				}
				_root.SetActive(false);
				ShowGameParts();
				if ((Object)(object)_newMenu != (Object)null)
				{
					_newMenu.SetActive(true);
				}
				ModIo.Want(null, null);
			}
			if (fromButton)
			{
				Log.Info("Map menu " + (Settings.NewMenu ? "ON" : "OFF (classic menu)") + ".");
			}
		}

		private void HideGameParts()
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_page == (Object)null)
			{
				return;
			}
			for (int i = 0; i < _page.childCount; i++)
			{
				Transform child = _page.GetChild(i);
				if ((Object)(object)child == (Object)null || ((Object)(object)_root != (Object)null && (Object)(object)child == (Object)(object)_root.transform) || ((Object)(object)_newMenu != (Object)null && (Object)(object)child == (Object)(object)_newMenu.transform))
				{
					continue;
				}
				Hidden hidden = null;
				foreach (Hidden item in _hidden)
				{
					if ((Object)(object)item.T == (Object)(object)child)
					{
						hidden = item;
						break;
					}
				}
				if (hidden == null)
				{
					hidden = new Hidden
					{
						T = child,
						Scale = child.localScale
					};
					_hidden.Add(hidden);
				}
				Vector3 localScale = child.localScale;
				if (localScale.x != 0.0001f || localScale.y != 0.0001f || localScale.z != 0.0001f)
				{
					child.localScale = new Vector3(0.0001f, 0.0001f, 0.0001f);
				}
			}
		}

		private void ShowGameParts()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			foreach (Hidden item in _hidden)
			{
				try
				{
					if ((Object)(object)item.T != (Object)null)
					{
						item.T.localScale = item.Scale;
					}
				}
				catch
				{
				}
			}
			_hidden.Clear();
		}

		private static string N(long n)
		{
			return n.ToString("N0", CultureInfo.InvariantCulture);
		}

		private static string Esc(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				return s.Replace("<", "(");
			}
			return "";
		}

		private void Render()
		{
			if (!_built || !Settings.NewMenu)
			{
				return;
			}
			int num = 0;
			foreach (MapEntry item in _model.All)
			{
				if (!item.Slz)
				{
					num++;
				}
			}
			Paint.SetText(_subTitle, N(_model.AllCount) + " maps  ·  " + N(num) + " from mods");
			RenderStatus();
			RenderSidebar();
			bool flag = _detail != null;
			Paint.Show(_gridView, !flag);
			Paint.Show(_detailView, flag);
			if (flag)
			{
				RenderDetails();
			}
			else
			{
				RenderGrid();
			}
			RenderNow();
			Wants();
		}

		private string StatusWords(bool plain)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			foreach (MapEntry item in _model.All)
			{
				if (!item.Slz)
				{
					num++;
					if (item.ModId > 0)
					{
						num2++;
					}
					else if (item.ModId == 0L)
					{
						num3++;
					}
				}
			}
			switch (ModIo.Status)
			{
			case ModIo.State.Disabled:
				return "mod.io pictures are off (BoneMenu)";
			case ModIo.State.NoLogin:
				if (!plain)
				{
					return "Log in to mod.io in BONELAB for map pictures";
				}
				return "Not logged in to mod.io: log in to mod.io in BONELAB's mod menu for map pictures + info.";
			case ModIo.State.LoginExpired:
				if (!plain)
				{
					return "mod.io login expired - log in again in BONELAB";
				}
				return "The mod.io login has expired: log in to mod.io again in BONELAB.";
			case ModIo.State.Offline:
				return "No connection to mod.io (saved pictures only)";
			case ModIo.State.Ready:
				if (num != 0)
				{
					return "mod.io: " + num2 + " of " + num + " mod maps found";
				}
				return "mod.io: no mod maps installed";
			default:
				return "mod.io: getting map info" + ((num > 0) ? (" (" + num2 + " of " + num + ")") : "") + "...";
			}
		}

		private void RenderStatus()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (_flash != null && realtimeSinceStartup < _flashUntil)
			{
				Paint.SetText(_statusText, "<color=#FFC73D>" + Esc(_flash) + "</color>");
				Paint.SetColor((Graphic)(object)_statusDot, Theme.Gold);
				return;
			}
			_flash = null;
			Paint.SetText(_statusText, StatusWords(plain: false));
			Color c;
			switch (ModIo.Status)
			{
			case ModIo.State.Ready:
				c = Theme.Green;
				break;
			case ModIo.State.NoLogin:
				c = Theme.Gold;
				break;
			case ModIo.State.LoginExpired:
			case ModIo.State.Offline:
				c = Theme.DangerHover;
				break;
			case ModIo.State.Disabled:
				c = Theme.Muted;
				break;
			default:
				c = Theme.Accent;
				break;
			}
			Paint.SetColor((Graphic)(