Decompiled source of UpgradeLib v1.0.2

UpgradeLib.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Esper.SkillWeb;
using Esper.SkillWeb.Graph;
using Esper.SkillWeb.UI;
using Esper.SkillWeb.UI.UGUI;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Notifications;
using Progress.Shop.Skill.UI;
using Research;
using SaveSystem;
using Store;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("UpgradeLib")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("UpgradeLib")]
[assembly: AssemblyTitle("UpgradeLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace UpgradeLib;

[BepInPlugin("com.upgradelib.roadsideresearch", "UpgradeLib", "1.0.2")]
public class Plugin : BasePlugin
{
	public const string GUID = "com.upgradelib.roadsideresearch";

	public const string Name = "UpgradeLib";

	public const string Version = "1.0.2";

	internal static ManualLogSource Log;

	public override void Load()
	{
		//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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BasePlugin)this).Log;
		Harmony val = new Harmony("com.upgradelib.roadsideresearch");
		val.PatchAll(typeof(CreateUIPatch));
		val.PatchAll(typeof(CreateUIPostfixPatch));
		val.PatchAll(typeof(SkillNodeUpgradePatch));
		val.PatchAll(typeof(GameLoadPatch));
		val.PatchAll(typeof(WebUnloadPatch));
		val.PatchAll(typeof(SkillButtonPatch));
		val.PatchAll(typeof(SkillIconPatch));
		val.PatchAll(typeof(SkillCostLabelPatch));
		val.PatchAll(typeof(SkillNameLabelPatch));
		val.PatchAll(typeof(SkillDescriptionLabelPatch));
		val.PatchAll(typeof(SkillUnlockPopulatorPatch));
		val.PatchAll(typeof(SkillEnablerPatch));
		val.PatchAll(typeof(SkillNodeLevelTextPatch));
		val.PatchAll(typeof(SkillNodeUpdateStatePatch));
		((BasePlugin)this).AddComponent<UpgradePanelComponent>();
		Log.LogInfo((object)"UpgradeLib v2 loaded! Tree-based upgrades will appear in skill webs.");
	}
}
[HarmonyPatch]
internal static class CreateUIPatch
{
	[HarmonyPatch(typeof(WebViewUGUI), "CreateUI")]
	[HarmonyPrefix]
	public static void BeforeCreateUI(WebViewUGUI __instance)
	{
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		bool flag = default(bool);
		try
		{
			if (((RuntimeWebViewer)__instance).web == null)
			{
				return;
			}
			string webName = ((RuntimeWebViewer)__instance).webName;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: CreateUI called for web '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(webName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
				}
				log.LogInfo(val);
			}
			CostType? costTypeFromWebName = GetCostTypeFromWebName(webName);
			if (costTypeFromWebName.HasValue)
			{
				UpgradePanelComponent.SaveCostType(__instance, costTypeFromWebName.Value);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(36, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: CreateUI prefix failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
			}
		}
	}

	private static CostType? GetCostTypeFromWebName(string webName)
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Expected O, but got Unknown
		if (string.IsNullOrEmpty(webName))
		{
			return null;
		}
		string text = webName.ToLowerInvariant();
		if (text.Contains("economy") || text.Contains("shop") || text.Contains("store") || text.Contains("econ"))
		{
			return CostType.Money;
		}
		if (text.Contains("research") || text.Contains("alien") || text.Contains("tech"))
		{
			return CostType.Research;
		}
		ManualLogSource log = Plugin.Log;
		if (log != null)
		{
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Unknown web name '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(webName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', skipping injection");
			}
			log.LogInfo(val);
		}
		return null;
	}
}
[HarmonyPatch]
internal static class CreateUIPostfixPatch
{
	[HarmonyPatch(typeof(WebViewUGUI), "CreateUI")]
	[HarmonyPostfix]
	public static void AfterCreateUI(WebViewUGUI __instance)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		try
		{
			UpgradePanelComponent.CreateCustomNodeUI(__instance);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(37, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: CreateUI postfix failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}
	}
}
[HarmonyPatch]
internal static class SkillNodeUpgradePatch
{
	[HarmonyPatch(typeof(SkillNode), "TryUpgrade")]
	[HarmonyPrefix]
	public static bool CustomUpgrade(SkillNode __instance, ref bool __result)
	{
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Expected O, but got Unknown
		//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Expected O, but got Unknown
		//IL_037a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Expected O, but got Unknown
		if (((Node)__instance).id < 10000)
		{
			return true;
		}
		if (UpgradePanelComponent.IsDragging)
		{
			__result = false;
			return false;
		}
		bool flag = default(bool);
		try
		{
			UpgradeDefinition byNodeId = UpgradeAPI.GetByNodeId(((Node)__instance).id);
			if (byNodeId == null)
			{
				return true;
			}
			if (UpgradeAPI.IsPurchased(byNodeId.Id))
			{
				NotificationsManager.QueueNotification("Already purchased!", false, 3f);
				__result = false;
				return false;
			}
			if (!UpgradeAPI.CanPurchase(byNodeId.Id))
			{
				string parentId = UpgradeAPI.GetParentId(byNodeId.Id);
				string text = ((parentId != null) ? UpgradeAPI.GetById(parentId) : null)?.Name ?? "prerequisite";
				NotificationsManager.QueueNotification("Requires: " + text, false, 3f);
				__result = false;
				return false;
			}
			float cost = byNodeId.Cost;
			if (byNodeId.CostType == CostType.Money)
			{
				float currentCurrency = CurrencyManager.CurrentCurrency;
				if (currentCurrency < cost)
				{
					NotificationsManager.QueueNotification($"Need ${cost:F0} — you have ${currentCurrency:F0}", false, 3f);
					__result = false;
					return false;
				}
				CurrencyManager.ChangeCurrency(0f - cost);
			}
			else
			{
				float currentResearch = ResearchManager.CurrentResearch;
				if (currentResearch < cost)
				{
					NotificationsManager.QueueNotification($"Need {cost:F0} research — you have {currentResearch:F0}", false, 3f);
					__result = false;
					return false;
				}
				ResearchManager.AddResearch(0f - cost);
			}
			UpgradeState.SetPurchased(byNodeId.Id);
			__instance.SetLevel(1, false);
			__instance.state = (State)3;
			SkillNodeUGUI val = default(SkillNodeUGUI);
			if ((Object)(object)WebViewUGUI.Active != (Object)null && WebViewUGUI.Active.loadedSkillNodes.TryGetValue(((Node)__instance).id, ref val))
			{
				val.ReloadUI();
			}
			if (byNodeId.Children != null)
			{
				SkillNodeUGUI val2 = default(SkillNodeUGUI);
				foreach (UpgradeDefinition child in byNodeId.Children)
				{
					int nodeIdForUpgrade = UpgradeAPI.GetNodeIdForUpgrade(child.Id);
					if (nodeIdForUpgrade < 0)
					{
						continue;
					}
					Web web = __instance.web;
					if (web != null && web.skillNodes.ContainsKey(nodeIdForUpgrade))
					{
						web.skillNodes[nodeIdForUpgrade].state = (State)1;
						if ((Object)(object)WebViewUGUI.Active != (Object)null && WebViewUGUI.Active.loadedSkillNodes.TryGetValue(nodeIdForUpgrade, ref val2))
						{
							val2.ReloadUI();
						}
					}
				}
			}
			UpgradePersistence.Save();
			ManualLogSource log;
			try
			{
				byNodeId.OnPurchased?.Invoke();
			}
			catch (Exception ex)
			{
				log = Plugin.Log;
				if (log != null)
				{
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("UpgradeLib: OnPurchased callback error: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val3);
				}
			}
			string text2 = ((byNodeId.CostType == CostType.Money) ? $"${cost:F0}" : $"{cost:F0} research");
			NotificationsManager.QueueNotification(byNodeId.Name + " purchased! (-" + text2 + ")", false, 4f);
			log = Plugin.Log;
			if (log != null)
			{
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(29, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("UpgradeLib: Purchased '");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(byNodeId.Id);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("' for ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(text2);
				}
				log.LogInfo(val4);
			}
			__result = true;
			return false;
		}
		catch (Exception ex2)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("UpgradeLib: Purchase failed: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<Exception>(ex2);
				}
				log.LogError(val5);
			}
			__result = false;
			return false;
		}
	}
}
[HarmonyPatch]
internal static class GameLoadPatch
{
	[HarmonyPatch(typeof(CurrencyManager), "Spawned")]
	[HarmonyPostfix]
	public static void OnCurrencyManagerSpawned()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		try
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"UpgradeLib: CurrencyManager spawned, loading saved upgrades...");
			}
			UpgradePersistence.Load();
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(37, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Failed to load on spawn: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log2.LogError(val);
			}
		}
	}
}
[HarmonyPatch]
internal static class WebUnloadPatch
{
	[HarmonyPatch(typeof(WebViewUGUI), "Unload")]
	[HarmonyPrefix]
	public static void BeforeUnload(WebViewUGUI __instance)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		try
		{
			UpgradePanelComponent.OnWebUnloaded(__instance);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Unload cleanup error: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
	}
}
[HarmonyPatch]
internal static class SkillButtonPatch
{
	[HarmonyPatch(typeof(SkillButton), "HandleNewData")]
	[HarmonyPrefix]
	public static bool Prefix(SkillNode newData)
	{
		if (newData == null || ((Node)newData).id < 10000)
		{
			return true;
		}
		return false;
	}
}
[HarmonyPatch]
internal static class SkillIconPatch
{
	[HarmonyPatch(typeof(SkillIcon), "HandleNewData")]
	[HarmonyPrefix]
	public static bool Prefix(SkillIcon __instance, SkillNode newData)
	{
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Expected O, but got Unknown
		//IL_0025: 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)
		if (newData == null || ((Node)newData).id < 10000)
		{
			return true;
		}
		try
		{
			Skill skill = newData.skill;
			if ((Object)(object)skill != (Object)null)
			{
				SkillIcon icon = skill.GetIcon(newData.state, true);
				Image val = ((Component)__instance).GetComponent<Image>();
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)__instance).GetComponentInChildren<Image>();
				}
				if ((Object)(object)val != (Object)null)
				{
					if ((Object)(object)icon.icon != (Object)null)
					{
						val.sprite = icon.icon;
					}
					((Graphic)val).color = icon.color;
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: SkillIcon patch error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}
		return false;
	}
}
[HarmonyPatch]
internal static class SkillCostLabelPatch
{
	[HarmonyPatch(typeof(SkillCostLabel), "HandleNewData")]
	[HarmonyPrefix]
	public static bool Prefix(SkillCostLabel __instance, SkillNode newData)
	{
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Expected O, but got Unknown
		if (newData == null || ((Node)newData).id < 10000)
		{
			return true;
		}
		try
		{
			UpgradeDefinition byNodeId = UpgradeAPI.GetByNodeId(((Node)newData).id);
			if (byNodeId == null)
			{
				return false;
			}
			string text = ((!UpgradeAPI.IsPurchased(byNodeId.Id)) ? ((byNodeId.CostType == CostType.Money) ? $"${byNodeId.Cost:F0}" : $"{byNodeId.Cost:F0} research") : "Owned");
			TMP_Text val = ((Component)__instance).GetComponent<TMP_Text>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance).GetComponentInChildren<TMP_Text>();
			}
			if ((Object)(object)val != (Object)null)
			{
				val.text = text;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: SkillCostLabel patch error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}
		return false;
	}
}
[HarmonyPatch]
internal static class SkillNameLabelPatch
{
	[HarmonyPatch(typeof(SkillNameLabel), "HandleNewData")]
	[HarmonyPrefix]
	public static bool Prefix(SkillNameLabel __instance, SkillNode newData)
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		if (newData == null || ((Node)newData).id < 10000)
		{
			return true;
		}
		try
		{
			UpgradeDefinition byNodeId = UpgradeAPI.GetByNodeId(((Node)newData).id);
			if (byNodeId == null)
			{
				return false;
			}
			TMP_Text val = ((Component)__instance).GetComponent<TMP_Text>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance).GetComponentInChildren<TMP_Text>();
			}
			if ((Object)(object)val != (Object)null)
			{
				val.text = byNodeId.Name;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: SkillNameLabel patch error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}
		return false;
	}
}
[HarmonyPatch]
internal static class SkillDescriptionLabelPatch
{
	[HarmonyPatch(typeof(SkillDescriptionLabel), "HandleNewData")]
	[HarmonyPrefix]
	public static bool Prefix(SkillDescriptionLabel __instance, SkillNode newData)
	{
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Expected O, but got Unknown
		if (newData == null || ((Node)newData).id < 10000)
		{
			return true;
		}
		try
		{
			UpgradeDefinition byNodeId = UpgradeAPI.GetByNodeId(((Node)newData).id);
			if (byNodeId == null)
			{
				return false;
			}
			string text;
			if (UpgradeAPI.IsPurchased(byNodeId.Id))
			{
				text = byNodeId.Description + "\n\nPurchased";
			}
			else if (!UpgradeAPI.CanPurchase(byNodeId.Id))
			{
				string parentId = UpgradeAPI.GetParentId(byNodeId.Id);
				text = string.Concat(str2: ((parentId != null) ? UpgradeAPI.GetById(parentId) : null)?.Name ?? "prerequisite", str0: byNodeId.Description, str1: "\n\nRequires: ");
			}
			else
			{
				text = byNodeId.Description;
			}
			TMP_Text val = ((Component)__instance).GetComponent<TMP_Text>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance).GetComponentInChildren<TMP_Text>();
			}
			if ((Object)(object)val != (Object)null)
			{
				val.text = text;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(47, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: SkillDescriptionLabel patch error: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}
		return false;
	}
}
[HarmonyPatch]
internal static class SkillUnlockPopulatorPatch
{
	[HarmonyPatch(typeof(SkillUnlockPopulator), "HandleNewData")]
	[HarmonyPrefix]
	public static bool Prefix(SkillUnlockPopulator __instance, SkillNode newData)
	{
		if (newData == null || ((Node)newData).id < 10000)
		{
			return true;
		}
		try
		{
			Traverse.Create((object)__instance).Method("ClearList", Array.Empty<object>()).GetValue();
		}
		catch
		{
		}
		return false;
	}
}
[HarmonyPatch]
internal static class SkillEnablerPatch
{
	[HarmonyPatch(typeof(SkillEnabler), "HandleNewData")]
	[HarmonyPrefix]
	public static bool Prefix(SkillEnabler __instance, SkillNode newData)
	{
		if (newData == null || ((Node)newData).id < 10000)
		{
			return true;
		}
		try
		{
			GameObject value = Traverse.Create((object)__instance).Field("_target").GetValue<GameObject>();
			if ((Object)(object)value != (Object)null)
			{
				value.SetActive(false);
			}
		}
		catch
		{
		}
		return false;
	}
}
[HarmonyPatch]
internal static class SkillNodeUpdateStatePatch
{
	[HarmonyPatch(typeof(SkillNode), "UpdateState", new Type[] { })]
	[HarmonyPrefix]
	public static bool SkipUpdateState(SkillNode __instance)
	{
		if (((Node)__instance).id >= 10000)
		{
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(SkillNode), "UpdateState", new Type[] { typeof(bool) })]
	[HarmonyPrefix]
	public static bool SkipUpdateStateBool(SkillNode __instance)
	{
		if (((Node)__instance).id >= 10000)
		{
			return false;
		}
		return true;
	}
}
[HarmonyPatch]
internal static class SkillNodeLevelTextPatch
{
	[HarmonyPatch(typeof(SkillNodeUGUI), "Refresh")]
	[HarmonyPostfix]
	public static void AfterRefresh(SkillNodeUGUI __instance)
	{
		FixCustomNode(__instance);
	}

