Decompiled source of CheckMyStuff v1.0.2

plugins/CheckMyStuff/CheckMyStuff.dll

Decompiled 10 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using CheckMyStuff.Barrel;
using CheckMyStuff.Classification;
using CheckMyStuff.Routing;
using CheckMyStuff.UI;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CheckMyStuff")]
[assembly: AssemblyFileVersion("1.0.2")]
[assembly: AssemblyCompany("R4V9N1")]
[assembly: AssemblyProduct("CheckMyStuff")]
[assembly: AssemblyDescription("Created by R4V9N1")]
[assembly: AssemblyVersion("1.0.2.0")]
namespace CheckMyStuff
{
	[BepInPlugin("r4v9n1.checkmystuff", "CheckMyStuff", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class CheckMyStuffPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "r4v9n1.checkmystuff";

		public const string PluginName = "CheckMyStuff";

		public const string PluginVersion = "1.0.2";

		public const string CreatorCredit = "Created by R4V9N1";

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("r4v9n1.checkmystuff").PatchAll(typeof(CheckMyStuffPlugin).Assembly);
			ItemDatabase.Initialize(typeof(CheckMyStuffPlugin).Assembly);
			ItemDatabase.ValidateCatalog();
			ChestLabelManager.ValidateContract();
			ChestLabelUi.ValidateContract();
			PrefabManager.OnVanillaPrefabsAvailable += RegisterBarrelWhenReady;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("CheckMyStuff 1.0.2 loaded: " + ItemDatabase.Count + " classified items; category and exact-item routing active."));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Waiting for Jotunn vanilla-prefab availability before registering the CheckMyStuff barrel.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Created by R4V9N1.");
		}

		private void Update()
		{
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				ItemTaxonomy.RefreshRuntimeItems(ObjectDB.instance);
			}
			ChestLabelUi.Draw();
			BarrelUi.Draw();
			SortingEngine.ProcessPendingRetry();
		}

		private void RegisterBarrelWhenReady()
		{
			try
			{
				if (!BarrelRegistrar.Register())
				{
					((BaseUnityPlugin)this).Logger.LogError((object)"CheckMyStuff barrel registration did not complete. Chest labels remain available.");
					return;
				}
				PrefabManager.OnVanillaPrefabsAvailable -= RegisterBarrelWhenReady;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"CheckMyStuff barrel registered after vanilla prefabs became available.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("CheckMyStuff barrel registration failed after vanilla prefabs became available: " + ex));
			}
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterBarrelWhenReady;
		}
	}
}
namespace CheckMyStuff.UI
{
	public static class BarrelUi
	{
		private const float PanelWidth = 360f;

		private const float PanelHeight = 454f;

		private const float MaxUseDistance = 5f;

		private static GameObject s_panel;

		private static RectTransform s_panelRect;

		private static GameObject s_confirmRoot;

		private static TMP_Text s_confirmText;

		private static TMP_Text s_statusText;

		private static BarrelController s_lastController;

		private static bool s_createFailureLogged;

