Decompiled source of Declutter v1.0.3

plugins/Declutter.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Declutter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+5b7d38a7387ce322d1c0106e8fe89c9ac4b47d62")]
[assembly: AssemblyProduct("Declutter")]
[assembly: AssemblyTitle("Declutter")]
[assembly: AssemblyVersion("1.0.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Declutter
{
	internal static class Categories
	{
		private static readonly HashSet<string> harvestAxes = new HashSet<string> { "AxeStone", "AxeFlint", "AxeBronze", "AxeIron", "AxeSilver_TW", "AxeBlackMetal" };

		public static readonly string[] GearGroups = new string[4] { "Tools", "Materials", "Weapons", "Armor" };

		public static readonly string[] FoodGroups = new string[5] { "Health", "Stamina", "Eitr", "Balanced", "Misc" };

		public static readonly string[] MeadGroups = new string[6] { "Health mead", "Stamina mead", "Eitr mead", "Resistance mead", "Utility mead", "Misc" };

		public static string Of(ItemDrop item)
		{
			(string, string) value;
			string text = (WikiData.Items.TryGetValue(((Object)item).name, out value) ? value.Item2 : "");
			if (text == "")
			{
				ItemDrop val = Biomes.FermentsTo(((Object)item).name);
				if (val != null && (Object)(object)val != (Object)(object)item)
				{
					return Of(val);
				}
			}
			if (text == "")
			{
				ItemDrop val2 = FoodItBecomes(item);
				if (val2 != null)
				{
					return Of(val2);
				}
			}
			if (text == "Food > Feast")
			{
				text = "Food";
			}
			if (text == "" || text == "Food")
			{
				text = Fallback(item.m_itemData.m_shared);
			}
			if (text == "Armor > Body")
			{
				text = "Armor > Chest";
			}
			if (text == "Misc Items > Forsaken offerings")
			{
				text = "Misc Items > Boss";
			}
			if (text == "Light sources")
			{
				text = "Light";
			}
			if (text == "Mead > Bog Witch")
			{
				text = "Mead > Utility";
			}
			string text2 = (text.Contains(" > ") ? text : (text + " > " + text));
			if (text2 == "Materials > Materials")
			{
				ItemDrop val3 = Biomes.ProductOf(((Object)item).name);
				if (val3 != null && (Object)(object)val3 != (Object)(object)item)
				{
					string text3 = Of(val3);
					string text4 = Group(text3);
					string text5 = ((text3 == "Weapons > Shields") ? "shields" : ((text4 == "Weapons") ? "weapons" : ((text4 == "Armor") ? "armor" : ((text4 != "Food" && ((Object)item).name.EndsWith("Uncooked", StringComparison.Ordinal)) ? "other" : null))));
					if (text5 != null)
					{
						text2 = "Materials > Casts: " + text5;
					}
				}
			}
			return text2;
		}

		private static ItemDrop FoodItBecomes(ItemDrop item)
		{
			ItemDrop val = Biomes.ProductOf(((Object)item).name) ?? item.m_itemData.m_shared.m_appendToolTip;
			if (!Object.op_Implicit((Object)(object)val) || !((Object)(object)val != (Object)(object)item) || !(Group(Of(val)) == "Food"))
			{
				return null;
			}
			return val;
		}

		public static bool AlsoTool(ItemDrop item)
		{
			return harvestAxes.Contains(((Object)item).name);
		}

		public static string Group(string path)
		{
			return path.Substring(0, path.IndexOf(" > ", StringComparison.Ordinal));
		}

		public static string Sub(string path)
		{
			return path.Substring(path.IndexOf(" > ", StringComparison.Ordinal) + 3);
		}

		public static bool SingleLevel(string path)
		{
			return Group(path) == Sub(path);
		}

		public static string SubLabel(string path)
		{
			if (!SingleLevel(path))
			{
				return Sub(path);
			}
			return Group(path);
		}

		public static bool IsFood(SharedData s)
		{
			return s.m_food + s.m_foodStamina + s.m_foodEitr > 0f;
		}

		public static string FoodType(SharedData s)
		{
			float food = s.m_food;
			float foodStamina = s.m_foodStamina;
			float foodEitr = s.m_foodEitr;
			if (food < foodEitr / 2f && foodStamina < foodEitr / 2f)
			{
				return "Eitr";
			}
			if (foodStamina < food / 2f)
			{
				return "Health";
			}
			if (food < foodStamina / 2f)
			{
				return "Stamina";
			}
			return "Balanced";
		}

		public static string RailGroup(ItemDrop item, bool foodStation, bool meadStation)
		{
			string path = Of(item);
			string text = Group(path);
			string text2 = Sub(path);
			if (meadStation)
			{
				if (!(text == "Mead") || Array.IndexOf(MeadGroups, text2 + " mead") < 0)
				{
					return "Misc";
				}
				return text2 + " mead";
			}
			if (foodStation)
			{
				if (text == "Food" && Array.IndexOf(FoodGroups, text2) >= 0)
				{
					return text2;
				}
				SharedData shared = item.m_itemData.m_shared;
				if (!IsFood(shared))
				{
					return "Misc";
				}
				return FoodType(shared);
			}
			switch (text)
			{
			case "Light":
			case "Tools":
			case "Bait":
				return "Tools";
			case "Weapons":
				return "Weapons";
			case "Armor":
			case "Trinket":
			case "Accessories":
				return "Armor";
			default:
				return "Materials";
			}
		}

		private static string UnknownSkillWeapon(SharedData s)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			if (s.m_attack != null && (int)s.m_attack.m_attackType == 2)
			{
				if ((s.m_name ?? "").IndexOf("bomb", StringComparison.OrdinalIgnoreCase) < 0)
				{
					return "Weapons > Throwing";
				}
				return "Weapons > Bombs";
			}
			if (!(((DamageTypes)(ref s.m_damages)).GetTotalDamage() > 0f))
			{
				return "Tools";
			}
			return "Weapons > Other";
		}

		private static string Fallback(SharedData s)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected I4, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00d4: Expected I4, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Invalid comparison between Unknown and I4
			if (IsFood(s))
			{
				return "Food > " + FoodType(s);
			}
			ItemType itemType = s.m_itemType;
			switch (itemType - 1)
			{
			case 2:
			case 3:
			case 13:
			case 21:
			{
				SkillType skillType = s.m_skillType;
				switch (skillType - 1)
				{
				default:
					if ((int)skillType != 104)
					{
						break;
					}
					return "Tools";
				case 0:
					return "Weapons > Swords";
				case 1:
					return "Weapons > Knives";
				case 2:
					return "Weapons > Clubs";
				case 6:
					return "Weapons > Axes";
				case 3:
					return "Weapons > Polearms";
				case 4:
					return "Weapons > Spears";
				case 10:
					return "Weapons > Unarmed";
				case 7:
					return "Weapons > Bows";
				case 13:
					return "Weapons > Crossbows";
				case 8:
					return "Weapons > Elemental Magic";
				case 9:
					return "Weapons > Blood Magic";
				case 11:
					return "Tools";
				case 5:
				case 12:
					break;
				}
				return UnknownSkillWeapon(s);
			}
			case 4:
				return "Weapons > Shields";
			case 5:
				return "Armor > Head";
			case 6:
				return "Armor > Body";
			case 10:
				return "Armor > Legs";
			case 16:
				return "Armor > Capes";
			case 11:
				return "Armor";
			case 17:
				return "Accessories";
			case 23:
				return "Trinket";
			case 8:
			case 22:
				if ((s.m_ammoType ?? "").IndexOf("bait", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return "Bait";
				}
				if (s.m_ammoType == "$ammo_arrows")
				{
					return "Weapons > Arrows";
				}
				if (s.m_ammoType == "$ammo_bolts")
				{
					return "Weapons > Bolts";
				}
				return "Weapons > Missiles";
			case 18:
				return "Tools";
			case 14:
				return "Light";
			case 1:
				return "Food > Mead";
			case 0:
				return "Materials";
			case 20:
				return "Fish";
			case 12:
				return "Trophies";
			default:
				return "Misc Items";
			}
		}
	}
	internal static class Biomes
	{
		private static readonly Biome[] progression;

		private static readonly string[] labels;

		public static readonly int Unknown;

		private static readonly Dictionary<string, int> cache;

		private static Dictionary<string, int> overrides;

		private static Dictionary<string, int> natural;

		private static Dictionary<string, List<Recipe>> recipesFor;

		private static Dictionary<string, Piece> stationPieces;

		private static Dictionary<string, List<Piece>> upgradesOf;

		private static readonly Dictionary<string, int> stationCache;

		private static Dictionary<string, List<string>> conversionsFor;

		private static readonly Dictionary<string, ItemDrop> fermentsTo;

		private static readonly Dictionary<string, ItemDrop> convertsTo;

		private static bool dumped;

		private static readonly Dictionary<string, Biome> corrections;

		private static readonly Dictionary<string, Biome> feasts;

		private static readonly HashSet<string> earliestIngredient;

		public static ItemDrop FermentsTo(string name)
		{
			Build();
			if (!fermentsTo.TryGetValue(name, out var value))
			{
				return null;
			}
			return value;
		}

		public static string Label(int tier)
		{
			return labels[Math.Min(tier, Unknown)];
		}

		private static int RankOfLabel(string label)
		{
			int num = Array.IndexOf(labels, label);
			if (num < 0 || num >= Unknown)
			{
				return Unknown;
			}
			return num;
		}

		public static void Reset()
		{
			cache.Clear();
			stationCache.Clear();
			fermentsTo.Clear();
			convertsTo.Clear();
			natural = null;
			dumped = false;
		}

		private static int Rank(Biome b)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < progression.Length; i++)
			{
				if ((b & progression[i]) != 0)
				{
					return i;
				}
			}
			return Unknown;
		}

		private static int MaxKnown(int a, int b)
		{
			if (a != Unknown)
			{
				if (b != Unknown)
				{
					return Math.Max(a, b);
				}
				return a;
			}
			return b;
		}

		private static int MinKnown(int a, int b)
		{
			if (a != Unknown)
			{
				if (b != Unknown)
				{
					return Math.Min(a, b);
				}
				return a;
			}
			return b;
		}

		private static bool Wiki(string prefab, out int tier)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			tier = (corrections.TryGetValue(prefab, out var value) ? Rank(value) : (WikiData.Items.TryGetValue(prefab, out (string, string) value2) ? RankOfLabel(value2.Item1) : Unknown));
			return tier != Unknown;
		}

		public static bool FromWiki(Recipe r)
		{
			if (Wiki(((Object)r.m_item).name, out var _))
			{
				return !overrides.ContainsKey(((Object)r.m_item).name);
			}
			return false;
		}

		public static int OfRecipe(Recipe r)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Build();
			if (overrides.TryGetValue(((Object)r.m_item).name, out var value))
			{
				return value;
			}
			if (feasts.TryGetValue(((Object)r.m_item).name, out var value2))
			{
				return Rank(value2);
			}
			return MaxKnown(WithoutStation(r), StationTier(r.m_craftingStation, r.m_minStationLevel));
		}

		private static int WithoutStation(Recipe r)
		{
			int num = Ingredients(r);
			if (!Wiki(((Object)r.m_item).name, out var tier))
			{
				return num;
			}
			return MaxKnown(tier, num);
		}

		private static int StationTier(CraftingStation station, int level)
		{
			Build();
			if (!Object.op_Implicit((Object)(object)station) || !stationPieces.TryGetValue(((Object)station).name, out var value))
			{
				return Unknown;
			}
			string key = ((Object)station).name + "#" + level;
			if (stationCache.TryGetValue(key, out var value2))
			{
				return value2;
			}
			value2 = PieceTier(value);
			if (level > 1 && upgradesOf.TryGetValue(((Object)station).name, out var value3))
			{
				List<int> list = (from x in value3.Select(PieceTier)
					orderby x
					select x).ToList();
				value2 = MaxKnown(value2, list[Math.Min(level - 1, list.Count) - 1]);
			}
			return stationCache[key] = value2;
		}

		private static int PieceTier(Piece p)
		{
			int num = Unknown;
			if (p.m_resources != null)
			{
				Requirement[] resources = p.m_resources;
				foreach (Requirement val in resources)
				{
					if (val != null && Object.op_Implicit((Object)(object)val.m_resItem) && val.m_amount > 0)
					{
						num = MaxKnown(num, OfItem(((Object)val.m_resItem).name));
					}
				}
			}
			return num;
		}

		private static int Ingredients(Recipe r)
		{
			bool flag = r.m_requireOnlyOneIngredient && earliestIngredient.Contains(((Object)r.m_item).name);
			int num = Unknown;
			Requirement[] resources = r.m_resources;
			foreach (Requirement val in resources)
			{
				if (Object.op_Implicit((Object)(object)val.m_resItem) && !val.m_upgraderResource && val.m_amount > 0)
				{
					int b = OfItem(((Object)val.m_resItem).name);
					num = (flag ? MinKnown(num, b) : MaxKnown(num, b));
				}
			}
			return num;
		}

		private static int OfItem(string name)
		{
			if (cache.TryGetValue(name, out var value))
			{
				return value;
			}
			if (overrides.TryGetValue(name, out value) || Wiki(name, out value))
			{
				return cache[name] = value;
			}
			cache[name] = Unknown;
			value = (natural.TryGetValue(name, out var value2) ? value2 : Unknown);
			if (recipesFor.TryGetValue(name, out var value3))
			{
				foreach (Recipe item in value3)
				{
					value = Math.Min(value, Ingredients(item));
				}
			}
			if (conversionsFor.TryGetValue(name, out var value4))
			{
				foreach (string item2 in value4)
				{
					value = Math.Min(value, OfItem(item2));
				}
			}
			return cache[name] = value;
		}

		private static void Build()
		{
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			if (natural != null)
			{
				return;
			}
			natural = new Dictionary<string, int>();
			stationPieces = new Dictionary<string, Piece>();
			upgradesOf = new Dictionary<string, List<Piece>>();
			recipesFor = new Dictionary<string, List<Recipe>>();
			conversionsFor = new Dictionary<string, List<string>>();
			LoadOverrides();
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if (Object.op_Implicit((Object)(object)recipe) && Object.op_Implicit((Object)(object)recipe.m_item))
				{
					Add(recipesFor, ((Object)recipe.m_item).name, recipe);
				}
			}
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				if (!Object.op_Implicit((Object)(object)prefab))
				{
					continue;
				}
				Piece component = prefab.GetComponent<Piece>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)prefab.GetComponent<CraftingStation>()))
				{
					stationPieces[((Object)prefab).name] = component;
				}
				StationExtension component2 = prefab.GetComponent<StationExtension>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.m_craftingStation))
				{
					Add(upgradesOf, ((Object)component2.m_craftingStation).name, component);
				}
				Smelter component3 = prefab.GetComponent<Smelter>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					foreach (ItemConversion item in component3.m_conversion)
					{
						AddConversion(item.m_from, item.m_to);
					}
				}
				CookingStation component4 = prefab.GetComponent<CookingStation>();
				if (Object.op_Implicit((Object)(object)component4))
				{
					foreach (ItemConversion item2 in component4.m_conversion)
					{
						AddConversion(item2.m_from, item2.m_to);
					}
				}
				Fermenter component5 = prefab.GetComponent<Fermenter>();
				if (!Object.op_Implicit((Object)(object)component5))
				{
					continue;
				}
				foreach (ItemConversion item3 in component5.m_conversion)
				{
					AddConversion(item3.m_from, item3.m_to);
					if (Object.op_Implicit((Object)(object)item3.m_from) && Object.op_Implicit((Object)(object)item3.m_to))
					{
						fermentsTo[((Object)item3.m_from).name] = item3.m_to;
					}
				}
			}
			SpawnSystemList[] array = Resources.FindObjectsOfTypeAll<SpawnSystemList>();
			for (int i = 0; i < array.Length; i++)
			{
				foreach (SpawnData spawner in array[i].m_spawners)
				{
					if (spawner.m_enabled)
					{
						Drops(spawner.m_prefab, Rank(spawner.m_biome), 0);
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)ZoneSystem.instance))
			{
				return;
			}
			foreach (ZoneVegetation item4 in ZoneSystem.instance.m_vegetation)
			{
				if (item4.m_enable)
				{
					Drops(item4.m_prefab, Rank(item4.m_biome), 0);
				}
			}
		}

		private static void AddConversion(ItemDrop from, ItemDrop to)
		{
			if (Object.op_Implicit((Object)(object)from) && Object.op_Implicit((Object)(object)to))
			{
				Add(conversionsFor, ((Object)to).name, ((Object)from).name);
				convertsTo[((Object)from).name] = to;
			}
		}

		public static ItemDrop ProductOf(string name)
		{
			Build();
			if (convertsTo.TryGetValue(name, out var value))
			{
				return value;
			}
			if (!name.EndsWith("Uncooked", StringComparison.Ordinal) || !Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return null;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name.Substring(0, name.Length - "Uncooked".Length));
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				return null;
			}
			return itemPrefab.GetComponent<ItemDrop>();
		}

		private static void Add<T>(Dictionary<string, List<T>> d, string key, T value)
		{
			if (!d.TryGetValue(key, out var value2))
			{
				value2 = (d[key] = new List<T>());
			}
			value2.Add(value);
		}

		private static void Note(GameObject item, int rank)
		{
			if (Object.op_Implicit((Object)(object)item) && (!natural.TryGetValue(((Object)item).name, out var value) || rank < value))
			{
				natural[((Object)item).name] = rank;
			}
		}

		private static void Note(DropTable table, int rank)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (table?.m_drops == null)
			{
				return;
			}
			foreach (DropData drop in table.m_drops)
			{
				Note(drop.m_item, rank);
			}
		}

		private static void Drops(GameObject go, int rank, int depth)
		{
			if (!Object.op_Implicit((Object)(object)go) || rank == Unknown || depth > 3)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)go.GetComponent<ItemDrop>()))
			{
				Note(go, rank);
			}
			CharacterDrop component = go.GetComponent<CharacterDrop>();
			if (Object.op_Implicit((Object)(object)component))
			{
				foreach (Drop drop in component.m_drops)
				{
					Note(drop.m_prefab, rank);
				}
			}
			Pickable component2 = go.GetComponent<Pickable>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				Note(component2.m_itemPrefab, rank);
				Note(component2.m_extraDrops, rank);
			}
			MineRock component3 = go.GetComponent<MineRock>();
			if (Object.op_Implicit((Object)(object)component3))
			{
				Note(component3.m_dropItems, rank);
			}
			MineRock5 component4 = go.GetComponent<MineRock5>();
			if (Object.op_Implicit((Object)(object)component4))
			{
				Note(component4.m_dropItems, rank);
			}
			DropOnDestroyed component5 = go.GetComponent<DropOnDestroyed>();
			if (Object.op_Implicit((Object)(object)component5))
			{
				Note(component5.m_dropWhenDestroyed, rank);
			}
			TreeBase component6 = go.GetComponent<TreeBase>();
			if (Object.op_Implicit((Object)(object)component6))
			{
				Note(component6.m_dropWhenDestroyed, rank);
				Drops(component6.m_logPrefab, rank, depth + 1);
			}
			TreeLog component7 = go.GetComponent<TreeLog>();
			if (Object.op_Implicit((Object)(object)component7))
			{
				Note(component7.m_dropWhenDestroyed, rank);
				Drops(component7.m_subLogPrefab, rank, depth + 1);
			}
			Destructible component8 = go.GetComponent<Destructible>();
			if (Object.op_Implicit((Object)(object)component8))
			{
				Drops(component8.m_spawnWhenDestroyed, rank, depth + 1);
			}
		}

		private static void LoadOverrides()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			overrides = new Dictionary<string, int>();
			string path = Path.Combine(Plugin.ConfigDir, "Declutter.overrides.txt");
			if (!File.Exists(path))
			{
				File.WriteAllText(path, "# Force an item's biome. Use the prefab name from Declutter.dump.csv.\n# Biomes: Meadows, BlackForest, Ocean, Swamp, Mountain, Plains, Mistlands, AshLands, DeepNorth\n# Example:\n# SomeModdedOre = Mountain\n");
				return;
			}
			string[] array = File.ReadAllLines(path);
			foreach (string text in array)
			{
				string[] array2 = text.Split('=');
				if (!text.TrimStart().StartsWith("#") && array2.Length == 2)
				{
					if (Enum.TryParse<Biome>(array2[1].Trim(), ignoreCase: true, out Biome result))
					{
						overrides[array2[0].Trim()] = Rank(result);
					}
					else
					{
						Plugin.Log.LogWarning((object)("bad override line: " + text));
					}
				}
			}
		}

		public static void DumpOnce()
		{
			if (dumped || !Object.op_Implicit((Object)(object)ObjectDB.instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				return;
			}
			dumped = true;
			Build();
			List<string> list = new List<string> { "prefab,name,station,station_level,station_biome,biome_without_station,enabled,biome,biome_source,category,category_source" };
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if (Object.op_Implicit((Object)(object)recipe) && Object.op_Implicit((Object)(object)recipe.m_item))
				{
					(string, string) value;
					bool flag = WikiData.Items.TryGetValue(((Object)recipe.m_item).name, out value) && value.Item2 != "" && value.Item2 != "Food";
					list.Add(string.Join(",", ((Object)recipe.m_item).name, "\"" + Localization.instance.Localize(recipe.m_item.m_itemData.m_shared.m_name).Replace("\"", "'") + "\"", Object.op_Implicit((Object)(object)recipe.m_craftingStation) ? ((Object)recipe.m_craftingStation).name : "(hand)", recipe.m_minStationLevel, Object.op_Implicit((Object)(object)recipe.m_craftingStation) ? Label(StationTier(recipe.m_craftingStation, recipe.m_minStationLevel)) : "", Label(WithoutStation(recipe)), recipe.m_enabled ? "yes" : "no", Label(OfRecipe(recipe)), overrides.ContainsKey(((Object)recipe.m_item).name) ? "override" : (FromWiki(recipe) ? "wiki" : "derived"), Categories.Of(recipe.m_item), flag ? "wiki" : "derived"));
				}
			}
			File.WriteAllLines(Path.Combine(Plugin.ConfigDir, "Declutter.dump.csv"), list);
		}

		static Biomes()
		{
			Biome[] array = new Biome[9];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			progression = (Biome[])(object)array;
			labels = new string[10] { "Meadows", "Black Forest", "Ocean", "Swamp", "Mountain", "Plains", "Mistlands", "Ashlands", "Deep North", "Unsorted" };
			Unknown = progression.Length;
			cache = new Dictionary<string, int>();
			stationCache = new Dictionary<string, int>();
			fermentsTo = new Dictionary<string, ItemDrop>();
			convertsTo = new Dictionary<string, ItemDrop>();
			corrections = new Dictionary<string, Biome>
			{
				["BoltBone"] = (Biome)512,
				["BoltIron"] = (Biome)512,
				["BoltBlackmetal"] = (Biome)512,
				["CrossbowArbalest"] = (Biome)512,
				["KnifeSkollAndHati"] = (Biome)512,
				["Lantern"] = (Biome)512,
				["TurretBoltWood"] = (Biome)4,
				["FishingBaitForest"] = (Biome)2,
				["FishingBaitOcean"] = (Biome)2,
				["FishRaw"] = (Biome)2,
				["CeramicPlate"] = (Biome)512,
				["ShieldCore"] = (Biome)512,
				["FireworksRocket_White"] = (Biome)16,
				["FireworksRocket_Cyan"] = (Biome)16,
				["Thunderstone"] = (Biome)8,
				["BarrelRings"] = (Biome)8,
				["CandleWick"] = (Biome)2,
				["MushroomBzerker"] = (Biome)4,
				["FragrantBundle"] = (Biome)4,
				["ScytheHandle"] = (Biome)4,
				["SpiceMountains"] = (Biome)4,
				["SpicePlains"] = (Biome)16,
				["SpiceMistlands"] = (Biome)512,
				["SpiceAshlands"] = (Biome)32,
				["SpiceDeepNorth"] = (Biome)64
			};
			feasts = new Dictionary<string, Biome>
			{
				["FeastMeadows_Material"] = (Biome)1,
				["FeastBlackforest_Material"] = (Biome)8,
				["FeastOceans_Material"] = (Biome)256,
				["FeastSwamps_Material"] = (Biome)2,
				["FeastMountains_Material"] = (Biome)4,
				["FeastPlains_Material"] = (Biome)16,
				["FeastMistlands_Material"] = (Biome)512,
				["FeastAshlands_Material"] = (Biome)32,
				["FeastDeepNorth_Material"] = (Biome)64
			};
			earliestIngredient = new HashSet<string> { "FishRaw" };
		}
	}
	[BepInPlugin("bazilisx.Declutter", "Declutter", "1.0.3")]
	public class Plugin : BaseUnityPlugin
	{
		private sealed class ConfigurationManagerAttributes
		{
			public bool? Browsable;

			public bool? IsAdvanced;

			public int? Order;
		}

		private class Clicker : MonoBehaviour, IPointerClickHandler, IEventSystemHandler, IPointerDownHandler
		{
			public Action onClick;

			public void OnPointerClick(PointerEventData e)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)e.button == 0)
				{
					onClick?.Invoke();
				}
			}

			public void OnPointerDown(PointerEventData e)
			{
			}
		}

		private class DragCheck : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerEnterHandler
		{
			public GameObject marker;

			public Func<bool> isOn;

			public Action<bool> setOn;

			public void OnPointerDown(PointerEventData e)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)e.button == 0)
				{
					dragValue = !isOn();
					Apply();
					dragging = "flyout";
				}
			}

			public void OnPointerEnter(PointerEventData e)
			{
				if (dragging == "flyout" && Input.GetMouseButton(0) && isOn() != dragValue)
				{
					Apply();
				}
			}

			private void Apply()
			{
				setOn(dragValue);
				marker.SetActive(dragValue);
			}
		}

		private class IconButton : MonoBehaviour, IPointerClickHandler, IEventSystemHandler, IPointerDownHandler, IPointerEnterHandler
		{
			public Action onClick;

			public Action onDisabledClick;

			public Image bg;

			public Image ring;

			public Image icon;

			public GameObject partial;

			public string dragRow;

			public Func<bool> isOn;

			public Action<bool> setOn;

			private bool disabled;

			private Color? tint;

			public void OnPointerClick(PointerEventData e)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)e.button == 0 && dragRow == null)
				{
					if (disabled)
					{
						onDisabledClick?.Invoke();
					}
					else
					{
						onClick?.Invoke();
					}
				}
			}

			public void OnPointerDown(PointerEventData e)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)e.button == 0 && dragRow != null)
				{
					if (disabled)
					{
						onDisabledClick?.Invoke();
						return;
					}
					dragValue = !isOn();
					Apply();
					dragging = dragRow;
				}
			}

			public void OnPointerEnter(PointerEventData e)
			{
				if (dragRow != null && dragging == dragRow && !disabled && Input.GetMouseButton(0) && isOn() != dragValue)
				{
					Apply();
				}
			}

			private void Apply()
			{
				setOn(dragValue);
				Set(dragValue, partial: false, disabled, tint);
			}

			public void Set(bool on, bool partial = false, bool disabled = false, Color? tint = null)
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: 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_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: 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_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				this.disabled = disabled;
				this.tint = tint;
				bool flag = on && !disabled;
				SetFrame(bg, !flag, disabled);
				((Graphic)ring).color = (flag ? gold : (disabled ? ringDisabled : ringOff));
				if (tint.HasValue)
				{
					Color value = tint.Value;
					((Graphic)icon).color = new Color(value.r, value.g, value.b, flag ? 1f : (disabled ? 0.18f : 0.35f));
				}
				else
				{
					((Graphic)icon).color = (flag ? gold : (disabled ? iconDisabled : dim));
				}
				this.partial.SetActive(partial && !disabled);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		private static class Awake_Patch
		{
			private static void Postfix()
			{
				Biomes.Reset();
				books.Clear();
				originalOffsets.Clear();
				descScroll = null;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		private static class Hide_Patch
		{
			private static void Postfix()
			{
				CloseFlyout();
				search = "";
				if (Object.op_Implicit((Object)(object)searchField))
				{
					searchField.SetTextWithoutNotify("");
				}
			}
		}

		[HarmonyPatch]
		private static class ZInput_TypingBlock
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				return new string[6] { "GetButton", "GetButtonDown", "GetButtonUp", "GetKey", "GetKeyDown", "GetKeyUp" }.SelectMany((string n) => from m in AccessTools.GetDeclaredMethods(typeof(ZInput))
					where m.Name == n && m.IsStatic && m.ReturnType == typeof(bool)
					select m);
			}

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

		[HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")]
		private static class UpdateRecipeList_Patch
		{
			private static void Prefix(InventoryGui __instance, ref List<Recipe> recipes)
			{
				try
				{
					if (dumpCsv.Value)
					{
						Biomes.DumpOnce();
					}
					if (__instance.InCraftTab())
					{
						stationRecipes = recipes.Where((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item)).ToList();
						List<Recipe> recipes2 = StationBook();
						meadStation = MeadStation(recipes2);
						foodStation = !meadStation && FoodStation(recipes2);
						bool searching = !string.IsNullOrWhiteSpace(search);
						recipes = recipes.Where((Recipe r) => Object.op_Implicit((Object)(object)r.m_item) && !Hidden(r) && (!searching || MatchesSearch(r))).ToList();
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}

			private static void Postfix(InventoryGui __instance)
			{
				try
				{
					EnsureUi(__instance);
					Relayout(__instance);
					RefreshUi(__instance);
				}
				catch (Exception ex)
				{
					Log.LogError((object)ex);
				}
			}
		}

		public const string Guid = "bazilisx.Declutter";

		public const string Name = "Declutter";

		public const string Version = "1.0.3";

		internal static ManualLogSource Log;

		private static ConfigEntry<bool> dumpCsv;

		private static ConfigEntry<Vector2> toolbarOffset;

		private static ConfigEntry<Vector2> railOffset;

		private static ConfigEntry<int> buttonScale;

		private static ConfigEntry<int> iconScale;

		private static ConfigEntry<int> buttonSpacing;

		private static ConfigEntry<int> biomeRows;

		private static ConfigEntry<int> itemText;

		private static ConfigEntry<int> itemSpacing;

		private static ConfigEntry<int> headerText;

		private static ConfigEntry<int> headerSpacing;

		private static ConfigEntry<int> headerIconScale;

		private static ConfigEntry<int> headerIconGap;

		private static ConfigEntry<bool> headerIcons;

		private static ConfigEntry<string> hiddenBiomesCfg;

		private static ConfigEntry<string> hiddenGroupsCfg;

		private static ConfigEntry<string> hiddenSubsCfg;

		private static ConfigEntry<string> stationSortCfg;

		private static ConfigEntry<string> collapsedCfg;

		private static Dictionary<string, HashSet<string>> hiddenBiomesBy;

		private static Dictionary<string, HashSet<string>> hiddenGroupsBy;

		private static Dictionary<string, HashSet<string>> hiddenSubsBy;

		private static Dictionary<string, string> stationSort;

		private static Dictionary<string, HashSet<string>> collapsed;

		private static readonly string[] biomeIcons = new string[9] { "biome_meadows", "biome_blackforest", "biome_ocean", "biome_swamp", "biome_mountain", "biome_plains", "biome_mistlands", "biome_ashlands", "biome_deepnorth" };

		private static readonly Dictionary<string, Color> forkColors = new Dictionary<string, Color>
		{
			["Health"] = new Color(1f, 0.5f, 0.5f),
			["Stamina"] = new Color(1f, 1f, 0.5f),
			["Eitr"] = new Color(0.6f, 0.6f, 1f),
			["Balanced"] = Color.white
		};

		private static readonly Dictionary<string, Color> meadColors = new Dictionary<string, Color>
		{
			["Health mead"] = forkColors["Health"],
			["Stamina mead"] = forkColors["Stamina"],
			["Eitr mead"] = forkColors["Eitr"],
			["Resistance mead"] = new Color(0.71f, 0.7f, 0.66f),
			["Utility mead"] = new Color(0.36f, 0.79f, 0.65f)
		};

		private static readonly Color gold = new Color(0.94f, 0.71f, 0.29f);

		private static readonly Color tan = new Color(0.8f, 0.71f, 0.54f);

		private static readonly Color textCol = new Color(0.91f, 0.86f, 0.77f);

		private static readonly Color dim = new Color(0.42f, 0.36f, 0.27f);

		private static readonly Color lineCol = new Color(0.35f, 0.27f, 0.19f);

		private static readonly Color link = new Color(0.5f, 0.7f, 1f);

		private static readonly Color ringOff = new Color(0.36f, 0.3f, 0.23f);

		private static readonly Color ringDisabled = new Color(0.22f, 0.18f, 0.14f);

		private static readonly Color iconDisabled = new Color(0.27f, 0.23f, 0.18f);

		private static readonly Color plainBg = new Color(0.17f, 0.15f, 0.13f);

		private static readonly Color panelCol = new Color(0.1f, 0.07f, 0.04f, 0.97f);

		private static RectTransform toolbar;

		private static RectTransform rail;

		private static RectTransform flyout;

		private static IconButton[] sortButtons;

		private static IconButton[] biomeButtons;

		private static Image biomeArrow;

		private static readonly List<GameObject> headers = new List<GameObject>();

		private static readonly List<string> headerLabels = new List<string>();

		private static ScrollRect descScroll;

		private static string lastDesc;

		private static (Transform parent, int index, Vector2 aMin, Vector2 aMax, Vector2 pivot, Vector2 oMin, Vector2 oMax) descOriginal;

		private static string lastHeader;

		private static float lastHeaderTime;

		private static GameObject tooltipPrefab;

		private static TMP_FontAsset font;

		private static Sprite frame;

		private static Color headerGold;

		private static float fontSize;

		private static float size;

		private static string flyGroup;

		private static bool foodStation;

		private static bool meadStation;

		private static string dragging;

		private static bool dragValue;

		private static TMP_InputField searchField;

		private static string search = "";

		private static int typingFrame = -10;

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

		private static readonly FieldInfo availableField = AccessTools.Field(typeof(InventoryGui), "m_availableRecipes");

		private static readonly FieldInfo baseSizeField = AccessTools.Field(typeof(InventoryGui), "m_recipeListBaseSize");

		private static readonly MethodInfo updateCraftingPanel = AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", (Type[])null, (Type[])null);

		private static PropertyInfo pairRecipe;

		private static PropertyInfo pairCanCraft;

		private static PropertyInfo pairElement;

		internal static string ConfigDir;

		private const float ListTopPad = 4f;

		private static readonly Dictionary<RectTransform, (Vector2 min, Vector2 max)> originalOffsets = new Dictionary<RectTransform, (Vector2, Vector2)>();

		private static List<Recipe> stationRecipes = new List<Recipe>();

		private static readonly Dictionary<string, List<Recipe>> books = new Dictionary<string, List<Recipe>>();

		private static HashSet<string> hiddenBiomes => ForStation(hiddenBiomesBy);

		private static HashSet<string> hiddenGroups => ForStation(hiddenGroupsBy);

		private static HashSet<string> hiddenSubs => ForStation(hiddenSubsBy);

		private void Awake()
		{
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Expected O, but got Unknown
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			int order = 1000;
			buttonScale = Setting<int>("1 - Buttons", "Button size %", 100, "Size of every toolbar and category button (both always match). Capped so the toolbar never runs past the crafting panel.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(60, 200));
			iconScale = Setting<int>("1 - Buttons", "Icon size %", 100, "Size of the icon inside each button.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(60, 125));
			buttonSpacing = Setting<int>("1 - Buttons", "Button spacing", 0, "Gap between neighbouring buttons on the toolbar and the category buttons, in pixels. 0 = frames touch.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10));
			biomeRows = Setting<int>("1 - Buttons", "Biome rows", 1, "1 = all nine biome buttons in one row. 2 = two rows (5 + 4), for narrow screens or big buttons.", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[2] { 1, 2 }));
			itemText = Setting<int>("2 - Recipe list", "Item text size %", 100, "Recipe names in the list.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(60, 140));
			itemSpacing = Setting<int>("2 - Recipe list", "Item spacing %", 100, "Space from one recipe row to the next.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(90, 150));
			headerText = Setting<int>("2 - Recipe list", "Header text size %", 100, "Biome header text.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(60, 140));
			headerSpacing = Setting<int>("2 - Recipe list", "Header spacing %", 100, "Space taken by each biome header (collapsed headers always stack a little tighter).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(80, 150));
			headerIcons = Setting<bool>("2 - Recipe list", "Header icons", def: true, "Show the biome icon in front of each header.");
			headerIconScale = Setting<int>("2 - Recipe list", "Header icon size %", 100, "Size of the biome icon in each header.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 150));
			headerIconGap = Setting<int>("2 - Recipe list", "Header icon gap", 5, "Space between a header's icon and its text, in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20));
			dumpCsv = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Advanced", "DumpCsv", false, new ConfigDescription("Write BepInEx/config/Declutter.dump.csv the first time a crafting menu opens, listing every recipe's biome and category and where each came from. Handy for bug reports and for writing overrides.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = order--,
					IsAdvanced = true
				}
			}));
			toolbarOffset = Setting<Vector2>("3 - Advanced", "ToolbarOffset", Vector2.zero, "Nudge the sort/biome toolbar (pixels) if it sits in the wrong spot.");
			railOffset = Setting<Vector2>("3 - Advanced", "CategoryOffset", Vector2.zero, "Nudge the category buttons (pixels) if it sits in the wrong spot.");
			ConfigurationManagerAttributes hidden = new ConfigurationManagerAttributes
			{
				Browsable = false
			};
			hiddenBiomesCfg = State("HiddenBiomes");
			hiddenGroupsCfg = State("HiddenGroups");
			hiddenSubsCfg = State("HiddenCategories");
			stationSortCfg = State("StationSort");
			collapsedCfg = State("CollapsedBiomes");
			LoadState();
			ConfigDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath);
			new Harmony("bazilisx.Declutter").PatchAll(Assembly.GetExecutingAssembly());
			ConfigEntry<T> Setting<T>(string section, string key, T def, string desc, AcceptableValueBase range = null)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Expected O, but got Unknown
				ConfigEntry<T> obj = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, def, new ConfigDescription(desc, range, new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Order = order--
					}
				}));
				obj.SettingChanged += delegate
				{
					RebuildUi();
				};
				return obj;
			}
			ConfigEntry<string> State(string key)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				return ((BaseUnityPlugin)this).Config.Bind<string>("State", key, "", new ConfigDescription("Managed in game.", (AcceptableValueBase)null, new object[1] { hidden }));
			}
		}

		private void Update()
		{
			if (dragging != null && !Input.GetMouseButton(0))
			{
				dragging = null;
				Changed();
			}
			if (Object.op_Implicit((Object)(object)searchField) && searchField.isFocused)
			{
				typingFrame = Time.frameCount;
			}
			if (Object.op_Implicit((Object)(object)descScroll) && Object.op_Implicit((Object)(object)descScroll.content) && Object.op_Implicit((Object)(object)InventoryGui.instance) && InventoryGui.instance.m_recipeDecription.text != lastDesc)
			{
				lastDesc = InventoryGui.instance.m_recipeDecription.text;
				descScroll.verticalNormalizedPosition = 1f;
			}
			if (Object.op_Implicit((Object)(object)flyout))
			{
				if (!InventoryGui.IsVisible())
				{
					CloseFlyout();
				}
				else if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) && !Over(flyout) && (!Object.op_Implicit((Object)(object)rail) || !Over(rail)))
				{
					CloseFlyout();
				}
			}
		}

		private static bool Typing()
		{
			if (!Object.op_Implicit((Object)(object)searchField) || !searchField.isFocused)
			{
				return Time.frameCount - typingFrame <= 1;
			}
			return true;
		}

		private static void RefreshList()
		{
			InventoryGui instance = InventoryGui.instance;
			if (Object.op_Implicit((Object)(object)instance) && InventoryGui.IsVisible() && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				updateCraftingPanel.Invoke(instance, new object[1] { false });
			}
		}

		private static bool MatchesSearch(Recipe r)
		{
			return CultureInfo.InvariantCulture.CompareInfo.IndexOf(Localization.instance.Localize(r.m_item.m_itemData.m_shared.m_name), search.Trim(), CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0;
		}

		private static bool Over(RectTransform rt)
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			Canvas rootCanvas = ((Component)rt).GetComponentInParent<Canvas>().rootCanvas;
			return RectTransformUtility.RectangleContainsScreenPoint(rt, Vector2.op_Implicit(Input.mousePosition), ((int)rootCanvas.renderMode == 0) ? null : rootCanvas.worldCamera);
		}

		private static float Pct(ConfigEntry<int> e)
		{
			return (float)e.Value / 100f;
		}

		private static void Remember(RectTransform rt)
		{
			//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)
			if (!originalOffsets.ContainsKey(rt))
			{
				originalOffsets[rt] = (rt.offsetMin, rt.offsetMax);
			}
		}

		private static void RebuildUi()
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			CloseFlyout();
			foreach (GameObject header in headers)
			{
				if (Object.op_Implicit((Object)(object)header))
				{
					Object.Destroy((Object)(object)header);
				}
			}
			headers.Clear();
			if (Object.op_Implicit((Object)(object)toolbar))
			{
				Object.Destroy((Object)(object)((Component)toolbar).gameObject);
			}
			if (Object.op_Implicit((Object)(object)rail))
			{
				Object.Destroy((Object)(object)((Component)rail).gameObject);
			}
			if (Object.op_Implicit((Object)(object)searchField))
			{
				Object.Destroy((Object)(object)((Component)searchField).gameObject);
			}
			RestoreDescription();
			toolbar = (rail = null);
			searchField = null;
			foreach (KeyValuePair<RectTransform, (Vector2, Vector2)> originalOffset in originalOffsets)
			{
				if (Object.op_Implicit((Object)(object)originalOffset.Key))
				{
					originalOffset.Key.offsetMin = originalOffset.Value.Item1;
					originalOffset.Key.offsetMax = originalOffset.Value.Item2;
				}
			}
			originalOffsets.Clear();
			RefreshList();
		}

		private static void LoadState()
		{
			hiddenBiomesBy = PerStation(hiddenBiomesCfg.Value);
			hiddenGroupsBy = PerStation(hiddenGroupsCfg.Value);
			hiddenSubsBy = PerStation(hiddenSubsCfg.Value);
			collapsed = PerStation(collapsedCfg.Value);
			stationSort = new Dictionary<string, string>();
			foreach (string[] item in from s in Split(stationSortCfg.Value, ';')
				select s.Split('=') into p
				where p.Length == 2
				select p)
			{
				stationSort[item[0]] = item[1];
			}
		}

		private static void SaveState()
		{
			hiddenBiomesCfg.Value = PerStation(hiddenBiomesBy);
			hiddenGroupsCfg.Value = PerStation(hiddenGroupsBy);
			hiddenSubsCfg.Value = PerStation(hiddenSubsBy);
			collapsedCfg.Value = PerStation(collapsed);
			stationSortCfg.Value = string.Join(";", from kv in stationSort
				where kv.Value != ""
				select kv.Key + "=" + kv.Value);
		}

		private static Dictionary<string, HashSet<string>> PerStation(string v)
		{
			Dictionary<string, HashSet<string>> dictionary = new Dictionary<string, HashSet<string>>();
			if (v != "" && v.IndexOf('=') < 0)
			{
				dictionary["*"] = new HashSet<string>(Split(v, ','));
			}
			else
			{
				foreach (string[] item in from s in Split(v, ';')
					select s.Split('=') into p
					where p.Length == 2
					select p)
				{
					dictionary[item[0]] = new HashSet<string>(Split(item[1], '|'));
				}
			}
			return dictionary;
		}

		private static string PerStation(Dictionary<string, HashSet<string>> d)
		{
			return string.Join(";", from kv in d
				where kv.Value.Count > 0
				select kv.Key + "=" + string.Join("|", kv.Value));
		}

		private static HashSet<string> ForStation(Dictionary<string, HashSet<string>> d)
		{
			string key = Station();
			if (!d.TryGetValue(key, out var value))
			{
				value = (d[key] = (d.TryGetValue("*", out var value2) ? new HashSet<string>(value2) : new HashSet<string>()));
			}
			return value;
		}

		private static string[] Split(string s, char sep)
		{
			return s.Split(new char[1] { sep }, StringSplitOptions.RemoveEmptyEntries);
		}

		private static string Station()
		{
			CraftingStation val = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? Player.m_localPlayer.GetCurrentCraftingStation() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return "hand";
			}
			return val.m_name;
		}

		private static string Flags()
		{
			if (!stationSort.TryGetValue(Station(), out var value))
			{
				return "";
			}
			return value;
		}

		private static bool On(char flag)
		{
			return Flags().IndexOf(flag) >= 0;
		}

		private static HashSet<string> Collapsed()
		{
			return ForStation(collapsed);
		}

		private static void Toggle(HashSet<string> set, string key)
		{
			if (!set.Remove(key))
			{
				set.Add(key);
			}
		}

		private static void Changed()
		{
			SaveState();
			RefreshList();
			if (Object.op_Implicit((Object)(object)flyout))
			{
				FillFlyout();
			}
		}

		private static List<Recipe> Available()
		{
			return stationRecipes;
		}

		private static List<Recipe> StationBook()
		{
			CraftingStation station = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? Player.m_localPlayer.GetCurrentCraftingStation() : null);
			string key = (Object.op_Implicit((Object)(object)station) ? station.m_name : "");
			if (!books.TryGetValue(key, out var value) || value.Count == 0)
			{
				value = (books[key] = ObjectDB.instance.m_recipes.Where(delegate(Recipe r)
				{
					if (Object.op_Implicit((Object)(object)r) && r.m_enabled && Object.op_Implicit((Object)(object)r.m_item))
					{
						if (!Object.op_Implicit((Object)(object)station))
						{
							return !Object.op_Implicit((Object)(object)r.m_craftingStation);
						}
						if (Object.op_Implicit((Object)(object)r.m_craftingStation))
						{
							return r.m_craftingStation.m_name == key;
						}
						return false;
					}
					return false;
				}).ToList());
			}
			return value;
		}

		private static bool IsFoodRecipe(Recipe r)
		{
			if (!(Categories.Group(Categories.Of(r.m_item)) == "Food"))
			{
				return Categories.IsFood(r.m_item.m_itemData.m_shared);
			}
			return true;
		}

		private static bool FoodStation(List<Recipe> recipes)
		{
			int num = recipes.Count(IsFoodRecipe);
			int num2 = recipes.Count(delegate(Recipe r)
			{
				string text = Categories.RailGroup(r.m_item, foodStation: false, meadStation: false);
				return text == "Weapons" || text == "Armor";
			});
			if (num > 0)
			{
				return num >= num2;
			}
			return false;
		}

		private static bool MeadStation(List<Recipe> recipes)
		{
			if (recipes.Count > 0)
			{
				return recipes.Count((Recipe r) => Object.op_Implicit((Object)(object)r.m_item) && Categories.Group(Categories.Of(r.m_item)) == "Mead") * 2 >= recipes.Count((Recipe r) => Object.op_Implicit((Object)(object)r.m_item));
			}
			return false;
		}

		private static string Group(Recipe r)
		{
			return Categories.RailGroup(r.m_item, foodStation, meadStation);
		}

		private static string SubKey(Recipe r)
		{
			return Group(r) + ">" + Categories.SubLabel(Categories.Of(r.m_item));
		}

		private static string KeyGroup(string key)
		{
			return key.Substring(0, key.IndexOf('>'));
		}

		private static IEnumerable<string> Keys(Recipe r)
		{
			yield return SubKey(r);
			if (!foodStation && !meadStation && Categories.AlsoTool(r.m_item))
			{
				yield return "Tools>Tools";
			}
		}

		private static string[] GroupOrder()
		{
			if (!meadStation)
			{
				if (!foodStation)
				{
					return Categories.GearGroups;
				}
				return Categories.FoodGroups;
			}
			return Categories.MeadGroups;
		}

		private static bool Hidden(Recipe r)
		{
			if (!On('B') || !hiddenBiomes.Contains(Biomes.Label(Biomes.OfRecipe(r))))
			{
				if (On('C'))
				{
					return Keys(r).All((string k) => hiddenGroups.Contains(KeyGroup(k)) || hiddenSubs.Contains(k));
				}
				return false;
			}
			return true;
		}

		private static void Relayout(InventoryGui gui)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject header in headers)
			{
				if (Object.op_Implicit((Object)(object)header))
				{
					Object.Destroy((Object)(object)header);
				}
			}
			headers.Clear();
			headerLabels.Clear();
			if (!gui.InCraftTab())
			{
				return;
			}
			IList list = (IList)availableField.GetValue(gui);
			if (list.Count == 0)
			{
				return;
			}
			if (pairRecipe == null)
			{
				Type type = list[0].GetType();
				pairRecipe = type.GetProperty("Recipe");
				pairCanCraft = type.GetProperty("CanCraft");
				pairElement = type.GetProperty("InterfaceElement");
			}
			foreach (object item2 in list)
			{
				FitText(((Component)((GameObject)pairElement.GetValue(item2)).transform.Find("name")).GetComponent<TMP_Text>(), 0.9f * Pct(itemText));
			}
			bool byBiome = On('B');
			bool byCat = On('C');
			bool alpha = On('A');
			bool craftFirst = On('K');
			float num = gui.m_recipeListSpace * 0.85f * Pct(itemSpacing);
			if (!byBiome && !byCat && !alpha && !craftFirst)
			{
				for (int i = 0; i < list.Count; i++)
				{
					((RectTransform)((GameObject)pairElement.GetValue(list[i])).transform).anchoredPosition = new Vector2(0f, 0f - (4f + (float)i * num));
				}
				gui.m_recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max((float)baseSizeField.GetValue(gui), 4f + (float)list.Count * num));
				return;
			}
			string[] order = GroupOrder();
			var list2 = (from anon in list.Cast<object>().Select(delegate(object p, int index)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Expected O, but got Unknown
					//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c2: Expected O, but got Unknown
					Recipe val = (Recipe)pairRecipe.GetValue(p);
					return new
					{
						pair = p,
						index = index,
						biome = (byBiome ? Biomes.OfRecipe(val) : 0),
						@group = ((byCat && !alpha) ? Array.IndexOf(order, Group(val)) : 0),
						sub = ((byCat && !alpha) ? Categories.SubLabel(Categories.Of(val.m_item)) : ""),
						canCraft = (bool)pairCanCraft.GetValue(p),
						name = (alpha ? Localization.instance.Localize(val.m_item.m_itemData.m_shared.m_name) : ""),
						element = (GameObject)pairElement.GetValue(p)
					};
				})
				orderby anon.biome, (craftFirst && !anon.canCraft) ? 1 : 0, anon.@group
				select anon).ThenBy(anon => anon.sub, StringComparer.OrdinalIgnoreCase).ThenBy(anon => anon.name, StringComparer.CurrentCultureIgnoreCase).ThenBy(anon => anon.index)
				.ToList();
			HashSet<string> hashSet = Collapsed();
			float y = 4f;
			int? num2 = null;
			list.Clear();
			foreach (var x in list2)
			{
				string item = Biomes.Label(x.biome);
				if (byBiome && x.biome != num2)
				{
					num2 = x.biome;
					headers.Add(MakeHeader(gui, x.biome, list2.Count(o => o.biome == x.biome), ref y));
				}
				if (byBiome && hashSet.Contains(item))
				{
					Object.Destroy((Object)(object)x.element);
					continue;
				}
				list.Add(x.pair);
				((RectTransform)x.element.transform).anchoredPosition = new Vector2(0f, 0f - y);
				y += num;
			}
			gui.m_recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max((float)baseSizeField.GetValue(gui), y));
		}

		private static void HeaderClicked(string label)
		{
			HashSet<string> hashSet = Collapsed();
			if (label == lastHeader && Time.unscaledTime - lastHeaderTime < 0.4f)
			{
				bool flag = hashSet.Contains(label);
				foreach (string headerLabel in headerLabels)
				{
					if (flag)
					{
						hashSet.Add(headerLabel);
					}
					else
					{
						hashSet.Remove(headerLabel);
					}
				}
				lastHeader = null;
			}
			else
			{
				Toggle(hashSet, label);
				lastHeader = label;
				lastHeaderTime = Time.unscaledTime;
			}
			Changed();
		}

		private static void FitText(TMP_Text t, float scale)
		{
			t.enableAutoSizing = false;
			t.fontSize = fontSize * 0.75f * scale;
			t.overflowMode = (TextOverflowModes)1;
		}

		private static GameObject MakeHeader(InventoryGui gui, int biome, int count, ref float y)
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: 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_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: 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_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			string label = Biomes.Label(biome);
			GameObject val = Object.Instantiate<GameObject>(gui.m_recipeElementPrefab, (Transform)(object)gui.m_recipeListRoot);
			((Object)val).name = "CCD_Header";
			val.SetActive(true);
			string[] array = new string[3] { "Durability", "QualityLevel", "selected" };
			foreach (string text in array)
			{
				Transform val2 = val.transform.Find(text);
				if (Object.op_Implicit((Object)(object)val2))
				{
					((Component)val2).gameObject.SetActive(false);
				}
			}
			Button component = val.GetComponent<Button>();
			((Selectable)component).transition = (Transition)0;
			if (Object.op_Implicit((Object)(object)((Selectable)component).targetGraphic))
			{
				((Selectable)component).targetGraphic.color = Color.clear;
			}
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				HeaderClicked(label);
			});
			headerLabels.Add(label);
			Transform obj = val.transform.Find("icon");
			Image val3 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			RectTransform val4 = (RectTransform)val.transform;
			if (Object.op_Implicit((Object)(object)val3))
			{
				val3.sprite = Icon((biome < biomeIcons.Length) ? biomeIcons[biome] : "sort_biome");
				((Graphic)val3).color = headerGold;
				val3.preserveAspect = true;
				((Component)val3).transform.localScale = Vector3.one * 0.63f * Pct(headerIconScale);
				Vector3[] array2 = (Vector3[])(object)new Vector3[4];
				((Graphic)val3).rectTransform.GetWorldCorners(array2);
				num = ((Transform)val4).InverseTransformPoint(array2[0]).x;
				num2 = ((Transform)val4).InverseTransformPoint(array2[2]).x;
				Rect rect = ((Graphic)val3).rectTransform.rect;
				num3 = ((Rect)(ref rect)).height * 0.63f;
				((Component)val3).gameObject.SetActive(headerIcons.Value);
			}
			TMP_Text component2 = ((Component)val.transform.Find("name")).GetComponent<TMP_Text>();
			FitText(component2, Pct(headerText));
			component2.richText = true;
			component2.text = label + " <size=80%>(" + count + ")";
			component2.enableVertexGradient = false;
			((Graphic)component2).color = gold;
			component2.fontStyle = (FontStyles)1;
			bool flag = !Collapsed().Contains(label);
			if (Object.op_Implicit((Object)(object)val3))
			{
				Vector3[] array3 = (Vector3[])(object)new Vector3[4];
				component2.rectTransform.GetWorldCorners(array3);
				float num4 = (headerIcons.Value ? (num2 + (float)headerIconGap.Value) : (num + 6f));
				RectTransform rectTransform = component2.rectTransform;
				rectTransform.offsetMin += new Vector2(num4 - ((Transform)val4).InverseTransformPoint(array3[0]).x, 0f);
			}
			if (flag)
			{
				float num5 = ((num3 > 0f) ? Mathf.Max(1f, num3 * 0.8125f / 12f) : 1.5f);
				GameObject obj2 = NewUI("underline", val.transform, typeof(Image));
				RectTransform val5 = (RectTransform)obj2.transform;
				val5.anchorMin = Vector2.zero;
				val5.anchorMax = new Vector2(1f, 0f);
				val5.pivot = new Vector2(0.5f, 0f);
				val5.offsetMin = new Vector2(4f, 2f);
				val5.offsetMax = new Vector2(-4f, 2f + num5);
				((Graphic)obj2.GetComponent<Image>()).color = headerGold;
				((Graphic)obj2.GetComponent<Image>()).raycastTarget = false;
			}
			RectTransform val6 = (RectTransform)Arrow(val.transform, 12f, flag, headerGold).transform;
			Vector2 val7 = default(Vector2);
			((Vector2)(ref val7))..ctor(1f, 0.5f);
			val6.anchorMax = val7;
			val6.anchorMin = val7;
			val6.anchoredPosition = new Vector2(-14f, 0f);
			((RectTransform)val.transform).anchoredPosition = new Vector2(0f, 0f - y);
			y += gui.m_recipeListSpace * 0.9f * Pct(headerSpacing) * (flag ? 1f : 0.72f);
			return val;
		}

		private static void EnsureUi(InventoryGui gui)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: 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_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: 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_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Expected O, but got Unknown
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: 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_04bf: 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_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c5: Expected O, but got Unknown
			//IL_07e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_080f: Unknown result type (might be due to invalid IL or missing references)
			//IL_081f: Unknown result type (might be due to invalid IL or missing references)
			//IL_082e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0838: Unknown result type (might be due to invalid IL or missing references)
			//IL_083d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0842: Unknown result type (might be due to invalid IL or missing references)
			//IL_0866: Unknown result type (might be due to invalid IL or missing references)
			//IL_087b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0880: Unknown result type (might be due to invalid IL or missing references)
			//IL_0936: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0909: Unknown result type (might be due to invalid IL or missing references)
			//IL_0918: Unknown result type (might be due to invalid IL or missing references)
			//IL_091d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)toolbar))
			{
				return;
			}
			TMP_Text component = ((Component)gui.m_recipeElementPrefab.transform.Find("name")).GetComponent<TMP_Text>();
			font = component.font;
			fontSize = (component.enableAutoSizing ? component.fontSizeMax : component.fontSize);
			UITooltip val = (Object.op_Implicit((Object)(object)gui.m_craftButton) ? ((Component)gui.m_craftButton).GetComponent<UITooltip>() : null);
			tooltipPrefab = (Object.op_Implicit((Object)(object)val) ? val.m_tooltipPrefab : null);
			Image val2 = (Image)(Object.op_Implicit((Object)(object)gui.m_craftButton) ? (((object)/*isinst with value type is only supported in some contexts*/) ?? ((object)((Component)gui.m_craftButton).GetComponent<Image>())) : null);
			frame = (Object.op_Implicit((Object)(object)val2) ? val2.sprite : null);
			Log.LogInfo((object)(Object.op_Implicit((Object)(object)frame) ? $"button frame: {((Object)frame).name}, border {frame.border}, ppu {frame.pixelsPerUnit}" : "Craft button sprite not found; using a plain chamfered background"));
			Material fontSharedMaterial = component.fontSharedMaterial;
			Color val3 = ((Object.op_Implicit((Object)(object)fontSharedMaterial) && fontSharedMaterial.HasProperty(ShaderUtilities.ID_FaceColor)) ? fontSharedMaterial.GetColor(ShaderUtilities.ID_FaceColor) : Color.white);
			headerGold = new Color(gold.r * val3.r, gold.g * val3.g, gold.b * val3.b, 1f);
			Log.LogInfo((object)$"list font face tint {val3}, row text gradient {component.enableVertexGradient}");
			RectTransform crafting = gui.m_crafting;
			RectTransform val4 = (RectTransform)((Component)gui.m_tabUpgrade).transform;
			RectTransform val5 = (RectTransform)((Component)gui.m_tabCraft).transform;
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			Vector3[] array2 = (Vector3[])(object)new Vector3[4];
			Vector3[] array3 = (Vector3[])(object)new Vector3[4];
			Vector3[] array4 = (Vector3[])(object)new Vector3[4];
			val4.GetWorldCorners(array);
			val5.GetWorldCorners(array2);
			crafting.GetWorldCorners(array3);
			ScrollRect componentInParent = ((Component)gui.m_recipeListRoot).GetComponentInParent<ScrollRect>();
			RectTransform val6 = (RectTransform)(Object.op_Implicit((Object)(object)componentInParent) ? ((Component)componentInParent).transform : ((Transform)gui.m_recipeListRoot).parent);
			val6.GetWorldCorners(array4);
			float num = buttonSpacing.Value;
			int num2 = ((biomeRows.Value != 2) ? 1 : 2);
			int num3 = ((num2 == 2) ? 5 : biomeIcons.Length);
			int num4 = 4 + num3;
			float x = ((Transform)crafting).InverseTransformPoint(array4[0]).x;
			float num5 = ((Transform)crafting).InverseTransformPoint(array3[2]).x - 8f;
			float num6 = ((Transform)crafting).InverseTransformPoint(array4[1]).y - ((Transform)crafting).InverseTransformPoint(array4[0]).y;
			float num7 = (num5 - x - 32f - (float)(num4 + 3) * num) / ((float)num4 + 1.32f);
			float num8 = (num6 * 0.55f - 5f * num) / 6f;
			Rect rect = val4.rect;
			float num9 = Mathf.Clamp(((Rect)(ref rect)).height * 0.85f, 18f, 30f) * 1.4f * Pct(buttonScale);
			size = Mathf.Max(16f, Mathf.Min(new float[3] { num9, num7, num8 }));
			float num10 = (float)num2 * size + (float)(num2 - 1) * num;
			toolbar = (RectTransform)NewUI("CCD_Toolbar", (Transform)(object)crafting, typeof(HorizontalLayoutGroup), typeof(ContentSizeFitter)).transform;
			RectTransform obj = toolbar;
			RectTransform obj2 = toolbar;
			Vector2 val7 = default(Vector2);
			((Vector2)(ref val7))..ctor(0.5f, 0.5f);
			obj2.anchorMax = val7;
			obj.anchorMin = val7;
			bool flag = MakeRoomBelowTabs(gui, ((Transform)crafting).InverseTransformPoint(array[0]).y, num10 + 18f);
			if (flag)
			{
				toolbar.pivot = new Vector2(0f, 1f);
				((Transform)toolbar).position = array2[0];
				RectTransform obj3 = toolbar;
				obj3.anchoredPosition += new Vector2(0f, -9f) + toolbarOffset.Value;
			}
			else
			{
				toolbar.pivot = new Vector2(0f, 0.5f);
				((Transform)toolbar).position = (array[2] + array[3]) / 2f;
				RectTransform obj4 = toolbar;
				obj4.anchoredPosition += new Vector2(8f, 0f) + toolbarOffset.Value;
			}
			((Transform)toolbar).SetAsLastSibling();
			Layout(((Component)toolbar).gameObject, horizontal: true);
			sortButtons = new IconButton[4]
			{
				MakeButton((Transform)(object)toolbar, Icon("sort_az"), "Sort by: Alphabetical", delegate
				{
					SetFlag('A');
				}),
				MakeButton((Transform)(object)toolbar, Icon("sort_category"), "Sort by: Category", delegate
				{
					SetFlag('C');
				}),
				MakeButton((Transform)(object)toolbar, Icon("sort_craftable"), "Sort by: Craftable first", delegate
				{
					SetFlag('K');
				}),
				MakeButton((Transform)(object)toolbar, Icon("sort_biome"), "Sort by: Biome", delegate
				{
					SetFlag('B');
				})
			};
			Spacer((Transform)(object)toolbar, 10f);
			biomeArrow = Arrow((Transform)(object)toolbar, size * 0.32f, open: false, dim).GetComponent<Image>();
			LayoutElement obj5 = ((Component)biomeArrow).gameObject.AddComponent<LayoutElement>();
			float preferredWidth = (obj5.preferredHeight = size * 0.32f);
			obj5.preferredWidth = preferredWidth;
			Spacer((Transform)(object)toolbar, 10f);
			Transform val8 = (Transform)(object)toolbar;
			Transform val9 = (Transform)(object)toolbar;
			if (num2 == 2)
			{
				Transform parent = Group((Transform)(object)toolbar, horizontal: false);
				val8 = Group(parent, horizontal: true);
				val9 = Group(parent, horizontal: true);
			}
			biomeButtons = new IconButton[biomeIcons.Length];
			for (int num12 = 0; num12 < biomeIcons.Length; num12++)
			{
				string label = Biomes.Label(num12);
				IconButton obj6 = (biomeButtons[num12] = MakeButton((num12 < num3) ? val8 : val9, Icon(biomeIcons[num12]), label, null));
				obj6.dragRow = "biome";
				obj6.isOn = () => !hiddenBiomes.Contains(label);
				obj6.setOn = delegate(bool on)
				{
					if (on)
					{
						hiddenBiomes.Remove(label);
					}
					else
					{
						hiddenBiomes.Add(label);
					}
				};
				obj6.onDisabledClick = delegate
				{
					SetFlag('B', on: true);
				};
			}
			val6.GetWorldCorners(array4);
			rail = (RectTransform)NewUI("CCD_Rail", ((Transform)val6).parent, typeof(VerticalLayoutGroup), typeof(ContentSizeFitter)).transform;
			RectTransform obj7 = rail;
			RectTransform obj8 = rail;
			((Vector2)(ref val7))..ctor(0.5f, 0.5f);
			obj8.anchorMax = val7;
			obj7.anchorMin = val7;
			rail.pivot = new Vector2(0f, 1f);
			((Transform)rail).position = array4[1];
			RectTransform obj9 = rail;
			obj9.anchoredPosition += new Vector2(2f, -6f) + railOffset.Value;
			Layout(((Component)rail).gameObject, horizontal: false);
			Remember(val6);
			val6.offsetMin += new Vector2(size + 12f, 0f);
			MakeSearchBox(val6, Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.verticalScrollbar : null);
			MakeDescriptionScroll(gui);
			if (flag)
			{
				Vector3[] array5 = (Vector3[])(object)new Vector3[4];
				val6.GetWorldCorners(array5);
				((Transform)toolbar).position = new Vector3(array5[0].x, ((Transform)toolbar).position.y, ((Transform)toolbar).position.z);
				RectTransform obj10 = toolbar;
				obj10.anchoredPosition += new Vector2(toolbarOffset.Value.x, 0f);
			}
			Log.LogInfo((object)string.Format("toolbar at {0} ({1}), button {2}", toolbar.anchoredPosition, flag ? "own row under the tabs" : "fallback: right of Upgrade", size));
		}

		private static bool MakeRoomBelowTabs(InventoryGui gui, float tabBottom, float rowHeight)
		{
			RectTransform panel = gui.m_crafting;
			List<string> moved = new List<string>();
			Visit((Transform)(object)panel, 0);
			Log.LogInfo((object)("made room under the tabs by moving down: " + ((moved.Count > 0) ? string.Join(", ", moved) : "(nothing found)")));
			return moved.Count > 0;
			void Visit(Transform t, int depth)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected O, but got Unknown
				//IL_009b: 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_00b4: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				foreach (Transform item in t)
				{
					Transform val = item;
					RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
					if (Object.op_Implicit((Object)(object)val2) && !((Object)val).name.StartsWith("CCD_"))
					{
						if (((Component)gui.m_tabCraft).transform.IsChildOf(val) || ((Component)gui.m_tabUpgrade).transform.IsChildOf(val))
						{
							if (depth < 4)
							{
								Visit(val, depth + 1);
							}
						}
						else
						{
							Vector3[] array = (Vector3[])(object)new Vector3[4];
							val2.GetWorldCorners(array);
							float y = ((Transform)panel).InverseTransformPoint(array[1]).y;
							float y2 = ((Transform)panel).InverseTransformPoint(array[0]).y;
							if (!(Mathf.Abs(y - tabBottom) > 16f) && !(y - y2 < rowHeight * 3f))
							{
								float num = rowHeight * ((Transform)panel).lossyScale.y / Mathf.Max(0.0001f, ((Transform)(RectTransform)((Transform)val2).parent).lossyScale.y);
								Remember(val2);
								val2.offsetMax -= new Vector2(0f, num);
								moved.Add(((Object)val).name);
							}
						}
					}
				}
			}
		}

		private static void MakeDescriptionScroll(InventoryGui gui)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_0152: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: 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_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text recipeDecription = gui.m_recipeDecription;
			GameObject val = ((gui.m_recipeRequirementList != null && gui.m_recipeRequirementList.Length != 0) ? gui.m_recipeRequirementList[0] : null);
			if (Object.op_Implicit((Object)(object)recipeDecription) && Object.op_Implicit((Object)(object)val))
			{
				RectTransform rectTransform = recipeDecription.rectTransform;
				RectTransform val2 = (RectTransform)((Transform)rectTransform).parent;
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				Vector3[] array2 = (Vector3[])(object)new Vector3[4];
				rectTransform.GetWorldCorners(array);
				((RectTransform)val.transform).GetWorldCorners(array2);
				float y = ((Transform)val2).InverseTransformPoint(array[1]).y;
				float num = ((Transform)val2).InverseTransformPoint(array2[1]).y + 6f;
				float x = ((Transform)val2).InverseTransformPoint(array[0]).x;
				float x2 = ((Transform)val2).InverseTransformPoint(array[2]).x;
				if (y - num < 40f)
				{
					Log.LogInfo((object)"description: no room for a scroll area");
					return;
				}
				GameObject obj = NewUI("CCD_DescScroll", (Transform)(object)val2, typeof(RectMask2D), typeof(ScrollRect), typeof(Image));
				((Graphic)obj.GetComponent<Image>()).color = Color.clear;
				RectTransform val3 = (RectTransform)obj.transform;
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(0.5f, 0.5f);
				val3.anchorMax = val4;
				val3.anchorMin = val4;
				val3.pivot = new Vector2(0f, 1f);
				Vector2 val5 = new Vector2(x, y);
				Rect rect = val2.rect;
				val3.anchoredPosition = val5 - ((Rect)(ref rect)).center;
				val3.sizeDelta = new Vector2(x2 - x, y - num);
				((Transform)val3).SetSiblingIndex(((Transform)rectTransform).GetSiblingIndex());
				descOriginal = (parent: (Transform)(object)val2, index: ((Transform)rectTransform).GetSiblingIndex(), aMin: rectTransform.anchorMin, aMax: rectTransform.anchorMax, pivot: rectTransform.pivot, oMin: rectTransform.offsetMin, oMax: rectTransform.offsetMax);
				((Transform)rectTransform).SetParent((Transform)(object)val3, false);
				rectTransform.anchorMin = new Vector2(0f, 1f);
				rectTransform.anchorMax = Vector2.one;
				rectTransform.pivot = new Vector2(0.5f, 1f);
				val4 = (rectTransform.offsetMin = (rectTransform.offsetMax = Vector2.zero));
				((Component)recipeDecription).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
				descScroll = obj.GetComponent<ScrollRect>();
				descScroll.viewport = val3;
				descScroll.content = rectTransform;
				descScroll.horizontal = false;
				descScroll.movementType = (MovementType)2;
				descScroll.scrollSensitivity = 25f;
			}
		}

		private static void RestoreDescription()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)descScroll))
			{
				RectTransform content = descScroll.content;
				if (Object.op_Implicit((Object)(object)content) && Object.op_Implicit((Object)(object)descOriginal.parent))
				{
					Object.Destroy((Object)(object)((Component)content).GetComponent<ContentSizeFitter>());
					((Transform)content).SetParent(descOriginal.parent, false);
					((Transform)content).SetSiblingIndex(descOriginal.index);
					content.anchorMin = descOriginal.aMin;
					content.anchorMax = descOriginal.aMax;
					content.pivot = descOriginal.pivot;
					content.offsetMin = descOriginal.oMin;
					content.offsetMax = descOriginal.oMax;
				}
				Object.Destroy((Object)(object)((Component)descScroll).gameObject);
				descScroll = null;
			}
		}

		private static void MakeSearchBox(RectTransform list, Scrollbar bar)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(size / 1.4f, 18f, 32f);
			float num2 = 6f;
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			list.GetWorldCorners(array);
			GameObject val = NewUI("CCD_Search", ((Transform)list).parent, typeof(Image), typeof(LayoutElement));
			val.SetActive(false);
			val.GetComponent<LayoutElement>().ignoreLayout = true;
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0f, 1f);
			((Transform)val2).position = array[1];
			Rect rect = list.rect;
			val2.sizeDelta = new Vector2(((Rect)(ref rect)).width, num);
			Remember(list);
			list.offsetMax -= new Vector2(0f, num + num2);
			if (Object.op_Implicit((Object)(object)bar) && !((Component)bar).transform.IsChildOf((Transform)(object)list))
			{
				Remember((RectTransform)((Component)bar).transform);
				RectTransform val4 = (RectTransform)((Component)bar).transform;
				val4.offsetMax -= new Vector2(0f, num + num2);
			}
			SetFrame(val.GetComponent<Image>(), dimmed: false);
			GameObject obj = NewUI("magnifier", val.transform, typeof(Image));
			RectTransform val5 = (RectTransform)obj.transform;
			Vector2 val6 = default(Vector2);
			((Vector2)(ref val6))..ctor(0f, 0.5f);
			val5.pivot = val6;
			val3 = (val5.anchorMin = (val5.anchorMax = val6));
			val5.sizeDelta = Vector2.one * num * 0.5f;
			val5.anchoredPosition = new Vector2(num * 0.3f, 0f);
			Image component = obj.GetComponent<Image>();
			component.sprite = Icon("search");
			((Graphic)component).color = tan;
			((Graphic)component).raycastTarget = false;
			GameObject area = NewUI("text area", val.transform, typeof(RectMask2D));
			RectTransform val9 = (RectTransform)area.transform;
			val9.anchorMin = Vector2.zero;
			val9.anchorMax = Vector2.one;
			val9.offsetMin = new Vector2(num * 0.95f, 2f);
			val9.offsetMax = new Vector2(-8f, -2f);
			float pt = Mathf.Min(fontSize * 0.75f * 0.9f * Pct(itemText), num * 0.6f);
			TextMeshProUGUI val10 = Text("placeholder", dim);
			((TMP_Text)val10).text = "Search…";
			((TMP_Text)val10).fontStyle = (FontStyles)2;
			TextMeshProUGUI textComponent = Text("text", textCol);
			searchField = val.AddComponent<TMP_InputField>();
			searchField.textViewport = val9;
			searchField.textComponent = (TMP_Text)(object)textComponent;
			searchField.placeholder = (Graphic)(object)val10;
			searchField.fontAsset = font;
			searchField.pointSize = pt;
			searchField.lineType = (LineType)0;
			searchField.restoreOriginalTextOnEscape = false;
			searchField.customCaretColor = true;
			searchField.caretColor = gold;
			searchField.selectionColor = new Color(gold.r, gold.g, gold.b, 0.35f);
			searchField.text = search;
			((UnityEvent<string>)(object)searchField.onValueChanged).AddListener((UnityAction<string>)delegate(string v)
			{
				search = v ?? "";
				RefreshList();
			});
			val.SetActive(true);
			TextMeshProUGUI Text(string name, Color color)
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				TextMeshProUGUI obj2 = NewUI(name, area.transform).AddComponent<TextMeshProUGUI>();
				Stretch(((Component)obj2).gameObject, 0f);
				((TMP_Text)obj2).font = font;
				((TMP_Text)obj2).fontSize = pt;
				((Graphic)obj2).color = color;
				((TMP_Text)obj2).alignment = (TextAlignmentOptions)4097;
				((TMP_Text)obj2).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)obj2).richText = false;
				return obj2;
			}
		}

		private static void Spacer(Transform parent, float width)
		{
			LayoutElement component = NewUI("spacer", parent, typeof(LayoutElement)).GetComponent<LayoutElement>();
			float preferredWidth = (component.minWidth = width);
			component.preferredWidth = preferredWidth;
		}

		private static void SetFlag(char flag)
		{
			SetFlag(flag, !On(flag));
		}

		private static void SetFlag(char flag, bool on)
		{
			stationSort[Station()] = Flags().Replace(flag.ToString(), "") + (on ? flag.ToString() : "");
			Changed();
		}

		private static void RefreshUi(InventoryGui gui)
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			EnsureUi(gui);
			bool flag = gui.InCraftTab();
			((Component)toolbar).gameObject.SetActive(flag);
			((Component)rail).gameObject.SetActive(flag);
			if (Object.op_Implicit((Object)(object)searchField))
			{
				((Component)searchField).gameObject.SetActive(flag);
			}
			if (!flag)
			{
				CloseFlyout();
				return;
			}
			List<Recipe> source = Available();
			sortButtons[0].Set(On('A'));
			sortButtons[1].Set(On('C'));
			sortButtons[2].Set(On('K'));
			sortButtons[3].Set(On('B'));
			((Graphic)biomeArrow).color = (On('B') ? gold : dim);
			HashSet<int> hashSet = new HashSet<int>(source.Select(Biomes.OfRecipe));
			for (int i = 0; i < biomeButtons.Length; i++)
			{
				string text = Biomes.Label(i);
				UITooltip component = ((Component)biomeButtons[i]).GetComponent<UITooltip>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.m_text = (hashSet.Contains(i) ? text : (text + " (none at this station)"));
				}
				biomeButtons[i].Set(!hiddenBiomes.Contains(text), partial: false, !On('B'));
			}
			foreach (Transform item in ((IEnumerable)rail).Cast<Transform>().ToList())
			{
				item.SetParent((Transform)null, false);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			bool flag2 = On('C');
			string[] array = GroupOrder();
			foreach (string g in array)
			{
				bool flag3 = meadColors.ContainsKey(g);
				bool flag4 = !flag3 && forkColors.ContainsKey(g);
				string group = g;
				List<string> subs = (from k in source.SelectMany(Keys)
					where KeyGroup(k) == g
					select k).Distinct().ToList();
				string text2 = (flag4 ? (g + " food") : g);
				IconButton iconButton = MakeButton((Transform)(object)rail, flag3 ? Icon("group_mead") : (flag4 ? GameSprite("food_icon") : Icon("group_" + g.ToLower())), (subs.Count > 0) ? text2 : (text2 + " (none at this station)"), null, size);
				iconButton.dragRow = "rail";
				iconButton.isOn = () => !hiddenGroups.Contains(group) && (subs.Count == 0 || subs.Any((string k) => !hiddenSubs.Contains(k)));
				iconButton.setOn = delegate(bool on)
				{
					if (!on)
					{
						hiddenGroups.Add(group);
					}
					else
					{
						hiddenGroups.Remove(group);
						if (subs.Count > 0 && subs.All(hiddenSubs.Contains))
						{
							hiddenSubs.RemoveWhere((string k) => k.StartsWith(group + ">"));
						}
					}
				};
				iconButton.onDisabledClick = delegate
				{
					SetFlag('C', on: true);
				};
				bool flag5 = iconButton.isOn();
				iconButton.Set(flag5, flag5 && subs.Any(hiddenSubs.Contains), !flag2, flag3 ? new Color?(meadColors[g]) : (flag4 ? new Color?(forkColors[g]) : ((Color?)null)));
				if (flag2 && !foodStation && !meadStation && subs.Count > 1)
				{
					AddFlyMarker(iconButton, group);
				}
			}
		}

		private static Transform Group(Transform parent, bool horizontal)
		{
			GameObject obj = NewUI("group", parent, horizontal ? typeof(HorizontalLayoutGroup) : typeof(VerticalLayoutGroup));
			HorizontalOrVerticalLayoutGroup component = obj.GetComponent<HorizontalOrVerticalLayoutGroup>();
			component.spacing = buttonSpacing.Value;
			((LayoutGroup)component).childAlignment = (TextAnchor)0;
			bool childControlWidth = (component.childControlHeight = true);
			component.childControlWidth = childControlWidth;
			childControlWidth = (component.childForceExpandHeight = false);
			component.childForceExpandWidth = childControlWidth;
			return obj.transform;
		}

		private static void Layout(GameObject go, bool horizontal)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			go.AddComponent<LayoutElement>().ignoreLayout = true;
			object obj = (horizontal ? ((object)go.GetComponent<HorizontalLayoutGroup>()) : ((object)go.GetComponent<VerticalLayoutGroup>()));
			((HorizontalOrVerticalLayoutGroup)obj).spacing = buttonSpacing.Value;
			((LayoutGroup)obj).childAlignment = (TextAnchor)((!horizontal) ? 1 : 3);
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth;
			childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false);
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth;
			ContentSizeFitter component = go.GetComponent<ContentSizeFitter>();
			FitMode horizontalFit = (FitMode)2;
			component.verticalFit = (FitMode)2;
			component.horizontalFit = horizontalFit;
		}

		private static IconButton MakeButton(Transform parent, Sprite sprite, string tooltip, Action onClick, float s = 0f)
		{
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			if (s <= 0f)
			{
				s = size;
			}
			GameObject val = NewUI("CCD_Button", parent, typeof(Image), typeof(LayoutElement));
			IconButton iconButton = val.AddComponent<IconButton>();
			iconButton.onClick = onClick;
			iconButton.bg = val.GetComponent<Image>();
			SetFrame(iconButton.bg, dimmed: false);
			LayoutElement component = val.GetComponent<LayoutElement>();
			float preferredWidth = (component.preferredHeight = s);
			component.preferredWidth = preferredWidth;
			GameObject val2 = NewUI("rin