	[HarmonyPatch(typeof(SkillNodeUGUI), "ReloadUI")]
	[HarmonyPostfix]
	public static void AfterReloadUI(SkillNodeUGUI __instance)
	{
		FixCustomNode(__instance);
	}

	private static void FixCustomNode(SkillNodeUGUI instance)
	{
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Invalid comparison between Unknown and I4
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Invalid comparison between Unknown and I4
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: 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_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		SkillNode skillNode = instance.skillNode;
		if (skillNode == null || ((Node)skillNode).id < 10000)
		{
			return;
		}
		UpgradeDefinition byNodeId = UpgradeAPI.GetByNodeId(((Node)skillNode).id);
		if (byNodeId == null)
		{
			return;
		}
		if (UpgradeState.IsPurchased(byNodeId.Id))
		{
			skillNode.state = (State)3;
		}
		else if (UpgradeAPI.CanPurchase(byNodeId.Id))
		{
			skillNode.state = (State)1;
		}
		else
		{
			skillNode.state = (State)0;
		}
		Skill skill = skillNode.skill;
		if ((Object)(object)skill != (Object)null && (Object)(object)instance.iconImage != (Object)null)
		{
			SkillIcon icon = skill.GetIcon(skillNode.state, true);
			if ((Object)(object)icon.icon != (Object)null)
			{
				instance.iconImage.sprite = icon.icon;
			}
			((Graphic)instance.iconImage).color = icon.color;
			if ((int)skillNode.state == 1)
			{
				((Graphic)instance.iconImage).CrossFadeColor(Color.black, 0f, true, true);
			}
		}
		State state = skillNode.state;
		Color val = (Color)(((int)state == 0) ? Color.black : (((int)state != 1) ? new Color(1f, 0.55f, 0f, 1f) : Color.white));
		Color val2 = val;
		Button componentInChildren = ((Component)instance).GetComponentInChildren<Button>();
		if ((Object)(object)componentInChildren != (Object)null)
		{
			ColorBlock colors = ((Selectable)componentInChildren).colors;
			((ColorBlock)(ref colors)).normalColor = val2;
			((ColorBlock)(ref colors)).highlightedColor = val2;
			((ColorBlock)(ref colors)).selectedColor = val2;
			((ColorBlock)(ref colors)).pressedColor = val2;
			((ColorBlock)(ref colors)).disabledColor = val2;
			((Selectable)componentInChildren).colors = colors;
		}
		if (!((Object)(object)instance.levelText == (Object)null))
		{
			if (UpgradeState.IsPurchased(byNodeId.Id))
			{
				((TMP_Text)instance.levelText).text = "";
				return;
			}
			((TMP_Text)instance.levelText).text = ((byNodeId.CostType == CostType.Money) ? $"${byNodeId.Cost:F0}" : $"{byNodeId.Cost:F0}");
		}
	}
}
internal static class SkillNodeFactory
{
	internal const int BaseNodeId = 10000;