		public static void Draw()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			BarrelController active = BarrelController.Active;
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)active == (Object)null)
			{
				HidePanel();
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null)
			{
				BarrelController.Close();
				HidePanel();
			}
			else if (!InventoryGui.IsVisible())
			{
				BarrelController.Close();
				HidePanel();
			}
			else if (instance.IsContainerOpen())
			{
				BarrelController.Close();
				HidePanel();
			}
			else if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)active).transform.position) > 5f)
			{
				CloseUi();
			}
			else
			{
				if ((Object)(object)s_panel == (Object)null && !TryCreatePanel(instance))
				{
					return;
				}
				if (active != s_lastController)
				{
					s_lastController = active;
					if ((Object)(object)s_statusText != (Object)null)
					{
						s_statusText.text = "Choose Store All or a category to store bag items.";
					}
				}
				SyncPanelPosition(instance);
				if (!s_panel.activeSelf)
				{
					s_panel.SetActive(true);
				}
			}
		}

		private static bool TryCreatePanel(InventoryGui gui)
		{
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_01f3: 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_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: 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_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_container == (Object)null || (Object)(object)gui.m_player == (Object)null)
			{
				LogCreateFailure("InventoryGui container/player panel unavailable.");
				return false;
			}
			RectTransform container = gui.m_container;
			RectTransform player = gui.m_player;
			Transform val = ((Transform)player).Find("Bkg");
			Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : null);
			Transform val3 = ((Transform)player).Find("sunken");
			Image val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<Image>() : null);
			TMP_FontAsset val5 = FindFont(gui, "Valheim-Norsebold");
			TMP_FontAsset val6 = FindFont(gui, "Valheim-AveriaSansLibre");
			TMP_FontAsset val7 = FindAnyNativeFont(gui);
			if ((Object)(object)val5 == (Object)null)
			{
				val5 = val7;
			}
			if ((Object)(object)val6 == (Object)null)
			{
				val6 = val7;
			}
			Button val8 = FindNativeButtonTemplate(gui);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null)
			{
				LogCreateFailure("Native barrel UI assets unavailable: background=" + ((Object)(object)val2 != (Object)null) + " titleFont=" + ((Object)(object)val5 != (Object)null) + " bodyFont=" + ((Object)(object)val6 != (Object)null) + " button=" + ((Object)(object)val8 != (Object)null));
				return false;
			}
			GameObject val9 = new GameObject("CheckMyStuffBarrelPanel", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val9.transform.SetParent(((Transform)container).parent, false);
			val9.transform.SetSiblingIndex(Mathf.Min(((Transform)container).GetSiblingIndex() + 1, ((Transform)container).parent.childCount - 1));
			SetLayerRecursively(val9, ((Component)gui).gameObject.layer);
			RectTransform component = val9.GetComponent<RectTransform>();
			component.anchorMin = container.anchorMin;
			component.anchorMax = container.anchorMax;
			component.pivot = container.pivot;
			component.anchoredPosition = container.anchoredPosition;
			component.sizeDelta = new Vector2(360f, 454f);
			Image component2 = val9.GetComponent<Image>();
			CopyImageStyle(val2, component2);
			((Graphic)component2).color = Color.white;
			((Graphic)component2).raycastTarget = true;
			if ((Object)(object)val4 != (Object)null)
			{
				GameObject obj = CreateImage("CheckMyStuffBarrelInset", (Transform)(object)component);
				RectTransform component3 = obj.GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0f, 1f);
				component3.anchorMax = new Vector2(0f, 1f);
				component3.pivot = new Vector2(0f, 1f);
				component3.anchoredPosition = new Vector2(10f, -44f);
				component3.sizeDelta = new Vector2(340f, 392f);
				Image component4 = obj.GetComponent<Image>();
				CopyImageStyle(val4, component4);
				((Graphic)component4).color = new Color(1f, 1f, 1f, 0.72f);
				((Graphic)component4).raycastTarget = false;
				obj.transform.SetAsFirstSibling();
			}
			Shadow obj2 = ((Component)CreateNativeText(val5, (Transform)(object)component, "CheckMyStuffBarrelTitle", "CHECKMYSTUFF", new Vector2(12f, -8f), new Vector2(336f, 30f), 25f, (TextAlignmentOptions)514, new Color(1f, 0.718f, 0.36f, 1f))).gameObject.AddComponent<Shadow>();
			obj2.effectColor = new Color(0f, 0f, 0f, 0.78f);
			obj2.effectDistance = new Vector2(2f, -2f);
			CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffBarrelSubtitle", "STORE BAG ITEMS BY CATEGORY", new Vector2(14f, -48f), new Vector2(332f, 26f), 13f, (TextAlignmentOptions)514, new Color(0.88f, 0.76f, 0.57f, 1f));
			CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffStoreAll", "Store All", new Vector2(14f, -86f), new Vector2(163f, 36f), ConfirmStoreAll);
			CheckMyStuffCategory[] selectableCategories = CheckMyStuffCategoryNames.GetSelectableCategories();
			for (int i = 0; i < selectableCategories.Length; i++)
			{
				CheckMyStuffCategory checkMyStuffCategory = selectableCategories[i];
				int num = i % 2;
				int num2 = i / 2;
				CheckMyStuffCategory capturedCategory = checkMyStuffCategory;
				CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffStore_" + checkMyStuffCategory, CheckMyStuffCategoryNames.ToDisplayName(checkMyStuffCategory), new Vector2(14f + (float)num * 169f, -130f - (float)num2 * 44f), new Vector2(163f, 36f), delegate
				{
					RouteCategory(capturedCategory);
				});
			}
			s_statusText = CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffBarrelStatus", "Choose Store All or a category to store bag items.", new Vector2(14f, -320f), new Vector2(332f, 52f), 12f, (TextAlignmentOptions)514, new Color(0.92f, 0.82f, 0.65f, 1f));
			CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffBarrelClose", "Close", new Vector2(14f, -384f), new Vector2(332f, 38f), CloseUi);
			CreateConfirmDialog(component, val8, val2, val4, val5, val6);
			s_panel = val9;
			s_panelRect = component;
			val9.SetActive(false);
			s_createFailureLogged = false;
			if (CheckMyStuffPlugin.Log != null)
			{
				CheckMyStuffPlugin.Log.LogInfo((object)"CheckMyStuff barrel UI initialized on the native Valheim inventory layer at the container-panel position.");
			}
			return true;
		}

		private static void SyncPanelPosition(InventoryGui gui)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)gui == (Object)null) && !((Object)(object)gui.m_container == (Object)null) && !((Object)(object)s_panelRect == (Object)null))
			{
				RectTransform container = gui.m_container;
				s_panelRect.anchorMin = container.anchorMin;
				s_panelRect.anchorMax = container.anchorMax;
				s_panelRect.pivot = container.pivot;
				s_panelRect.anchoredPosition = container.anchoredPosition;
				s_panelRect.sizeDelta = new Vector2(360f, 454f);
			}
		}

		private static void ConfirmStoreAll()
		{
			BarrelController active = BarrelController.Active;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)active == (Object)null || (Object)(object)localPlayer == (Object)null || (Object)(object)s_confirmRoot == (Object)null)
			{
				return;
			}
			int num = SortingEngine.CountStorable(localPlayer, ((Component)active).transform);
			if (num <= 0)
			{
				if ((Object)(object)s_statusText != (Object)null)
				{
					s_statusText.text = "Nothing to store: no bag items match an enabled labeled chest in range.";
				}
				return;
			}
			s_confirmText.text = "Are you sure you want to store " + num + " item" + ((num == 1) ? "" : "s") + "?";
			s_confirmRoot.transform.SetAsLastSibling();
			s_confirmRoot.SetActive(true);
		}

		private static void HideConfirm()
		{
			if ((Object)(object)s_confirmRoot != (Object)null && s_confirmRoot.activeSelf)
			{
				s_confirmRoot.SetActive(false);
			}
		}

		private static void CreateConfirmDialog(RectTransform panelRect, Button buttonTemplate, Image backgroundSource, Image sunkenSource, TMP_FontAsset titleFont, TMP_FontAsset bodyFont)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_019e: 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_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = CreateImage("CheckMyStuffConfirm", (Transform)(object)panelRect);
			RectTransform component = obj.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = Vector2.zero;
			Image component2 = obj.GetComponent<Image>();
			((Graphic)component2).color = new Color(0f, 0f, 0f, 0.6f);
			((Graphic)component2).raycastTarget = true;
			GameObject obj2 = CreateImage("CheckMyStuffConfirmBox", (Transform)(object)component);
			RectTransform component3 = obj2.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 1f);
			component3.anchorMax = new Vector2(0f, 1f);
			component3.pivot = new Vector2(0f, 1f);
			component3.anchoredPosition = new Vector2(20f, -140f);
			component3.sizeDelta = new Vector2(320f, 170f);
			Image component4 = obj2.GetComponent<Image>();
			CopyImageStyle(((Object)(object)sunkenSource != (Object)null) ? sunkenSource : backgroundSource, component4);
			((Graphic)component4).color = Color.white;
			((Graphic)component4).raycastTarget = true;
			CreateNativeText(titleFont, (Transform)(object)component3, "CheckMyStuffConfirmTitle", "Store All", new Vector2(10f, -10f), new Vector2(300f, 30f), 20f, (TextAlignmentOptions)514, new Color(1f, 0.718f, 0.36f, 1f));
			s_confirmText = CreateNativeText(bodyFont, (Transform)(object)component3, "CheckMyStuffConfirmText", string.Empty, new Vector2(10f, -46f), new Vector2(300f, 52f), 15f, (TextAlignmentOptions)514, new Color(0.92f, 0.82f, 0.65f, 1f));
			CreateNativeButton(buttonTemplate, backgroundSource, bodyFont, (Transform)(object)component3, "CheckMyStuffConfirmYes", "Yes", new Vector2(14f, -112f), new Vector2(140f, 40f), delegate
			{
				HideConfirm();
				RouteCategory(null);
			});
			CreateNativeButton(buttonTemplate, backgroundSource, bodyFont, (Transform)(object)component3, "CheckMyStuffConfirmNo", "No", new Vector2(166f, -112f), new Vector2(140f, 40f), HideConfirm);
			s_confirmRoot = obj;
			obj.SetActive(false);
		}

		private static void RouteCategory(CheckMyStuffCategory? category)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			BarrelController active = BarrelController.Active;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)active == (Object)null || (Object)(object)localPlayer == (Object)null || !InventoryGui.IsVisible() || (Object)(object)InventoryGui.instance == (Object)null || InventoryGui.instance.IsContainerOpen())
			{
				return;
			}
			Vector3 val = ((Component)localPlayer).transform.position - ((Component)active).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude > 25f || !PrivateArea.CheckAccess(((Component)active).transform.position, 0f, false, false))
			{
				return;
			}
			SortingResult sortingResult = (category.HasValue ? SortingEngine.SortCategory(localPlayer, ((Component)active).transform, category.Value) : SortingEngine.SortAll(localPlayer, ((Component)active).transform));
			if (!((Object)(object)s_statusText == (Object)null))
			{
				s_statusText.text = (category.HasValue ? CheckMyStuffCategoryNames.ToDisplayName(category.Value) : "Store All") + ": moved " + sortingResult.ItemsMoved + " item(s) from " + sortingResult.StacksTouched + " stack(s) into " + sortingResult.ChestsUsed + " chest(s).";
				if (sortingResult.EligibleStacks > 0 && sortingResult.RemainingStacks > 0)
				{
					TMP_Text obj = s_statusText;
					obj.text = obj.text + " " + sortingResult.RemainingStacks + " stack(s) did not fit (matching chests full).";
				}
			}
		}

		private static void CloseUi()
		{
			BarrelController.Close();
			HidePanel();
			if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible())
			{
				InventoryGui.instance.Hide();
			}
		}

		private static Button FindNativeButtonTemplate(InventoryGui gui)
		{
			if ((Object)(object)gui == (Object)null)
			{
				return null;
			}
			Button[] array = (Button[])(object)new Button[6] { gui.m_takeAllButton, gui.m_stackAllButton, gui.m_dropButton, gui.m_craftButton, gui.m_tabCraft, gui.m_tabUpgrade };
			for (int i = 0; i < array.Length; i++)
			{
				if (IsUsableButtonTemplate(array[i]))
				{
					return array[i];
				}
			}
			Button[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Button>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if (IsUsableButtonTemplate(componentsInChildren[j]))
				{
					return componentsInChildren[j];
				}
			}
			return null;
		}

		private static bool IsUsableButtonTemplate(Button button)
		{
			if ((Object)(object)button == (Object)null)
			{
				return false;
			}
			Image component = ((Component)button).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				return (Object)(object)component.sprite != (Object)null;
			}
			return false;
		}

		private static Button CreateNativeButton(Button template, Image fallbackImage, TMP_FontAsset font, Transform parent, string name, string label, Vector2 anchoredPosition, Vector2 size, Action action)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_01ff: 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_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: 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)
			GameObject val = new GameObject(name, new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image),
				typeof(Button)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = anchoredPosition;
			component.sizeDelta = size;
			Image component2 = val.GetComponent<Image>();
			Image val2 = (((Object)(object)template != (Object)null) ? ((Component)template).GetComponent<Image>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				CopyImageStyle(val2, component2);
				((Graphic)component2).color = ((Graphic)val2).color;
			}
			else if ((Object)(object)fallbackImage != (Object)null)
			{
				CopyImageStyle(fallbackImage, component2);
				((Graphic)component2).color = new Color(0.44f, 0.3f, 0.2f, 0.96f);
			}
			Button component3 = val.GetComponent<Button>();
			((Selectable)component3).targetGraphic = (Graphic)(object)component2;
			if ((Object)(object)template != (Object)null)
			{
				((Selectable)component3).transition = ((Selectable)template).transition;
				((Selectable)component3).colors = ((Selectable)template).colors;
				((Selectable)component3).spriteState = ((Selectable)template).spriteState;
				((Selectable)component3).navigation = ((Selectable)template).navigation;
			}
			((UnityEventBase)component3.onClick).RemoveAllListeners();
			((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
			{
				action();
			});
			TMP_Text obj = CreateNativeText(font, (Transform)(object)component, name + "_Text", label, Vector2.zero, size, 14f, (TextAlignmentOptions)514, new Color(0.96f, 0.84f, 0.6f, 1f));
			RectTransform rectTransform = obj.rectTransform;
			obj.enableAutoSizing = true;
			obj.fontSizeMin = 9f;
			obj.fontSizeMax = 14f;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = Vector2.zero;
			rectTransform.sizeDelta = Vector2.zero;
			return component3;
		}

		private static TMP_Text CreateNativeText(TMP_FontAsset font, Transform parent, string name, string value, Vector2 anchoredPosition, Vector2 size, float fontSize, TextAlignmentOptions alignment, Color color)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(TextMeshProUGUI)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = anchoredPosition;
			component.sizeDelta = size;
			TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component2).text = value;
			((TMP_Text)component2).font = font;
			((TMP_Text)component2).fontSize = fontSize;
			((TMP_Text)component2).alignment = alignment;
			((Graphic)component2).color = color;
			((Graphic)component2).raycastTarget = false;
			((TMP_Text)component2).overflowMode = (TextOverflowModes)1;
			return (TMP_Text)(object)component2;
		}

		private static TMP_FontAsset FindFont(InventoryGui gui, string fontName)
		{
			if ((Object)(object)gui == (Object)null)
			{
				return null;
			}
			TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null && string.Equals(((Object)val.font).name, fontName, StringComparison.Ordinal))
				{
					return val.font;
				}
			}
			return null;
		}

		private static TMP_FontAsset FindAnyNativeFont(InventoryGui gui)
		{
			if ((Object)(object)gui == (Object)null)
			{
				return null;
			}
			TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null)
				{
					return val.font;
				}
			}
			return null;
		}

		private static GameObject CreateImage(string name, Transform parent)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			return val;
		}

		private static void CopyImageStyle(Image source, Image destination)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)source == (Object)null) && !((Object)(object)destination == (Object)null))
			{
				destination.sprite = source.sprite;
				destination.overrideSprite = source.overrideSprite;
				destination.type = source.type;
				destination.preserveAspect = source.preserveAspect;
				destination.fillCenter = source.fillCenter;
				((Graphic)destination).material = ((Graphic)source).material;
				destination.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier;
			}
		}

		private static void SetLayerRecursively(GameObject root, int layer)
		{
			if (!((Object)(object)root == (Object)null))
			{
				root.layer = layer;
				Transform transform = root.transform;
				for (int i = 0; i < transform.childCount; i++)
				{
					SetLayerRecursively(((Component)transform.GetChild(i)).gameObject, layer);
				}
			}
		}

		private static void HidePanel()
		{
			s_lastController = null;
			HideConfirm();
			if ((Object)(object)s_panel != (Object)null && s_panel.activeSelf)
			{
				s_panel.SetActive(false);
			}
		}

		private static void LogCreateFailure(string message)
		{
			if (!s_createFailureLogged && CheckMyStuffPlugin.Log != null)
			{
				CheckMyStuffPlugin.Log.LogWarning((object)("CheckMyStuff native barrel UI could not initialize: " + message));
				s_createFailureLogged = true;
			}
		}
	}
	public static class ChestLabelUi
	{
		private enum OptionsMode
		{
			None,
			Category,
			Subcategory
		}

		private const float PanelWidth = 350f;

		private const float CollapsedHeight = 232f;

		private const float ExpandedHeight = 525f;

		private const float PanelGap = 12f;

		private static readonly FieldInfo CurrentContainerField = typeof(InventoryGui).GetField("m_currentContainer", BindingFlags.Instance | BindingFlags.NonPublic);

		private static GameObject s_panel;

		private static RectTransform s_panelRect;

		private static RectTransform s_categoryOptionsRoot;

		private static RectTransform s_subcategoryOptionsRoot;

		private static Button s_categoryButton;

		private static Button s_subcategoryButton;

		private static Button s_enabledButton;

		private static TMP_Text s_categoryButtonText;

		private static TMP_Text s_subcategoryButtonText;

		private static TMP_Text s_enabledButtonText;

		private static TMP_Text s_statusText;

		private static Container s_lastContainer;

		private static OptionsMode s_optionsMode;

		private static bool s_createFailureLogged;

		private static Button s_buttonTemplate;

		private static Image s_backgroundSource;

		private static TMP_FontAsset s_bodyFont;

		private static CheckMyStuffCategory? s_subcategoryOptionsCategory;

		private static ItemTaxonomyPath s_taxonomyBrowsePath;

		private static int s_taxonomyPage;

		private const int TaxonomyPageSize = 8;

		private const float CheckboxSize = 18f;

		private static Container s_syncedContainer;

		private static uint s_syncedRevision;

		public static void ValidateContract()
		{
			if (CurrentContainerField == null || CurrentContainerField.FieldType != typeof(Container))
			{
				throw new InvalidOperationException("InventoryGui.m_currentContainer contract is unavailable.");
			}
		}

		public static void Draw()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_container == (Object)null || (Object)(object)instance.m_player == (Object)null || !InventoryGui.IsVisible())
			{
				HidePanel();
				return;
			}
			Container currentContainer = GetCurrentContainer(instance);
			if ((Object)(object)currentContainer == (Object)null || !ChestLabelManager.IsSupportedChest(currentContainer))
			{
				HidePanel();
			}
			else if (!BarrelController.HasSorterInRange(((Component)currentContainer).transform.position))
			{
				HidePanel();
			}
			else if (!((Object)(object)s_panel == (Object)null) || TryCreatePanel(instance))
			{
				if (currentContainer != s_lastContainer)
				{
					s_lastContainer = currentContainer;
					SetOptionsMode(OptionsMode.None);
				}
				ZNetView component = ((Component)currentContainer).GetComponent<ZNetView>();
				uint num = (((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null) ? component.GetZDO().DataRevision : 0u);
				if (currentContainer != s_syncedContainer || num != s_syncedRevision || num == 0)
				{
					s_syncedContainer = currentContainer;
					s_syncedRevision = num;
					SyncState(currentContainer);
				}
				if (!s_panel.activeSelf)
				{
					s_panel.SetActive(true);
				}
			}
		}

		private static bool TryCreatePanel(InventoryGui gui)
		{
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: 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_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_0528: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_057a: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ef: Expected O, but got Unknown
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			RectTransform container = gui.m_container;
			RectTransform player = gui.m_player;
			Transform val = ((Transform)player).Find("Bkg");
			Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : null);
			Transform val3 = ((Transform)player).Find("sunken");
			Image val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<Image>() : null);
			TMP_FontAsset val5 = FindFont(gui, "Valheim-Norsebold");
			TMP_FontAsset val6 = FindFont(gui, "Valheim-AveriaSansLibre");
			TMP_FontAsset val7 = FindAnyNativeFont(gui);
			if ((Object)(object)val5 == (Object)null)
			{
				val5 = val7;
			}
			if ((Object)(object)val6 == (Object)null)
			{
				val6 = val7;
			}
			Button val8 = FindNativeButtonTemplate(gui);
			if ((Object)(object)container == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null)
			{
				LogCreateFailure(container, val2, val5, val6, val8);
				return false;
			}
			s_buttonTemplate = val8;
			s_backgroundSource = val2;
			s_bodyFont = val6;
			GameObject val9 = new GameObject("CheckMyStuffChestLabelPanel", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val9.transform.SetParent((Transform)(object)container, false);
			SetLayerRecursively(val9, ((Component)gui).gameObject.layer);
			RectTransform component = val9.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(12f, 0f);
			component.sizeDelta = new Vector2(350f, 232f);
			Image component2 = val9.GetComponent<Image>();
			CopyImageStyle(val2, component2);
			((Graphic)component2).color = Color.white;
			((Graphic)component2).raycastTarget = true;
			if ((Object)(object)val4 != (Object)null)
			{
				GameObject obj = CreateImage("CheckMyStuffNativeInset", (Transform)(object)component);
				RectTransform component3 = obj.GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0f, 1f);
				component3.anchorMax = new Vector2(0f, 1f);
				component3.pivot = new Vector2(0f, 1f);
				component3.anchoredPosition = new Vector2(8f, -38f);
				component3.sizeDelta = new Vector2(334f, 184f);
				Image component4 = obj.GetComponent<Image>();
				CopyImageStyle(val4, component4);
				((Graphic)component4).color = new Color(1f, 1f, 1f, 0.78f);
				((Graphic)component4).raycastTarget = false;
				obj.transform.SetAsFirstSibling();
			}
			Shadow obj2 = ((Component)CreateNativeText(val5, (Transform)(object)component, "CheckMyStuffTitle", "CHECKMYSTUFF", new Vector2(12f, -7f), new Vector2(326f, 36f), 23f, (TextAlignmentOptions)514, new Color(1f, 0.718f, 0.36f, 1f))).gameObject.AddComponent<Shadow>();
			obj2.effectColor = new Color(0f, 0f, 0f, 0.78f);
			obj2.effectDistance = new Vector2(2f, -2f);
			CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffCategoryLabel", "Category", new Vector2(14f, -44f), new Vector2(220f, 18f), 13f, (TextAlignmentOptions)513, new Color(0.92f, 0.82f, 0.65f, 1f));
			s_categoryButton = CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffCategoryButton", "Unassigned", new Vector2(12f, -63f), new Vector2(326f, 36f), delegate
			{
				ToggleOptions(OptionsMode.Category);
			});
			s_categoryButtonText = ((Component)s_categoryButton).GetComponentInChildren<TMP_Text>(true);
			CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffSubcategoryLabel", "Subcategory", new Vector2(14f, -98f), new Vector2(220f, 18f), 13f, (TextAlignmentOptions)513, new Color(0.92f, 0.82f, 0.65f, 1f));
			s_subcategoryButton = CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffSubcategoryButton", "All Types", new Vector2(12f, -117f), new Vector2(326f, 36f), delegate
			{
				ToggleOptions(OptionsMode.Subcategory);
			});
			s_subcategoryButtonText = ((Component)s_subcategoryButton).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)s_subcategoryButtonText != (Object)null)
			{
				s_subcategoryButtonText.enableAutoSizing = false;
				s_subcategoryButtonText.fontSize = 13f;
				s_subcategoryButtonText.textWrappingMode = (TextWrappingModes)0;
				s_subcategoryButtonText.overflowMode = (TextOverflowModes)1;
				s_subcategoryButtonText.margin = new Vector4(8f, 0f, 8f, 0f);
			}
			s_enabledButton = CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffEnabledButton", "Enabled: OFF", new Vector2(12f, -155f), new Vector2(326f, 36f), ToggleEnabled);
			s_enabledButtonText = ((Component)s_enabledButton).GetComponentInChildren<TMP_Text>(true);
			s_statusText = CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffStatus", "Choose a category to label this chest.", new Vector2(12f, -191f), new Vector2(326f, 32f), 11f, (TextAlignmentOptions)514, new Color(0.88f, 0.78f, 0.62f, 0.95f));
			s_categoryOptionsRoot = CreateOptionsRoot((Transform)(object)component, "CheckMyStuffCategoryOptions", ((Component)gui).gameObject.layer);
			s_subcategoryOptionsRoot = CreateOptionsRoot((Transform)(object)component, "CheckMyStuffSubcategoryOptions", ((Component)gui).gameObject.layer);
			BuildCategoryOptions();
			s_panel = val9;
			s_panelRect = component;
			SetOptionsMode(OptionsMode.None);
			val9.SetActive(false);
			s_createFailureLogged = false;
			if (CheckMyStuffPlugin.Log != null)
			{
				CheckMyStuffPlugin.Log.LogInfo((object)"CheckMyStuff chest label UI initialized with native Category + Subcategory + Enabled controls.");
			}
			return true;
		}

		private static RectTransform CreateOptionsRoot(Transform parent, string name, int layer)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			SetLayerRecursively(val, layer);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = new Vector2(350f, 525f);
			return component;
		}

		private static void BuildCategoryOptions()
		{
			//IL_0085: 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)
			if ((Object)(object)s_categoryOptionsRoot == (Object)null)
			{
				return;
			}
			CheckMyStuffCategory[] selectableCategories = CheckMyStuffCategoryNames.GetSelectableCategories();
			for (int i = 0; i < selectableCategories.Length; i++)
			{
				CheckMyStuffCategory checkMyStuffCategory = selectableCategories[i];
				int num = i % 2;
				int num2 = i / 2;
				CheckMyStuffCategory capturedCategory = checkMyStuffCategory;
				CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_categoryOptionsRoot, "CheckMyStuffCategory_" + checkMyStuffCategory, CheckMyStuffCategoryNames.ToDisplayName(checkMyStuffCategory), new Vector2(12f + (float)num * 166f, -226f - (float)num2 * 40f), new Vector2(158f, 36f), delegate
				{
					SelectCategory(capturedCategory);
				});
			}
			CreateNavigation(0, 1, delegate
			{
				SetOptionsMode(OptionsMode.None);
			}, null);
		}

		private static void RebuildSubcategoryOptions(CheckMyStuffCategory category)
		{
			if (!((Object)(object)s_subcategoryOptionsRoot == (Object)null))
			{
				if (!s_subcategoryOptionsCategory.HasValue || s_subcategoryOptionsCategory.Value != category)
				{
					s_taxonomyBrowsePath = ItemTaxonomy.GetInitialBrowsePath(category);
					s_taxonomyPage = 0;
				}
				s_subcategoryOptionsCategory = category;
				RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage);
			}
		}

		private static void RebuildTaxonomyOptions(CheckMyStuffCategory category, ItemTaxonomyPath parent, int page)
		{
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_subcategoryOptionsRoot == (Object)null)
			{
				return;
			}
			ItemTaxonomyPath itemTaxonomyPath = parent ?? new ItemTaxonomyPath(null, null, null, null);
			if (ItemTaxonomy.IsFinalChoice(category, itemTaxonomyPath) && itemTaxonomyPath.Depth > ItemTaxonomy.GetInitialBrowsePath(category).Depth)
			{
				ItemTaxonomyPath parent2 = itemTaxonomyPath.Parent();
				int val = ItemTaxonomy.GetChildren(category, parent2).IndexOf(itemTaxonomyPath.GetPart(itemTaxonomyPath.Depth - 1));
				RebuildTaxonomyOptions(category, parent2, Math.Max(0, val) / 8);
				return;
			}
			ClearOptionButtons((Transform)(object)s_subcategoryOptionsRoot);
			s_subcategoryOptionsCategory = category;
			s_taxonomyBrowsePath = itemTaxonomyPath;
			List<string> children = ItemTaxonomy.GetChildren(category, s_taxonomyBrowsePath);
			ChestLabelState state = null;
			if ((Object)(object)s_lastContainer != (Object)null)
			{
				ChestLabelManager.TryRead(s_lastContainer, out state);
			}
			int num = Math.Max(1, (children.Count + 8 - 1) / 8);
			s_taxonomyPage = Math.Max(0, Math.Min(page, num - 1));
			int num2 = s_taxonomyPage * 8;
			int num3 = Math.Min(children.Count, num2 + 8);
			for (int i = num2; i < num3; i++)
			{
				string value = children[i];
				int num4 = i - num2;
				ItemTaxonomyPath childPath = s_taxonomyBrowsePath.WithChild(value);
				bool finalChoice = ItemTaxonomy.IsFinalChoice(category, childPath);
				Button val2 = CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomy_" + s_taxonomyPage + "_" + num4, ItemTaxonomy.GetOptionDisplayName(value), new Vector2(12f + (float)(num4 % 2) * 166f, -270f - (float)(num4 / 2) * 40f), new Vector2(158f, 36f), delegate
				{
					if (finalChoice)
					{
						SelectTaxonomyPath(childPath);
					}
					else
					{
						RebuildTaxonomyOptions(category, childPath, 0);
					}
				});
				TMP_Text componentInChildren = ((Component)val2).GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.rectTransform.anchoredPosition = new Vector2(13f, 0f);
					componentInChildren.rectTransform.sizeDelta = new Vector2(-26f, 0f);
				}
				CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, ((Component)val2).transform, "CheckMyStuffTick_" + s_taxonomyPage + "_" + num4, IsTicked(state, childPath) ? "X" : string.Empty, new Vector2(4f, -9f), new Vector2(18f, 18f), delegate
				{
					ToggleTaxonomyPath(category, childPath);
				});
			}
			UpdateBrowseIndicator(category, s_taxonomyBrowsePath);
			ItemTaxonomyPath selectedPath = s_taxonomyBrowsePath;
			if (selectedPath.Depth == 0)
			{
				CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomyAllTypes", "All Types", new Vector2(12f, -226f), new Vector2(158f, 36f), SelectAllTypes);
			}
			else
			{
				CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomyUse", "All Types", new Vector2(12f, -226f), new Vector2(158f, 36f), delegate
				{
					SelectTaxonomyPath(selectedPath);
				});
			}
			CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomyClearAll", "Clear All", new Vector2(178f, -226f), new Vector2(158f, 36f), delegate
			{
				ClearAllSelections(category);
			});
			CreateNavigation(s_taxonomyPage, num, delegate
			{
				if (s_taxonomyPage > 0)
				{
					RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage - 1);
				}
				else if (s_taxonomyBrowsePath.Depth > ItemTaxonomy.GetInitialBrowsePath(category).Depth)
				{
					ItemTaxonomyPath parent3 = s_taxonomyBrowsePath.Parent();
					List<string> children2 = ItemTaxonomy.GetChildren(category, parent3);
					string part = s_taxonomyBrowsePath.GetPart(s_taxonomyBrowsePath.Depth - 1);
					int page2 = Math.Max(0, children2.IndexOf(part)) / 8;
					RebuildTaxonomyOptions(category, parent3, page2);
				}
				else
				{
					SetOptionsMode(OptionsMode.None);
					if ((Object)(object)s_lastContainer != (Object)null)
					{
						SyncState(s_lastContainer);
					}
				}
			}, delegate
			{
				RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage + 1);
			});
		}

		private static void CreateNavigation(int page, int count, Action previous, Action next)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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)
			Transform parent = (Transform)(object)((next == null) ? s_categoryOptionsRoot : s_subcategoryOptionsRoot);
			List<string> list = new List<string>();
			for (int i = 0; i < count; i++)
			{
				list.Add((i == page) ? ("<color=#FFD479>" + (i + 1) + "</color>") : (i + 1).ToString());
			}
			TMP_Text obj = CreateNativeText(s_bodyFont, parent, "CheckMyStuffPageNumbers", string.Join("..", list.ToArray()), new Vector2(12f, -440f), new Vector2(326f, 24f), 12f, (TextAlignmentOptions)514, Color.white);
			obj.enableAutoSizing = true;
			obj.fontSizeMin = 8f;
			obj.fontSizeMax = 12f;
			CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, parent, "CheckMyStuffTaxonomyPrevious", "Previous", new Vector2(12f, -470f), new Vector2(158f, 36f), previous);
			((Selectable)CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, parent, "CheckMyStuffTaxonomyNext", "Next", new Vector2(180f, -470f), new Vector2(158f, 36f), delegate
			{
				if (next != null)
				{
					next();
				}
			})).interactable = next != null && page + 1 < count;
		}

		private static void ClearOptionButtons(Transform root)
		{
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				Transform child = root.GetChild(num);
				if ((Object)(object)child != (Object)null)
				{
					((Component)child).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)child).gameObject);
				}
			}
		}

		private static void ToggleOptions(OptionsMode requested)
		{
			OptionsMode optionsMode = ((s_optionsMode != requested) ? requested : OptionsMode.None);
			bool flag = s_optionsMode == OptionsMode.Subcategory && optionsMode != OptionsMode.Subcategory;
			if (optionsMode == OptionsMode.Subcategory && (Object)(object)s_lastContainer != (Object)null && ChestLabelManager.TryRead(s_lastContainer, out var state) && state != null)
			{
				s_taxonomyBrowsePath = state.Selection ?? ItemTaxonomy.GetInitialBrowsePath(state.Category);
				s_taxonomyPage = 0;
				RebuildSubcategoryOptions(state.Category);
			}
			SetOptionsMode(optionsMode);
			if (flag && (Object)(object)s_lastContainer != (Object)null)
			{
				SyncState(s_lastContainer);
			}
		}

		private static void UpdateBrowseIndicator(CheckMyStuffCategory category, ItemTaxonomyPath browsePath)
		{
			string selectionDisplayName = ItemTaxonomy.GetSelectionDisplayName(category, browsePath);
			if ((Object)(object)s_subcategoryButtonText != (Object)null)
			{
				s_subcategoryButtonText.text = selectionDisplayName;
			}
		}

		private static void SetOptionsMode(OptionsMode mode)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			s_optionsMode = mode;
			if ((Object)(object)s_categoryOptionsRoot != (Object)null)
			{
				((Component)s_categoryOptionsRoot).gameObject.SetActive(mode == OptionsMode.Category);
			}
			if ((Object)(object)s_subcategoryOptionsRoot != (Object)null)
			{
				((Component)s_subcategoryOptionsRoot).gameObject.SetActive(mode == OptionsMode.Subcategory);
			}
			if ((Object)(object)s_panelRect != (Object)null)
			{
				s_panelRect.sizeDelta = new Vector2(350f, (mode == OptionsMode.None) ? 232f : 525f);
			}
		}

		private static void SelectCategory(CheckMyStuffCategory category)
		{
			Container val = s_lastContainer;
			if (!((Object)(object)val == (Object)null))
			{
				ChestLabelState state;
				bool enabled = ChestLabelManager.TryRead(val, out state) && state.Enabled;
				if (!ChestLabelManager.TryWrite(val, category, "AllTypes", enabled))
				{
					LogWriteFailure("Could not write chest category " + CheckMyStuffCategoryNames.ToDisplayName(category) + ".");
					return;
				}
				s_taxonomyBrowsePath = ItemTaxonomy.GetInitialBrowsePath(category);
				s_taxonomyPage = 0;
				RebuildSubcategoryOptions(category);
				SetOptionsMode(OptionsMode.None);
				SyncState(val);
			}
		}

		private static void SelectAllTypes()
		{
			Container val = s_lastContainer;
			if (!((Object)(object)val == (Object)null) && ChestLabelManager.TryRead(val, out var state))
			{
				if (!ChestLabelManager.TryWrite(val, state.Category, "AllTypes", state.Enabled))
				{
					LogWriteFailure("Could not reset the chest taxonomy selection.");
					return;
				}
				SetOptionsMode(OptionsMode.None);
				SyncState(val);
			}
		}

		private static void ClearAllSelections(CheckMyStuffCategory category)
		{
			Container val = s_lastContainer;
			if (!((Object)(object)val == (Object)null) && ChestLabelManager.TryRead(val, out var state) && state != null)
			{
				if (!ChestLabelManager.TryWriteSelections(val, state.Category, new ItemTaxonomyPath[0], state.Enabled))
				{
					LogWriteFailure("Could not clear chest label selections.");
					return;
				}
				RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage);
				SyncState(val);
			}
		}

		private static bool IsTicked(ChestLabelState state, ItemTaxonomyPath path)
		{
			if (state == null || path == null)
			{
				return false;
			}
			string text = TaxonomyOrganization.Key(path);
			foreach (ItemTaxonomyPath selection in state.Selections)
			{
				if (TaxonomyOrganization.Key(selection) == text)
				{
					return true;
				}
			}
			return false;
		}

		private static void ToggleTaxonomyPath(CheckMyStuffCategory category, ItemTaxonomyPath path)
		{
			Container val = s_lastContainer;
			if ((Object)(object)val == (Object)null || path == null || !ChestLabelManager.TryRead(val, out var state) || state == null)
			{
				return;
			}
			List<ItemTaxonomyPath> list = new List<ItemTaxonomyPath>(state.Selections);
			string key = TaxonomyOrganization.Key(path);
			int num = list.FindIndex((ItemTaxonomyPath p) => TaxonomyOrganization.Key(p) == key);
			if (num >= 0)
			{
				list.RemoveAt(num);
			}
			else
			{
				if (list.Count > 0 && list[0].Depth != path.Depth)
				{
					if ((Object)(object)Player.m_localPlayer != (Object)null)
					{
						((Character)Player.m_localPlayer).Message((MessageType)2, "Tick entries on one level only: untick the others first.", 0, (Sprite)null, false);
					}
					return;
				}
				list.Add(path);
			}
			if (!ChestLabelManager.TryWriteSelections(val, state.Category, list, state.Enabled))
			{
				LogWriteFailure("Could not write chest label selections.");
				return;
			}
			if (list.Count == 0 && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "Nothing ticked: this chest now takes all " + CheckMyStuffCategoryNames.ToDisplayName(state.Category) + ".", 0, (Sprite)null, false);
			}
			RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage);
			SyncState(val);
		}

		private static void SelectTaxonomyPath(ItemTaxonomyPath selection)
		{
			Container val = s_lastContainer;
			if (!((Object)(object)val == (Object)null) && selection != null && ChestLabelManager.TryRead(val, out var state) && state != null)
			{
				if (!ChestLabelManager.TryWriteSelection(val, state.Category, selection, state.Enabled))
				{
					LogWriteFailure("Could not write chest taxonomy selection: " + ItemTaxonomy.GetSelectionDisplayName(state.Category, selection));
					return;
				}
				SetOptionsMode(OptionsMode.None);
				SyncState(val);
			}
		}

		private static void ToggleEnabled()
		{
			Container val = s_lastContainer;
			if (!((Object)(object)val == (Object)null) && ChestLabelManager.TryRead(val, out var state))
			{
				if (!ChestLabelManager.TrySetEnabled(val, !state.Enabled))
				{
					LogWriteFailure("Could not update chest Enabled state.");
				}
				else
				{
					SyncState(val);
				}
			}
		}

		private static void SyncState(Container container)
		{
			ChestLabelState state;
			bool flag = ChestLabelManager.TryRead(container, out state);
			string text = (flag ? CheckMyStuffCategoryNames.ToDisplayName(state.Category) : "Unassigned");
			string text2 = ((!flag) ? "All Types" : ((state.Selection != null) ? ItemTaxonomy.GetSelectionsDisplayName(state.Category, state.Selections) : ((state.Subcategory != "AllTypes") ? state.Subcategory : "All Types")));
			if ((Object)(object)s_categoryButtonText != (Object)null)
			{
				s_categoryButtonText.text = text;
			}
			if ((Object)(object)s_subcategoryButton != (Object)null)
			{
				((Selectable)s_subcategoryButton).interactable = flag;
			}
			if ((Object)(object)s_subcategoryButtonText != (Object)null)
			{
				s_subcategoryButtonText.text = text2;
			}
			if ((Object)(object)s_enabledButton != (Object)null)
			{
				((Selectable)s_enabledButton).interactable = flag;
			}
			if ((Object)(object)s_enabledButtonText != (Object)null)
			{
				s_enabledButtonText.text = "Enabled: " + ((flag && state.Enabled) ? "ON" : "OFF");
			}
			if (flag && (!s_subcategoryOptionsCategory.HasValue || s_subcategoryOptionsCategory.Value != state.Category))
			{
				RebuildSubcategoryOptions(state.Category);
			}
			if ((Object)(object)s_statusText != (Object)null)
			{
				s_statusText.text = (flag ? string.Empty : "Choose a category to label this chest.");
			}
			if (flag && s_optionsMode == OptionsMode.Subcategory)
			{
				UpdateBrowseIndicator(state.Category, s_taxonomyBrowsePath);
			}
		}

		private static Button FindNativeButtonTemplate(InventoryGui gui)
		{
			if ((Object)(object)gui == (Object)null)
			{
				return null;
			}
			Button[] array = (Button[])(object)new Button[6] { gui.m_takeAllButton, gui.m_stackAllButton, gui.m_dropButton, gui.m_craftButton, gui.m_tabCraft, gui.m_tabUpgrade };
			for (int i = 0; i < array.Length; i++)
			{
				if (IsUsableButtonTemplate(array[i]))
				{
					return array[i];
				}
			}
			Button[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Button>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if (IsUsableButtonTemplate(componentsInChildren[j]))
				{
					return componentsInChildren[j];
				}
			}
			return null;
		}

		private static bool IsUsableButtonTemplate(Button button)
		{
			if ((Object)(object)button == (Object)null)
			{
				return false;
			}
			Image component = ((Component)button).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				return (Object)(object)component.sprite != (Object)null;
			}
			return false;
		}

		private static TMP_Text CreateNativeText(TMP_FontAsset font, Transform parent, string name, string value, Vector2 anchoredPosition, Vector2 size, float fontSize, TextAlignmentOptions alignment, Color color)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(TextMeshProUGUI)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = anchoredPosition;
			component.sizeDelta = size;
			TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component2).text = value;
			((TMP_Text)component2).font = font;
			((TMP_Text)component2).fontSize = fontSize;
			((TMP_Text)component2).alignment = alignment;
			((Graphic)component2).color = color;
			((Graphic)component2).raycastTarget = false;
			((TMP_Text)component2).overflowMode = (TextOverflowModes)1;
			return (TMP_Text)(object)component2;
		}

		private static Button CreateNativeButton(Button template, Image fallbackImage, TMP_FontAsset font, Transform parent, string name, string label, Vector2 anchoredPosition, Vector2 size, Action action)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: 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)
			GameObject val = new GameObject(name, new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image),
				typeof(Button)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = anchoredPosition;
			component.sizeDelta = size;
			Image component2 = val.GetComponent<Image>();
			Image val2 = (((Object)(object)template != (Object)null) ? ((Component)template).GetComponent<Image>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				CopyImageStyle(val2, component2);
				((Graphic)component2).color = ((Graphic)val2).color;
			}
			else if ((Object)(object)fallbackImage != (Object)null)
			{
				CopyImageStyle(fallbackImage, component2);
				((Graphic)component2).color = new Color(0.5f, 0.35f, 0.22f, 0.95f);
			}
			Button component3 = val.GetComponent<Button>();
			((Selectable)component3).targetGraphic = (Graphic)(object)component2;
			if ((Object)(object)template != (Object)null)
			{
				((Selectable)component3).transition = ((Selectable)template).transition;
				((Selectable)component3).colors = ((Selectable)template).colors;
				((Selectable)component3).spriteState = ((Selectable)template).spriteState;
				((Selectable)component3).navigation = ((Selectable)template).navigation;
			}
			((UnityEventBase)component3.onClick).RemoveAllListeners();
			((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
			{
				action();
			});
			TMP_Text obj = CreateNativeText(font, (Transform)(object)component, name + "_Text", label, Vector2.zero, size, 13f, (TextAlignmentOptions)514, new Color(0.96f, 0.84f, 0.6f, 1f));
			obj.enableAutoSizing = true;
			obj.fontSizeMin = 9f;
			obj.fontSizeMax = obj.fontSize;
			RectTransform rectTransform = obj.rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = Vector2.zero;
			rectTransform.sizeDelta = Vector2.zero;
			return component3;
		}

		private static GameObject CreateImage(string name, Transform parent)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			})
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			return val;
		}

		private static void CopyImageStyle(Image source, Image destination)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)source == (Object)null) && !((Object)(object)destination == (Object)null))
			{
				destination.sprite = source.sprite;
				destination.overrideSprite = source.overrideSprite;
				destination.type = source.type;
				destination.preserveAspect = source.preserveAspect;
				destination.fillCenter = source.fillCenter;
				((Graphic)destination).material = ((Graphic)source).material;
				destination.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier;
			}
		}

		private static TMP_FontAsset FindFont(InventoryGui gui, string fontName)
		{
			if ((Object)(object)gui == (Object)null)
			{
				return null;
			}
			TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.font == (Object)null) && string.Equals(((Object)val.font).name, fontName, StringComparison.Ordinal))
				{
					return val.font;
				}
			}
			return null;
		}

		private static TMP_FontAsset FindAnyNativeFont(InventoryGui gui)
		{
			if ((Object)(object)gui == (Object)null)
			{
				return null;
			}
			TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null)
				{
					return val.font;
				}
			}
			return null;
		}

		private static void SetLayerRecursively(GameObject root, int layer)
		{
			if (!((Object)(object)root == (Object)null))
			{
				root.layer = layer;
				Transform transform = root.transform;
				for (int i = 0; i < transform.childCount; i++)
				{
					SetLayerRecursively(((Component)transform.GetChild(i)).gameObject, layer);
				}
			}
		}

		private static void LogCreateFailure(RectTransform containerRect, Image backgroundSource, TMP_FontAsset titleFont, TMP_FontAsset bodyFont, Button buttonTemplate)
		{
			if (!s_createFailureLogged && CheckMyStuffPlugin.Log != null)
			{
				CheckMyStuffPlugin.Log.LogWarning((object)("CheckMyStuff native chest UI template audit failed. container=" + ((Object)(object)containerRect != (Object)null) + " playerBkg=" + ((Object)(object)backgroundSource != (Object)null) + " titleFont=" + ((Object)(object)titleFont != (Object)null) + " bodyFont=" + ((Object)(object)bodyFont != (Object)null) + " buttonTemplate=" + ((Object)(object)buttonTemplate != (Object)null) + ". The panel will retry on later frames."));
				s_createFailureLogged = true;
			}
		}

		private static Container GetCurrentContainer(InventoryGui gui)
		{
			if ((Object)(object)gui == (Object)null || CurrentContainerField == null)
			{
				return null;
			}
			object? value = CurrentContainerField.GetValue(gui);
			return (Container)((value is Container) ? value : null);
		}

		private static void HidePanel()
		{
			s_lastContainer = null;
			SetOptionsMode(OptionsMode.None);
			if ((Object)(object)s_panel != (Object)null && s_panel.activeSelf)
			{
				s_panel.SetActive(false);
			}
		}

		private static void LogWriteFailure(string message)
		{
			if (CheckMyStuffPlugin.Log != null)
			{
				CheckMyStuffPlugin.Log.LogWarning((object)message);
			}
		}
	}
	[HarmonyPatch(typeof(Container), "GetHoverText")]
	internal static class ContainerHoverPatch
	{
		private static Container s_container;

		private static uint s_revision;

		private static string s_label;

		private static void Postfix(Container __instance, ref string __result)
		{
			if (!((Object)(object)__instance == (Object)null) && !string.IsNullOrEmpty(__result))
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				uint num = (((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null) ? component.GetZDO().DataRevision : 0u);
				if (__instance != s_container || num != s_revision || num == 0)
				{
					s_container = __instance;
					s_revision = num;
					s_label = ((ChestLabelManager.TryRead(__instance, out var state) && state != null && state.Enabled) ? ItemTaxonomy.GetLabelShortName(state) : null);
				}
				__result = AppendLabel(__result, s_label);
			}
		}

		internal static string AppendLabel(string hoverText, string label)
		{
			if (!string.IsNullOrEmpty(label))
			{
				return hoverText + "\n" + label;
			}
			return hoverText;
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int),
		typeof(bool)
	})]
	internal static class ItemTooltipPatch
	{
		private const string WeightLine = "\n$item_weight";

		private static readonly Dictionary<string, string> Lines = new Dictionary<string, string>(StringComparer.Ordinal);

		private static int s_revision = int.MinValue;

		private static void Postfix(ItemData item, bool appending, ref string __result)
		{
			if (!appending && item != null && !string.IsNullOrEmpty(__result))
			{
				__result = InsertPath(__result, GetLine(item));
			}
		}

		internal static string InsertPath(string tooltip, string path)
		{
			if (string.IsNullOrEmpty(tooltip) || string.IsNullOrEmpty(path))
			{
				return tooltip;
			}
			string text = "\n<size=80%>" + path + "</size>";
			int num = tooltip.IndexOf("\n$item_weight", StringComparison.Ordinal);
			if (num < 0)
			{
				return tooltip + text;
			}
			return tooltip.Insert(num, text);
		}

		private static string GetLine(ItemData item)
		{
			if (s_revision != ItemTaxonomy.Revision)
			{
				Lines.Clear();
				s_revision = ItemTaxonomy.Revision;
			}
			string text = (((Object)(object)item.m_dropPrefab == (Object)null) ? null : Utils.GetPrefabName(((Object)item.m_dropPrefab).name));
			if (text != null && Lines.TryGetValue(text, out var value))
			{
				return value;
			}
			value = (ItemClassifier.TryClassifyTaxonomy(item, out var _, out var path, out var _) ? ItemTaxonomy.GetTooltipPath(path) : string.Empty);
			if (text != null)
			{
				Lines[text] = value;
			}
			return value;
		}
	}
}
namespace CheckMyStuff.Routing
{
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ContainerAwakePatch
	{
		private static void Postfix(Container __instance)
		{
			ContainerFinder.Register(__instance);
		}
	}
	public static class ContainerFinder
	{
		private static readonly MethodInfo LoadInventory = typeof(Container).GetMethod("Load", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly List<Container> Snapshot = new List<Container>();

		private const string RequestOwnerRpc = "CheckMyStuff_RequestOwner";

		private const string OwnerReplyRpc = "CheckMyStuff_OwnerReply";

		private const float OwnerRequestCooldown = 3f;

		private static readonly HashSet<ZNetView> RpcViews = new HashSet<ZNetView>();

		private static readonly Dictionary<ZDOID, float> OwnerRequests = new Dictionary<ZDOID, float>();

		public static event Action OwnershipGranted;

		public static void Register(Container container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return;
			}
			for (int num = Snapshot.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)Snapshot[num] == (Object)null)
				{
					Snapshot.RemoveAt(num);
				}
				else if ((Object)(object)Snapshot[num] == (Object)(object)container)
				{
					return;
				}
			}
			Snapshot.Add(container);
			RegisterOwnershipRpcs(container);
		}

		private static void RegisterOwnershipRpcs(Container container)
		{
			ZNetView view = GetView(container);
			if ((Object)(object)view == (Object)null)
			{
				return;
			}
			if (RpcViews.Count > 256)
			{
				RpcViews.RemoveWhere((ZNetView v) => (Object)(object)v == (Object)null);
			}
			if (RpcViews.Add(view))
			{
				view.Register("CheckMyStuff_RequestOwner", (Action<long>)delegate(long sender)
				{
					RPC_RequestOwner(container, view, sender);
				});
				view.Register<bool>("CheckMyStuff_OwnerReply", (Action<long, bool>)delegate(long sender, bool granted)
				{
					RPC_OwnerReply(granted);
				});
			}
		}

		private static void RPC_RequestOwner(Container container, ZNetView view, long sender)
		{
			if (!((Object)(object)view == (Object)null) && view.IsValid() && view.IsOwner() && view.GetZDO() != null)
			{
				bool flag = (Object)(object)container != (Object)null && !IsInUse(container);
				if (flag)
				{
					view.GetZDO().SetOwner(sender);
				}
				view.InvokeRPC(sender, "CheckMyStuff_OwnerReply", new object[1] { flag });
			}
		}

		private static void RPC_OwnerReply(bool granted)
		{
			if (granted && ContainerFinder.OwnershipGranted != null)
			{
				ContainerFinder.OwnershipGranted();
			}
		}

		private static void RequestOwnership(ZNetView view)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			ZDOID uid = view.GetZDO().m_uid;
			if (!OwnerRequests.TryGetValue(uid, out var value) || !(Time.time - value < 3f))
			{
				OwnerRequests[uid] = Time.time;
				view.InvokeRPC("CheckMyStuff_RequestOwner", Array.Empty<object>());
			}
		}

		public static bool TryPrepareForWrite(Container container)
		{
			if ((Object)(object)container == (Object)null || !ChestLabelManager.IsSupportedChest(container) || IsInUse(container))
			{
				return false;
			}
			if (!HasVanillaAccess(container))
			{
				return false;
			}
			ZNetView view = GetView(container);
			if ((Object)(object)view == (Object)null || !view.IsValid() || view.GetZDO() == null)
			{
				return false;
			}
			if (!view.IsOwner())
			{
				if (view.GetZDO().GetOwner() != 0L)
				{
					RequestOwnership(view);
					return false;
				}
				view.ClaimOwnership();
			}
			if (!view.IsOwner() || LoadInventory == null || IsInUse(container))
			{
				return false;
			}
			LoadInventory.Invoke(container, null);
			return !IsInUse(container);
		}

		public static List<Container> FindMatchingForItem(Vector3 origin, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = new List<Container>();
			float num = 2500f;
			for (int i = 0; i < Snapshot.Count; i++)
			{
				Container val = Snapshot[i];
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 val2 = ((Component)val).transform.position - origin;
					if (!(((Vector3)(ref val2)).sqrMagnitude > num) && TryMatchState(val, category, itemPath, legacySubcategory, out var _))
					{
						list.Add(val);
					}
				}
			}
			Dictionary<Container, int> depths = new Dictionary<Container, int>();
			foreach (Container item in list)
			{
				depths[item] = ((TryReadState(item, out var state2) && state2 != null) ? ((state2.Selection != null && !ChestLabelManager.IsCategoryRoot(state2.Category, state2.Selection)) ? state2.Selection.Depth : ((state2.Selection == null && state2.Subcategory != "AllTypes") ? 1 : 0)) : 0);
			}
			list.Sort(delegate(Container left, Container right)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				int num2 = depths[right].CompareTo(depths[left]);
				if (num2 != 0)
				{
					return num2;
				}
				Vector3 val3 = ((Component)left).transform.position - origin;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				val3 = ((Component)right).transform.position - origin;
				return sqrMagnitude.CompareTo(((Vector3)(ref val3)).sqrMagnitude);
			});
			return list;
		}

		public static bool TryPrepareForItem(Container container, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory)
		{
			if (TryMatchState(container, category, itemPath, legacySubcategory, out var _))
			{
				return TryPrepareForWrite(container);
			}
			return false;
		}

		private static bool TryMatchState(Container container, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory, out ChestLabelState state)
		{
			state = null;
			if ((Object)(object)container == (Object)null || !ChestLabelManager.IsSupportedChest(container) || IsInUse(container) || !HasVanillaAccess(container) || !ChestLabelManager.TryRead(container, out state) || state == null || !state.Enabled || container.GetInventory() == null)
			{
				return false;
			}
			return state.Accepts(category, itemPath, legacySubcategory);
		}

		private static bool TryReadState(Container container, out ChestLabelState state)
		{
			if (!ChestLabelManager.TryRead(container, out state) || state == null)
			{
				state = new ChestLabelState(CheckMyStuffCategory.Misc, "AllTypes", enabled: false);
				return false;
			}
			return true;
		}

		private static bool IsInUse(Container container)
		{
			if ((Object)(object)container == (Object)null || container.IsInUse())
			{
				return true;
			}
			ZNetView view = GetView(container);
			if ((Object)(object)view != (Object)null && view.IsValid() && view.GetZDO() != null)
			{
				return view.GetZDO().GetInt(ZDOVars.s_inUse, 0) != 0;
			}
			return false;
		}

		private static bool HasVanillaAccess(Container container)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)container == (Object)null)
			{
				return false;
			}
			if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false))
			{
				return false;
			}
			if ((int)container.m_privacy == 2)
			{
				return true;
			}
			if ((int)container.m_privacy == 0)
			{
				Piece component = ((Component)container).GetComponent<Piece>();
				if ((Object)(object)component == (Object)null || (Object)(object)Game.instance == (Object)null || Game.instance.GetPlayerProfile() == null)
				{
					return false;
				}
				return component.GetCreator() == Game.instance.GetPlayerProfile().GetPlayerID();
			}
			return false;
		}

		private static ZNetView GetView(Container container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return null;
			}
			if (Object.op_Implicit((Object)(object)container.m_rootObjectOverride))
			{
				return ((Component)container.m_rootObjectOverride).GetComponent<ZNetView>();
			}
			return ((Component)container).GetComponent<ZNetView>();
		}
	}
	public sealed class SortingResult
	{
		public CheckMyStuffCategory? Category { get; }

		public int ItemsMoved { get; internal set; }

		public int StacksTouched { get; internal set; }

		public int ChestsUsed { get; internal set; }

		public int EligibleStacks { get; internal set; }

		public int RemainingStacks { get; internal set; }

		public SortingResult(CheckMyStuffCategory? category)
		{
			Category = category;
		}
	}
	public static class SortingEngine
	{
		private static Player s_lastPlayer;

		private static Transform s_lastBarrel;

		private static CheckMyStuffCategory? s_lastCategory;

		private static float s_lastSortTime;

		private static float s_retryAt;

		static SortingEngine()
		{
			s_lastSortTime = -999f;
			s_retryAt = -1f;
			ContainerFinder.OwnershipGranted += delegate
			{
				if (Time.time - s_lastSortTime <= 5f)
				{
					s_retryAt = Time.time + 0.5f;
				}
			};
		}

		internal static void ProcessPendingRetry()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (s_retryAt < 0f || Time.time < s_retryAt)
			{
				return;
			}
			s_retryAt = -1f;
			Player val = s_lastPlayer;
			Transform val2 = s_lastBarrel;
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Vector3 val3 = ((Component)val).transform.position - val2.position;
			if (!(((Vector3)(ref val3)).sqrMagnitude > 2500f) && PrivateArea.CheckAccess(val2.position, 0f, false, false))
			{
				SortingResult sortingResult = SortBag(val, val2, s_lastCategory);
				if (sortingResult.ItemsMoved > 0)
				{
					((Character)val).Message((MessageType)1, "Stored " + sortingResult.ItemsMoved + " more item(s) into " + sortingResult.ChestsUsed + " chest(s) near another player.", 0, (Sprite)null, false);
				}
			}
		}

		public static SortingResult SortCategory(Player player, Transform barrelTransform, CheckMyStuffCategory category)
		{
			return SortBag(player, barrelTransform, category);
		}

		public static SortingResult SortAll(Player player, Transform barrelTransform)
		{
			return SortBag(player, barrelTransform, null);
		}

		private static SortingResult SortBag(Player player, Transform barrelTransform, CheckMyStuffCategory? category)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			SortingResult sortingResult = new SortingResult(category);
			if ((Object)(object)player == (Object)null || (Object)(object)barrelTransform == (Object)null)
			{
				return sortingResult;
			}
			s_lastPlayer = player;
			s_lastBarrel = barrelTransform;
			s_lastCategory = category;
			s_lastSortTime = Time.time;
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return sortingResult;
			}
			List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
			HashSet<Container> hashSet = new HashSet<Container>();
			for (int i = 0; i < list.Count; i++)
			{
				ItemData val = list[i];
				if (IsEligibleBagItem(player, inventory, val, out var actualCategory, out var itemPath, out var legacySubcategory) && (!category.HasValue || actualCategory == category.Value))
				{
					sortingResult.EligibleStacks++;
					int stack = val.m_stack;
					List<Container> list2 = ContainerFinder.FindMatchingForItem(barrelTransform.position, actualCategory, itemPath, legacySubcategory);
					RouteThroughContainers(inventory, val, list2, actualCategory, itemPath, legacySubcategory, hashSet, sortingResult);
					if (val.m_stack < stack)
					{
						sortingResult.StacksTouched++;
					}
					if (val.m_stack > 0 && list2 != null && list2.Count > 0)
					{
						sortingResult.RemainingStacks++;
					}
				}
			}
			sortingResult.ChestsUsed = hashSet.Count;
			return sortingResult;
		}

		public static int CountStorable(Player player, Transform barrelTransform)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)barrelTransform == (Object)null)
			{
				return 0;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return 0;
			}
			int num = 0;
			foreach (ItemData item in new List<ItemData>(inventory.GetAllItems()))
			{
				if (IsEligibleBagItem(player, inventory, item, out var actualCategory, out var itemPath, out var legacySubcategory))
				{
					List<Container> list = ContainerFinder.FindMatchingForItem(barrelTransform.position, actualCategory, itemPath, legacySubcategory);
					if (list != null && list.Count > 0)
					{
						num += item.m_stack;
					}
				}
			}
			return num;
		}

		private static void RouteThroughContainers(Inventory source, ItemData item, List<Container> containers, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory, HashSet<Container> usedContainers, SortingResult result)
		{
			if (containers == null)
			{
				return;
			}
			for (int i = 0; i < containers.Count; i++)
			{
				if (item.m_stack <= 0)
				{
					break;
				}
				Container val = containers[i];
				if (ContainerFinder.TryPrepareForItem(val, category, itemPath, legacySubcategory))
				{
					int num = MoveIntoContainer(source, item, val.GetInventory());
					if (num > 0)
					{
						usedContainers.Add(val);
						result.ItemsMoved += num;
					}
				}
			}
		}

		private static bool IsEligibleBagItem(Player player, Inventory source, ItemData item, out CheckMyStuffCategory actualCategory, out ItemTaxonomyPath itemPath, out string legacySubcategory)
		{
			actualCategory = CheckMyStuffCategory.Ingredients;
			itemPath = new ItemTaxonomyPath(null, null, null, null);
			legacySubcategory = "AllTypes";
			if ((Object)(object)player == (Object)null || item == null || item.m_shared == null || item.m_stack <= 0)
			{
				return false;
			}
			if (source == null || source != ((Humanoid)player).GetInventory() || item.m_gridPos.y <= 0 || item.m_gridPos.y >= source.GetHeight() || item.m_gridPos.x < 0 || item.m_gridPos.x >= source.GetWidth() || source.GetItemAt(item.m_gridPos.x, item.m_gridPos.y) != item)
			{
				return false;
			}
			if (item.m_equipped || ((Humanoid)player).IsItemEquiped(item))
			{
				return false;
			}
			if (item.m_shared.m_questItem)
			{
				return false;
			}
			if (!ItemClassifier.TryClassifyTaxonomy(item, out actualCategory, out itemPath, out legacySubcategory))
			{
				return false;
			}
			return true;
		}

		private static int MoveIntoContainer(Inventory source, ItemData item, Inventory target)
		{
			if (source == null || item == null || target == null || source == target || item.m_stack <= 0)
			{
				return 0;
			}
			int stack = item.m_stack;
			FillExistingStacks(source, item, target);
			FillEmptySlots(source, item, target);
			return stack - item.m_stack;
		}

		private static void FillExistingStacks(Inventory source, ItemData item, Inventory target)
		{
			List<ItemData> list = new List<ItemData>(target.GetAllItems());
			for (int i = 0; i < list.Count; i++)
			{
				if (item.m_stack <= 0)
				{
					break;
				}
				ItemData val = list[i];
				if (val != null && CanStackWithoutDataLoss(val, item) && val.m_stack < val.m_shared.m_maxStackSize)
				{
					int val2 = val.m_shared.m_maxStackSize - val.m_stack;
					int num = Math.Min(item.m_stack, val2);
					int stack = item.m_stack;
					target.MoveItemToThis(source, item, num, val.m_gridPos.x, val.m_gridPos.y);
					if (item.m_stack >= stack)
					{
						break;
					}
				}
			}
		}

		private static void FillEmptySlots(Inventory source, ItemData item, Inventory target)
		{
			int width = target.GetWidth();
			int height = target.GetHeight();
			for (int i = 0; i < height; i++)
			{
				if (item.m_stack <= 0)
				{
					break;
				}
				for (int j = 0; j < width; j++)
				{
					if (item.m_stack <= 0)
					{
						break;
					}
					if (target.GetItemAt(j, i) == null)
					{
						int num = Math.Min(item.m_stack, item.m_shared.m_maxStackSize);
						int stack = item.m_stack;
						target.MoveItemToThis(source, item, num, j, i);
						if (item.m_stack >= stack)
						{
							return;
						}
					}
				}
			}
		}

		internal static bool CanStackWithoutDataLoss(ItemData target, ItemData item)
		{
			if (target == null || item == null || target.m_shared == null || item.m_shared == null || !target.IsSameType(item) || (Object)(object)target.m_dropPrefab != (Object)(object)item.m_dropPrefab || target.m_quality != item.m_quality || target.m_variant != item.m_variant || target.m_crafterID != item.m_crafterID || target.m_crafterName != item.m_crafterName || target.m_cheated != item.m_cheated || target.m_pickedUp != item.m_pickedUp || target.m_durability != item.m_durability || target.m_customData.Count != item.m_customData.Count)
			{
				return false;
			}
			foreach (KeyValuePair<string, string> customDatum in item.m_customData)
			{
				if (!target.m_customData.TryGetValue(customDatum.Key, out var value) || value != customDatum.Value)
				{
					return false;
				}
			}
			return true;
		}
	}
}
namespace CheckMyStuff.Classification
{
	public enum CheckMyStuffCategory
	{
		Ingredients,
		BuildAndCraft,
		Equipment,
		Consumables,
		Greenhouse,
		Trophies,
		Valuables,
		Misc
	}
	public static class CheckMyStuffCategoryNames
	{
		public static CheckMyStuffCategory[] GetSelectableCategories()
		{
			CheckMyStuffCategory[] obj = new CheckMyStuffCategory[7]
			{
				CheckMyStuffCategory.Consumables,
				CheckMyStuffCategory.Equipment,
				CheckMyStuffCategory.Greenhouse,
				CheckMyStuffCategory.Ingredients,
				CheckMyStuffCategory.BuildAndCraft,
				CheckMyStuffCategory.Misc,
				CheckMyStuffCategory.Trophies
			};
			Array.Sort(obj, (CheckMyStuffCategory left, CheckMyStuffCategory right) => StringComparer.OrdinalIgnoreCase.Compare(ToDisplayName(left), ToDisplayName(right)));
			return obj;
		}

