Decompiled source of StockAlert v1.1.8

StockAlert.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Eremite;
using Eremite.Buildings;
using Eremite.Buildings.UI;
using Eremite.Characters;
using Eremite.Characters.Villagers;
using Eremite.MapObjects;
using Eremite.MapObjects.UI;
using Eremite.Model;
using Eremite.Model.Configs;
using Eremite.Model.Meta;
using Eremite.Model.State;
using Eremite.Services;
using Eremite.Services.Monitors;
using Eremite.View.HUD;
using Eremite.View.HUD.Monitors;
using Eremite.View.HUD.TradeRoutes;
using Eremite.View.Menu.Pick;
using Eremite.View.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using StockAlert.Config;
using StockAlert.Core.Models;
using StockAlert.Game;
using StockAlert.Game.Discovery;
using StockAlert.Infrastructure.Bootstrap;
using StockAlert.Infrastructure.Plugin;
using StockAlert.UI.HUD;
using StockAlert.UI.Panels;
using StockAlert.UI.World;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("StockAlert")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+83db0f3a9403369fd5cb6d6c1db7f7fe789d8f9b")]
[assembly: AssemblyProduct("StockAlert")]
[assembly: AssemblyTitle("StockAlert")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace StockAlert
{
	public static class StockAlertInfo
	{
		public const string Id = "com.stockalert.ats";

		public const string Name = "StockAlert";

		public const string Version = "1.1.8";
	}
}
namespace StockAlert.UI.World
{
	internal static class BuilderStatusIndicators
	{
		private sealed class BuilderIndicator
		{
			private readonly GameObject _iconObject;

			private readonly SpriteRenderer _renderer;

			private readonly Transform _transform;

			public BuilderIndicator(Villager villager)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected O, but got Unknown
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Expected O, but got Unknown
				//IL_009d: 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)
				_iconObject = new GameObject("BuilderStatusIcon");
				_renderer = _iconObject.AddComponent<SpriteRenderer>();
				((Renderer)_renderer).material = new Material(Shader.Find("Sprites/Default"));
				((Renderer)_renderer).sortingLayerName = "UI";
				((Renderer)_renderer).sortingOrder = 5000;
				_iconObject.transform.SetParent(((Component)((Actor)villager).ActorView).transform, false);
				_iconObject.transform.localPosition = new Vector3(0f, 1.6f, 0f);
				_transform = _iconObject.transform;
				_transform.localScale = Vector3.one;
				_iconObject.AddComponent<BillboardToCamera>();
			}

			public void Show(Sprite sprite)
			{
				if (!((Object)(object)_renderer == (Object)null) && !((Object)(object)sprite == (Object)null))
				{
					if ((Object)(object)_renderer.sprite != (Object)(object)sprite)
					{
						_renderer.sprite = sprite;
					}
					UpdateScale(sprite);
					if (!((Renderer)_renderer).enabled)
					{
						((Renderer)_renderer).enabled = true;
					}
				}
			}

			private void UpdateScale(Sprite sprite)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_transform == (Object)null) && !((Object)(object)sprite == (Object)null))
				{
					Bounds bounds = sprite.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float num = Mathf.Max(size.x, size.y);
					if (num <= 0.001f)
					{
						_transform.localScale = Vector3.one;
						return;
					}
					float num2 = 0.5f / num;
					_transform.localScale = Vector3.one * num2;
				}
			}

			public void Destroy()
			{
				if ((Object)(object)_iconObject != (Object)null)
				{
					Object.Destroy((Object)(object)_iconObject);
				}
			}
		}

		private sealed class BillboardToCamera : MonoBehaviour
		{
			private void LateUpdate()
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				Camera main = Camera.main;
				if ((Object)(object)main != (Object)null)
				{
					((Component)this).transform.forward = ((Component)main).transform.forward;
				}
			}
		}

		private static readonly Dictionary<int, BuilderIndicator> ActiveIndicators = new Dictionary<int, BuilderIndicator>();

		private static PropertyInfo _piVillagersService;

		private static PropertyInfo _piVillagers;

		private static FieldInfo _fiActorBrain;

		private static FieldInfo _fiBrainStack;

		private static Sprite _idleSprite;

		private static Sprite _builderSprite;

		public static void Refresh()
		{
			if (!ConfigManager.ShowBuilderStatusIcons || !GameAPI.IsGameActive())
			{
				Clear();
			}
			else
			{
				if (!EnsureSprites())
				{
					return;
				}
				HashSet<int> seenVillagers = new HashSet<int>();
				foreach (Villager builderVillager in GetBuilderVillagers())
				{
					if ((Object)(object)builderVillager == (Object)null || !builderVillager.IsAlive())
					{
						continue;
					}
					ActorView actorView = ((Actor)builderVillager).ActorView;
					if ((Object)(object)actorView == (Object)null)
					{
						continue;
					}
					seenVillagers.Add(((Actor)builderVillager).Id);
					Sprite val = (IsVillagerIdle(builderVillager) ? _idleSprite : _builderSprite);
					if (!((Object)(object)val == (Object)null))
					{
						if (!ActiveIndicators.TryGetValue(((Actor)builderVillager).Id, out var value))
						{
							value = new BuilderIndicator(builderVillager);
							ActiveIndicators[((Actor)builderVillager).Id] = value;
						}
						value.Show(val);
					}
				}
				List<int> list = ActiveIndicators.Keys.Where((int id) => !seenVillagers.Contains(id)).ToList();
				foreach (int item in list)
				{
					ActiveIndicators[item].Destroy();
					ActiveIndicators.Remove(item);
				}
			}
		}

		public static void Clear()
		{
			foreach (BuilderIndicator value in ActiveIndicators.Values)
			{
				value.Destroy();
			}
			ActiveIndicators.Clear();
		}

		public static int GetIdleBuilderCount()
		{
			return GetBuilderVillagers().Count((Villager villager) => (Object)(object)villager != (Object)null && villager.IsAlive() && IsVillagerIdle(villager));
		}

		public static bool HasIdleBuilderOfRace(string raceName)
		{
			if (string.IsNullOrWhiteSpace(raceName))
			{
				return false;
			}
			return GetIdleBuilderRaceIds().Contains(raceName);
		}

		public static bool HasIdleBuilderOfRace(RaceModel race)
		{
			if ((Object)(object)race == (Object)null || string.IsNullOrWhiteSpace(((SO)race).Name))
			{
				return false;
			}
			return GetIdleBuilderRaceIds().Contains(((SO)race).Name);
		}

		public static Sprite GetIdleBuilderSprite()
		{
			EnsureSprites();
			return _idleSprite;
		}

		public static IReadOnlyList<string> GetIdleBuilderRaceSummaries()
		{
			return (from villager in GetBuilderVillagers()
				where (Object)(object)villager != (Object)null && villager.IsAlive() && IsVillagerIdle(villager)
				group villager by villager.Race into @group
				orderby GetRaceDisplayName(@group.First(), @group.Count())
				select $"{GetRaceDisplayName(@group.First(), 1)}: {@group.Count()}").ToList();
		}

		private static HashSet<string> GetIdleBuilderRaceIds()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (Villager builderVillager in GetBuilderVillagers())
			{
				if (!((Object)(object)builderVillager == (Object)null) && builderVillager.IsAlive() && IsVillagerIdle(builderVillager))
				{
					if (!string.IsNullOrWhiteSpace(builderVillager.Race))
					{
						hashSet.Add(builderVillager.Race);
					}
					RaceModel raceModel = builderVillager.raceModel;
					if (!string.IsNullOrWhiteSpace((raceModel != null) ? ((SO)raceModel).Name : null))
					{
						hashSet.Add(((SO)builderVillager.raceModel).Name);
					}
				}
			}
			return hashSet;
		}

		private static string GetRaceDisplayName(Villager villager, int count)
		{
			return ((Object)(object)villager.raceModel != (Object)null) ? villager.raceModel.GetDisplayNameFor(count) : villager.Race;
		}

		private static IEnumerable<Villager> GetBuilderVillagers()
		{
			Settings settings = GameAPI.GetSettings();
			object obj;
			if (settings == null)
			{
				obj = null;
			}
			else
			{
				ProfessionModel defaultProfession = settings.DefaultProfession;
				obj = ((defaultProfession != null) ? ((SO)defaultProfession).Name : null);
			}
			string builderProfession = (string)obj;
			if (string.IsNullOrWhiteSpace(builderProfession))
			{
				yield break;
			}
			if (_piVillagersService == null)
			{
				_piVillagersService = typeof(GameMB).GetProperty("VillagersService", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			object villagersService = _piVillagersService?.GetValue(null, null);
			if (villagersService == null)
			{
				yield break;
			}
			if ((object)_piVillagers == null)
			{
				_piVillagers = villagersService.GetType().GetProperty("Villagers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (!(_piVillagers?.GetValue(villagersService, null) is IDictionary villagers))
			{
				yield break;
			}
			foreach (DictionaryEntry item in villagers)
			{
				object value = item.Value;
				Villager villager = (Villager)((value is Villager) ? value : null);
				if (villager != null && string.Equals(((Actor)villager).Profession, builderProfession, StringComparison.OrdinalIgnoreCase))
				{
					yield return villager;
				}
			}
		}

		private static bool IsVillagerIdle(Villager villager)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Invalid comparison between Unknown and I4
			try
			{
				if ((object)_fiActorBrain == null)
				{
					_fiActorBrain = typeof(Actor).GetField("brain", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				object obj = _fiActorBrain?.GetValue(villager);
				if (obj == null)
				{
					return false;
				}
				if ((object)_fiBrainStack == null)
				{
					_fiBrainStack = obj.GetType().GetField("stack", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				if (!(_fiBrainStack?.GetValue(obj) is Stack<ActorTask> stack) || stack.Count == 0)
				{
					return false;
				}
				ActorTask val = stack.Peek();
				return val != null && (int)val.WorkStatus == 0;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private static bool EnsureSprites()
		{
			if ((Object)(object)_idleSprite == (Object)null)
			{
				_idleSprite = FindHudSprite("/HUD/GoodsHUD/SacrificeMarker/Content") ?? GameAPI.GetSettings()?.monitorsConfig?.noBuildersIcon;
			}
			if ((Object)(object)_builderSprite == (Object)null)
			{
				_builderSprite = FindBuilderHudSprite() ?? GameAPI.GetSettings()?.monitorsConfig?.noBuildersIcon;
			}
			return (Object)(object)_idleSprite != (Object)null && (Object)(object)_builderSprite != (Object)null;
		}

		private static Sprite FindBuilderHudSprite()
		{
			RacesStatsHUD val = Object.FindObjectOfType<RacesStatsHUD>();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform val2 = FindDescendantByName(((Component)val).transform, "BuildersIcon");
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			Image componentInChildren = ((Component)val2).GetComponentInChildren<Image>(true);
			return (componentInChildren != null) ? componentInChildren.sprite : null;
		}

		private static Sprite FindHudSprite(string path)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				return null;
			}
			GameObject val = GameObject.Find(path);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null)
			{
				return component.sprite;
			}
			Image componentInChildren = val.GetComponentInChildren<Image>(true);
			return (componentInChildren != null) ? componentInChildren.sprite : null;
		}

		private static Transform FindDescendantByName(Transform root, string name)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform child = root.GetChild(i);
				if (string.Equals(((Object)child).name, name, StringComparison.Ordinal))
				{
					return child;
				}
				Transform val = FindDescendantByName(child, name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class BuildingAlertIndicators
	{
		private readonly struct IndicatorSnapshot : IEquatable<IndicatorSnapshot>
		{
			public bool Active { get; }

			public Color Color { get; }

			public bool ShowProductIcons { get; }

			public float ProductIconScale { get; }

			public string ProductGoodsKey { get; }

			public IndicatorSnapshot(bool active, Color color, IReadOnlyList<string> productGoodIds)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				Active = active;
				Color = color;
				ShowProductIcons = ConfigManager.ShowBuildingSpecificItemIndicators;
				ProductIconScale = ConfigManager.BuildingShortageIconScale;
				ProductGoodsKey = ((productGoodIds == null || productGoodIds.Count == 0) ? string.Empty : string.Join("|", productGoodIds.Select(BuildProductGoodsKey)));
			}

			public bool Equals(IndicatorSnapshot other)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				int result;
				if (Active == other.Active)
				{
					Color color = Color;
					if (((Color)(ref color)).Equals(other.Color) && ShowProductIcons == other.ShowProductIcons && Mathf.Approximately(ProductIconScale, other.ProductIconScale))
					{
						result = (string.Equals(ProductGoodsKey, other.ProductGoodsKey, StringComparison.Ordinal) ? 1 : 0);
						goto IL_0060;
					}
				}
				result = 0;
				goto IL_0060;
				IL_0060:
				return (byte)result != 0;
			}

			private static string BuildProductGoodsKey(string goodId)
			{
				GoodInfo goodInfo = Discovery.Goods.FirstOrDefault((GoodInfo g) => string.Equals(g.Id, goodId, StringComparison.OrdinalIgnoreCase));
				return goodId + ((goodInfo != null && goodInfo.IsIngredientBlocked) ? ":blocked" : ":normal");
			}
		}

		private const int MaxProductIcons = 4;

		private const int ProductIconGridRows = 2;

		private const float ProductIconBorderThicknessScale = 0.08f;

		private const string ProductIconBorderRootName = "IngredientBlockedBorder";

		private const string ProductIconsRootName = "StockAlertProductIcons";

		private static readonly Color WhiteColor = Color.white;

		private static readonly Color RedColor = new Color(1f, 0.25f, 0.25f, 1f);

		private static readonly Color YellowColor = new Color(1f, 0.85f, 0.2f, 1f);

		private static readonly Color BorderRedColor = new Color(0.62f, 0.04f, 0.04f, 1f);

		private static readonly Dictionary<int, IndicatorSnapshot> LastApplied = new Dictionary<int, IndicatorSnapshot>();

		private static Sprite _solidSprite;

		public static void Refresh()
		{
			if (!ConfigManager.ShowBuildingAlertIndicators)
			{
				RestoreVanilla();
				return;
			}
			Settings settings = GameAPI.GetSettings();
			HashSet<string> lowGoods = new HashSet<string>(from g in Discovery.Goods
				where g.IsBelowThreshold
				select g.Id, StringComparer.OrdinalIgnoreCase);
			HashSet<string> blockedIngredientGoods = new HashSet<string>(Discovery.BlockedIngredientGoods, StringComparer.OrdinalIgnoreCase);
			HashSet<int> seenBuildings = new HashSet<int>();
			foreach (IWorkshop recipeBuilding in GetRecipeBuildings())
			{
				ProductionBuilding @base = recipeBuilding.Base;
				if (!((Object)(object)@base == (Object)null))
				{
					seenBuildings.Add(((Building)@base).Id);
					ApplyIndicatorState(@base, recipeBuilding, lowGoods, blockedIngredientGoods, settings);
				}
			}
			foreach (ProductionBuilding gatheringSourceBuilding in GameAPI.GetGatheringSourceBuildings())
			{
				if (!((Object)(object)gatheringSourceBuilding == (Object)null))
				{
					seenBuildings.Add(((Building)gatheringSourceBuilding).Id);
					ApplyGatheringIndicatorState(gatheringSourceBuilding, blockedIngredientGoods);
				}
			}
			List<int> list = LastApplied.Keys.Where((int id) => !seenBuildings.Contains(id)).ToList();
			foreach (int item in list)
			{
				RemoveProductIcons(item);
				LastApplied.Remove(item);
			}
		}

		public static void RefreshForView(ProductionBuildingView buildingView)
		{
			if (!ConfigManager.ShowBuildingAlertIndicators || (Object)(object)buildingView == (Object)null)
			{
				return;
			}
			IWorkshop val = GetRecipeBuildings().FirstOrDefault((Func<IWorkshop, bool>)delegate(IWorkshop w)
			{
				object obj;
				if (w == null)
				{
					obj = null;
				}
				else
				{
					ProductionBuilding @base = w.Base;
					obj = ((@base != null) ? ((Building)@base).BuildingView : null);
				}
				return obj == buildingView;
			});
			if (!((Object)(object)((val != null) ? val.Base : null) == (Object)null))
			{
				Settings settings = GameAPI.GetSettings();
				HashSet<string> lowGoods = new HashSet<string>(from g in Discovery.Goods
					where g.IsBelowThreshold
					select g.Id, StringComparer.OrdinalIgnoreCase);
				HashSet<string> blockedIngredientGoods = new HashSet<string>(Discovery.BlockedIngredientGoods, StringComparer.OrdinalIgnoreCase);
				ApplyIndicatorState(val.Base, val, lowGoods, blockedIngredientGoods, settings);
			}
		}

		public static void RestoreVanilla()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			foreach (IWorkshop recipeBuilding in GetRecipeBuildings())
			{
				ProductionBuilding @base = recipeBuilding.Base;
				if ((Object)(object)@base == (Object)null)
				{
					continue;
				}
				BuildingView buildingView = ((Building)@base).BuildingView;
				object obj;
				if (buildingView == null)
				{
					obj = null;
				}
				else
				{
					Transform transform = ((Component)buildingView).transform;
					if (transform == null)
					{
						obj = null;
					}
					else
					{
						Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
						obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
					}
				}
				GameObject val = (GameObject)obj;
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MakeIconClickThrough(val);
				bool active = ((Building)@base).BuildingState != null && ((Building)@base).BuildingState.finished && !((Building)@base).BuildingState.isSleeping && @base.CountWorkers() == 0;
				val.SetActive(active);
				foreach (SpriteRenderer baseIconRenderer in GetBaseIconRenderers(val))
				{
					baseIconRenderer.color = WhiteColor;
				}
				DestroyProductIcons(val);
			}
			LastApplied.Clear();
		}

		private static IEnumerable<IWorkshop> GetRecipeBuildings()
		{
			foreach (IWorkshop recipeBuilding in GameAPI.GetRecipeBuildings())
			{
				yield return recipeBuilding;
			}
		}

		private static void ApplyIndicatorState(ProductionBuilding building, IWorkshop workshop, HashSet<string> lowGoods, HashSet<string> blockedIngredientGoods, Settings settings)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_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)
			BuildingView buildingView = ((Building)building).BuildingView;
			object obj;
			if (buildingView == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = ((Component)buildingView).transform;
				if (transform == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
					obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				}
			}
			GameObject val = (GameObject)obj;
			if (!((Object)(object)val == (Object)null))
			{
				MakeIconClickThrough(val);
				int num = building.CountWorkers();
				WorkplaceModel[] workplaces = building.Workplaces;
				int num2 = ((workplaces != null) ? workplaces.Length : 0);
				List<string> enabledLowRecipeGoods = GetEnabledLowRecipeGoods(workshop, lowGoods);
				bool flag = enabledLowRecipeGoods.Count > 0;
				bool flag2 = workshop.Recipes.Any((WorkshopRecipeState r) => IsEnabledGatheringSupplyRecipe(r, blockedIngredientGoods, settings));
				bool flag3 = flag || flag2;
				bool flag4 = false;
				Color color = WhiteColor;
				if (num == 0)
				{
					flag4 = true;
					color = (flag3 ? RedColor : WhiteColor);
				}
				else if (flag3 && num < num2)
				{
					flag4 = true;
					color = YellowColor;
				}
				ApplySnapshot(((Building)building).Id, val, flag4, color, (flag4 && flag && ConfigManager.ShowBuildingSpecificItemIndicators) ? enabledLowRecipeGoods : null);
			}
		}

		private static void ApplyGatheringIndicatorState(ProductionBuilding building, HashSet<string> blockedIngredientGoods)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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)
			BuildingView buildingView = ((Building)building).BuildingView;
			object obj;
			if (buildingView == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = ((Component)buildingView).transform;
				if (transform == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
					obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				}
			}
			GameObject val = (GameObject)obj;
			if (!((Object)(object)val == (Object)null))
			{
				MakeIconClickThrough(val);
				int num = building.CountWorkers();
				WorkplaceModel[] workplaces = building.Workplaces;
				int num2 = ((workplaces != null) ? workplaces.Length : 0);
				bool flag = HasRelevantGatheringRecipe(building, blockedIngredientGoods);
				bool active = false;
				Color color = WhiteColor;
				if (num == 0)
				{
					active = true;
					color = (flag ? RedColor : WhiteColor);
				}
				else if (flag && num < num2)
				{
					active = true;
					color = YellowColor;
				}
				ApplySnapshot(((Building)building).Id, val, active, color, null);
			}
		}

		private static bool HasRelevantGatheringRecipe(ProductionBuilding building, HashSet<string> blockedIngredientGoods)
		{
			if ((Object)(object)((building != null) ? ((Building)building).BuildingModel : null) == (Object)null || blockedIngredientGoods == null || blockedIngredientGoods.Count == 0)
			{
				return false;
			}
			List<RecipeState> recipeStates = GetRecipeStates(building);
			if (recipeStates == null || recipeStates.Count == 0)
			{
				return false;
			}
			foreach (string blockedIngredientGood in blockedIngredientGoods)
			{
				if (string.IsNullOrWhiteSpace(blockedIngredientGood))
				{
					continue;
				}
				Settings settings = GameAPI.GetSettings();
				GoodModel val = ((settings != null) ? settings.GetGood(blockedIngredientGood) : null);
				if ((Object)(object)val == (Object)null || !((Building)building).BuildingModel.IsSourceOf(val))
				{
					continue;
				}
				foreach (RecipeState item in recipeStates)
				{
					if (item == null || !item.active || !RecipeProducesGood(building, item, blockedIngredientGood))
					{
						continue;
					}
					return true;
				}
			}
			return false;
		}

		private static List<RecipeState> GetRecipeStates(ProductionBuilding building)
		{
			GathererHut val = (GathererHut)(object)((building is GathererHut) ? building : null);
			if (val == null)
			{
				return ((Camp)(((building is Camp) ? building : null)?)).state?.recipes;
			}
			return val.state?.recipes;
		}

		private static bool RecipeProducesGood(ProductionBuilding building, RecipeState recipeState, string blockedGood)
		{
			GathererHut val = (GathererHut)(object)((building is GathererHut) ? building : null);
			if (val == null)
			{
				Camp val2 = (Camp)(object)((building is Camp) ? building : null);
				if (val2 != null)
				{
					CampRecipeModel recipeModel = val2.GetRecipeModel(recipeState);
					return string.Equals((recipeModel != null) ? ((RecipeModel)recipeModel).GetProducedGood() : null, blockedGood, StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}
			GathererHutRecipeModel recipeModel2 = val.GetRecipeModel(recipeState);
			return string.Equals((recipeModel2 != null) ? ((RecipeModel)recipeModel2).GetProducedGood() : null, blockedGood, StringComparison.OrdinalIgnoreCase);
		}

		private static void ApplySnapshot(int buildingId, GameObject icon, bool active, Color color, IReadOnlyList<string> productGoodIds)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			IndicatorSnapshot indicatorSnapshot = new IndicatorSnapshot(active, color, productGoodIds);
			bool activeSelf = icon.activeSelf;
			Color currentIconColor = GetCurrentIconColor(icon);
			if (LastApplied.TryGetValue(buildingId, out var value) && value.Equals(indicatorSnapshot) && activeSelf == active && ColorsEqual(currentIconColor, color))
			{
				return;
			}
			icon.SetActive(active);
			foreach (SpriteRenderer baseIconRenderer in GetBaseIconRenderers(icon))
			{
				baseIconRenderer.color = color;
			}
			ApplyProductIcons(buildingId, icon, active ? productGoodIds : null);
			LastApplied[buildingId] = indicatorSnapshot;
		}

		private static Color GetCurrentIconColor(GameObject icon)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icon == (Object)null)
			{
				return Color.clear;
			}
			SpriteRenderer val = GetBaseIconRenderers(icon).FirstOrDefault();
			return ((Object)(object)val != (Object)null) ? val.color : Color.clear;
		}

		private static List<string> GetEnabledLowRecipeGoods(IWorkshop workshop, HashSet<string> lowGoods)
		{
			List<string> list = new List<string>();
			if (((workshop != null) ? workshop.Recipes : null) == null || lowGoods == null || lowGoods.Count == 0)
			{
				return list;
			}
			foreach (WorkshopRecipeState recipe in workshop.Recipes)
			{
				if (IsEnabledLowRecipe(recipe, lowGoods) && !list.Any((string g) => string.Equals(g, recipe.productName, StringComparison.OrdinalIgnoreCase)))
				{
					list.Add(recipe.productName);
					if (list.Count >= 4)
					{
						break;
					}
				}
			}
			return list;
		}

		private static void ApplyProductIcons(int buildingId, GameObject icon, IReadOnlyList<string> productGoodIds)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icon == (Object)null || productGoodIds == null || productGoodIds.Count == 0)
			{
				DestroyProductIcons(icon);
				return;
			}
			SpriteRenderer val = GetBaseIconRenderers(icon).FirstOrDefault((Func<SpriteRenderer, bool>)((SpriteRenderer r) => (Object)(object)((r != null) ? r.sprite : null) != (Object)null));
			if ((Object)(object)val == (Object)null)
			{
				DestroyProductIcons(icon);
				return;
			}
			GameObject orCreateProductIconsRoot = GetOrCreateProductIconsRoot(icon);
			if ((Object)(object)orCreateProductIconsRoot == (Object)null)
			{
				return;
			}
			Vector2 rendererSizeInIconSpace = GetRendererSizeInIconSpace(icon.transform, val);
			float num = Mathf.Max(0.01f, rendererSizeInIconSpace.y * ConfigManager.BuildingShortageIconScale);
			float num2 = num / 2.08f;
			float num3 = num2 * 0.08f;
			float num4 = Mathf.Max(rendererSizeInIconSpace.x * 0.55f + num2 * 0.5f, num2 * 1.15f);
			int num5 = 0;
			int i;
			for (i = 0; i < productGoodIds.Count; i++)
			{
				GoodInfo goodInfo = Discovery.Goods.FirstOrDefault((GoodInfo g) => string.Equals(g.Id, productGoodIds[i], StringComparison.OrdinalIgnoreCase));
				Sprite val2 = goodInfo?.Icon;
				if (!((Object)(object)val2 == (Object)null))
				{
					GameObject orCreateProductIcon = GetOrCreateProductIcon(orCreateProductIconsRoot, num5);
					SpriteRenderer component = orCreateProductIcon.GetComponent<SpriteRenderer>();
					if (!((Object)(object)component == (Object)null))
					{
						component.sprite = val2;
						component.color = WhiteColor;
						((Renderer)component).sortingLayerName = ((Renderer)val).sortingLayerName;
						((Renderer)component).sortingOrder = ((Renderer)val).sortingOrder + 1;
						ApplyProductIconBorder(orCreateProductIcon, val2, goodInfo.IsIngredientBlocked, val);
						int num6 = num5 % 2;
						int num7 = num5 / 2;
						float num8 = ((num6 == 0) ? ((num2 + num3) * 0.5f) : ((0f - (num2 + num3)) * 0.5f));
						orCreateProductIcon.transform.localPosition = new Vector3(num4 + (float)num7 * (num2 + num3), num8, 0f);
						orCreateProductIcon.transform.localRotation = Quaternion.identity;
						orCreateProductIcon.transform.localScale = Vector3.one * GetScaleForHeight(val2, num2);
						orCreateProductIcon.SetActive(true);
						num5++;
					}
				}
			}
			for (int j = num5; j < orCreateProductIconsRoot.transform.childCount; j++)
			{
				((Component)orCreateProductIconsRoot.transform.GetChild(j)).gameObject.SetActive(false);
			}
			orCreateProductIconsRoot.SetActive(num5 > 0);
			if (num5 == 0)
			{
				DestroyProductIcons(icon);
				LastApplied.Remove(buildingId);
			}
		}

		private static GameObject GetOrCreateProductIconsRoot(GameObject icon)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = icon.transform.Find("StockAlertProductIcons");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			GameObject val2 = new GameObject("StockAlertProductIcons");
			val2.transform.SetParent(icon.transform, false);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			return val2;
		}

		private static GameObject GetOrCreateProductIcon(GameObject root, int index)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			while (root.transform.childCount <= index)
			{
				GameObject val = new GameObject("ProductIcon");
				val.transform.SetParent(root.transform, false);
				SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
				((Renderer)val2).material = new Material(Shader.Find("Sprites/Default"));
			}
			return ((Component)root.transform.GetChild(index)).gameObject;
		}

		private static void ApplyProductIconBorder(GameObject productIcon, Sprite sprite, bool active, SpriteRenderer baseRenderer)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			GameObject orCreateProductIconBorder = GetOrCreateProductIconBorder(productIcon);
			if (!((Object)(object)orCreateProductIconBorder == (Object)null))
			{
				orCreateProductIconBorder.SetActive(active);
				if (active && !((Object)(object)sprite == (Object)null))
				{
					Bounds bounds = sprite.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float num = Mathf.Max(size.y * 0.08f, 0.01f);
					float num2 = size.x + num * 2f;
					float num3 = size.y + num * 2f;
					Transform obj = orCreateProductIconBorder.transform.Find("Top");
					ConfigureBorderPart((obj != null) ? ((Component)obj).GetComponent<SpriteRenderer>() : null, 0f, num3 * 0.5f - num * 0.5f, num2, num, baseRenderer);
					Transform obj2 = orCreateProductIconBorder.transform.Find("Bottom");
					ConfigureBorderPart((obj2 != null) ? ((Component)obj2).GetComponent<SpriteRenderer>() : null, 0f, (0f - num3) * 0.5f + num * 0.5f, num2, num, baseRenderer);
					Transform obj3 = orCreateProductIconBorder.transform.Find("Left");
					ConfigureBorderPart((obj3 != null) ? ((Component)obj3).GetComponent<SpriteRenderer>() : null, (0f - num2) * 0.5f + num * 0.5f, 0f, num, num3, baseRenderer);
					Transform obj4 = orCreateProductIconBorder.transform.Find("Right");
					ConfigureBorderPart((obj4 != null) ? ((Component)obj4).GetComponent<SpriteRenderer>() : null, num2 * 0.5f - num * 0.5f, 0f, num, num3, baseRenderer);
				}
			}
		}

		private static GameObject GetOrCreateProductIconBorder(GameObject productIcon)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)productIcon == (Object)null)
			{
				return null;
			}
			Transform val = productIcon.transform.Find("IngredientBlockedBorder");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			GameObject val2 = new GameObject("IngredientBlockedBorder");
			val2.transform.SetParent(productIcon.transform, false);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			CreateBorderPart(val2.transform, "Top");
			CreateBorderPart(val2.transform, "Bottom");
			CreateBorderPart(val2.transform, "Left");
			CreateBorderPart(val2.transform, "Right");
			val2.SetActive(false);
			return val2;
		}

		private static void CreateBorderPart(Transform parent, string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			val2.sprite = GetSolidSprite();
			((Renderer)val2).material = new Material(Shader.Find("Sprites/Default"));
		}

		private static void ConfigureBorderPart(SpriteRenderer renderer, float x, float y, float width, float height, SpriteRenderer baseRenderer)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)renderer == (Object)null))
			{
				renderer.color = BorderRedColor;
				((Renderer)renderer).sortingLayerName = ((Renderer)baseRenderer).sortingLayerName;
				((Renderer)renderer).sortingOrder = ((Renderer)baseRenderer).sortingOrder + 2;
				((Component)renderer).transform.localPosition = new Vector3(x, y, 0f);
				((Component)renderer).transform.localRotation = Quaternion.identity;
				((Component)renderer).transform.localScale = new Vector3(width, height, 1f);
			}
		}

		private static Vector2 GetRendererSizeInIconSpace(Transform iconTransform, SpriteRenderer renderer)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)iconTransform == (Object)null || (Object)(object)((renderer != null) ? renderer.sprite : null) == (Object)null)
			{
				return Vector2.one;
			}
			Bounds bounds = renderer.sprite.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			Vector3 val = iconTransform.InverseTransformVector(((Component)renderer).transform.TransformVector(new Vector3(size.x, 0f, 0f)));
			float magnitude = ((Vector3)(ref val)).magnitude;
			val = iconTransform.InverseTransformVector(((Component)renderer).transform.TransformVector(new Vector3(0f, size.y, 0f)));
			float magnitude2 = ((Vector3)(ref val)).magnitude;
			return new Vector2(Mathf.Max(0.01f, magnitude), Mathf.Max(0.01f, magnitude2));
		}

		private static float GetScaleForHeight(Sprite sprite, float targetHeight)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			float num;
			if (sprite == null)
			{
				num = 0f;
			}
			else
			{
				Bounds bounds = sprite.bounds;
				num = ((Bounds)(ref bounds)).size.y;
			}
			float num2 = num;
			return (num2 > 0.001f) ? (targetHeight / num2) : 1f;
		}

		private static Sprite GetSolidSprite()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_003f: Expected O, but got Unknown
			//IL_0040: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_solidSprite != (Object)null)
			{
				return _solidSprite;
			}
			Texture2D val = new Texture2D(4, 4, (TextureFormat)5, false)
			{
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1,
				hideFlags = (HideFlags)61
			};
			val.SetPixels(Enumerable.Repeat<Color>(Color.white, 16).ToArray());
			val.Apply(false, true);
			_solidSprite = Sprite.Create(val, new Rect(0f, 0f, 4f, 4f), new Vector2(0.5f, 0.5f), 4f);
			return _solidSprite;
		}

		private static IEnumerable<SpriteRenderer> GetBaseIconRenderers(GameObject icon)
		{
			return from r in icon.GetComponentsInChildren<SpriteRenderer>(true)
				where (Object)(object)r != (Object)null && !IsProductIconTransform(((Component)r).transform)
				select r;
		}

		private static bool IsProductIconTransform(Transform transform)
		{
			while ((Object)(object)transform != (Object)null)
			{
				if (string.Equals(((Object)transform).name, "StockAlertProductIcons", StringComparison.Ordinal))
				{
					return true;
				}
				transform = transform.parent;
			}
			return false;
		}

		private static void RemoveProductIcons(int buildingId)
		{
			foreach (IWorkshop recipeBuilding in GetRecipeBuildings())
			{
				if (recipeBuilding == null)
				{
					continue;
				}
				ProductionBuilding @base = recipeBuilding.Base;
				if (((@base != null) ? new int?(((Building)@base).Id) : null) != buildingId)
				{
					continue;
				}
				BuildingView buildingView = ((Building)recipeBuilding.Base).BuildingView;
				object obj;
				if (buildingView == null)
				{
					obj = null;
				}
				else
				{
					Transform transform = ((Component)buildingView).transform;
					if (transform == null)
					{
						obj = null;
					}
					else
					{
						Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
						obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
					}
				}
				GameObject icon = (GameObject)obj;
				DestroyProductIcons(icon);
				break;
			}
		}

		private static void DestroyProductIcons(GameObject icon)
		{
			object obj;
			if (icon == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = icon.transform;
				obj = ((transform != null) ? transform.Find("StockAlertProductIcons") : null);
			}
			Transform val = (Transform)obj;
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private static bool ColorsEqual(Color a, Color b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Approximately(a.r, b.r) && Mathf.Approximately(a.g, b.g) && Mathf.Approximately(a.b, b.b) && Mathf.Approximately(a.a, b.a);
		}

		private static void MakeIconClickThrough(GameObject icon)
		{
			if ((Object)(object)icon == (Object)null)
			{
				return;
			}
			Graphic[] componentsInChildren = icon.GetComponentsInChildren<Graphic>(true);
			foreach (Graphic val in componentsInChildren)
			{
				val.raycastTarget = false;
			}
			Selectable[] componentsInChildren2 = icon.GetComponentsInChildren<Selectable>(true);
			foreach (Selectable val2 in componentsInChildren2)
			{
				val2.interactable = false;
			}
			GraphicRaycaster[] componentsInChildren3 = icon.GetComponentsInChildren<GraphicRaycaster>(true);
			foreach (GraphicRaycaster val3 in componentsInChildren3)
			{
				((Behaviour)val3).enabled = false;
			}
			EventTrigger[] componentsInChildren4 = icon.GetComponentsInChildren<EventTrigger>(true);
			foreach (EventTrigger val4 in componentsInChildren4)
			{
				((Behaviour)val4).enabled = false;
			}
			Component[] componentsInChildren5 = icon.GetComponentsInChildren<Component>(true);
			foreach (Component val5 in componentsInChildren5)
			{
				Type type = ((object)val5)?.GetType();
				if (type == null)
				{
					continue;
				}
				string name = type.Name;
				if (name.IndexOf("Collider", StringComparison.Ordinal) >= 0)
				{
					PropertyInfo property = type.GetProperty("enabled");
					if (property != null && property.CanWrite)
					{
						property.SetValue(val5, false, null);
					}
				}
			}
		}

		private static bool IsEnabledLowRecipe(WorkshopRecipeState recipeState, HashSet<string> lowGoods)
		{
			if (recipeState == null || !((RecipeState)recipeState).active || string.IsNullOrWhiteSpace(recipeState.productName) || !lowGoods.Contains(recipeState.productName))
			{
				return false;
			}
			return true;
		}

		private static bool IsEnabledGatheringSupplyRecipe(WorkshopRecipeState recipeState, HashSet<string> blockedIngredientGoods, Settings settings)
		{
			if (recipeState == null || !((RecipeState)recipeState).active || blockedIngredientGoods == null || blockedIngredientGoods.Count == 0 || string.IsNullOrWhiteSpace(recipeState.productName) || !blockedIngredientGoods.Contains(recipeState.productName))
			{
				return false;
			}
			WorkshopRecipeModel val = ((settings != null) ? settings.GetWorkshopRecipe(((RecipeState)recipeState).model) : null);
			return val?.requiredGoods == null || val.requiredGoods.Length == 0;
		}
	}
	[HarmonyPatch(typeof(ProductionBuildingView), "ShowWorkers")]
	internal static class BuildingAlertIndicatorsViewPatch
	{
		[HarmonyPostfix]
		private static void ShowWorkersPostfix(ProductionBuildingView __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && GameAPI.IsGameActive())
			{
				BuildingAlertIndicators.RefreshForView(__instance);
			}
		}
	}
	internal sealed class IdleBuilderRaceMenuMarker : MonoBehaviour
	{
		private RacesMenuSlot _slot;

		private GameObject _markerObject;

		private Image _markerImage;

		private float _nextRefreshTime;

		public static void Attach(RacesMenuSlot slot)
		{
			if (!((Object)(object)slot == (Object)null))
			{
				IdleBuilderRaceMenuMarker component = ((Component)slot).GetComponent<IdleBuilderRaceMenuMarker>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)slot).gameObject.AddComponent<IdleBuilderRaceMenuMarker>();
					component.Initialize(slot);
				}
				else
				{
					component.Initialize(slot);
				}
			}
		}

		private void Initialize(RacesMenuSlot slot)
		{
			_slot = slot;
			CleanupLegacyMarkers();
			Refresh();
		}

		private void OnEnable()
		{
			Refresh();
		}

		private void Update()
		{
			if (!(Time.unscaledTime < _nextRefreshTime))
			{
				_nextRefreshTime = Time.unscaledTime + 0.25f;
				Refresh();
			}
		}

		private void Refresh()
		{
			if ((Object)(object)_slot == (Object)null || !ConfigManager.ShowBuilderStatusIcons)
			{
				Hide();
				return;
			}
			RaceModel race = _slot.GetRace();
			if ((Object)(object)race == (Object)null || !BuilderStatusIndicators.HasIdleBuilderOfRace(race))
			{
				Hide();
				return;
			}
			Sprite idleBuilderSprite = BuilderStatusIndicators.GetIdleBuilderSprite();
			if ((Object)(object)idleBuilderSprite == (Object)null)
			{
				Hide();
				return;
			}
			EnsureMarker();
			if (!((Object)(object)_markerImage == (Object)null))
			{
				_markerImage.sprite = idleBuilderSprite;
				_markerObject.SetActive(true);
			}
		}

		private void EnsureMarker()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_markerObject != (Object)null) && !((Object)(object)_slot == (Object)null))
			{
				Transform obj = ((Component)_slot).transform.Find("Content");
				RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)_slot).GetComponent<RectTransform>();
				}
				if (!((Object)(object)val == (Object)null))
				{
					_markerObject = new GameObject("StockAlertIdleBuilderRaceMarker", new Type[3]
					{
						typeof(RectTransform),
						typeof(CanvasRenderer),
						typeof(Image)
					});
					_markerObject.transform.SetParent((Transform)(object)val, false);
					_markerImage = _markerObject.GetComponent<Image>();
					((Graphic)_markerImage).raycastTarget = false;
					_markerImage.preserveAspect = true;
					RectTransform component = _markerObject.GetComponent<RectTransform>();
					component.anchorMin = new Vector2(0f, 0.5f);
					component.anchorMax = new Vector2(0f, 0.5f);
					component.pivot = new Vector2(0.5f, 0.5f);
					component.sizeDelta = new Vector2(22f, 22f);
					component.anchoredPosition = new Vector2(-2f, 0f);
					_markerObject.transform.SetAsLastSibling();
					_markerObject.SetActive(false);
				}
			}
		}

		private void CleanupLegacyMarkers()
		{
			if (!((Object)(object)_slot == (Object)null))
			{
				Transform val = ((Component)_slot).transform.Find("Content");
				if (!((Object)(object)val == (Object)null))
				{
					DestroyChild(val, "IdleBuilderRaceMarker");
					DestroyChild(val, "StockAlertIdleBuilderRaceMarker");
					_markerObject = null;
					_markerImage = null;
				}
			}
		}

		private static void DestroyChild(Transform parent, string childName)
		{
			Transform val = parent.Find(childName);
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private void Hide()
		{
			if ((Object)(object)_markerObject != (Object)null)
			{
				_markerObject.SetActive(false);
			}
		}
	}
	internal static class IdleBuildersAlert
	{
		public const string AlertPrefix = "You have idle builders:";

		private static News _activeNews;

		private static string _lastContent;

		public static void Refresh()
		{
			if (!ConfigManager.ShowIdleBuildersAlert || !GameAPI.IsGameActive())
			{
				Clear();
				return;
			}
			int idleBuilderCount = BuilderStatusIndicators.GetIdleBuilderCount();
			if (idleBuilderCount <= 0)
			{
				Clear();
				return;
			}
			string content = BuildContent(idleBuilderCount);
			List<News> currentNews = GameAPI.GetCurrentNews();
			News val = ((IEnumerable<News>)currentNews).FirstOrDefault((Func<News, bool>)((News news) => news != null && news.content == content));
			if (val != null)
			{
				_activeNews = val;
				_lastContent = content;
				return;
			}
			if (_activeNews != null)
			{
				GameAPI.RemoveNews(_activeNews);
				_activeNews = null;
			}
			if (!(_lastContent == content) || !currentNews.Any((News news) => news != null && news.content != null && news.content.StartsWith("You have idle builders:")))
			{
				_activeNews = GameAPI.PublishNews(content, null, (AlertSeverity)1);
				_lastContent = content;
			}
		}

		public static void Clear()
		{
			if (_activeNews != null)
			{
				GameAPI.RemoveNews(_activeNews);
				_activeNews = null;
			}
			_lastContent = null;
		}

		private static string BuildContent(int count)
		{
			IReadOnlyList<string> idleBuilderRaceSummaries = BuilderStatusIndicators.GetIdleBuilderRaceSummaries();
			if (idleBuilderRaceSummaries.Count == 0)
			{
				return string.Format("{0} {1}", "You have idle builders:", count);
			}
			string arg = string.Join("\n", idleBuilderRaceSummaries);
			return string.Format("{0} {1}\n{2}", "You have idle builders:", count, arg);
		}
	}
	internal static class ItemLocatorOverlay
	{
		private const float MarkerHeightOffset = 0.55f;

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

		private static string _trackedGoodId;

		private static GameObject _template;

		private static string _lastToggledGoodId;

		private static int _lastToggleFrame = -1;

		public static bool IsTracking => !string.IsNullOrWhiteSpace(_trackedGoodId);

		public static void Toggle(string goodId)
		{
			if (!string.IsNullOrWhiteSpace(goodId) && (_lastToggleFrame != Time.frameCount || !string.Equals(_lastToggledGoodId, goodId, StringComparison.OrdinalIgnoreCase)))
			{
				_lastToggleFrame = Time.frameCount;
				_lastToggledGoodId = goodId;
				if (string.Equals(_trackedGoodId, goodId, StringComparison.OrdinalIgnoreCase))
				{
					Clear();
					return;
				}
				_trackedGoodId = goodId;
				Refresh();
			}
		}

		public static void Clear()
		{
			_trackedGoodId = null;
			foreach (GameObject value in Markers.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			Markers.Clear();
		}

		public static void Refresh()
		{
			if (!GameAPI.IsGameActive() || string.IsNullOrWhiteSpace(_trackedGoodId))
			{
				Clear();
				return;
			}
			Settings settings = GameAPI.GetSettings();
			Sprite val = ((settings != null) ? settings.GetGood(_trackedGoodId) : null)?.icon;
			if ((Object)(object)val == (Object)null)
			{
				Clear();
				return;
			}
			GameObject val2 = ResolveTemplate();
			if ((Object)(object)val2 == (Object)null)
			{
				Clear();
				return;
			}
			List<TrackedItemLocation> trackedItemLocations = GameAPI.GetTrackedItemLocations(_trackedGoodId);
			HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (TrackedItemLocation item in trackedItemLocations.Where((TrackedItemLocation l) => l != null && !string.IsNullOrWhiteSpace(l.Key)))
			{
				UpsertMarker(item, val, val2);
				seen.Add(item.Key);
			}
			List<string> list = Markers.Keys.Where((string key) => !seen.Contains(key)).ToList();
			foreach (string item2 in list)
			{
				if (Markers.TryGetValue(item2, out var value) && (Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
				Markers.Remove(item2);
			}
		}

		private static void UpsertMarker(TrackedItemLocation location, Sprite icon, GameObject template)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Vector3 markerWorldPosition = GetMarkerWorldPosition(location);
			if (!Markers.TryGetValue(location.Key, out var value) || (Object)(object)value == (Object)null)
			{
				value = Object.Instantiate<GameObject>(template, template.transform.parent);
				((Object)value).name = "StockAlertItemLocator_" + location.Key;
				Markers[location.Key] = value;
			}
			ApplyVisuals(value, icon, location);
			ApplyTarget(value, markerWorldPosition);
			value.SetActive(true);
		}

		private static void ApplyVisuals(GameObject marker, Sprite icon, TrackedItemLocation location)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = marker.transform.Find("Icon");
			object obj2 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			if (obj2 == null)
			{
				Transform obj3 = marker.transform.Find("Mask/Icon");
				obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null);
			}
			Image val = (Image)obj2;
			if ((Object)(object)val != (Object)null)
			{
				val.sprite = icon;
				val.preserveAspect = true;
				((Graphic)val).color = Color.white;
				((Graphic)val).raycastTarget = false;
			}
			Transform val2 = marker.transform.Find("Grade");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			Transform obj4 = marker.transform.Find("BG");
			Image val3 = ((obj4 != null) ? ((Component)obj4).GetComponent<Image>() : null);
			if ((Object)(object)val3 != (Object)null)
			{
				((Graphic)val3).raycastTarget = false;
			}
			Image[] componentsInChildren = marker.GetComponentsInChildren<Image>(true);
			foreach (Image val4 in componentsInChildren)
			{
				((Graphic)val4).raycastTarget = false;
			}
			ApplyAmountBadge(marker, location);
		}

		private static void ApplyAmountBadge(GameObject marker, TrackedItemLocation location)
		{
			GameObject orCreateAmountBadge = GetOrCreateAmountBadge(marker);
			if ((Object)(object)orCreateAmountBadge == (Object)null)
			{
				return;
			}
			bool flag = location != null && location.Amount > 0 && location.Key.StartsWith("building:", StringComparison.OrdinalIgnoreCase);
			orCreateAmountBadge.SetActive(flag);
			if (flag)
			{
				TextMeshProUGUI componentInChildren = orCreateAmountBadge.GetComponentInChildren<TextMeshProUGUI>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = location.Amount.ToString();
				}
			}
		}

		private static GameObject GetOrCreateAmountBadge(GameObject marker)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_011d: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			Transform val = marker.transform.Find("StockAlertAmountBadge");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			RectTransform val2 = marker.GetComponent<RectTransform>() ?? marker.GetComponentInChildren<RectTransform>(true);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObject val3 = new GameObject("StockAlertAmountBadge", new Type[1] { typeof(RectTransform) });
			RectTransform component = val3.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)val2, false);
			component.anchorMin = new Vector2(1f, 0f);
			component.anchorMax = new Vector2(1f, 0f);
			component.pivot = new Vector2(1f, 0f);
			component.anchoredPosition = new Vector2(8f, -8f);
			component.sizeDelta = new Vector2(32f, 20f);
			GameObject val4 = new GameObject("Text", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			RectTransform component2 = val4.GetComponent<RectTransform>();
			((Transform)component2).SetParent((Transform)(object)component, false);
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			TextMeshProUGUI component3 = val4.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component3).font = TMP_Settings.defaultFontAsset;
			((TMP_Text)component3).fontSize = 15f;
			((TMP_Text)component3).enableAutoSizing = false;
			((TMP_Text)component3).fontStyle = (FontStyles)1;
			((TMP_Text)component3).alignment = (TextAlignmentOptions)514;
			((Graphic)component3).color = new Color(1f, 0.99f, 0.9f, 1f);
			((Graphic)component3).raycastTarget = false;
			((TMP_Text)component3).margin = new Vector4(1f, 0f, 1f, 0f);
			((TMP_Text)component3).fontSharedMaterial = ((TMP_Text)component3).fontMaterial;
			((TMP_Text)component3).outlineWidth = 0.25f;
			((TMP_Text)component3).outlineColor = Color32.op_Implicit(new Color(0.05f, 0.05f, 0.05f, 1f));
			return val3;
		}

		private static void ApplyTarget(GameObject marker, Vector3 worldPosition)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			WorldIndicator val = marker.GetComponent<WorldIndicator>();
			if ((Object)(object)val == (Object)null)
			{
				val = marker.GetComponentInChildren<WorldIndicator>(true);
			}
			if (val != null)
			{
				val.SetTarget(worldPosition);
			}
		}

		private static Vector3 GetMarkerWorldPosition(TrackedItemLocation location)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			Object source = location.Source;
			Component val = (Component)(object)((source is Component) ? source : null);
			if (val != null && (Object)(object)val != (Object)null)
			{
				Renderer[] array = (from renderer in val.GetComponentsInChildren<Renderer>(true)
					where (Object)(object)renderer != (Object)null && !IsLocatorRenderer(((Component)renderer).transform)
					select renderer).ToArray();
				if (array.Length != 0)
				{
					Bounds bounds = array[0].bounds;
					for (int i = 1; i < array.Length; i++)
					{
						((Bounds)(ref bounds)).Encapsulate(array[i].bounds);
					}
					return new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y + 0.55f, ((Bounds)(ref bounds)).center.z);
				}
			}
			return location.FallbackPosition + new Vector3(0f, 0.55f, 0f);
		}

		private static bool IsLocatorRenderer(Transform transform)
		{
			while ((Object)(object)transform != (Object)null)
			{
				if (((Object)transform).name.StartsWith("StockAlertItemLocator_", StringComparison.Ordinal))
				{
					return true;
				}
				transform = transform.parent;
			}
			return false;
		}

		private static GameObject ResolveTemplate()
		{
			if ((Object)(object)_template != (Object)null)
			{
				return _template;
			}
			DepositIndicator? obj = ((IEnumerable<DepositIndicator>)Resources.FindObjectsOfTypeAll<DepositIndicator>()).FirstOrDefault((Func<DepositIndicator, bool>)IsSceneObject);
			object obj2 = ((obj != null) ? ((Component)obj).gameObject : null);
			if (obj2 == null)
			{
				LakeIndicator? obj3 = ((IEnumerable<LakeIndicator>)Resources.FindObjectsOfTypeAll<LakeIndicator>()).FirstOrDefault((Func<LakeIndicator, bool>)IsSceneObject);
				obj2 = ((obj3 != null) ? ((Component)obj3).gameObject : null);
				if (obj2 == null)
				{
					OreIndicator? obj4 = ((IEnumerable<OreIndicator>)Resources.FindObjectsOfTypeAll<OreIndicator>()).FirstOrDefault((Func<OreIndicator, bool>)IsSceneObject);
					obj2 = ((obj4 != null) ? ((Component)obj4).gameObject : null);
					if (obj2 == null)
					{
						BuildingIndicator? obj5 = ((IEnumerable<BuildingIndicator>)Resources.FindObjectsOfTypeAll<BuildingIndicator>()).FirstOrDefault((Func<BuildingIndicator, bool>)IsSceneObject);
						obj2 = ((obj5 != null) ? ((Component)obj5).gameObject : null);
					}
				}
			}
			_template = (GameObject)obj2;
			return _template;
		}

		private static bool IsSceneObject(Component component)
		{
			//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)
			int result;
			if ((Object)(object)component != (Object)null)
			{
				Scene scene = component.gameObject.scene;
				result = (((Scene)(ref scene)).IsValid() ? 1 : 0);
			}
			else
			{
				result = 0;
			}
			return (byte)result != 0;
		}
	}
	internal sealed class QueuedWorkerSlotCompanion : MonoBehaviour
	{
		private static readonly List<QueuedWorkerSlotCompanion> Instances = new List<QueuedWorkerSlotCompanion>();

		private static FieldInfo _fiBuilding;

		private static FieldInfo _fiWorkplace;

		private static FieldInfo _fiRaceIcon;

		private static PropertyInfo _piIsRemoved;

		private static PropertyInfo _piReactiveValue;

		private BuildingWorkerSlot _slot;

		private GameObject _queuedIconObject;

		private Image _queuedIconImage;

		private Button _queuedIconButton;

		private float _nextRefreshTime;

		public static void Attach(BuildingWorkerSlot slot)
		{
			if (!((Object)(object)slot == (Object)null) && !((Object)(object)((Component)slot).GetComponent<QueuedWorkerSlotCompanion>() != (Object)null))
			{
				((Component)slot).gameObject.AddComponent<QueuedWorkerSlotCompanion>().Initialize(slot);
			}
		}

		public static void ClearAll()
		{
			QueuedWorkerSlotCompanion[] array = Instances.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				array[i]?.Hide();
			}
		}

		private void Initialize(BuildingWorkerSlot slot)
		{
			_slot = slot;
			Instances.Add(this);
			EnsureUi();
			Refresh();
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
		}

		private void Update()
		{
			if (!(Time.unscaledTime < _nextRefreshTime))
			{
				_nextRefreshTime = Time.unscaledTime + 0.25f;
				Refresh();
			}
		}

		private void Refresh()
		{
			if ((Object)(object)_slot == (Object)null)
			{
				Hide();
				return;
			}
			if (!ConfigManager.EnableQueuedWorkerAssignments)
			{
				Hide();
				return;
			}
			if (!TryGetContext(out var building, out var _, out var workplaceIndex))
			{
				Hide();
				return;
			}
			if (IsBuildingRemoved(building))
			{
				WorkerAssignmentQueue.ClearQueuedRace(building, workplaceIndex);
				Hide();
				return;
			}
			RaceModel queuedRace = WorkerAssignmentQueue.GetQueuedRace(building, workplaceIndex);
			if ((Object)(object)queuedRace == (Object)null)
			{
				Hide();
				return;
			}
			EnsureUi();
			_queuedIconImage.sprite = queuedRace.roundIcon;
			((Graphic)_queuedIconImage).material = null;
			_queuedIconObject.SetActive(true);
		}

		private bool TryGetContext(out ProductionBuilding building, out WorkplaceModel workplace, out int workplaceIndex)
		{
			building = null;
			workplace = null;
			workplaceIndex = -1;
			if ((Object)(object)_slot == (Object)null)
			{
				return false;
			}
			if ((object)_fiBuilding == null)
			{
				_fiBuilding = typeof(BuildingWorkerSlot).GetField("building", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if ((object)_fiWorkplace == null)
			{
				_fiWorkplace = typeof(BuildingWorkerSlot).GetField("workplace", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			object? obj = _fiBuilding?.GetValue(_slot);
			building = (ProductionBuilding)((obj is ProductionBuilding) ? obj : null);
			object? obj2 = _fiWorkplace?.GetValue(_slot);
			workplace = (WorkplaceModel)((obj2 is WorkplaceModel) ? obj2 : null);
			if ((Object)(object)building == (Object)null || workplace == null)
			{
				return false;
			}
			workplaceIndex = building.GetIndexOf(workplace);
			return workplaceIndex >= 0;
		}

		private void EnsureUi()
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_0134: 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_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)
			if ((Object)(object)_queuedIconObject != (Object)null)
			{
				return;
			}
			if ((object)_fiRaceIcon == null)
			{
				_fiRaceIcon = typeof(BuildingWorkerSlot).GetField("raceIcon", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			object? obj = _fiRaceIcon?.GetValue(_slot);
			Image val = (Image)((obj is Image) ? obj : null);
			if (!((Object)(object)val == (Object)null))
			{
				_queuedIconObject = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent, false);
				((Object)_queuedIconObject).name = "QueuedWorkerIcon";
				_queuedIconImage = _queuedIconObject.GetComponent<Image>();
				_queuedIconButton = _queuedIconObject.GetComponent<Button>();
				if ((Object)(object)_queuedIconButton == (Object)null)
				{
					_queuedIconButton = _queuedIconObject.AddComponent<Button>();
				}
				((UnityEventBase)_queuedIconButton.onClick).RemoveAllListeners();
				((UnityEvent)_queuedIconButton.onClick).AddListener(new UnityAction(OpenQueueMenu));
				RectTransform component = _queuedIconObject.GetComponent<RectTransform>();
				Rect rect = component.rect;
				float num;
				if (!(((Rect)(ref rect)).width > 0f))
				{
					num = Mathf.Max(32f, component.sizeDelta.x);
				}
				else
				{
					rect = component.rect;
					num = ((Rect)(ref rect)).width;
				}
				float num2 = num;
				component.anchoredPosition += new Vector2(0f - (num2 + 8f), 0f);
				_queuedIconObject.SetActive(false);
			}
		}

		private void OpenQueueMenu()
		{
			if (!ConfigManager.EnableQueuedWorkerAssignments || !TryGetContext(out var building, out var workplace, out var _))
			{
				return;
			}
			RacesMenu val = FindRacesMenu();
			if (!((Object)(object)val == (Object)null))
			{
				val.SetUp(_queuedIconObject.GetComponent<RectTransform>(), (Building)(object)building, (Action<RaceModel>)delegate(RaceModel race)
				{
					WorkerAssignmentQueue.SetQueuedRace(building, workplace, race);
				}, (Action)delegate
				{
					WorkerAssignmentQueue.ClearQueuedRace(building, workplace);
				});
			}
		}

		private static RacesMenu FindRacesMenu()
		{
			return ((IEnumerable<RacesMenu>)Resources.FindObjectsOfTypeAll<RacesMenu>()).FirstOrDefault((Func<RacesMenu, bool>)delegate(RacesMenu menu)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				int result;
				if ((Object)(object)menu != (Object)null)
				{
					Scene scene = ((Component)menu).gameObject.scene;
					result = (((Scene)(ref scene)).IsValid() ? 1 : 0);
				}
				else
				{
					result = 0;
				}
				return (byte)result != 0;
			});
		}

		private static bool IsBuildingRemoved(ProductionBuilding building)
		{
			try
			{
				if ((object)_piIsRemoved == null)
				{
					_piIsRemoved = typeof(Building).GetProperty("IsRemoved", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				object obj = _piIsRemoved?.GetValue(building, null);
				if (obj == null)
				{
					return false;
				}
				if ((object)_piReactiveValue == null)
				{
					_piReactiveValue = obj.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				object obj2 = _piReactiveValue?.GetValue(obj, null);
				bool flag = default(bool);
				int num;
				if (obj2 is bool)
				{
					flag = (bool)obj2;
					num = 1;
				}
				else
				{
					num = 0;
				}
				return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private void Hide()
		{
			if ((Object)(object)_queuedIconObject != (Object)null)
			{
				_queuedIconObject.SetActive(false);
			}
		}
	}
	internal sealed class TrackedGoodClickTarget : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		public string GoodId;

		public static void Attach(Component target, string goodId)
		{
			if (!((Object)(object)target == (Object)null) && !string.IsNullOrWhiteSpace(goodId))
			{
				TrackedGoodClickTarget trackedGoodClickTarget = target.GetComponent<TrackedGoodClickTarget>();
				if ((Object)(object)trackedGoodClickTarget == (Object)null)
				{
					trackedGoodClickTarget = target.gameObject.AddComponent<TrackedGoodClickTarget>();
				}
				trackedGoodClickTarget.GoodId = goodId;
			}
		}

		public void OnPointerClick(PointerEventData eventData)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (eventData != null && (int)eventData.button == 0 && IsModifierPressed() && !string.IsNullOrWhiteSpace(GoodId))
			{
				ItemLocatorOverlay.Toggle(GoodId);
				((AbstractEventData)eventData).Use();
			}
		}

		private static bool IsModifierPressed()
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				return ((ButtonControl)current.leftCtrlKey).isPressed || ((ButtonControl)current.rightCtrlKey).isPressed || current.ctrlKey.isPressed;
			}
			return Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
		}
	}
}
namespace StockAlert.UI.Panels
{
	public static class UI
	{
		private sealed class SettingsPanelBehaviour : MonoBehaviour
		{
			private static Texture2D _windowBackground;

			private static Texture2D _panelBackground;

			private static Texture2D _buttonBackground;

			private static Texture2D _buttonHoverBackground;

			private static Texture2D _fieldBackground;

			private static Font _uiFont;

			private static GUIStyle _windowStyle;

			private static GUIStyle _titleStyle;

			private static GUIStyle _bodyStyle;

			private static GUIStyle _hintStyle;

			private static GUIStyle _toggleStyle;

			private static GUIStyle _buttonStyle;

			private static GUIStyle _fieldStyle;

			private static GUIStyle _sectionStyle;

			private Rect _windowRect = new Rect(40f, 40f, 430f, 415f);

			private string _multiplierInput = "2.0";

			private string _buildingShortageIconScaleInput = "0.90";

			private GameObject _clickBlockerCanvasObject;

			private RectTransform _clickBlockerRect;

			public bool Visible { get; private set; }

			public void Toggle()
			{
				Visible = !Visible;
				EnsureClickBlocker();
				UpdateClickBlockerState();
			}

			private void OnGUI()
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				if (!Visible)
				{
					UpdateClickBlockerState();
					return;
				}
				EnsureStyles();
				EnsureClickBlocker();
				_windowRect = GUILayout.Window(((Object)this).GetInstanceID(), _windowRect, new WindowFunction(DrawWindow), GUIContent.none, _windowStyle, Array.Empty<GUILayoutOption>());
				UpdateClickBlockerRect();
				UpdateClickBlockerState();
			}

			private void DrawWindow(int windowId)
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_01c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0220: Unknown result type (might be due to invalid IL or missing references)
				//IL_07ad: Unknown result type (might be due to invalid IL or missing references)
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(20f, 14f, ((Rect)(ref _windowRect)).width - 40f, 36f);
				GUI.Label(val, "Stock Alert Settings (1.1.8)", _titleStyle);
				GUI.Box(new Rect(18f, 50f, ((Rect)(ref _windowRect)).width - 36f, 1f), GUIContent.none, _sectionStyle);
				GUILayout.Space(42f);
				GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
				KeyboardShortcut toggleSettingsKey = ConfigManager.ToggleSettingsKey;
				GUILayout.Label("Toggle key: " + ((object)(KeyboardShortcut)(ref toggleSettingsKey)).ToString(), _bodyStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Use these settings to control the HUD and optional production automation.", _hintStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(12f);
				bool flag = GUILayout.Toggle(ConfigManager.ShowHud, "Show HUD", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag != ConfigManager.ShowHud)
				{
					ConfigManager.ShowHud = flag;
				}
				bool flag2 = GUILayout.Toggle(ConfigManager.MovableHud, "Movable HUD", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag2 != ConfigManager.MovableHud)
				{
					ConfigManager.MovableHud = flag2;
				}
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Space(20f);
				GUILayout.Label("HUD anchor", _bodyStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(92f) });
				if (GUILayout.Toggle(ConfigManager.HudAnchor == ConfigManager.HudHorizontalAnchor.Left, "Left", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(72f) }) && ConfigManager.HudAnchor != 0)
				{
					ConfigManager.HudAnchor = ConfigManager.HudHorizontalAnchor.Left;
					ConfigManager.HudPosition = new Vector2(-1f, -1f);
				}
				if (GUILayout.Toggle(ConfigManager.HudAnchor == ConfigManager.HudHorizontalAnchor.Right, "Right", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(72f) }) && ConfigManager.HudAnchor != ConfigManager.HudHorizontalAnchor.Right)
				{
					ConfigManager.HudAnchor = ConfigManager.HudHorizontalAnchor.Right;
					ConfigManager.HudPosition = new Vector2(-1f, -1f);
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
				bool flag3 = GUILayout.Toggle(ConfigManager.ShowBuildingAlertIndicators, "Building shortage indicators", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag3 != ConfigManager.ShowBuildingAlertIndicators)
				{
					ConfigManager.ShowBuildingAlertIndicators = flag3;
					if (flag3)
					{
						BuildingAlertIndicators.Refresh();
					}
					else
					{
						BuildingAlertIndicators.RestoreVanilla();
					}
				}
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Space(20f);
				bool flag4 = GUILayout.Toggle(ConfigManager.ShowBuildingSpecificItemIndicators, "Specific item indicator", _toggleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) });
				if (flag4 != ConfigManager.ShowBuildingSpecificItemIndicators)
				{
					ConfigManager.ShowBuildingSpecificItemIndicators = flag4;
					if (ConfigManager.ShowBuildingAlertIndicators)
					{
						BuildingAlertIndicators.Refresh();
					}
				}
				bool enabled = GUI.enabled;
				GUI.enabled = enabled && ConfigManager.ShowBuildingSpecificItemIndicators;
				GUILayout.Label("Size", _bodyStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) });
				string text = GUILayout.TextField(_buildingShortageIconScaleInput ?? string.Empty, _fieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) });
				if (text != _buildingShortageIconScaleInput)
				{
					_buildingShortageIconScaleInput = text;
					if (TryParseBuildingShortageIconScale(_buildingShortageIconScaleInput, out var value))
					{
						ConfigManager.BuildingShortageIconScale = value;
						_buildingShortageIconScaleInput = ConfigManager.BuildingShortageIconScale.ToString("0.00");
						if (ConfigManager.ShowBuildingAlertIndicators)
						{
							BuildingAlertIndicators.Refresh();
						}
					}
				}
				GUILayout.Label("(0.20 - 2.00)", _hintStyle, Array.Empty<GUILayoutOption>());
				GUI.enabled = enabled;
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
				bool flag5 = GUILayout.Toggle(ConfigManager.ShowBuilderStatusIcons, "Builder status icons", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag5 != ConfigManager.ShowBuilderStatusIcons)
				{
					ConfigManager.ShowBuilderStatusIcons = flag5;
					if (flag5)
					{
						BuilderStatusIndicators.Refresh();
					}
					else
					{
						BuilderStatusIndicators.Clear();
					}
				}
				bool flag6 = GUILayout.Toggle(ConfigManager.ShowIdleBuildersAlert, "Idle builders alert", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag6 != ConfigManager.ShowIdleBuildersAlert)
				{
					ConfigManager.ShowIdleBuildersAlert = flag6;
					if (!flag6)
					{
						IdleBuildersAlert.Clear();
					}
				}
				bool flag7 = GUILayout.Toggle(ConfigManager.EnableQueuedWorkerAssignments, "Queued worker assignments", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag7 != ConfigManager.EnableQueuedWorkerAssignments)
				{
					ConfigManager.EnableQueuedWorkerAssignments = flag7;
					if (!flag7)
					{
						WorkerAssignmentQueue.ClearAll();
						QueuedWorkerSlotCompanion.ClearAll();
					}
				}
				bool flag8 = GUILayout.Toggle(ConfigManager.ShowIngredientWheelBuildingStock, "Ingredient wheel building stock", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag8 != ConfigManager.ShowIngredientWheelBuildingStock)
				{
					ConfigManager.ShowIngredientWheelBuildingStock = flag8;
				}
				bool flag9 = GUILayout.Toggle(ConfigManager.ShowEmbarkationCostRanges, "Embarkation cost ranges", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag9 != ConfigManager.ShowEmbarkationCostRanges)
				{
					ConfigManager.ShowEmbarkationCostRanges = flag9;
				}
				bool flag10 = GUILayout.Toggle(ConfigManager.ShowTradeRouteProfit, "Trade route profit", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag10 != ConfigManager.ShowTradeRouteProfit)
				{
					ConfigManager.ShowTradeRouteProfit = flag10;
				}
				bool flag11 = GUILayout.Toggle(ConfigManager.SeasonEndingTradeRoutesAlert, "Season ending trade routes alert", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag11 != ConfigManager.SeasonEndingTradeRoutesAlert)
				{
					ConfigManager.SeasonEndingTradeRoutesAlert = flag11;
				}
				GUILayout.Space(10f);
				bool flag12 = GUILayout.Toggle(ConfigManager.AutoAdjustProductionLimits, "Auto-adjust production limits from consumers", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag12 != ConfigManager.AutoAdjustProductionLimits)
				{
					ConfigManager.AutoAdjustProductionLimits = flag12;
					if (flag12)
					{
						AutoProductionLimits.ApplyCurrentTargets();
					}
				}
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Space(20f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Consumer multiplier", _bodyStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) });
				string text2 = GUILayout.TextField(_multiplierInput ?? string.Empty, _fieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) });
				if (text2 != _multiplierInput)
				{
					_multiplierInput = text2;
					if (TryParseMultiplier(_multiplierInput, out var value2))
					{
						ConfigManager.AutoAdjustMultiplier = value2;
						_multiplierInput = ConfigManager.AutoAdjustMultiplier.ToString("0.0");
						if (ConfigManager.AutoAdjustProductionLimits)
						{
							AutoProductionLimits.ApplyCurrentTargets();
						}
					}
				}
				GUILayout.Label("(1.0 - 9.0)", _hintStyle, Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
				GUILayout.Space(4f);
				bool flag13 = GUILayout.Toggle(ConfigManager.AutoAdjustPurgingFire, "Auto-adjust Purging Fire to cysts + 1", _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag13 != ConfigManager.AutoAdjustPurgingFire)
				{
					ConfigManager.AutoAdjustPurgingFire = flag13;
					if (flag13)
					{
						AutoProductionLimits.ApplyCurrentTargets();
					}
				}
				GUILayout.Space(12f);
				if (GUILayout.Button("Close", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					Visible = false;
				}
				GUILayout.EndVertical();
				GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
			}

			public void RefreshInputs()
			{
				_multiplierInput = ConfigManager.AutoAdjustMultiplier.ToString("0.0");
				_buildingShortageIconScaleInput = ConfigManager.BuildingShortageIconScale.ToString("0.00");
			}

			private void EnsureClickBlocker()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Expected O, but got Unknown
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_clickBlockerCanvasObject != (Object)null))
				{
					_clickBlockerCanvasObject = new GameObject("StockAlertClickBlockerCanvas");
					Object.DontDestroyOnLoad((Object)(object)_clickBlockerCanvasObject);
					Canvas val = _clickBlockerCanvasObject.AddComponent<Canvas>();
					val.renderMode = (RenderMode)0;
					val.sortingOrder = 32767;
					_clickBlockerCanvasObject.AddComponent<GraphicRaycaster>();
					GameObject val2 = new GameObject("StockAlertClickBlocker");
					val2.transform.SetParent(_clickBlockerCanvasObject.transform, false);
					_clickBlockerRect = val2.AddComponent<RectTransform>();
					_clickBlockerRect.anchorMin = new Vector2(0f, 1f);
					_clickBlockerRect.anchorMax = new Vector2(0f, 1f);
					_clickBlockerRect.pivot = new Vector2(0f, 1f);
					Image val3 = val2.AddComponent<Image>();
					((Graphic)val3).color = new Color(0f, 0f, 0f, 0.001f);
					((Graphic)val3).raycastTarget = true;
				}
			}

			private void UpdateClickBlockerRect()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_clickBlockerRect == (Object)null))
				{
					_clickBlockerRect.anchoredPosition = new Vector2(((Rect)(ref _windowRect)).x, 0f - ((Rect)(ref _windowRect)).y);
					_clickBlockerRect.sizeDelta = new Vector2(((Rect)(ref _windowRect)).width, ((Rect)(ref _windowRect)).height);
				}
			}

			private void UpdateClickBlockerState()
			{
				if ((Object)(object)_clickBlockerCanvasObject != (Object)null)
				{
					_clickBlockerCanvasObject.SetActive(Visible);
				}
			}

			private static void EnsureStyles()
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: 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_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: 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_0102: 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_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0116: Expected O, but got Unknown
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Expected O, but got Unknown
				//IL_0130: Expected O, but got Unknown
				//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0204: Unknown result type (might be due to invalid IL or missing references)
				//IL_0209: Unknown result type (might be due to invalid IL or missing references)
				//IL_0222: Unknown result type (might be due to invalid IL or missing references)
				//IL_0227: Unknown result type (might be due to invalid IL or missing references)
				//IL_0240: Unknown result type (might be due to invalid IL or missing references)
				//IL_0245: Unknown result type (might be due to invalid IL or missing references)
				//IL_025e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0263: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0281: Unknown result type (might be due to invalid IL or missing references)
				//IL_029a: Unknown result type (might be due to invalid IL or missing references)
				//IL_029f: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_030e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0313: Unknown result type (might be due to invalid IL or missing references)
				//IL_0323: Expected O, but got Unknown
				//IL_0339: Unknown result type (might be due to invalid IL or missing references)
				//IL_033e: Unknown result type (might be due to invalid IL or missing references)
				//IL_034a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0353: Unknown result type (might be due to invalid IL or missing references)
				//IL_035b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0363: Unknown result type (might be due to invalid IL or missing references)
				//IL_0368: Unknown result type (might be due to invalid IL or missing references)
				//IL_0372: Expected O, but got Unknown
				//IL_0373: 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_0392: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a2: Expected O, but got Unknown
				//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e4: Expected O, but got Unknown
				//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0408: Unknown result type (might be due to invalid IL or missing references)
				//IL_040d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0417: Expected O, but got Unknown
				//IL_0418: Unknown result type (might be due to invalid IL or missing references)
				//IL_041e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0428: Expected O, but got Unknown
				//IL_0429: Unknown result type (might be due to invalid IL or missing references)
				//IL_0431: Unknown result type (might be due to invalid IL or missing references)
				//IL_044b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0450: Unknown result type (might be due to invalid IL or missing references)
				//IL_045b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0475: Unknown result type (might be due to invalid IL or missing references)
				//IL_047a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0485: Unknown result type (might be due to invalid IL or missing references)
				//IL_049f: Unknown result type (might be due to invalid IL or missing references)
				//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_04af: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_04de: Expected O, but got Unknown
				//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0502: Unknown result type (might be due to invalid IL or missing references)
				//IL_0513: Unknown result type (might be due to invalid IL or missing references)
				//IL_052d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0532: Unknown result type (might be due to invalid IL or missing references)
				//IL_053d: Unknown result type (might be due to invalid IL or missing references)
				//IL_054e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0568: Unknown result type (might be due to invalid IL or missing references)
				//IL_056d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0578: Unknown result type (might be due to invalid IL or missing references)
				//IL_0589: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c2: Expected O, but got Unknown
				//IL_05c8: Expected O, but got Unknown
				//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_05fb: Expected O, but got Unknown
				//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_060d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0627: Unknown result type (might be due to invalid IL or missing references)
				//IL_062c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0637: Unknown result type (might be due to invalid IL or missing references)
				//IL_0648: Unknown result type (might be due to invalid IL or missing references)
				//IL_0662: Unknown result type (might be due to invalid IL or missing references)
				//IL_0667: Unknown result type (might be due to invalid IL or missing references)
				//IL_0672: Unknown result type (might be due to invalid IL or missing references)
				//IL_0677: Unknown result type (might be due to invalid IL or missing references)
				//IL_0681: Expected O, but got Unknown
				//IL_0687: Expected O, but got Unknown
				//IL_0691: Unknown result type (might be due to invalid IL or missing references)
				//IL_0696: Unknown result type (might be due to invalid IL or missing references)
				//IL_06a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_06b6: Expected O, but got Unknown
				//IL