	private static Sprite _defaultSprite;

	private static Sprite GetDefaultSprite()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_defaultSprite != (Object)null)
		{
			return _defaultSprite;
		}
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color[] array = (Color[])(object)new Color[4096];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = Color.white;
		}
		val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
		val.Apply();
		((Object)val).hideFlags = (HideFlags)61;
		_defaultSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
		((Object)_defaultSprite).hideFlags = (HideFlags)61;
		return _defaultSprite;
	}

	internal static SkillNode CreateNode(UpgradeDefinition def, int index, Vector2 position)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Expected O, but got Unknown
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Expected O, but got Unknown
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Expected O, but got Unknown
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Expected O, but got Unknown
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		Skill val = ScriptableObject.CreateInstance<Skill>();
		val.skillName = def.Name;
		val.maxLevel = 1;
		val.levelRequirement = 0;
		val.size = (Size)1;
		((Object)val).hideFlags = (HideFlags)61;
		bool flag = (Object)(object)def.Icon != (Object)null;
		Sprite defaultSprite = GetDefaultSprite();
		Sprite icon = def.LockedIcon ?? UpgradePanelComponent.VanillaLockSprite ?? defaultSprite;
		Color color = (Color)(((??)def.LockedColor) ?? Color.white);
		Sprite icon2 = def.Icon ?? defaultSprite;
		Color color2 = (Color)(((??)def.UnlockedColor) ?? (flag ? Color.white : new Color(0.9f, 0.85f, 0.5f)));
		Color color3 = (Color)(((??)def.PurchasedColor) ?? (flag ? Color.white : new Color(0.3f, 0.6f, 1f)));
		val.lockedIcon = new SkillIcon
		{
			icon = icon,
			color = color
		};
		val.unlockedIcon = new SkillIcon
		{
			icon = icon2,
			color = color2
		};
		val.obtainedIcon = new SkillIcon
		{
			icon = icon2,
			color = color3
		};
		val.maxedIcon = new SkillIcon
		{
			icon = icon2,
			color = color3
		};
		DefaultSkillDataset val2 = ScriptableObject.CreateInstance<DefaultSkillDataset>();
		val2.description = def.Description;
		val2.skillType = (SkillType)0;
		((Object)val2).hideFlags = (HideFlags)61;
		val.dataset = (SkillDataset)(object)val2;
		int num = 10000 + index;
		List<Connection> val3 = new List<Connection>();
		return new SkillNode(num, val, position, val3);
	}
}
public static class UpgradeAPI
{
	private static readonly Dictionary<string, UpgradeDefinition> _allNodes = new Dictionary<string, UpgradeDefinition>();

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

	private static readonly List<UpgradeDefinition> _roots = new List<UpgradeDefinition>();

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

	internal static readonly Dictionary<int, string> NodeIdToUpgradeId = new Dictionary<int, string>();

	private static int _nextNodeIndex = 0;

	public static void RegisterTree(UpgradeDefinition root)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Expected O, but got Unknown
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		bool flag = default(bool);
		if (root == null || string.IsNullOrEmpty(root.Id))
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)"UpgradeLib: Cannot register null/empty tree");
			}
		}
		else if (_allNodes.ContainsKey(root.Id))
		{
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(48, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Node '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(root.Id);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' already registered, skipping");
				}
				log2.LogWarning(val);
			}
		}
		else if (string.IsNullOrWhiteSpace(root.Title))
		{
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(108, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: Tree root '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(root.Id);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' must have a Title. Set root.Title or use RegisterInTree to add to an existing tree.");
				}
				log2.LogError(val2);
			}
		}
		else if (_treesByTitle.ContainsKey(root.Title))
		{
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(87, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: A tree with title '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(root.Title);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' already exists. Use RegisterInTree to add nodes to it.");
				}
				log2.LogWarning(val);
			}
		}
		else
		{
			_roots.Add(root);
			_treesByTitle[root.Title] = root;
			RegisterNode(root, null);
			if (UpgradeState.IsLoaded)
			{
				FireCallbacksRecursive(root);
			}
		}
	}

	public static void RegisterInTree(string treeTitle, UpgradeDefinition node)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Expected O, but got Unknown
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Expected O, but got Unknown
		if (node == null || string.IsNullOrEmpty(node.Id))
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)"UpgradeLib: Cannot add null/empty node to tree");
			}
			return;
		}
		if (string.IsNullOrWhiteSpace(treeTitle))
		{
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)"UpgradeLib: treeTitle cannot be empty");
			}
			return;
		}
		bool flag = default(bool);
		ManualLogSource log3;
		if (_allNodes.ContainsKey(node.Id))
		{
			log3 = Plugin.Log;
			if (log3 != null)
			{
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(48, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Node '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(node.Id);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' already registered, skipping");
				}
				log3.LogWarning(val);
			}
			return;
		}
		if (!_treesByTitle.TryGetValue(treeTitle, out var value))
		{
			log3 = Plugin.Log;
			if (log3 != null)
			{
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(77, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: No tree with title '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(treeTitle);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' found. Register it first with RegisterTree.");
				}
				log3.LogWarning(val);
			}
			return;
		}
		value.Children.Add(node);
		RegisterNode(node, value.Id);
		if (UpgradeState.IsLoaded)
		{
			FireCallbacksRecursive(node);
		}
		log3 = Plugin.Log;
		if (log3 != null)
		{
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(36, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: Added node '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(node.Id);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' to tree '");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(treeTitle);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
			}
			log3.LogInfo(val2);
		}
	}

	private static void RegisterNode(UpgradeDefinition node, string parentId)
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Expected O, but got Unknown
		int num = 10000 + _nextNodeIndex;
		_nextNodeIndex++;
		_allNodes[node.Id] = node;
		NodeIdToUpgradeId[num] = node.Id;
		if (parentId != null)
		{
			_parentMap[node.Id] = parentId;
		}
		ManualLogSource log = Plugin.Log;
		if (log != null)
		{
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Registered node '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(node.Id);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (nodeId=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", parent=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(parentId ?? "root");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
			}
			log.LogInfo(val);
		}
		if (node.Children == null)
		{
			return;
		}
		foreach (UpgradeDefinition child in node.Children)
		{
			if (child != null && !string.IsNullOrEmpty(child.Id))
			{
				child.CostType = node.CostType;
				if (child.Category == "General" && node.Category != "General")
				{
					child.Category = node.Category;
				}
				if ((Object)(object)child.Icon == (Object)null && (Object)(object)node.Icon != (Object)null)
				{
					child.Icon = node.Icon;
				}
				if ((Object)(object)child.LockedIcon == (Object)null && (Object)(object)node.LockedIcon != (Object)null)
				{
					child.LockedIcon = node.LockedIcon;
				}
				if (!child.LockedColor.HasValue && node.LockedColor.HasValue)
				{
					child.LockedColor = node.LockedColor;
				}
				if (!child.UnlockedColor.HasValue && node.UnlockedColor.HasValue)
				{
					child.UnlockedColor = node.UnlockedColor;
				}
				if (!child.PurchasedColor.HasValue && node.PurchasedColor.HasValue)
				{
					child.PurchasedColor = node.PurchasedColor;
				}
				if (string.IsNullOrEmpty(child.VanillaIconMatch) && !string.IsNullOrEmpty(node.VanillaIconMatch))
				{
					child.VanillaIconMatch = node.VanillaIconMatch;
				}
				RegisterNode(child, node.Id);
			}
		}
	}

	private static void FireCallbacksRecursive(UpgradeDefinition node)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		if (UpgradeState.IsPurchased(node.Id))
		{
			try
			{
				node.OnPurchased?.Invoke();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(47, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: OnPurchased callback error for '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(node.Id);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val);
				}
			}
		}
		if (node.Children == null)
		{
			return;
		}
		foreach (UpgradeDefinition child in node.Children)
		{
			FireCallbacksRecursive(child);
		}
	}

	public static bool IsPurchased(string id)
	{
		return UpgradeState.IsPurchased(id);
	}

	public static bool CanPurchase(string id)
	{
		if (UpgradeState.IsPurchased(id))
		{
			return false;
		}
		if (!_allNodes.ContainsKey(id))
		{
			return false;
		}
		if (!_parentMap.TryGetValue(id, out var value))
		{
			return true;
		}
		return UpgradeState.IsPurchased(value);
	}

	public static string GetParentId(string id)
	{
		if (!_parentMap.TryGetValue(id, out var value))
		{
			return null;
		}
		return value;
	}

	public static bool IsRoot(string id)
	{
		if (!_parentMap.ContainsKey(id))
		{
			return _allNodes.ContainsKey(id);
		}
		return false;
	}

	public static IReadOnlyList<UpgradeDefinition> GetRootsByType(CostType costType)
	{
		return _roots.Where((UpgradeDefinition r) => r.CostType == costType).ToList();
	}

	public static IReadOnlyList<UpgradeDefinition> GetAllNodes()
	{
		return _allNodes.Values.ToList();
	}

	internal static UpgradeDefinition GetById(string id)
	{
		if (!_allNodes.TryGetValue(id, out var value))
		{
			return null;
		}
		return value;
	}

	internal static UpgradeDefinition GetByNodeId(int nodeId)
	{
		if (NodeIdToUpgradeId.TryGetValue(nodeId, out var value))
		{
			return GetById(value);
		}
		return null;
	}

	internal static int GetNodeIdForUpgrade(string upgradeId)
	{
		foreach (KeyValuePair<int, string> item in NodeIdToUpgradeId)
		{
			if (item.Value == upgradeId)
			{
				return item.Key;
			}
		}
		return -1;
	}

	internal static bool IsCustomNode(int nodeId)
	{
		return nodeId >= 10000;
	}
}
public enum CostType
{
	Money,
	Research
}
public class UpgradeDefinition
{
	public string Id;