		public static string ToDisplayName(CheckMyStuffCategory category)
		{
			return category switch
			{
				CheckMyStuffCategory.BuildAndCraft => "Materials", 
				CheckMyStuffCategory.Greenhouse => "Garden", 
				_ => category.ToString(), 
			};
		}
	}
	public static class CheckMyStuffSubcategories
	{
		public const string AllTypes = "AllTypes";

		public const string Fermentables = "Fermentables";

		public const string CookingIngredients = "CookingIngredients";

		public const string RawFood = "RawFood";

		public const string OtherIngredients = "OtherIngredients";

		public const string SmeltingAndProcessing = "SmeltingAndProcessing";

		public const string BuildingMaterials = "BuildingMaterials";

		public const string CraftingMaterials = "CraftingMaterials";

		public const string OtherMaterials = "OtherMaterials";

		public const string Weapons = "Weapons";

		public const string Armor = "Armor";

		public const string Shields = "Shields";

		public const string Ammo = "Ammo";

		public const string Tools = "Tools";

		public const string Accessories = "Accessories";

		public const string Food = "Food";

		public const string MeadsAndPotions = "MeadsAndPotions";

		public const string OtherConsumables = "OtherConsumables";

		public const string SeedsAndPlanting = "SeedsAndPlanting";

		public const string FarmingMaterials = "FarmingMaterials";