	public string Name;

	public string Description;

	public CostType CostType;

	public float Cost;

	public Action OnPurchased;

	public string Category = "General";

	public string Title;

	public List<UpgradeDefinition> Children = new List<UpgradeDefinition>();

	public Sprite Icon;

	public Sprite LockedIcon;

	public Color? LockedColor;

	public Color? UnlockedColor;

	public Color? PurchasedColor;

	public string VanillaIconMatch;
}
public class UpgradePanelComponent : MonoBehaviour
{
	private static readonly HashSet<int> _injectedWebInstances = new HashSet<int>();

	private static readonly Dictionary<int, CostType> _pendingCostType = new Dictionary<int, CostType>();

	private static readonly Dictionary<int, float> _maxScroll = new Dictionary<int, float>();

	private static readonly Dictionary<int, float> _originalContentY = new Dictionary<int, float>();

	private static float _originalHovercardOffsetMinX = float.NaN;

	private static float _originalDescOffsetMinX = float.NaN;

	private const float GridSpacingX = 250f;

	private const float GridSpacingY = 200f;

	private const float GapBelowVanilla = 300f;

	private const float TreeGap = 400f;

	private const float ScrollWheelSpeed = 40f;

	private const float DragThreshold = 8f;

	private const float ScreenTopY = 1.85f;

	private const float ScreenBottomY = 1.17f;

	private static float _currentScroll;

	private static bool _dragActive;

	private static bool _dragPending;

	private static Vector2 _dragStartMouse;

	private static float _dragStartScroll;

	private static int _trackedInstanceId;

	private static Scrollbar _scrollbar;

	private static bool _suppressScrollbarCallback;

	private static bool _scrollbarDragActive;

	private const float ScrollbarWidth = 6f;

	internal static bool IsDragging => _dragActive;

	internal static Sprite VanillaLockSprite { get; private set; }

	internal static void SaveCostType(WebViewUGUI webView, CostType costType)
	{
		_pendingCostType[((Object)webView).GetInstanceID()] = costType;
	}

	internal static bool HasCustomNodes(int instanceId)
	{
		return _injectedWebInstances.Contains(instanceId);
	}

	private void Update()
	{
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		WebViewUGUI active = WebViewUGUI.Active;
		if ((Object)(object)active == (Object)null)
		{
			_trackedInstanceId = 0;
			if ((Object)(object)_scrollbar != (Object)null && ((Component)_scrollbar).gameObject.activeSelf)
			{
				((Component)_scrollbar).gameObject.SetActive(false);
			}
			return;
		}
		int instanceID = ((Object)active).GetInstanceID();
		if (!_injectedWebInstances.Contains(instanceID))
		{
			return;
		}
		if (_trackedInstanceId != instanceID)
		{
			_trackedInstanceId = instanceID;
			_currentScroll = 0f;
			_scrollbarDragActive = false;
			_dragActive = false;
			_dragPending = false;
		}
		if (!_maxScroll.TryGetValue(instanceID, out var value) || value <= 0f)
		{
			if ((Object)(object)_scrollbar != (Object)null && ((Component)_scrollbar).gameObject.activeSelf)
			{
				((Component)_scrollbar).gameObject.SetActive(false);
			}
			return;
		}
		if ((Object)(object)_scrollbar != (Object)null && !((Component)_scrollbar).gameObject.activeSelf)
		{
			((Component)_scrollbar).gameObject.SetActive(true);
		}
		float y = Input.mouseScrollDelta.y;
		if (y != 0f)
		{
			_currentScroll = Mathf.Clamp(_currentScroll - y * 40f, 0f, value);
			ApplyScroll(active, instanceID);
			SyncScrollbarFromScroll(instanceID);
		}
		if (Input.GetMouseButtonDown(0) && IsPointerOverScrollbar())
		{
			_scrollbarDragActive = true;
			ApplyScrollbarDrag(active, instanceID, value);
		}
		if (_scrollbarDragActive && Input.GetMouseButton(0))
		{
			ApplyScrollbarDrag(active, instanceID, value);
		}
		if (Input.GetMouseButtonDown(0) && !IsPointerOverScrollbar() && !_scrollbarDragActive)
		{
			_dragStartMouse = Vector2.op_Implicit(Input.mousePosition);
			_dragStartScroll = _currentScroll;
			_dragPending = true;
			_dragActive = false;
		}
		if (_dragPending && Input.GetMouseButton(0))
		{
			Vector2 val = Vector2.op_Implicit(Input.mousePosition) - _dragStartMouse;
			if (!_dragActive && ((Vector2)(ref val)).magnitude > 8f)
			{
				_dragActive = true;
			}
			if (_dragActive)
			{
				_currentScroll = Mathf.Clamp(_dragStartScroll + val.y, 0f, value);
				ApplyScroll(active, instanceID);
				SyncScrollbarFromScroll(instanceID);
			}
		}
		if (Input.GetMouseButtonUp(0))
		{
			_scrollbarDragActive = false;
			_dragPending = false;
			_dragActive = false;
		}
	}

	private static void ApplyScroll(WebViewUGUI webView, int instanceId)
	{
		//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_003f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)webView.content == (Object)null) && _originalContentY.TryGetValue(instanceId, out var value))
		{
			Vector2 anchoredPosition = webView.content.anchoredPosition;
			anchoredPosition.y = value + _currentScroll;
			webView.content.anchoredPosition = anchoredPosition;
			CullNodesOutsideBounds(webView);
		}
	}

	private static void CullNodesOutsideBounds(WebViewUGUI webView)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		Enumerator<int, SkillNodeUGUI> enumerator = webView.loadedSkillNodes.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<int, SkillNodeUGUI> current = enumerator.Current;
			try
			{
				SkillNodeUGUI value = current.Value;
				if (!((Object)(object)value == (Object)null))
				{
					float y = ((Component)value).transform.position.y;
					bool active = y >= 1.17f && y <= 1.85f;
					((Component)value).gameObject.SetActive(active);
				}
			}
			catch
			{
			}
		}
		if (webView.loadedConnections != null)
		{
			Enumerator<Connection, ConnectionUGUI> enumerator2 = webView.loadedConnections.GetEnumerator();
			while (enumerator2.MoveNext())
			{
				KeyValuePair<Connection, ConnectionUGUI> current2 = enumerator2.Current;
				try
				{
					ConnectionUGUI value2 = current2.Value;
					if (!((Object)(object)value2 == (Object)null))
					{
						bool active2 = true;
						SkillNodeUGUI output = value2.Output;
						SkillNodeUGUI input = value2.Input;
						if ((Object)(object)output != (Object)null && !((Component)output).gameObject.activeSelf)
						{
							active2 = false;
						}
						if ((Object)(object)input != (Object)null && !((Component)input).gameObject.activeSelf)
						{
							active2 = false;
						}
						((Component)value2).gameObject.SetActive(active2);
					}
				}
				catch
				{
				}
			}
		}
		if ((Object)(object)webView.content != (Object)null)
		{
			for (int i = 0; i < ((Transform)webView.content).childCount; i++)
			{
				try
				{
					Transform child = ((Transform)webView.content).GetChild(i);
					if (((Object)child).name == "ShopWebTitles" || ((Object)child).name == "ResearchWebTitles")
					{
						for (int j = 0; j < child.childCount; j++)
						{
							Transform child2 = child.GetChild(j);
							float y2 = child2.position.y;
							bool active3 = y2 >= 1.17f && y2 <= 1.85f;
							((Component)child2).gameObject.SetActive(active3);
						}
					}
				}
				catch
				{
				}
			}
		}
		if (!((Object)(object)webView.graphContent != (Object)null))
		{
			return;
		}
		for (int k = 0; k < ((Transform)webView.graphContent).childCount; k++)
		{
			try
			{
				Transform child3 = ((Transform)webView.graphContent).GetChild(k);
				if (((Object)child3).name == "UpgradeLibTitles")
				{
					for (int l = 0; l < child3.childCount; l++)
					{
						Transform child4 = child3.GetChild(l);
						float y3 = child4.position.y;
						bool active4 = y3 >= 1.17f && y3 <= 1.85f;
						((Component)child4).gameObject.SetActive(active4);
					}
				}
			}
			catch
			{
			}
		}
	}

	private static int GetSubtreeHeight(UpgradeDefinition node)
	{
		if (node.Children == null || node.Children.Count == 0)
		{
			return 1;
		}
		int num = 0;
		foreach (UpgradeDefinition child in node.Children)
		{
			num += GetSubtreeHeight(child);
		}
		return num;
	}

	private static void LayoutTree(UpgradeDefinition node, float leftX, float topY, Dictionary<string, Vector2> positions)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		int subtreeHeight = GetSubtreeHeight(node);
		float num = topY - (float)(subtreeHeight - 1) * 200f / 2f;
		positions[node.Id] = new Vector2(leftX, num);
		if (node.Children == null || node.Children.Count == 0)
		{
			return;
		}
		float num2 = topY;
		foreach (UpgradeDefinition child in node.Children)
		{
			int subtreeHeight2 = GetSubtreeHeight(child);
			LayoutTree(child, leftX + 250f, num2, positions);
			num2 -= (float)subtreeHeight2 * 200f;
		}
	}

	private static void DumpVanillaIcons(WebViewUGUI webView)
	{
		//IL_0134: 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_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Expected O, but got Unknown
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0330: Unknown result type (might be due to invalid IL or missing references)
		//IL_034f: Unknown result type (might be due to invalid IL or missing references)
		//IL_036e: Unknown result type (might be due to invalid IL or missing references)
		//IL_038d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Unknown result type (might be due to invalid IL or missing references)
		ManualLogSource log = Plugin.Log;
		if (log != null)
		{
			log.LogInfo((object)"=== UpgradeLib: Vanilla Skill Icon Dump ===");
		}
		Enumerator<int, SkillNodeUGUI> enumerator = webView.loadedSkillNodes.GetEnumerator();
		bool flag = default(bool);
		while (enumerator.MoveNext())
		{
			KeyValuePair<int, SkillNodeUGUI> current = enumerator.Current;
			try
			{
				SkillNodeUGUI value = current.Value;
				if ((Object)(object)value == (Object)null)
				{
					continue;
				}
				SkillNode skillNode = value.skillNode;
				if (skillNode == null || ((Node)skillNode).id >= 10000)
				{
					continue;
				}
				Skill skill = skillNode.skill;
				if ((Object)(object)skill == (Object)null)
				{
					continue;
				}
				string text = (((Object)(object)skill.lockedIcon.icon != (Object)null) ? ((Object)skill.lockedIcon.icon).name : "null");
				string text2 = (((Object)(object)skill.unlockedIcon.icon != (Object)null) ? ((Object)skill.unlockedIcon.icon).name : "null");
				string text3 = (((Object)(object)skill.obtainedIcon.icon != (Object)null) ? ((Object)skill.obtainedIcon.icon).name : "null");
				string text4 = (((Object)(object)skill.maxedIcon.icon != (Object)null) ? ((Object)skill.maxedIcon.icon).name : "null");
				Color color = skill.lockedIcon.color;
				Color color2 = skill.unlockedIcon.color;
				Color color3 = skill.obtainedIcon.color;
				Color color4 = skill.maxedIcon.color;
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(80, 23, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  Node ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((Node)skillNode).id);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" \"");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(skill.skillName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" state=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<State>(skillNode.state);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  locked=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color.r, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color.g, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color.b, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color.a, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  unlocked=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color2.r, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color2.g, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color2.b, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color2.a, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  obtained=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color3.r, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color3.g, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color3.b, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color3.a, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  maxed=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color4.r, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color4.g, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color4.b, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(color4.a, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
					}
					log2.LogInfo(val);
				}
			}
			catch
			{
			}
		}
		ManualLogSource log3 = Plugin.Log;
		if (log3 != null)
		{
			log3.LogInfo((object)"=== End Vanilla Skill Icon Dump ===");
		}
	}

	private static void ResolveVanillaIcons(WebViewUGUI webView, IReadOnlyList<UpgradeDefinition> roots)
	{
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Expected O, but got Unknown
		DumpVanillaIcons(webView);
		if ((Object)(object)VanillaLockSprite == (Object)null)
		{
			Enumerator<int, SkillNodeUGUI> enumerator = webView.loadedSkillNodes.GetEnumerator();
			bool flag = default(bool);
			while (enumerator.MoveNext())
			{
				KeyValuePair<int, SkillNodeUGUI> current = enumerator.Current;
				try
				{
					SkillNodeUGUI value = current.Value;
					if ((Object)(object)value == (Object)null)
					{
						continue;
					}
					SkillNode skillNode = value.skillNode;
					if (skillNode == null || ((Node)skillNode).id >= 10000)
					{
						continue;
					}
					Skill skill = skillNode.skill;
					if ((Object)(object)skill == (Object)null)
					{
						continue;
					}
					Sprite icon = skill.lockedIcon.icon;
					if (!((Object)(object)icon != (Object)null))
					{
						continue;
					}
					VanillaLockSprite = icon;
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Cached vanilla Lock sprite '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)icon).name);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
						}
						log.LogInfo(val);
					}
					break;
				}
				catch
				{
				}
			}
		}
		foreach (UpgradeDefinition root in roots)
		{
			ResolveIconsRecursive(webView, root);
		}
	}

	private static void ResolveIconsRecursive(WebViewUGUI webView, UpgradeDefinition node)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		if ((Object)(object)node.Icon == (Object)null && !string.IsNullOrEmpty(node.VanillaIconMatch))
		{
			Sprite val = FindVanillaIcon(webView, node.VanillaIconMatch);
			if ((Object)(object)val != (Object)null)
			{
				node.Icon = val;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(42, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: Matched vanilla icon '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)val).name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' for '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(node.Id);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
					}
					log.LogInfo(val2);
				}
			}
		}
		if (node.Children == null)
		{
			return;
		}
		foreach (UpgradeDefinition child in node.Children)
		{
			ResolveIconsRecursive(webView, child);
		}
	}

	private static Sprite FindVanillaIcon(WebViewUGUI webView, string searchTerm)
	{
		if (string.IsNullOrEmpty(searchTerm))
		{
			return null;
		}
		string value = searchTerm.ToLowerInvariant();
		Enumerator<int, SkillNodeUGUI> enumerator = webView.loadedSkillNodes.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<int, SkillNodeUGUI> current = enumerator.Current;
			try
			{
				SkillNodeUGUI value2 = current.Value;
				if ((Object)(object)value2 == (Object)null)
				{
					continue;
				}
				SkillNode skillNode = value2.skillNode;
				if (skillNode == null || ((Node)skillNode).id >= 10000)
				{
					continue;
				}
				Skill skill = skillNode.skill;
				if ((Object)(object)skill == (Object)null)
				{
					continue;
				}
				if (skill.skillName != null && skill.skillName.ToLowerInvariant().Contains(value))
				{
					Sprite val = skill.unlockedIcon.icon ?? skill.obtainedIcon.icon;
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				Sprite[] array = (Sprite[])(object)new Sprite[4]
				{
					skill.unlockedIcon.icon,
					skill.obtainedIcon.icon,
					skill.maxedIcon.icon,
					skill.lockedIcon.icon
				};
				foreach (Sprite val2 in array)
				{
					if ((Object)(object)val2 != (Object)null && ((Object)val2).name != null && ((Object)val2).name.ToLowerInvariant().Contains(value))
					{
						return val2;
					}
				}
			}
			catch
			{
			}
		}
		return null;
	}

	internal static void CreateCustomNodeUI(WebViewUGUI webView)
	{
		//IL_0335: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: Expected O, but got Unknown
		//IL_037f: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_040a: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b3: Expected O, but got Unknown
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05dc: Expected O, but got Unknown
		int instanceID = ((Object)webView).GetInstanceID();
		if (!_pendingCostType.TryGetValue(instanceID, out var value))
		{
			return;
		}
		_pendingCostType.Remove(instanceID);
		if (_injectedWebInstances.Contains(instanceID))
		{
			return;
		}
		Web web = ((RuntimeWebViewer)webView).web;
		if (web == null)
		{
			return;
		}
		IReadOnlyList<UpgradeDefinition> rootsByType = UpgradeAPI.GetRootsByType(value);
		if (rootsByType.Count == 0)
		{
			return;
		}
		ResolveVanillaIcons(webView, rootsByType);
		float num = float.MaxValue;
		float num2 = float.MaxValue;
		float num3 = float.MinValue;
		int num4 = 0;
		Enumerator<int, SkillNodeUGUI> enumerator = webView.loadedSkillNodes.GetEnumerator();
		while (enumerator.MoveNext())
		{
			SkillNodeUGUI value2 = enumerator.Current.Value;
			RectTransform val = value2.rectTransform ?? ((Component)value2).GetComponent<RectTransform>();
			if (!((Object)(object)val == (Object)null))
			{
				Vector2 anchoredPosition = val.anchoredPosition;
				if (anchoredPosition.y < num)
				{
					num = anchoredPosition.y;
				}
				if (anchoredPosition.x < num2)
				{
					num2 = anchoredPosition.x;
				}
				if (anchoredPosition.x > num3)
				{
					num3 = anchoredPosition.x;
				}
				num4++;
			}
		}
		if (num4 == 0)
		{
			return;
		}
		SkillNodeUGUI skillNodeSmallPrefab = webView.skillNodeSmallPrefab;
		if ((Object)(object)skillNodeSmallPrefab == (Object)null)
		{
			return;
		}
		if ((Object)(object)webView.content != (Object)null)
		{
			_originalContentY[instanceID] = webView.content.anchoredPosition.y;
		}
		float num5 = num - 300f;
		Dictionary<string, Vector2> dictionary = new Dictionary<string, Vector2>();
		Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
		float num6 = num5;
		for (int i = 0; i < rootsByType.Count; i++)
		{
			dictionary2[rootsByType[i].Id] = num6;
			LayoutTree(rootsByType[i], num2, num6, dictionary);
			int subtreeHeight = GetSubtreeHeight(rootsByType[i]);
			num6 -= (float)subtreeHeight * 200f + 400f;
		}
		float num7 = num5;
		int num8 = 0;
		Dictionary<string, SkillNode> dictionary3 = new Dictionary<string, SkillNode>();
		bool flag = default(bool);
		ManualLogSource log;
		foreach (KeyValuePair<string, Vector2> item in dictionary)
		{
			UpgradeDefinition byId = UpgradeAPI.GetById(item.Key);
			if (byId == null)
			{
				continue;
			}
			int globalIndex = GetGlobalIndex(byId.Id);
			if (globalIndex < 0)
			{
				continue;
			}
			Vector2 value3 = item.Value;
			SkillNode val2 = SkillNodeFactory.CreateNode(byId, globalIndex, value3);
			val2.web = web;
			if (UpgradeState.IsPurchased(byId.Id))
			{
				val2.SetLevel(1, false);
				val2.state = (State)3;
			}
			else if (UpgradeAPI.CanPurchase(byId.Id))
			{
				val2.state = (State)1;
			}
			else
			{
				val2.state = (State)0;
			}
			web.skillNodes[((Node)val2).id] = val2;
			dictionary3[byId.Id] = val2;
			try
			{
				GameObject val3 = Object.Instantiate<GameObject>(((Component)skillNodeSmallPrefab).gameObject, (Transform)(object)webView.graphContent);
				SkillNodeUGUI component = val3.GetComponent<SkillNodeUGUI>();
				if ((Object)(object)component != (Object)null)
				{
					component.SetSkill(val2, webView);
					RectTransform val4 = component.rectTransform ?? val3.GetComponent<RectTransform>();
					if ((Object)(object)val4 != (Object)null)
					{
						val4.anchoredPosition = value3;
						((Transform)val4).localPosition = new Vector3(((Transform)val4).localPosition.x, ((Transform)val4).localPosition.y, webView.SkillNodeZOffset);
					}
					webView.loadedSkillNodes[((Node)val2).id] = component;
				}
			}
			catch (Exception ex)
			{
				log = Plugin.Log;
				if (log != null)
				{
					BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(40, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("UpgradeLib: Failed to create UI for '");
						((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(byId.Name);
						((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val5);
				}
			}
			if (value3.y < num7)
			{
				num7 = value3.y;
			}
			num8++;
		}
		CreateTreeConnections(webView, rootsByType, dictionary3);
		if (num8 <= 0)
		{
			return;
		}
		_injectedWebInstances.Add(instanceID);
		CreateTreeTitles(webView, rootsByType, dictionary2, num2);
		float num9 = Mathf.Abs(num - num7) + 400f;
		float num10 = (((Object)(object)webView.content != (Object)null) ? ((Transform)webView.content).localScale.y : 1f);
		_maxScroll[instanceID] = num9 * num10;
		if ((Object)(object)webView.content != (Object)null && (Object)(object)((Transform)webView.content).parent != (Object)null)
		{
			GameObject gameObject = ((Component)((Transform)webView.content).parent).gameObject;
			RectMask2D component2 = gameObject.GetComponent<RectMask2D>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.Destroy((Object)(object)component2);
			}
			Mask component3 = gameObject.GetComponent<Mask>();
			if ((Object)(object)component3 != (Object)null)
			{
				Object.Destroy((Object)(object)component3);
			}
		}
		CreateScrollbar(webView, _maxScroll[instanceID]);
		log = Plugin.Log;
		if (log != null)
		{
			BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(71, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("UpgradeLib: WebView field check:");
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" content=");
				((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<bool>((Object)(object)webView.content != (Object)null);
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" bounds=");
				((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<bool>((Object)(object)webView.bounds != (Object)null);
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" canvas=");
				((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<bool>((Object)(object)webView.canvas != (Object)null);
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" graphContent=");
				((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<bool>((Object)(object)webView.graphContent != (Object)null);
			}
			log.LogInfo(val6);
		}
		if ((Object)(object)webView.bounds == (Object)null && (Object)(object)webView.content != (Object)null)
		{
			webView.bounds = webView.content;
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)"UpgradeLib: Fixed null bounds → content");
			}
		}
		if ((Object)(object)webView.canvas == (Object)null)
		{
			Canvas componentInParent = ((Component)webView).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				webView.canvas = componentInParent;
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"UpgradeLib: Fixed null canvas");
				}
			}
		}
		log = Plugin.Log;
		if (log != null)
		{
			BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(43, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("UpgradeLib: Injected ");
				((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<int>(num8);
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" tree nodes, scroll=");
				((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<float>(_maxScroll[instanceID], "F0");
				((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("px");
			}
			log.LogInfo(val6);
		}
		CullNodesOutsideBounds(webView);
	}

	private static void CreateTreeConnections(WebViewUGUI webView, IReadOnlyList<UpgradeDefinition> roots, Dictionary<string, SkillNode> createdNodes)
	{
		ConnectionUGUI templateConn = null;
		try
		{
			Enumerator<Connection, ConnectionUGUI> enumerator = webView.loadedConnections.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<Connection, ConnectionUGUI> current = enumerator.Current;
				if ((Object)(object)current.Value != (Object)null)
				{
					templateConn = current.Value;
					break;
				}
			}
		}
		catch
		{
		}
		foreach (UpgradeDefinition root in roots)
		{
			CreateConnectionsRecursive(webView, root, createdNodes, templateConn);
		}
	}

	private static void CreateConnectionsRecursive(WebViewUGUI webView, UpgradeDefinition node, Dictionary<string, SkillNode> createdNodes, ConnectionUGUI templateConn)
	{
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Expected O, but got Unknown
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		if (node.Children == null)
		{
			return;
		}
		bool flag = default(bool);
		foreach (UpgradeDefinition child in node.Children)
		{
			if (!createdNodes.TryGetValue(node.Id, out var value) || !createdNodes.TryGetValue(child.Id, out var value2))
			{
				continue;
			}
			try
			{
				Connection val = new Connection(((Node)value).id, ((Node)value2).id, 0, 0, 0);
				((Node)value).connections.Add(val);
				if ((Object)(object)templateConn != (Object)null)
				{
					ConnectionUGUI component = Object.Instantiate<GameObject>(((Component)templateConn).gameObject, (Transform)(object)webView.graphContent).GetComponent<ConnectionUGUI>();
					if ((Object)(object)component != (Object)null)
					{
						component.SetConnection(val, webView);
						webView.loadedConnections[val] = component;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(46, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("UpgradeLib: Failed to create connection ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(node.Id);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" -> ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(child.Id);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val2);
				}
			}
			CreateConnectionsRecursive(webView, child, createdNodes, templateConn);
		}
	}

	private static void CreateTreeTitles(WebViewUGUI webView, IReadOnlyList<UpgradeDefinition> roots, Dictionary<string, float> treeTopYs, float minX)
	{
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Expected O, but got Unknown
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Expected O, but got Unknown
		TMP_FontAsset val = null;
		Enumerator<int, SkillNodeUGUI> enumerator = webView.loadedSkillNodes.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<int, SkillNodeUGUI> current = enumerator.Current;
			try
			{
				SkillNodeUGUI value = current.Value;
				TMP_Text val2 = ((value != null) ? ((Component)value).GetComponentInChildren<TMP_Text>() : null);
				if ((Object)(object)((val2 != null) ? val2.font : null) != (Object)null)
				{
					val = val2.font;
					break;
				}
			}
			catch
			{
			}
		}
		GameObject val3 = new GameObject("UpgradeLibTitles");
		val3.transform.SetParent((Transform)(object)webView.graphContent, false);
		bool flag = default(bool);
		foreach (UpgradeDefinition root in roots)
		{
			if (string.IsNullOrEmpty(root.Title) || !treeTopYs.TryGetValue(root.Id, out var value2))
			{
				continue;
			}
			try
			{
				GameObject val4 = new GameObject("Title_" + root.Id);
				val4.transform.SetParent(val3.transform, false);
				TextMeshProUGUI val5 = val4.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val5).text = root.Title;
				((TMP_Text)val5).fontSize = 84f;
				((Graphic)val5).color = Color.white;
				((TMP_Text)val5).alignment = (TextAlignmentOptions)513;
				((TMP_Text)val5).overflowMode = (TextOverflowModes)0;
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)val5).font = val;
				}
				RectTransform component = val4.GetComponent<RectTransform>();
				component.anchoredPosition = new Vector2(minX, value2 + 140f);
				component.sizeDelta = new Vector2(800f, 60f);
				component.pivot = new Vector2(0f, 0.5f);
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(36, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("UpgradeLib: Created title '");
						((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(root.Title);
						((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("' at (");
						((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<float>(minX);
						((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<float>(value2 + 140f);
						((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(")");
					}
					log.LogInfo(val6);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					BepInExWarningLogInterpolatedStringHandler val7 = new BepInExWarningLogInterpolatedStringHandler(39, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("UpgradeLib: Failed to create title '");
						((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(root.Title);
						((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(ex.Message);
					}
					log.LogWarning(val7);
				}
			}
		}
	}

	internal static void OnWebUnloaded(WebViewUGUI webView)
	{
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		int instanceID = ((Object)webView).GetInstanceID();
		_injectedWebInstances.Remove(instanceID);
		_pendingCostType.Remove(instanceID);
		_maxScroll.Remove(instanceID);
		_originalContentY.Remove(instanceID);
		if ((Object)(object)webView.content != (Object)null && (Object)(object)((Transform)webView.content).parent != (Object)null)
		{
			try
			{
				Transform parent = ((Transform)webView.content).parent;
				for (int i = 0; i < parent.childCount; i++)
				{
					Transform child = parent.GetChild(i);
					RectTransform val = (RectTransform)(((object)((child is RectTransform) ? child : null)) ?? ((object)((Component)child).GetComponent<RectTransform>()));
					if (!((Object)(object)val == (Object)null))
					{
						if (((Object)child).name == "Hovercard" && !float.IsNaN(_originalHovercardOffsetMinX))
						{
							Vector2 offsetMin = val.offsetMin;
							val.offsetMin = new Vector2(_originalHovercardOffsetMinX, offsetMin.y);
						}
						else if (((Object)child).name == "Progress_Skill_Description" && !float.IsNaN(_originalDescOffsetMinX))
						{
							Vector2 offsetMin2 = val.offsetMin;
							val.offsetMin = new Vector2(_originalDescOffsetMinX, offsetMin2.y);
						}
					}
				}
			}
			catch
			{
			}
			_originalHovercardOffsetMinX = float.NaN;
			_originalDescOffsetMinX = float.NaN;
		}
		if ((Object)(object)_scrollbar != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)_scrollbar).gameObject);
			_scrollbar = null;
		}
		if (_trackedInstanceId == instanceID)
		{
			_trackedInstanceId = 0;
			_currentScroll = 0f;
			_scrollbarDragActive = false;
			_dragActive = false;
			_dragPending = false;
		}
	}

	private static void CreateScrollbar(WebViewUGUI webView, float maxScroll)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Expected O, but got Unknown
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_scrollbar != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)_scrollbar).gameObject);
			_scrollbar = null;
		}
		if (!((Object)(object)webView.content == (Object)null) && !((Object)(object)((Transform)webView.content).parent == (Object)null))
		{
			Transform parent = ((Transform)webView.content).parent;
			GameObject val = new GameObject("UpgradeLib_Scrollbar");
			val.transform.SetParent(parent, false);
			RectTransform scrollbarRT = val.GetComponent<RectTransform>() ?? val.AddComponent<RectTransform>();
			GameObject val2 = new GameObject("Background");
			val2.transform.SetParent(val.transform, false);
			((Graphic)val2.AddComponent<Image>()).color = new Color(0.1f, 0.1f, 0.1f, 0.6f);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			GameObject val3 = new GameObject("SlidingArea");
			val3.transform.SetParent(val.transform, false);
			RectTransform obj = val3.GetComponent<RectTransform>() ?? val3.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(0f, 10f);
			obj.offsetMax = new Vector2(0f, -10f);
			GameObject val4 = new GameObject("Handle");
			val4.transform.SetParent(val3.transform, false);
			((Graphic)val4.AddComponent<Image>()).color = new Color(0.7f, 0.7f, 0.7f, 0.8f);
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.sizeDelta = Vector2.zero;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			_scrollbar = val.AddComponent<Scrollbar>();
			_scrollbar.handleRect = component2;
			_scrollbar.direction = (Direction)3;
			_scrollbar.numberOfSteps = 0;
			_scrollbar.value = 0f;
			_scrollbar.size = CalculateScrollbarSize(maxScroll);
			((UnityEvent<float>)(object)_scrollbar.onValueChanged).AddListener(UnityAction<float>.op_Implicit((Action<float>)OnScrollbarValueChanged));
			PositionScrollbar(webView, scrollbarRT);
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"UpgradeLib: Scrollbar created");
			}
		}
	}

	private static void PositionScrollbar(WebViewUGUI webView, RectTransform scrollbarRT)
	{
		//IL_0082: 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_00ca: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Expected O, but got Unknown
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		Transform parent = ((Transform)webView.content).parent;
		RectTransform val = null;
		RectTransform val2 = null;
		for (int i = 0; i < parent.childCount; i++)
		{
			Transform child = parent.GetChild(i);
			if (((Object)child).name == "Hovercard")
			{
				val = (RectTransform)(((object)((child is RectTransform) ? child : null)) ?? ((object)((Component)child).GetComponent<RectTransform>()));
			}
			else if (((Object)child).name == "Progress_Skill_Description")
			{
				val2 = (RectTransform)(((object)((child is RectTransform) ? child : null)) ?? ((object)((Component)child).GetComponent<RectTransform>()));
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			Vector2 offsetMin = val.offsetMin;
			if (float.IsNaN(_originalHovercardOffsetMinX))
			{
				_originalHovercardOffsetMinX = offsetMin.x;
			}
			val.offsetMin = new Vector2(offsetMin.x + 6f, offsetMin.y);
		}
		if ((Object)(object)val2 != (Object)null)
		{
			Vector2 offsetMin2 = val2.offsetMin;
			if (float.IsNaN(_originalDescOffsetMinX))
			{
				_originalDescOffsetMinX = offsetMin2.x;
			}
			val2.offsetMin = new Vector2(offsetMin2.x + 6f, offsetMin2.y);
		}
		if ((Object)(object)val != (Object)null)
		{
			scrollbarRT.anchorMin = val.anchorMin;
			scrollbarRT.anchorMax = val.anchorMax;
			scrollbarRT.pivot = new Vector2(1f, 0.5f);
			scrollbarRT.sizeDelta = new Vector2(6f, val.sizeDelta.y);
			float x = val.anchoredPosition.x;
			Rect rect = val.rect;
			scrollbarRT.anchoredPosition = new Vector2(x - ((Rect)(ref rect)).width * val.pivot.x, val.anchoredPosition.y);
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(56, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("UpgradeLib: Scrollbar placed left of Hovercard (offset=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(scrollbarRT.anchoredPosition.x, "F1");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")");
				}
				log.LogInfo(val3);
			}
		}
		else
		{
			scrollbarRT.anchorMin = new Vector2(1f, 0f);
			scrollbarRT.anchorMax = new Vector2(1f, 1f);
			scrollbarRT.pivot = new Vector2(1f, 0.5f);
			scrollbarRT.sizeDelta = new Vector2(6f, 0f);
			scrollbarRT.anchoredPosition = new Vector2(-50f, 0f);
		}
	}

	private static float CalculateScrollbarSize(float maxScroll)
	{
		if (maxScroll <= 0f)
		{
			return 1f;
		}
		float num = 600f + maxScroll;
		return Mathf.Clamp(600f / num, 0.05f, 1f);
	}

	private static void SyncScrollbarFromScroll(int instanceId)
	{
		if (!((Object)(object)_scrollbar == (Object)null) && _maxScroll.TryGetValue(instanceId, out var value) && !(value <= 0f))
		{
			_suppressScrollbarCallback = true;
			_scrollbar.value = _currentScroll / value;
			_suppressScrollbarCallback = false;
		}
	}

	private static void OnScrollbarValueChanged(float value)
	{
		if (_suppressScrollbarCallback)
		{
			return;
		}
		WebViewUGUI active = WebViewUGUI.Active;
		if (!((Object)(object)active == (Object)null))
		{
			int instanceID = ((Object)active).GetInstanceID();
			if (_maxScroll.TryGetValue(instanceID, out var value2) && !(value2 <= 0f))
			{
				_currentScroll = value * value2;
				ApplyScroll(active, instanceID);
			}
		}
	}

	private static bool IsPointerOverScrollbar()
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_scrollbar == (Object)null)
		{
			return false;
		}
		RectTransform component = ((Component)_scrollbar).GetComponent<RectTransform>();
		if ((Object)(object)component == (Object)null)
		{
			return false;
		}
		Camera val = Camera.main;
		try
		{
			Canvas componentInParent = ((Component)_scrollbar).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.worldCamera != (Object)null)
			{
				val = componentInParent.worldCamera;
			}
		}
		catch
		{
		}
		return RectTransformUtility.RectangleContainsScreenPoint(component, Vector2.op_Implicit(Input.mousePosition), val);
	}

	private static void ApplyScrollbarDrag(WebViewUGUI webView, int instanceId, float maxScroll)
	{
		//IL_005c: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_scrollbar == (Object)null)
		{
			return;
		}
		RectTransform component = ((Component)_scrollbar).GetComponent<RectTransform>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		Camera val = Camera.main;
		try
		{
			Canvas componentInParent = ((Component)_scrollbar).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.worldCamera != (Object)null)
			{
				val = componentInParent.worldCamera;
			}
		}
		catch
		{
		}
		Vector2 val2 = default(Vector2);
		RectTransformUtility.ScreenPointToLocalPointInRectangle(component, Vector2.op_Implicit(Input.mousePosition), val, ref val2);
		Rect rect = component.rect;
		float height = ((Rect)(ref rect)).height;
		if (!(height <= 0f))
		{
			rect = component.rect;
			_currentScroll = Mathf.Clamp01((((Rect)(ref rect)).yMax - val2.y) / height) * maxScroll;
			ApplyScroll(webView, instanceId);
			SyncScrollbarFromScroll(instanceId);
		}
	}

	private static int GetGlobalIndex(string upgradeId)
	{
		int nodeIdForUpgrade = UpgradeAPI.GetNodeIdForUpgrade(upgradeId);
		if (nodeIdForUpgrade < 0)
		{
			return -1;
		}
		return nodeIdForUpgrade - 10000;
	}
}
internal class UpgradeSaveData
{
	public string GasStationName { get; set; }