		public const string Trophies = "Trophies";

		public const string TraderGoods = "TraderGoods";

		public const string OtherValuables = "OtherValuables";

		public const string Customization = "Customization";

		public const string Miscellaneous = "Miscellaneous";

		private static readonly string[] Ingredients = new string[5] { "AllTypes", "Fermentables", "CookingIngredients", "RawFood", "OtherIngredients" };

		private static readonly string[] BuildAndCraft = new string[5] { "AllTypes", "SmeltingAndProcessing", "BuildingMaterials", "CraftingMaterials", "OtherMaterials" };

		private static readonly string[] Equipment = new string[7] { "AllTypes", "Weapons", "Armor", "Shields", "Ammo", "Tools", "Accessories" };

		private static readonly string[] Consumables = new string[4] { "AllTypes", "Food", "MeadsAndPotions", "OtherConsumables" };

		private static readonly string[] Greenhouse = new string[3] { "AllTypes", "SeedsAndPlanting", "FarmingMaterials" };

		private static readonly string[] TrophyOptions = new string[2] { "AllTypes", "Trophies" };

		private static readonly string[] Valuables = new string[3] { "AllTypes", "TraderGoods", "OtherValuables" };

		private static readonly string[] Misc = new string[3] { "AllTypes", "Customization", "Miscellaneous" };

		public static string[] GetOptions(CheckMyStuffCategory category)
		{
			return category switch
			{
				CheckMyStuffCategory.Ingredients => (string[])Ingredients.Clone(), 
				CheckMyStuffCategory.BuildAndCraft => (string[])BuildAndCraft.Clone(), 
				CheckMyStuffCategory.Equipment => (string[])Equipment.Clone(), 
				CheckMyStuffCategory.Consumables => (string[])Consumables.Clone(), 
				CheckMyStuffCategory.Greenhouse => (string[])Greenhouse.Clone(), 
				CheckMyStuffCategory.Trophies => (string[])TrophyOptions.Clone(), 
				CheckMyStuffCategory.Valuables => (string[])Valuables.Clone(), 
				CheckMyStuffCategory.Misc => (string[])Misc.Clone(), 
				_ => new string[1] { "AllTypes" }, 
			};
		}

		public static bool IsValid(CheckMyStuffCategory category, string subcategory)
		{
			if (string.IsNullOrEmpty(subcategory))
			{
				return false;
			}
			string[] options = GetOptions(category);
			for (int i = 0; i < options.Length; i++)
			{
				if (string.Equals(options[i], subcategory, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		public static string Normalize(CheckMyStuffCategory category, string subcategory)
		{
			if (!IsValid(category, subcategory))
			{
				return "AllTypes";
			}
			return subcategory;
		}
	}
	public sealed class ChestLabelState
	{
		private static readonly ItemTaxonomyPath[] NoSelections = new ItemTaxonomyPath[0];

		public CheckMyStuffCategory Category { get; }

		public string Subcategory { get; }

		public bool Enabled { get; }

		public ItemTaxonomyPath Selection { get; }

		public IList<ItemTaxonomyPath> Selections { get; }

		public ChestLabelState(CheckMyStuffCategory category, string subcategory, bool enabled, ItemTaxonomyPath selection = null)
			: this(category, subcategory, enabled, (selection == null) ? NoSelections : new ItemTaxonomyPath[1] { selection })
		{
		}

		public ChestLabelState(CheckMyStuffCategory category, string subcategory, bool enabled, IList<ItemTaxonomyPath> selections)
		{
			Category = category;
			Subcategory = subcategory;
			Enabled = enabled;
			List<ItemTaxo