	public int InGameDay { get; set; }

	public string SaveDateTime { get; set; }

	public List<string> Purchased { get; set; } = new List<string>();

}
internal static class UpgradePersistence
{
	private static string _configDir;

	private static string GetConfigDir()
	{
		if (_configDir == null)
		{
			_configDir = Path.Combine(Paths.ConfigPath, "UpgradeLib");
			if (!Directory.Exists(_configDir))
			{
				Directory.CreateDirectory(_configDir);
			}
		}
		return _configDir;
	}

	private static int GetSlotIndex()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		try
		{
			RootSaveData currentSaveData = SaveManager.CurrentSaveData;
			if (currentSaveData != null)
			{
				return currentSaveData.SlotIndex;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(44, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Could not read save slot index: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
		return 0;
	}

	private static string GetGasStationName()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		try
		{
			RootSaveData currentSaveData = SaveManager.CurrentSaveData;
			if (currentSaveData != null)
			{
				return currentSaveData.GasStationName ?? "";
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Could not read gas station name: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
		return "";
	}

	private static string GetSaveDateTime()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		try
		{
			RootSaveData currentSaveData = SaveManager.CurrentSaveData;
			if (currentSaveData != null)
			{
				DateTime dateTime = currentSaveData.DateTime;
				return ((DateTime)(ref dateTime)).ToString("O");
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UpgradeLib: Could not read save DateTime: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
		return "";
	}

	private static string GetFilePath()
	{
		int slotIndex = GetSlotIndex();
		return Path.Combine(GetConfigDir(), $"upgrades_slot_{slotIndex}.json");
	}

	internal static void Load()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Expected O, but got Unknown
		//IL_0373: Unknown result type (might be due to invalid IL or missing references)
		//IL_037a: Expected O, but got Unknown
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Expected O, but got Unknown
		string filePath = GetFilePath();
		ManualLogSource log = Plugin.Log;
		bool flag = default(bool);
		if (log != null)
		{
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag);
			if (flag)
			{