Decompiled source of MoreRealisticLaundering Forked Mono v1.3.3

MoreRealisticLaundering-Mono.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using FishNet;
using FishNet.Managing;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using MoreRealisticLaundering;
using MoreRealisticLaundering.Cartel;
using MoreRealisticLaundering.Config;
using MoreRealisticLaundering.Laundering;
using MoreRealisticLaundering.Patches;
using MoreRealisticLaundering.PhoneApp;
using MoreRealisticLaundering.Util;
using Newtonsoft.Json;
using S1API.Cartel;
using S1API.Utils;
using ScheduleOne;
using ScheduleOne.Cartel;
using ScheduleOne.DevUtilities;
using ScheduleOne.GameTime;
using ScheduleOne.Map;
using ScheduleOne.Messaging;
using ScheduleOne.Money;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.CharacterClasses;
using ScheduleOne.NPCs.Relation;
using ScheduleOne.Persistence;
using ScheduleOne.PlayerScripts;
using ScheduleOne.Product;
using ScheduleOne.Property;
using ScheduleOne.UI;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Phone.ProductManagerApp;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(MRLCore), "MoreRealisticLaundering", "1.3.3", "KampfBallerina", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonAdditionalDependencies(new string[] { "S1API" })]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MoreRealisticLaundering-Mono")]
[assembly: AssemblyConfiguration("Release Mono")]
[assembly: AssemblyFileVersion("1.3.3.0")]
[assembly: AssemblyInformationalVersion("1.3.3+77d20a3692831cbe767141d0accd1814229e8113")]
[assembly: AssemblyProduct("MoreRealisticLaundering-Mono")]
[assembly: AssemblyTitle("MoreRealisticLaundering-Mono")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal static class ModVersion
{
	public const string Current = "1.3.3";
}
namespace MoreRealisticLaundering
{
	public class MRLCore : MelonMod
	{
		public static LaunderingApp launderingApp = new LaunderingApp();

		private bool isFirstStart = true;

		private bool isLegitVersion;

		public bool isWaitAndApplyCapsRunning;

		public ConfigState config;

		public MoneyManager moneyManager;

		public NotificationsManager notificationsManager;

		public Sprite CreditCardIcon;

		public Dictionary<string, float> maxiumumLaunderValues = new Dictionary<string, float>();

		public Dictionary<string, string> aliasMap;

		public readonly HashSet<string> processedBusinesses = new HashSet<string>();

		public readonly HashSet<string> createdBusinessesEntries = new HashSet<string>();

		private readonly HashSet<string> createdAppEntries = new HashSet<string>();

		private readonly HashSet<LaunderingOperation> boostedOperations = new HashSet<LaunderingOperation>();

		public static MRLCore Instance { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			aliasMap = new Dictionary<string, string>
			{
				{ "Laundromat", "Laundromat" },
				{ "Taco Ticklers", "Taco Ticklers" },
				{ "TacoTicklers", "Taco Ticklers" },
				{ "Car Wash", "Car Wash" },
				{ "CarWash", "Car Wash" },
				{ "Post Office", "Post Office" },
				{ "PostOffice", "Post Office" }
			};
			((MelonBase)this).LoggerInstance.Msg("Loaded. Waiting for a save to start drip and cartel washes.");
		}

		public override void OnUpdate()
		{
			launderingApp?.TickUi();
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				try
				{
					((MelonBase)this).LoggerInstance.Msg("Main scene loaded. Starting laundering hooks.");
					config = ConfigManager.Load();
					isLegitVersion = config.Use_Legit_Version;
					FillCapDictionary();
					InitializeListeners();
					moneyManager = Object.FindObjectOfType<MoneyManager>();
					notificationsManager = Object.FindObjectOfType<NotificationsManager>();
					CartelService.Stop();
					DripTracker.Instance.Stop();
					DripTracker.Instance.Start();
					CartelService.Start();
					MelonCoroutines.Start(StartCoroutinesAfterDelay());
					isFirstStart = false;
					return;
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Error("Failed to start on Main: " + ex);
					return;
				}
			}
			if (sceneName.Equals("Menu", StringComparison.OrdinalIgnoreCase) && !isFirstStart)
			{
				ResetAllVariables();
			}
		}

		private void InitializeListeners()
		{
			try
			{
				Business.onOperationStarted = (Action<LaunderingOperation>)Delegate.Remove(Business.onOperationStarted, new Action<LaunderingOperation>(OnLaunderingStarted));
				Business.onOperationFinished = (Action<LaunderingOperation>)Delegate.Remove(Business.onOperationFinished, new Action<LaunderingOperation>(OnLaunderingFinished));
			}
			catch
			{
			}
			try
			{
				Business.onOperationStarted = (Action<LaunderingOperation>)Delegate.Combine(Business.onOperationStarted, new Action<LaunderingOperation>(OnLaunderingStarted));
				Business.onOperationFinished = (Action<LaunderingOperation>)Delegate.Combine(Business.onOperationFinished, new Action<LaunderingOperation>(OnLaunderingFinished));
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to register laundering listeners: " + ex.Message);
			}
		}

		public IEnumerator StartCoroutinesAfterDelay()
		{
			if (isLegitVersion)
			{
				((MelonBase)this).LoggerInstance.Msg("Use_Legit_Version is true — Tax & Wash phone app will not be added.");
				MelonCoroutines.Start(WaitAndApplyCaps());
			}
			else
			{
				yield return (object)new WaitForSecondsRealtime(5f);
				MelonCoroutines.Start(WaitAndApplyCaps());
				MelonCoroutines.Start(launderingApp.InitializeLaunderApp());
			}
		}

		private void ResetAllVariables()
		{
			DripTracker.Instance.Stop();
			CartelService.Stop();
			config = null;
			isLegitVersion = false;
			maxiumumLaunderValues.Clear();
			createdAppEntries.Clear();
			processedBusinesses.Clear();
			createdBusinessesEntries.Clear();
			boostedOperations.Clear();
			moneyManager = null;
			notificationsManager = null;
			CreditCardIcon = null;
			if (launderingApp != null)
			{
				launderingApp.CancelPendingInit();
				launderingApp.ClearUiForMenu();
			}
			try
			{
				Business.onOperationStarted = (Action<LaunderingOperation>)Delegate.Remove(Business.onOperationStarted, new Action<LaunderingOperation>(OnLaunderingStarted));
				Business.onOperationFinished = (Action<LaunderingOperation>)Delegate.Remove(Business.onOperationFinished, new Action<LaunderingOperation>(OnLaunderingFinished));
			}
			catch
			{
			}
		}

		public void FillCapDictionary()
		{
			maxiumumLaunderValues.Clear();
			maxiumumLaunderValues["Laundromat"] = config.Businesses.Laundromat.Laundromat_Cap;
			maxiumumLaunderValues["Taco Ticklers"] = config.Businesses.TacoTicklers.Taco_Ticklers_Cap;
			maxiumumLaunderValues["Car Wash"] = config.Businesses.CarWash.Car_Wash_Cap;
			maxiumumLaunderValues["PostOffice"] = config.Businesses.PostOffice.Post_Office_Cap;
			maxiumumLaunderValues["Post Office"] = config.Businesses.PostOffice.Post_Office_Cap;
		}

		public IEnumerator WaitAndApplyCaps()
		{
			isWaitAndApplyCapsRunning = true;
			while (true)
			{
				if (Business.OwnedBusinesses != null)
				{
					foreach (Business business in Business.OwnedBusinesses)
					{
						if (!((Object)(object)business == (Object)null) && !processedBusinesses.Contains(((Object)business).name) && config != null)
						{
							ApplyCap(business);
							processedBusinesses.Add(((Object)business).name);
							if (!createdBusinessesEntries.Contains(((Object)business).name))
							{
								createdBusinessesEntries.Add(((Object)business).name);
								CreateAppEntryForBusiness(business);
							}
							if (processedBusinesses.Count >= 4)
							{
								isWaitAndApplyCapsRunning = false;
								yield break;
							}
						}
					}
				}
				yield return (object)new WaitForSeconds(3f);
			}
		}

		public void ApplyCap(Business business)
		{
			if (aliasMap.TryGetValue(((Object)business).name, out var value) && maxiumumLaunderValues.TryGetValue(value, out var value2))
			{
				business.LaunderCapacity = value2;
			}
		}

		public void CreateAppEntryForBusiness(Business business)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if (isLegitVersion || createdAppEntries.Contains(((Object)business).name))
			{
				return;
			}
			if (!launderingApp._isLaunderingAppLoaded)
			{
				MelonCoroutines.Start(WaitForLaunderingAppAndCreateEntry(business));
			}
			else if (!((Object)(object)launderingApp.DansHardwareTemplate == (Object)null))
			{
				string text = BusinessUtil.Display(((Object)business).name);
				Color newBackgroundColor;
				string imagePath;
				string newSubtitle;
				switch (BusinessUtil.Canonical(((Object)business).name))
				{
				default:
					return;
				case "Laundromat":
					newBackgroundColor = Color32.op_Implicit(ColorUtil.GetColor("Yellow"));
					imagePath = "Laundromat.png";
					newSubtitle = "Efficient, subtle, and always turning dirty into clean.";
					break;
				case "Taco Ticklers":
					newBackgroundColor = Color32.op_Implicit(ColorUtil.GetColor("Orange"));
					imagePath = "TacoTickler.png";
					newSubtitle = "We wrap more than burritos.";
					break;
				case "Car Wash":
					newBackgroundColor = Color32.op_Implicit(ColorUtil.GetColor("Dark Blue"));
					imagePath = "CarWash.png";
					newSubtitle = "From powder to polish – all clean.";
					break;
				case "Post Office":
					newBackgroundColor = Color32.op_Implicit(ColorUtil.GetColor("Light Blue"));
					imagePath = "PostOffice.png";
					newSubtitle = "Dead drops, fake names but real profits.";
					break;
				}
				launderingApp.AddEntryFromTemplate(text, text, newSubtitle, business, launderingApp.DansHardwareTemplate, newBackgroundColor, imagePath);
				createdAppEntries.Add(((Object)business).name);
			}
		}

		private IEnumerator WaitForLaunderingAppAndCreateEntry(Business business)
		{
			while (!launderingApp._isLaunderingAppLoaded)
			{
				yield return (object)new WaitForSeconds(2f);
			}
			CreateAppEntryForBusiness(business);
		}

		public void ReapplyLaunderingTimes()
		{
			try
			{
				if (config == null || Business.OwnedBusinesses == null)
				{
					return;
				}
				foreach (Business ownedBusiness in Business.OwnedBusinesses)
				{
					if (ownedBusiness?.LaunderingOperations == null)
					{
						continue;
					}
					foreach (LaunderingOperation launderingOperation in ownedBusiness.LaunderingOperations)
					{
						AdjustLaunderingTime(launderingOperation);
					}
				}
			}
			catch
			{
			}
		}

		public void AdjustLaunderingTime(LaunderingOperation operation)
		{
			if (operation != null && !((Object)(object)operation.business == (Object)null) && aliasMap.TryGetValue(((Object)operation.business).name, out var value))
			{
				operation.completionTime_Minutes = ConfigManager.GetLaunderingTimeHours(config, value) * 60;
				boostedOperations.Add(operation);
			}
		}

		private void OnLaunderingStarted(LaunderingOperation operation)
		{
			if (operation != null)
			{
				bool flag = CartelService.TryClaimStart(operation);
				bool flag2 = flag || CartelJobStore.IsCartelJob(operation);
				string acceptedByPlayerCode = (flag ? CartelService.ConsumeArmedPlayerCode() : null);
				DripTracker.Instance.Track(operation, flag2);
				if (flag2)
				{
					CartelJobStore.Add(operation, acceptedByPlayerCode);
				}
				AdjustLaunderingTime(operation);
			}
		}

		private void OnLaunderingFinished(LaunderingOperation operation)
		{
			try
			{
				if ((Object)(object)operation?.business == (Object)null)
				{
					return;
				}
				bool flag = CartelService.IsCartelOperation(operation);
				DripTracker.Instance.OnFinished(operation);
				if (!flag && !config.Use_Drip_Payout)
				{
					string businessName = BusinessUtil.Display(((Object)operation.business).name);
					float amount = operation.amount;
					float num = Mathf.RoundToInt(amount * (ConfigManager.GetTaxationPercentage(config, ((Object)operation.business).name) / 100f));
					if (num > 0f)
					{
						RemoveTaxesFromBankBalance(num, businessName);
					}
					ApplyLumpSumProtection(amount);
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Error in OnLaunderingFinished: " + ex.Message);
			}
		}

		public MoneyManager EnsureMoneyManager()
		{
			if ((Object)(object)moneyManager == (Object)null)
			{
				try
				{
					moneyManager = Object.FindObjectOfType<MoneyManager>();
				}
				catch
				{
				}
			}
			return moneyManager;
		}

		private void RemoveTaxesFromBankBalance(float amount, string businessName)
		{
			if (!((Object)(object)moneyManager == (Object)null))
			{
				moneyManager.CreateOnlineTransaction("Tax for " + businessName, 0f - amount, 1f, "Tax for " + businessName);
				NotifyTaxDeduction(businessName, amount);
			}
		}

		private void ApplyLumpSumProtection(float gross)
		{
			if (config.Use_Protection_Cut && !CartelService.IsCartelDefeated() && !((Object)(object)moneyManager == (Object)null))
			{
				float num = Mathf.RoundToInt(gross * (config.Protection_Cut_Percentage / 100f));
				if (!(num <= 0f))
				{
					moneyManager.CreateOnlineTransaction("Cartel protection", 0f - num, 1f, "Cartel protection");
					NotifyCartelDues(num);
				}
			}
		}

		public void NotifyDripPayout(string businessName, float amount)
		{
			if (config != null && config.Notify_Drip_Payouts && !(amount < 1f))
			{
				SendMoneyNotification(businessName, $"<color=#54E717>${amount:N0}</color> deposited");
			}
		}

		public void NotifyTaxDeduction(string businessName, float amount)
		{
			if (config != null && config.Notify_Tax_Deductions && !(amount < 1f))
			{
				SendMoneyNotification(businessName, $"<color=#E60000>${amount:N0}</color> Lost in Taxes");
			}
		}

		public void NotifyCartelDues(float amount)
		{
			if (config != null && config.Notify_Cartel_Dues && !(amount < 1f))
			{
				SendMoneyNotification("Cartel", $"<color=#E60000>${amount:N0}</color> protection cut");
			}
		}

		private void SendMoneyNotification(string title, string message)
		{
			if (!((Object)(object)notificationsManager == (Object)null))
			{
				notificationsManager.SendNotification(title, message, GetCreditCardIcon(), 5f, true);
			}
		}

		public Sprite GetCreditCardIcon()
		{
			if ((Object)(object)CreditCardIcon != (Object)null)
			{
				return CreditCardIcon;
			}
			GameObject val = GameObject.Find("UI/HUD/HotbarContainer/Slots/CashSlotContainer/OnlineSlot/ItemUI_Cash/Icon");
			if ((Object)(object)val != (Object)null)
			{
				Image component = val.GetComponent<Image>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null && ((Object)component.sprite).name == "CreditCard")
				{
					CreditCardIcon = component.sprite;
					return component.sprite;
				}
			}
			return null;
		}

		public void ChangeAppIconImage(GameObject appIcon, string resourceName)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)appIcon == (Object)null || resourceName == null)
			{
				return;
			}
			Transform val = appIcon.transform.Find("Mask/Image");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Image component = ((Component)val).GetComponent<Image>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Sprite val2 = Utils.LoadPhoneHomeIcon(resourceName);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			component.sprite = val2;
			component.preserveAspect = false;
			component.type = (Type)0;
			((Graphic)component).color = Color.white;
			RectTransform val3 = (RectTransform)(object)((val is RectTransform) ? val : null);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.anchorMin = Vector2.zero;
				val3.anchorMax = Vector2.one;
				val3.offsetMin = Vector2.zero;
				val3.offsetMax = Vector2.zero;
				((Transform)val3).localScale = Vector3.one;
			}
			Transform parent = val.parent;
			if ((Object)(object)parent != (Object)null)
			{
				Image component2 = ((Component)parent).GetComponent<Image>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Graphic)component2).color = Color.white;
				}
			}
		}

		public void RegisterApp(GameObject app, string title = "Unknown App")
		{
			if (!((Object)(object)app == (Object)null))
			{
				GameObject val = Utils.FindAppIconsContainer();
				if ((Object)(object)val == (Object)null)
				{
					((MelonBase)this).LoggerInstance.Error("Could not find AppIcons container to register " + title);
				}
				else
				{
					app.transform.SetParent(val.transform, false);
				}
			}
		}
	}
}
namespace MoreRealisticLaundering.Util
{
	public static class ColorUtil
	{
		public static Dictionary<string, Color32> GetColors()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_008d: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_0211: Unknown result type (might be due to invalid IL or missing references)
			return new Dictionary<string, Color32>
			{
				{
					"Dark Blue",
					new Color32((byte)33, (byte)64, (byte)115, byte.MaxValue)
				},
				{
					"Light Blue",
					new Color32((byte)83, (byte)126, (byte)158, byte.MaxValue)
				},
				{
					"Light Purple",
					new Color32((byte)87, (byte)82, (byte)153, (byte)127)
				},
				{
					"Purple",
					new Color32((byte)108, (byte)35, (byte)114, byte.MaxValue)
				},
				{
					"Bright Green",
					new Color32((byte)85, (byte)198, (byte)30, byte.MaxValue)
				},
				{
					"Olive Green",
					new Color32((byte)67, (byte)99, (byte)33, byte.MaxValue)
				},
				{
					"Dark Green",
					new Color32((byte)91, (byte)127, (byte)9, byte.MaxValue)
				},
				{
					"Cyan",
					new Color32((byte)9, (byte)115, (byte)119, byte.MaxValue)
				},
				{
					"Dark Red",
					new Color32((byte)99, (byte)33, (byte)37, byte.MaxValue)
				},
				{
					"Yellow",
					new Color32((byte)208, (byte)174, (byte)54, byte.MaxValue)
				},
				{
					"Orange",
					new Color32((byte)178, (byte)78, (byte)44, byte.MaxValue)
				},
				{
					"Grey",
					new Color32((byte)49, (byte)49, (byte)49, byte.MaxValue)
				},
				{
					"Light Grey",
					new Color32((byte)90, (byte)90, (byte)90, byte.MaxValue)
				},
				{
					"Ultra Light Grey",
					new Color32((byte)150, (byte)150, (byte)150, byte.MaxValue)
				},
				{
					"Dark Grey",
					new Color32((byte)30, (byte)30, (byte)30, byte.MaxValue)
				},
				{
					"Redpurple",
					new Color32((byte)112, (byte)21, (byte)37, byte.MaxValue)
				},
				{
					"White",
					new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
				},
				{
					"Black",
					new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue)
				}
			};
		}

		public static Color32 GetColor(string colorName)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Color32> colors = GetColors();
			if (colors.TryGetValue(colorName, out var value))
			{
				return value;
			}
			throw new KeyNotFoundException("Color '" + colorName + "' not found.");
		}
	}
	public static class FontLoader
	{
		public static Font openSansBold;

		public static bool openSansBoldIsInitialized;

		public static Font openSansSemiBold;

		public static bool openSansSemiBoldIsInitialized;

		public static IEnumerator InitializeFonts()
		{
			for (float timer = 0f; timer < 30f; timer += 0.5f)
			{
				TryLoadFonts();
				if (openSansBoldIsInitialized && openSansSemiBoldIsInitialized)
				{
					yield break;
				}
				yield return (object)new WaitForSecondsRealtime(0.5f);
			}
			TryLoadFontsFromResources();
			ApplyFallbackIfNeeded();
			MelonLogger.Warning("OpenSans fonts were not found on phone apps in time; using fallback fonts.");
		}

		public static Font FindFontFromOtherApp(string fontName)
		{
			TryLoadFonts();
			if (fontName == "openSansBold")
			{
				return openSansBold ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			if (fontName == "openSansSemiBold")
			{
				return openSansSemiBold ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			return Resources.GetBuiltinResource<Font>("Arial.ttf");
		}

		private static void TryLoadFonts()
		{
			if (!openSansBoldIsInitialized)
			{
				TryAssignFromObject(Utils.GetAppCanvasByName("ProductManagerApp/Container/Topbar"), preferBold: true);
			}
			if (!openSansBoldIsInitialized)
			{
				TryAssignFromObject(Utils.GetAppCanvasByName("ProductManagerApp"), preferBold: true);
			}
			if (!openSansSemiBoldIsInitialized)
			{
				TryAssignFromObject(Utils.GetAppCanvasByName("DeliveryApp/Container/Scroll View/Viewport/Content"), preferBold: false);
			}
			if (!openSansSemiBoldIsInitialized)
			{
				TryAssignFromObject(Utils.GetAppCanvasByName("DeliveryApp"), preferBold: false);
			}
			if (!openSansBoldIsInitialized || !openSansSemiBoldIsInitialized)
			{
				TryLoadFontsFromResources();
			}
			if ((Object)(object)openSansBold != (Object)null && (Object)(object)openSansSemiBold == (Object)null)
			{
				Assign(openSansBold, preferBold: false);
			}
			if ((Object)(object)openSansSemiBold != (Object)null && (Object)(object)openSansBold == (Object)null)
			{
				Assign(openSansSemiBold, preferBold: true);
			}
		}

		private static void TryAssignFromObject(GameObject root, bool preferBold)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Text[] componentsInChildren = root.GetComponentsInChildren<Text>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)componentsInChildren[i].font != (Object)null)
				{
					Assign(componentsInChildren[i].font, preferBold);
				}
				if (preferBold ? openSansBoldIsInitialized : openSansSemiBoldIsInitialized)
				{
					return;
				}
			}
			TMP_Text[] componentsInChildren2 = root.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text obj in componentsInChildren2)
			{
				object obj2;
				if (obj == null)
				{
					obj2 = null;
				}
				else
				{
					TMP_FontAsset font = obj.font;
					obj2 = ((font != null) ? font.sourceFontFile : null);
				}
				Font val = (Font)obj2;
				if ((Object)(object)val != (Object)null)
				{
					Assign(val, preferBold);
				}
				if (preferBold ? openSansBoldIsInitialized : openSansSemiBoldIsInitialized)
				{
					break;
				}
			}
		}

		private static void TryLoadFontsFromResources()
		{
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			if (array == null)
			{
				return;
			}
			foreach (Font val in array)
			{
				if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(((Object)val).name) && (((Object)val).name.IndexOf("opensans", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val).name.IndexOf("open sans", StringComparison.OrdinalIgnoreCase) >= 0))
				{
					bool flag = ((Object)val).name.IndexOf("semi", StringComparison.OrdinalIgnoreCase) >= 0;
					Assign(val, !flag);
				}
			}
		}

		private static void Assign(Font font, bool preferBold)
		{
			if ((Object)(object)font == (Object)null)
			{
				return;
			}
			if (preferBold)
			{
				if (!openSansBoldIsInitialized)
				{
					openSansBold = font;
					openSansBoldIsInitialized = true;
				}
			}
			else if (!openSansSemiBoldIsInitialized)
			{
				openSansSemiBold = font;
				openSansSemiBoldIsInitialized = true;
			}
		}

		private static void ApplyFallbackIfNeeded()
		{
			Font builtinResource = Resources.GetBuiltinResource<Font>("Arial.ttf");
			if ((Object)(object)openSansBold == (Object)null)
			{
				openSansBold = openSansSemiBold ?? builtinResource;
			}
			if ((Object)(object)openSansSemiBold == (Object)null)
			{
				openSansSemiBold = openSansBold ?? builtinResource;
			}
			openSansBoldIsInitialized = true;
			openSansSemiBoldIsInitialized = true;
		}
	}
	public static class Utils
	{
		private const string AppsCanvasPath = "Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas";

		private const string ScrollViewAppIconsPath = "Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIconsScrollView/Viewport/AppIcons";

		private const string StubAppIconsPath = "Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons";

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

		public static GameObject FindAppIconsContainer()
		{
			try
			{
				if (PlayerSingleton<HomeScreen>.InstanceExists && (Object)(object)PlayerSingleton<HomeScreen>.Instance.appIconContainer != (Object)null)
				{
					return ((Component)PlayerSingleton<HomeScreen>.Instance.appIconContainer).gameObject;
				}
			}
			catch
			{
			}
			GameObject val = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIconsScrollView/Viewport/AppIcons");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			return GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons");
		}

		public static bool IsStubAppIconsContainer(GameObject container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return false;
			}
			string transformPath = GetTransformPath(container.transform);
			return transformPath != null && transformPath.EndsWith("/HomeScreen/AppIcons", StringComparison.Ordinal) && transformPath.IndexOf("AppIconsScrollView", StringComparison.Ordinal) < 0;
		}

		private static string GetTransformPath(Transform t)
		{
			if ((Object)(object)t == (Object)null)
			{
				return null;
			}
			List<string> list = new List<string>();
			while ((Object)(object)t != (Object)null)
			{
				list.Add(((Object)t).name);
				t = t.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		public static GameObject FindAppsCanvas()
		{
			return GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas/") ?? GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas");
		}

		public static IEnumerator WaitUntilFound(Func<GameObject> finder, Action<GameObject> callback, float timeout = 30f)
		{
			GameObject obj = null;
			float timer = 0f;
			while ((Object)(object)obj == (Object)null && timer < timeout)
			{
				obj = finder();
				if ((Object)(object)obj != (Object)null)
				{
					break;
				}
				yield return (object)new WaitForSecondsRealtime(0.1f);
				timer += 0.1f;
			}
			callback?.Invoke(obj);
		}

		public static GameObject GetAppIconByName(string Name, int? Index, string newObjectName = null)
		{
			int valueOrDefault = Index.GetValueOrDefault();
			GameObject val = FindAppIconsContainer();
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Error("Could not find AppIcons container.");
				return null;
			}
			GameObject[] array = (from t in val.GetComponentsInChildren<Transform>(true)
				let labelText = GetLabelText(((Component)t).gameObject.transform.Find("Label"))
				where !string.IsNullOrEmpty(labelText) && labelText.StartsWith(Name)
				select ((Component)t).gameObject).ToArray();
			if (valueOrDefault >= array.Length)
			{
				MelonLogger.Error($"Index {valueOrDefault} is out of range. Returning null.");
				return null;
			}
			GameObject val2 = array[valueOrDefault];
			if (newObjectName != null)
			{
				((Object)val2).name = newObjectName;
			}
			return val2;
		}

		public static GameObject ChangeLabelFromAppIcon(string appIconName, string newLabel, bool allowOriginal = false)
		{
			if (string.IsNullOrEmpty(appIconName) || string.IsNullOrEmpty(newLabel))
			{
				MelonLogger.Error("AppIcon name or new label is null or empty.");
				return null;
			}
			GameObject appIconByName = GetAppIconByName(appIconName, 1, newLabel);
			if ((Object)(object)appIconByName == (Object)null && allowOriginal)
			{
				appIconByName = GetAppIconByName(appIconName, 0, newLabel);
			}
			if ((Object)(object)appIconByName == (Object)null)
			{
				return null;
			}
			SetLabelText(appIconByName.transform.Find("Label"), newLabel);
			return appIconByName;
		}

		public static GameObject GetAppCanvasByName(string Name)
		{
			GameObject val = FindAppsCanvas();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform val2 = val.transform.Find(Name);
			return ((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null;
		}

		public static string GetLabelText(Transform target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return null;
			}
			Text component = ((Component)target).GetComponent<Text>();
			if ((Object)(object)component != (Object)null && component.text != null)
			{
				return component.text;
			}
			TMP_Text component2 = ((Component)target).GetComponent<TMP_Text>();
			return ((Object)(object)component2 != (Object)null) ? component2.text : null;
		}

		public static void SetLabelText(Transform target, string value)
		{
			if (!((Object)(object)target == (Object)null))
			{
				Text component = ((Component)target).GetComponent<Text>();
				if ((Object)(object)component != (Object)null)
				{
					component.text = value;
				}
				TMP_Text component2 = ((Component)target).GetComponent<TMP_Text>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.text = value;
				}
			}
		}

		public static void SetLabelColor(Transform target, Color color)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				Text component = ((Component)target).GetComponent<Text>();
				if ((Object)(object)component != (Object)null)
				{
					((Graphic)component).color = color;
				}
				TMP_Text component2 = ((Component)target).GetComponent<TMP_Text>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Graphic)component2).color = color;
				}
			}
		}

		public static void SetLabelAlignment(Transform target, TextAnchor alignment)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				Text component = ((Component)target).GetComponent<Text>();
				if ((Object)(object)component != (Object)null)
				{
					component.alignment = alignment;
				}
				TMP_Text component2 = ((Component)target).GetComponent<TMP_Text>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.alignment = ToTmpAlignment(alignment);
				}
			}
		}

		private static TextAlignmentOptions ToTmpAlignment(TextAnchor alignment)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			return (TextAlignmentOptions)((int)alignment switch
			{
				5 => 4100, 
				3 => 4097, 
				4 => 4098, 
				2 => 260, 
				0 => 257, 
				1 => 258, 
				8 => 1028, 
				6 => 1025, 
				7 => 1026, 
				_ => 4097, 
			});
		}

		public static IEnumerator WaitForObjectByFrame(string path, Action<GameObject> callback)
		{
			GameObject obj = null;
			while ((Object)(object)obj == (Object)null)
			{
				obj = GameObject.Find(path);
				yield return null;
			}
			callback?.Invoke(obj);
		}

		public static IEnumerator WaitForObject(string path, Action<GameObject> callback, float timeout = 30f)
		{
			GameObject obj = null;
			float timer = 0f;
			while ((Object)(object)obj == (Object)null && timer < timeout)
			{
				obj = GameObject.Find(path);
				if ((Object)(object)obj != (Object)null)
				{
					break;
				}
				yield return (object)new WaitForSecondsRealtime(0.1f);
				timer += 0.1f;
			}
			callback?.Invoke(obj);
		}

		public static void ClearChildren(Transform parent, Func<GameObject, bool> keepFilter = null)
		{
			GameObject[] array = (from t in ((Component)parent).GetComponentsInChildren<Transform>(true)
				select ((Component)t).gameObject into obj
				where (Object)(object)obj.transform != (Object)(object)parent
				select obj).ToArray();
			GameObject[] array2 = array;
			foreach (GameObject val in array2)
			{
				if (keepFilter == null || !keepFilter(val))
				{
					val.transform.parent = null;
					Object.Destroy((Object)(object)val);
				}
			}
		}

		public static Texture2D LoadCustomImage(string path)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			string path2 = Path.Combine(MelonEnvironment.UserDataDirectory, path);
			Texture2D result;
			if (!File.Exists(path2))
			{
				result = null;
				Debug.LogError((object)"Specified path does not exist.");
			}
			else
			{
				byte[] array = File.ReadAllBytes(path2);
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, array);
				result = val;
			}
			return result;
		}

		public static byte[] LoadEmbeddedResource(string resourceName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = "MoreRealisticLaundering.Assets." + resourceName;
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				MelonLogger.Warning("Embedded resource not found: " + text);
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			return array;
		}

		public static Texture2D LoadEmbeddedTexture(string resourceName)
		{
			return LoadEmbeddedTexture(resourceName, readable: false);
		}

		public static Texture2D LoadEmbeddedTexture(string resourceName, bool readable)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			byte[] array = LoadEmbeddedResource(resourceName);
			if (array == null)
			{
				return null;
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (ImageConversion.LoadImage(val, array, !readable))
			{
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)1;
				return val;
			}
			MelonLogger.Error("Failed to load texture from embedded resource: " + resourceName);
			return null;
		}

		public static Sprite LoadEmbeddedSprite(string resourceName)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = LoadEmbeddedTexture(resourceName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		public static Sprite LoadPhoneHomeIcon(string resourceName)
		{
			if (string.IsNullOrEmpty(resourceName))
			{
				return null;
			}
			if (PhoneHomeIcons.TryGetValue(resourceName, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Sprite val = BuildPhoneHomeIcon(resourceName) ?? LoadEmbeddedSprite(resourceName);
			if ((Object)(object)val != (Object)null)
			{
				PhoneHomeIcons[resourceName] = val;
			}
			return val;
		}

		private static Sprite BuildPhoneHomeIcon(string resourceName)
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = LoadEmbeddedTexture(resourceName, readable: true);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Color[] pixels = val.GetPixels();
			int width = ((Texture)val).width;
			int height = ((Texture)val).height;
			Object.DestroyImmediate((Object)(object)val);
			int num = width;
			int num2 = height;
			int num3 = -1;
			int num4 = -1;
			for (int i = 0; i < height; i++)
			{
				int num5 = i * width;
				for (int j = 0; j < width; j++)
				{
					if (!(pixels[num5 + j].a <= 0.08f))
					{
						if (j < num)
						{
							num = j;
						}
						if (i < num2)
						{
							num2 = i;
						}
						if (j > num3)
						{
							num3 = j;
						}
						if (i > num4)
						{
							num4 = i;
						}
					}
				}
			}
			if (num3 < num)
			{
				return null;
			}
			int num6 = num3 - num + 1;
			int num7 = num4 - num2 + 1;
			int num8 = Mathf.RoundToInt(40.96f);
			int num9 = 256 - num8 * 2;
			float num10 = Mathf.Min((float)num9 / (float)num6, (float)num9 / (float)num7);
			int num11 = Mathf.Max(1, Mathf.RoundToInt((float)num6 * num10));
			int num12 = Mathf.Max(1, Mathf.RoundToInt((float)num7 * num10));
			int num13 = (256 - num11) / 2;
			int num14 = (256 - num12) / 2;
			Color val2 = Color32.op_Implicit(ColorUtil.GetColor("Cyan"));
			Texture2D val3 = new Texture2D(256, 256, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			Color[] array = (Color[])(object)new Color[65536];
			for (int k = 0; k < array.Length; k++)
			{
				array[k] = val2;
			}
			for (int l = 0; l < num12; l++)
			{
				int num15 = num2 + Mathf.Clamp(Mathf.FloorToInt((float)l / num10), 0, num7 - 1);
				int num16 = num15 * width;
				int num17 = (num14 + l) * 256;
				for (int m = 0; m < num11; m++)
				{
					int num18 = num + Mathf.Clamp(Mathf.FloorToInt((float)m / num10), 0, num6 - 1);
					Color val4 = pixels[num16 + num18];
					if (!(val4.a < 0.01f))
					{
						int num19 = num17 + num13 + m;
						Color val5 = Color.Lerp(array[num19], val4, val4.a);
						val5.a = 1f;
						array[num19] = val5;
					}
				}
			}
			val3.SetPixels(array);
			val3.Apply(false, true);
			return Sprite.Create(val3, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 100f);
		}
	}
}
namespace MoreRealisticLaundering.PhoneApp
{
	public class LaunderingApp
	{
		private class HoverTarget
		{
			public RectTransform Hit;

			public CanvasGroup Border;

			public Transform ScaleRoot;

			public Vector3 BaseScale;

			public string SelectId;
		}

		public GameObject DansHardwareTemplate;

		public GameObject GasMartWestTemplate;

		public GameObject viewPortContentSpaceTemplate;

		public Transform launderingAppViewportContentTransform;

		public bool _isLaunderingAppLoaded;

		public Transform optionsTransform;

		public Transform globalOptionsTransform;

		public Transform cartelOptionsTransform;

		public Transform notificationOptionsTransform;

		public GameObject checkboxTemplate;

		public GameObject detailsTitleObject;

		public GameObject detailsSubtitleObject;

		public GameObject InstructionsTextObject;

		public Transform settingsContentTransform;

		public Sprite appIconSprite;

		public Sprite laundromatSprite;

		public Sprite tacoTicklersSprite;

		public Sprite carWashSprite;

		public Sprite postOfficeSprite;

		public Sprite inputBackgroundSprite;

		public bool isSaveStillRunning;

		private GameObject _appPanel;

		private GameObject _homeIcon;

		private ProductManagerApp _productApp;

		private Business _selectedBusiness;

		private Action _closeAppAction;

		private bool _openQueued;

		private int _openDelayFrames;

		private int _initGeneration;

		private bool _iconRecoverQueued;

		private string _lastIconId = "TaxNWash";

		private string _lastIconTitle = "Tax & Wash";

		private string _lastIconPath = "LaunderingIcon.png";

		private readonly List<HoverTarget> _hoverTargets = new List<HoverTarget>();

		private string _selectedCardName;

		private object _panelFade;

		private static Sprite _roundedFillSprite;

		private static Sprite _roundedBorderSprite;

		private static Sprite _roundedBorderThickSprite;

		public static bool OpeningTaxWash;

		public void CancelPendingInit()
		{
			_initGeneration++;
			_iconRecoverQueued = false;
		}

		public void ClearUiForMenu()
		{
			_isLaunderingAppLoaded = false;
			launderingAppViewportContentTransform = null;
			if ((Object)(object)_homeIcon != (Object)null)
			{
				try
				{
					Object.Destroy((Object)(object)_homeIcon);
				}
				catch
				{
				}
				_homeIcon = null;
			}
			if ((Object)(object)_appPanel != (Object)null)
			{
				try
				{
					Object.Destroy((Object)(object)_appPanel);
				}
				catch
				{
				}
				_appPanel = null;
			}
			if ((Object)(object)DansHardwareTemplate != (Object)null)
			{
				Object.Destroy((Object)(object)DansHardwareTemplate);
			}
			if ((Object)(object)GasMartWestTemplate != (Object)null)
			{
				Object.Destroy((Object)(object)GasMartWestTemplate);
			}
			if ((Object)(object)viewPortContentSpaceTemplate != (Object)null)
			{
				Object.Destroy((Object)(object)viewPortContentSpaceTemplate);
			}
			DansHardwareTemplate = null;
			GasMartWestTemplate = null;
			viewPortContentSpaceTemplate = null;
		}

		public IEnumerator InitializeLaunderApp()
		{
			int gen = ++_initGeneration;
			while (MRLCore.Instance == null)
			{
				if (gen != _initGeneration)
				{
					yield break;
				}
				yield return (object)new WaitForSecondsRealtime(0.5f);
			}
			MelonCoroutines.Start(FontLoader.InitializeFonts());
			while (!FontLoader.openSansBoldIsInitialized || !FontLoader.openSansSemiBoldIsInitialized)
			{
				if (gen != _initGeneration)
				{
					yield break;
				}
				yield return (object)new WaitForSecondsRealtime(0.5f);
			}
			if (gen == _initGeneration)
			{
				yield return MelonCoroutines.Start(CreateApp("TaxNWash", "Tax & Wash", "LaunderingIcon.png", gen));
			}
		}

		public IEnumerator CreateApp(string idName, string title, string iconPath)
		{
			yield return CreateApp(idName, title, iconPath, _initGeneration);
		}

		private IEnumerator CreateApp(string idName, string title, string iconPath, int gen)
		{
			_hoverTargets.Clear();
			_selectedCardName = null;
			_lastIconId = idName;
			_lastIconTitle = title;
			_lastIconPath = iconPath;
			yield return MelonCoroutines.Start(Utils.WaitUntilFound(Utils.FindAppIconsContainer, null, 45f));
			if (gen != _initGeneration)
			{
				yield break;
			}
			GameObject parentCanvas = null;
			GameObject productsApp = null;
			GameObject deliveriesApp = null;
			yield return MelonCoroutines.Start(Utils.WaitUntilFound(Utils.FindAppsCanvas, delegate(GameObject obj)
			{
				parentCanvas = obj;
			}, 45f));
			yield return MelonCoroutines.Start(Utils.WaitUntilFound(() => Utils.GetAppCanvasByName("ProductManagerApp"), delegate(GameObject obj)
			{
				productsApp = obj;
			}, 45f));
			yield return MelonCoroutines.Start(Utils.WaitUntilFound(() => Utils.GetAppCanvasByName("DeliveryApp"), delegate(GameObject obj)
			{
				deliveriesApp = obj;
			}, 45f));
			if (gen != _initGeneration)
			{
				yield break;
			}
			if ((Object)(object)parentCanvas == (Object)null || (Object)(object)productsApp == (Object)null || (Object)(object)deliveriesApp == (Object)null)
			{
				MelonLogger.Error("Tax & Wash: phone AppsCanvas/ProductManagerApp/DeliveryApp was not found.");
				yield break;
			}
			Transform existing = parentCanvas.transform.Find(idName) ?? parentCanvas.transform.Find("MRL_TaxWash") ?? parentCanvas.transform.Find("TaxNWash");
			if ((Object)(object)existing != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)existing).gameObject);
			}
			DestroyDeadTaxWashIcons();
			DestroyLabeledIcons("DeliveriesCopy");
			DestroyLabeledIcons("ProductsCopy");
			KeepSingleIcon("Deliveries");
			KeepSingleIcon("Products");
			GameObject mrlApp = null;
			try
			{
				mrlApp = CreateVisualPanel(productsApp, deliveriesApp, parentCanvas.transform, title);
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Tax & Wash CreateApp failed: " + ex);
			}
			if ((Object)(object)mrlApp == (Object)null)
			{
				MelonLogger.Error("Tax & Wash: visual panel was not created.");
				yield break;
			}
			if ((Object)(object)mrlApp.GetComponent<ProductManagerApp>() != (Object)null)
			{
				MelonLogger.Error("Tax & Wash: ProductManagerApp was present on the visual panel.");
			}
			DeactivateAppContainers(mrlApp.transform);
			mrlApp.SetActive(true);
			_appPanel = mrlApp;
			_productApp = null;
			KeepSingleIcon("Deliveries");
			KeepSingleIcon("Products");
			GameObject appIcon = null;
			for (int attempt = 0; attempt < 5; attempt++)
			{
				if (!((Object)(object)appIcon == (Object)null))
				{
					break;
				}
				if (gen != _initGeneration)
				{
					yield break;
				}
				if (attempt > 0)
				{
					yield return (object)new WaitForSecondsRealtime(1f);
				}
				try
				{
					appIcon = CreateIndependentIcon(idName, title, iconPath);
				}
				catch (Exception ex2)
				{
					MelonLogger.Error("Tax & Wash icon setup failed: " + ex2);
				}
			}
			_homeIcon = appIcon;
			DestroyExtraTaxWashIcons(appIcon);
			HookPhoneClose();
			if ((Object)(object)appIcon == (Object)null)
			{
				MelonLogger.Error("Tax & Wash: could not create a home icon after retries.");
				yield break;
			}
			Transform parent = appIcon.transform.parent;
			MelonLogger.Msg("Tax & Wash home icon registered under '" + ((parent != null) ? ((Object)parent).name : null) + "'.");
			yield return MelonCoroutines.Start(EnsureIconOnLiveContainer(gen, idName, title, iconPath));
			if (gen == _initGeneration)
			{
				if ((Object)(object)settingsContentTransform != (Object)null)
				{
					((Component)settingsContentTransform).gameObject.SetActive(true);
					AddOptionsForBusiness(settingsContentTransform);
					AddGlobalOptions(settingsContentTransform);
					AddCartelOptions(settingsContentTransform);
					AddNotificationOptions(settingsContentTransform);
					PackDetailsContent();
				}
				if ((Object)(object)DansHardwareTemplate != (Object)null)
				{
					AddEntryFromTemplate("Global Settings", "Global Settings", "Payout timing, hours, and drip options.", null, DansHardwareTemplate, Color32.op_Implicit(ColorUtil.GetColor("Cyan")), "LaunderingIcon.png", null, isFirstEntry: true);
					AddEntryFromTemplate("Cartel Settings", "Cartel Settings", "Protection cut, wash jobs, and influence.", null, DansHardwareTemplate, Color32.op_Implicit(ColorUtil.GetColor("Dark Red")), "CartelIcon.png");
					AddEntryFromTemplate("Notification Settings", "Notification Settings", "Deposit, tax, and cartel alerts.", null, DansHardwareTemplate, Color32.op_Implicit(ColorUtil.GetColor("Purple")), "NotificationIcon.png");
				}
				_isLaunderingAppLoaded = (Object)(object)_homeIcon != (Object)null;
				if (_isLaunderingAppLoaded)
				{
					MelonLogger.Msg("Tax & Wash phone app ready.");
				}
			}
		}

		private IEnumerator EnsureIconOnLiveContainer(int gen, string idName, string title, string iconPath)
		{
			for (int i = 0; i < 12; i++)
			{
				if (gen != _initGeneration)
				{
					break;
				}
				yield return (object)new WaitForSecondsRealtime(0.5f);
				GameObject live = Utils.FindAppIconsContainer();
				bool iconAlive = (Object)(object)_homeIcon != (Object)null;
				try
				{
					if (iconAlive)
					{
						_ = _homeIcon.transform;
					}
				}
				catch
				{
					iconAlive = false;
				}
				if (!iconAlive)
				{
					MelonLogger.Warning("Tax & Wash home icon was destroyed — recreating.");
					_homeIcon = CreateIndependentIcon(idName, title, iconPath);
					DestroyExtraTaxWashIcons(_homeIcon);
				}
				else
				{
					if (!((Object)(object)live != (Object)null) || !((Object)(object)_homeIcon.transform.parent != (Object)(object)live.transform))
					{
						continue;
					}
					Transform parent = _homeIcon.transform.parent;
					int num;
					if (!Utils.IsStubAppIconsContainer((parent != null) ? ((Component)parent).gameObject : null))
					{
						Transform parent2 = _homeIcon.transform.parent;
						num = (((Object)(object)live != (Object)(object)((parent2 != null) ? ((Component)parent2).gameObject : null)) ? 1 : 0);
					}
					else
					{
						num = 1;
					}
					if (num == 0)
					{
						continue;
					}
					MelonLogger.Msg("Tax & Wash: re-parenting home icon to '" + ((Object)live).name + "'.");
					_homeIcon.transform.SetParent(live.transform, false);
					try
					{
						if (PlayerSingleton<HomeScreen>.InstanceExists && (Object)(object)PlayerSingleton<HomeScreen>.Instance.uiPanel != (Object)null)
						{
							UISelectable selectable = _homeIcon.GetComponent<UISelectable>() ?? _homeIcon.GetComponentInChildren<UISelectable>(true);
							if ((Object)(object)selectable != (Object)null)
							{
								PlayerSingleton<HomeScreen>.Instance.uiPanel.AddSelectable(selectable);
								selectable.SetSelectedImageVisible(false);
							}
						}
					}
					catch
					{
					}
				}
			}
		}

		private GameObject CreateVisualPanel(GameObject productsApp, GameObject deliveriesApp, Transform parent, string title)
		{
			GameObject val = InstantiateInactive(productsApp, parent, "MRL_TaxWash");
			StripPhoneBehaviours(val);
			RemoveOverlayCanvas(val);
			Transform val2 = FindMainAppContainer(val.transform);
			if ((Object)(object)val2 == (Object)null)
			{
				MelonLogger.Error("Tax & Wash: cloned ProductManagerApp has no Container.");
				return val;
			}
			Transform val3 = val2.Find("Scroll View");
			if ((Object)(object)val3 != (Object)null)
			{
				((Component)val3).gameObject.SetActive(false);
				((Object)((Component)val3).gameObject).name = "DeactivatedScrollView";
			}
			ImportOriginalDeliveryScroll(deliveriesApp, val2);
			EnsureLeftListFrame(val2);
			CustomizeClonedApp(val, title);
			return val;
		}

		private static void RemoveOverlayCanvas(GameObject panel)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if ((Object)(object)panel == (Object)null)
			{
				return;
			}
			Canvas[] components = panel.GetComponents<Canvas>();
			foreach (Canvas val in components)
			{
				if (!((Object)(object)val == (Object)null) && (int)val.renderMode == 0)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		private static Transform FindDeep(Transform root, string name)
		{
			if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform child = root.GetChild(i);
				if (!((Object)(object)child == (Object)null))
				{
					if (((Object)child).name == name)
					{
						return child;
					}
					Transform val = FindDeep(child, name);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
			}
			return null;
		}

		private static Transform FindAncestorNamed(Transform start, string name)
		{
			Transform val = start;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name == name)
				{
					return val;
				}
				val = val.parent;
			}
			return null;
		}

		private static bool IsShopCard(Transform child)
		{
			if ((Object)(object)child == (Object)null)
			{
				return false;
			}
			string name = ((Object)child).name;
			switch (name)
			{
			default:
				if (!(name == "Image"))
				{
					return (Object)(object)child.Find("Header") != (Object)null || (Object)(object)child.Find("Container") != (Object)null;
				}
				goto case "Header";
			case "Header":
			case "Topbar":
			case "Space":
			case "Viewport":
			case "Scrollbar Horizontal":
			case "Scrollbar Vertical":
			case "Dropshadow":
			case "Background":
			case "Instruction":
				return false;
			}
		}

		private static Transform FindCardChrome(Transform entry)
		{
			if ((Object)(object)entry == (Object)null)
			{
				return null;
			}
			return entry.Find("Header") ?? entry.Find("Container") ?? FindDeep(entry, "Header");
		}

		private static Transform FindFirstShopCard(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform child = root.GetChild(i);
				if (IsShopCard(child))
				{
					return child;
				}
				Transform val = FindFirstShopCard(child);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static Transform FindListContent(Transform scrollView)
		{
			if ((Object)(object)scrollView == (Object)null)
			{
				return null;
			}
			if (CountShopCards(scrollView) >= 2)
			{
				return scrollView;
			}
			Transform val = scrollView.Find("Viewport/Content");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Transform val2 = scrollView.Find("Viewport") ?? FindDeep(scrollView, "Viewport");
			if ((Object)(object)val2 != (Object)null)
			{
				val = val2.Find("Content") ?? FindDeep(val2, "Content");
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			Transform val3 = FindFirstShopCard(scrollView);
			return ((Object)(object)val3 != (Object)null) ? val3.parent : null;
		}

		private static Transform FindMainAppContainer(Transform app)
		{
			if ((Object)(object)app == (Object)null)
			{
				return null;
			}
			Transform val = null;
			int num = -1;
			for (int i = 0; i < app.childCount; i++)
			{
				Transform child = app.GetChild(i);
				if (!((Object)(object)child == (Object)null) && !(((Object)child).name != "Container"))
				{
					int num2 = 0;
					if ((Object)(object)child.Find("Topbar") != (Object)null)
					{
						num2 += 10;
					}
					if ((Object)(object)child.Find("Details") != (Object)null)
					{
						num2 += 10;
					}
					if ((Object)(object)child.Find("Scroll View") != (Object)null)
					{
						num2 += 3;
					}
					if ((Object)(object)child.Find("Header") != (Object)null)
					{
						num2++;
					}
					if ((Object)(object)child.Find("Content") != (Object)null)
					{
						num2++;
					}
					if (num2 > num)
					{
						num = num2;
						val = child;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = app.Find("Container");
			}
			for (int j = 0; j < app.childCount; j++)
			{
				Transform child2 = app.GetChild(j);
				if ((Object)(object)child2 != (Object)null && ((Object)child2).name == "Container" && (Object)(object)child2 != (Object)(object)val)
				{
					((Component)child2).gameObject.SetActive(false);
				}
			}
			return val;
		}

		private static void DeactivateAppContainers(Transform app)
		{
			if ((Object)(object)app == (Object)null)
			{
				return;
			}
			for (int i = 0; i < app.childCount; i++)
			{
				Transform child = app.GetChild(i);
				if ((Object)(object)child != (Object)null && ((Object)child).name == "Container")
				{
					((Component)child).gameObject.SetActive(false);
				}
			}
		}

		private void ImportOriginalDeliveryScroll(GameObject deliveriesApp, Transform container)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)deliveriesApp == (Object)null || (Object)(object)container == (Object)null)
			{
				return;
			}
			Transform val = FindOriginalDeliveryListScroll(deliveriesApp.transform);
			if (!((Object)(object)val == (Object)null))
			{
				GameObject val2 = InstantiateInactive(((Component)val).gameObject, container, "Scroll View");
				Transform val3 = val2.transform.Find("OrderSubmitted");
				if ((Object)(object)val3 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val3).gameObject);
				}
				RectTransform component = val2.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.sizeDelta = new Vector2(-100f, -60f);
					component.anchoredPosition = new Vector2(-50f, -30f);
				}
				val2.SetActive(true);
			}
		}

		private void EnsureLeftListFrame(Transform container)
		{
			if ((Object)(object)container == (Object)null || (Object)(object)container.Find("Scroll View") != (Object)null)
			{
				return;
			}
			Transform val = container.Find("DeactivatedScrollView");
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Error("Tax & Wash: no left-list Scroll View is available.");
				return;
			}
			((Object)((Component)val).gameObject).name = "Scroll View";
			((Component)val).gameObject.SetActive(true);
			Transform val2 = val.Find("Viewport/Content");
			if ((Object)(object)val2 != (Object)null)
			{
				Utils.ClearChildren(val2);
			}
		}

		private static Transform FindOriginalDeliveryListScroll(Transform deliveryRoot)
		{
			if ((Object)(object)deliveryRoot == (Object)null)
			{
				return null;
			}
			Transform result = null;
			int num = 0;
			Transform[] componentsInChildren = ((Component)deliveryRoot).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || ((Object)val).name != "Scroll View")
				{
					continue;
				}
				Transform val2 = val.Find("Viewport/Content");
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int num2 = 0;
				for (int j = 0; j < val2.childCount; j++)
				{
					Transform child = val2.GetChild(j);
					if ((Object)(object)child != (Object)null && (Object)(object)child.Find("Header") != (Object)null)
					{
						num2++;
					}
				}
				if (num2 > num)
				{
					num = num2;
					result = val;
				}
			}
			return result;
		}

		private static int CountShopCards(Transform parent)
		{
			if ((Object)(object)parent == (Object)null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < parent.childCount; i++)
			{
				if (IsShopCard(parent.GetChild(i)))
				{
					num++;
				}
			}
			return num;
		}

		private static bool LooksLikeShopList(Transform listContent)
		{
			if ((Object)(object)listContent == (Object)null)
			{
				return false;
			}
			int num = 0;
			if ((Object)(object)listContent.Find("Dan's Hardware") != (Object)null)
			{
				num++;
			}
			if ((Object)(object)listContent.Find("Gas-Mart (West)") != (Object)null)
			{
				num++;
			}
			if ((Object)(object)listContent.Find("Gas-Mart (Central)") != (Object)null)
			{
				num++;
			}
			if ((Object)(object)listContent.Find("Gas-Mart (North)") != (Object)null)
			{
				num++;
			}
			if ((Object)(object)listContent.Find("Gas-Mart (South)") != (Object)null)
			{
				num++;
			}
			if (num >= 2)
			{
				return true;
			}
			return (Object)(object)listContent.Find("Space") != (Object)null && CountShopCards(listContent) >= 2;
		}

		private static Transform FindDeliveryShopListScroll(Transform deliveryRoot)
		{
			if ((Object)(object)deliveryRoot == (Object)null)
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)deliveryRoot).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !(((Object)val).name != "Scroll View") && LooksLikeShopList(FindListContent(val)))
				{
					return val;
				}
			}
			Transform val2 = FindDeep(deliveryRoot, "Dan's Hardware") ?? FindDeep(deliveryRoot, "Gas-Mart (West)");
			if ((Object)(object)val2 != (Object)null && LooksLikeShopList(val2.parent))
			{
				return FindAncestorNamed(val2, "Scroll View") ?? val2.parent;
			}
			Transform result = null;
			int num = 0;
			foreach (Transform val3 in componentsInChildren)
			{
				if (!((Object)(object)val3 == (Object)null) && !(((Object)val3).name != "Scroll View"))
				{
					int num2 = CountShopCards(FindListContent(val3));
					if (num2 > num)
					{
						num = num2;
						result = val3;
					}
				}
			}
			if (num >= 2)
			{
				return result;
			}
			for (int k = 0; k < deliveryRoot.childCount; k++)
			{
				Transform child = deliveryRoot.GetChild(k);
				if (!((Object)(object)child == (Object)null) && !(((Object)child).name != "Container"))
				{
					Transform val4 = child.Find("Scroll View");
					if ((Object)(object)val4 != (Object)null)
					{
						return val4;
					}
				}
			}
			return result;
		}

		private static void HideOverlappingProductUi(Transform parent, Transform keep)
		{
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			bool flag = ((Object)parent).name == "Content";
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if ((Object)(object)child == (Object)null || (Object)(object)child == (Object)(object)keep)
				{
					continue;
				}
				string name = ((Object)child).name;
				switch (name)
				{
				case "Details":
				case "Instruction":
				case "Background":
				case "Header":
				case "Topbar":
					continue;
				}
				if (!(name == "Scroll View") && (flag || name.IndexOf("Favour", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Product", StringComparison.OrdinalIgnoreCase) >= 0 || name == "FiltersPanel"))
				{
					((Component)child).gameObject.SetActive(false);
				}
			}
		}

		private static void CopyRectTransform(RectTransform source, RectTransform dest)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)source == (Object)null) && !((Object)(object)dest == (Object)null))
			{
				dest.anchorMin = source.anchorMin;
				dest.anchorMax = source.anchorMax;
				dest.pivot = source.pivot;
				dest.anchoredPosition = source.anchoredPosition;
				dest.sizeDelta = source.sizeDelta;
				dest.offsetMin = source.offsetMin;
				dest.offsetMax = source.offsetMax;
				((Transform)dest).localScale = ((Transform)source).localScale;
				((Transform)dest).localRotation = ((Transform)source).localRotation;
			}
		}

		private void CustomizeClonedApp(GameObject mrlApp, string title)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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_049a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindMainAppContainer(mrlApp.transform);
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Error("Tax & Wash: visual panel has no Container.");
				return;
			}
			Transform val2 = FindDeep(val, "FiltersPanel");
			if ((Object)(object)val2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val2).gameObject);
			}
			Transform val3 = val.Find("Topbar") ?? val.Find("Header") ?? FindDeep(val, "Topbar") ?? FindDeep(val, "Header");
			if ((Object)(object)val3 != (Object)null)
			{
				((Component)val3).gameObject.SetActive(true);
				Color val4 = Color32.op_Implicit(ColorUtil.GetColor("Cyan"));
				Image component = ((Component)val3).GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					Color color = val4;
					color.a = 1f;
					((Graphic)component).color = color;
				}
				Transform val5 = val3.Find("Background");
				if ((Object)(object)val5 != (Object)null)
				{
					Image component2 = ((Component)val5).GetComponent<Image>();
					if ((Object)(object)component2 != (Object)null)
					{
						Color color2 = val4;
						color2.a = 1f;
						((Graphic)component2).color = color2;
					}
					((Component)val5).gameObject.SetActive(true);
				}
				Transform target = val3.Find("Title") ?? FindDeep(val3, "Title");
				Utils.SetLabelText(target, title);
				Utils.SetLabelColor(target, Color32.op_Implicit(ColorUtil.GetColor("White")));
				Transform val6 = val3.Find("Subtitle") ?? FindDeep(val3, "Subtitle");
				if ((Object)(object)val6 != (Object)null)
				{
					((Component)val6).gameObject.SetActive(true);
					Utils.SetLabelText(val6, "by KampfBallerina");
					Utils.SetLabelAlignment(val6, (TextAnchor)5);
					Utils.SetLabelColor(val6, Color32.op_Implicit(ColorUtil.GetColor("White")));
					RectTransform component3 = ((Component)val6).GetComponent<RectTransform>();
					if ((Object)(object)component3 != (Object)null)
					{
						component3.anchorMax = new Vector2(0.98f, 1f);
					}
				}
			}
			Transform val7 = val.Find("Details") ?? FindDeep(val, "Details");
			if ((Object)(object)val7 == (Object)null)
			{
				Transform val8 = FindDeep(val, "Instruction");
				if ((Object)(object)val8 != (Object)null)
				{
					val7 = val8.parent;
				}
			}
			if ((Object)(object)val7 != (Object)null)
			{
				((Component)val7).gameObject.SetActive(true);
				ApplyOriginalTwoColumnLayout(val);
				MakeOpaqueChrome(val);
				Transform val9 = val7.Find("Scroll View/Viewport/Content/Title") ?? FindDeep(val7, "Title");
				if ((Object)(object)val9 != (Object)null)
				{
					detailsTitleObject = ((Component)val9).gameObject;
					detailsTitleObject.SetActive(false);
					Utils.SetLabelText(val9, "DetailsTitleText");
				}
				Transform val10 = val7.Find("Scroll View/Viewport/Content/Description") ?? FindDeep(val7, "Description");
				if ((Object)(object)val10 != (Object)null)
				{
					Utils.SetLabelText(val10, "This is going to be the description of the app.");
					((Component)val10).gameObject.SetActive(false);
					detailsSubtitleObject = ((Component)val10).gameObject;
				}
				settingsContentTransform = val7.Find("Scroll View/Viewport/Content");
				if ((Object)(object)settingsContentTransform == (Object)null)
				{
					Transform val11 = FindDeep(val7, "Scroll View");
					settingsContentTransform = (((Object)(object)val11 != (Object)null) ? val11.Find("Viewport/Content") : null);
				}
				string[] array = new string[9] { "Value", "Effects", "Addiction", "Recipes", "RecipesContainer", "Listed", "Delisted", "NotDiscovered", "Properties" };
				foreach (string text in array)
				{
					Transform val12 = (((Object)(object)settingsContentTransform != (Object)null) ? (settingsContentTransform.Find(text) ?? FindDeep(settingsContentTransform, text)) : null);
					if ((Object)(object)val12 != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val12).gameObject);
					}
				}
				Transform val13 = val7.Find("Instruction") ?? FindDeep(val7, "Instruction");
				if ((Object)(object)val13 != (Object)null)
				{
					InstructionsTextObject = ((Component)val13).gameObject;
					((Component)val13).gameObject.SetActive(true);
					Utils.SetLabelText(val13, "Select a section to adjust settings");
					Utils.SetLabelColor(val13, Color.white);
				}
			}
			CreateTemplates(val, settingsContentTransform);
			StripLeftoverDetailsWidgets(settingsContentTransform);
			PackDetailsContent();
			RestoreTaxWashChrome(mrlApp);
		}

		private static void ApplyOriginalTwoColumnLayout(Transform container)
		{
			//IL_005b: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)container == (Object)null)
			{
				return;
			}
			Transform val = container.Find("Scroll View");
			Transform val2 = container.Find("Details");
			if ((Object)(object)val != (Object)null)
			{
				RectTransform component = ((Component)val).GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.anchorMin = new Vector2(0f, 0f);
					component.anchorMax = new Vector2(0.48f, 1f);
					component.pivot = new Vector2(0.5f, 0.5f);
					component.offsetMin = new Vector2(8f, 8f);
					component.offsetMax = new Vector2(-4f, -60f);
				}
				StretchLeftList(val);
			}
			if ((Object)(object)val2 != (Object)null)
			{
				RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.anchorMin = new Vector2(0.49f, 0f);
					component2.anchorMax = new Vector2(1f, 1f);
					component2.pivot = new Vector2(0.5f, 0.5f);
					component2.offsetMin = new Vector2(4f, 8f);
					component2.offsetMax = new Vector2(-8f, -60f);
				}
				Transform val3 = val2.Find("Image");
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(false);
				}
				EnsureRectMask(val2);
				val2.SetAsLastSibling();
				Transform val4 = val2.Find("Scroll View");
				if ((Object)(object)val4 != (Object)null)
				{
					RectTransform component3 = ((Component)val4).GetComponent<RectTransform>();
					StretchFill(component3);
				}
			}
		}

		private static void MakeOpaqueChrome(Transform container)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)container == (Object)null)
			{
				return;
			}
			Color color = Color32.op_Implicit(ColorUtil.GetColor("Dark Grey"));
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.10980392f, 0.10980392f, 0.10980392f, 1f);
			MakeSolidNamed(container, "Background", color);
			MakeSolidNamed(container, "Wallpaper", color);
			Transform val = container.Find("Gradient");
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
			}
			Transform val2 = container.Find("Details");
			if ((Object)(object)val2 != (Object)null)
			{
				Transform val3 = val2.Find("Image");
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(false);
				}
				if ((Object)(object)val2.Find("Background") == (Object)null)
				{
					CreateSolidBackdrop(val2, "Background", color2);
				}
				else
				{
					MakeSolidNamed(val2, "Background", color2);
				}
				Canvas[] components = ((Component)val2).GetComponents<Canvas>();
				for (int i = 0; i < components.Length; i++)
				{
					if ((Object)(object)components[i] != (Object)null)
					{
						Object.DestroyImmediate((Object)(object)components[i]);
					}
				}
			}
			CanvasGroup[] componentsInChildren = ((Component)container).GetComponentsInChildren<CanvasGroup>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if ((Object)(object)componentsInChildren[j] != (Object)null)
				{
					componentsInChildren[j].alpha = 1f;
				}
			}
		}

		private static void MakeSolidNamed(Transform parent, string name, Color color)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			if (!((Object)(object)parent == (Object)null))
			{
				Transform val = parent.Find(name);
				if (!((Object)(object)val == (Object)null))
				{
					Image val2 = ((Component)val).GetComponent<Image>() ?? ((Component)val).gameObject.AddComponent<Image>();
					val2.sprite = null;
					((Graphic)val2).color = new Color(color.r, color.g, color.b, 1f);
					val2.type = (Type)0;
					((Graphic)val2).raycastTarget = true;
					((Component)val).gameObject.SetActive(true);
					StretchFill(((Component)val).GetComponent<RectTransform>());
				}
			}
		}

		private static void CreateSolidBackdrop(Transform parent, string name, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.transform.SetAsFirstSibling();
			RectTransform rt = val.AddComponent<RectTransform>();
			StretchFill(rt);
			Image val2 = val.AddComponent<Image>();
			val2.sprite = null;
			((Graphic)val2).color = color;
			((Graphic)val2).raycastTarget = true;
		}

		private static void EnsureRectMask(Transform panel)
		{
			if (!((Object)(object)panel == (Object)null))
			{
				if ((Object)(object)((Component)panel).GetComponent<RectMask2D>() == (Object)null)
				{
					((Component)panel).gameObject.AddComponent<RectMask2D>();
				}
				Transform val = panel.Find("Viewport");
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<RectMask2D>() == (Object)null)
				{
					((Component)val).gameObject.AddComponent<RectMask2D>();
				}
			}
		}

		private static void StretchFill(RectTransform rt)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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)
			if (!((Object)(object)rt == (Object)null))
			{
				rt.anchorMin = Vector2.zero;
				rt.anchorMax = Vector2.one;
				rt.offsetMin = Vector2.zero;
				rt.offsetMax = Vector2.zero;
			}
		}

		private static void StretchLeftList(Transform scroll)
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: 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_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Expected O, but got Unknown
			if ((Object)(object)scroll == (Object)null)
			{
				return;
			}
			RectMask2D component = ((Component)scroll).GetComponent<RectMask2D>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			Transform val = scroll.Find("Scrollbar Vertical");
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
			}
			Transform val2 = scroll.Find("Scrollbar Horizontal");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			ScrollRect component2 = ((Component)scroll).GetComponent<ScrollRect>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.verticalScrollbar = null;
				component2.horizontalScrollbar = null;
				component2.horizontal = false;
			}
			Transform val3 = scroll.Find("Viewport");
			if ((Object)(object)val3 != (Object)null)
			{
				RectTransform component3 = ((Component)val3).GetComponent<RectTransform>();
				StretchFill(component3);
				if ((Object)(object)component3 != (Object)null)
				{
					component3.offsetMin = new Vector2(10f, 8f);
					component3.offsetMax = new Vector2(-10f, -8f);
				}
				if ((Object)(object)((Component)val3).GetComponent<RectMask2D>() == (Object)null)
				{
					((Component)val3).gameObject.AddComponent<RectMask2D>();
				}
			}
			Transform val4 = (((Object)(object)val3 != (Object)null) ? val3.Find("Content") : null);
			if (!((Object)(object)val4 == (Object)null))
			{
				RectTransform component4 = ((Component)val4).GetComponent<RectTransform>();
				if ((Object)(object)component4 != (Object)null)
				{
					component4.anchorMin = new Vector2(0f, 1f);
					component4.anchorMax = new Vector2(1f, 1f);
					component4.pivot = new Vector2(0.5f, 1f);
					component4.offsetMin = new Vector2(0f, component4.offsetMin.y);
					component4.offsetMax = new Vector2(0f, component4.offsetMax.y);
					component4.sizeDelta = new Vector2(0f, component4.sizeDelta.y);
				}
				VerticalLayoutGroup val5 = ((Component)val4).GetComponent<VerticalLayoutGroup>() ?? ((Component)val4).gameObject.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)val5).childAlignment = (TextAnchor)0;
				((HorizontalOrVerticalLayoutGroup)val5).spacing = 8f;
				((LayoutGroup)val5).padding = new RectOffset(6, 6, 6, 8);
				((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = false;
				((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false;
			}
		}

		private static Sprite RoundedFillSprite()
		{
			return _roundedFillSprite ?? (_roundedFillSprite = CreateRoundedSprite(64, 14, 0, fill: true));
		}

		private static Sprite RoundedBorderSprite(bool thick = false)
		{
			if (thick)
			{
				return _roundedBorderThickSprite ?? (_roundedBorderThickSprite = CreateRoundedSprite(64, 14, 4, fill: false));
			}
			return _roundedBorderSprite ?? (_roundedBorderSprite = CreateRoundedSprite(64, 14, 2, fill: false));
		}

		private static Sprite CreateRoundedSprite(int size, int radius, int borderWidth, bool fill)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			Color32[] array = (Color32[])(object)new Color32[size * size];
			float num = (float)size * 0.5f;
			float num2 = radius;
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num3 = (float)j + 0.5f - num;
					float num4 = (float)i + 0.5f - num;
					float num5 = Mathf.Abs(num3) - (num - num2);
					float num6 = Mathf.Abs(num4) - (num - num2);
					float num7 = Mathf.Sqrt(Mathf.Max(num5, 0f) * Mathf.Max(num5, 0f) + Mathf.Max(num6, 0f) * Mathf.Max(num6, 0f));
					float num8 = num7 + Mathf.Min(Mathf.Max(num5, num6), 0f) - num2;
					float num9;
					if (fill)
					{
						num9 = Mathf.Clamp01(0.5f - num8);
					}
					else
					{
						float num10 = Mathf.Clamp01(0.5f - num8);
						float num11 = Mathf.Clamp01(0.5f - (num8 + (float)borderWidth));
						num9 = num10 * (1f - num11);
					}
					array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Mathf.RoundToInt(num9 * 255f));
				}
			}
			val.SetPixels32(array);
			val.Apply(false, false);
			((Object)val).hideFlags = (HideFlags)61;
			int num12 = Mathf.Max(radius + 1, radius + borderWidth);
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)num12, (float)num12, (float)num12, (float)num12));
			((Object)val2).hideFlags = (HideFlags)61;
			return val2;
		}

		private static void StripLeftoverDetailsWidgets(Transform content)
		{
			if ((Object)(object)content == (Object)null)
			{
				return;
			}
			for (int num = content.childCount - 1; num >= 0; num--)
			{
				Transform child = content.GetChild(num);
				if (!((Object)(object)child == (Object)null))
				{
					string name = ((Object)child).name;
					switch (name)
					{
					default:
						if (!(name == "Checkbox Template"))
						{
							Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
						}
						break;
					case "Title":
					case "Description":
					case "Options":
					case "GlobalOptions":
					case "CartelOptions":
					case "NotificationOptions":
						break;
					}
				}
			}
		}

		private void PackDetailsContent()
		{
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Expected O, but got Unknown
			Transform val = settingsContentTransform;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = val.Find("Space");
			if ((Object)(object)val2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val2).gameObject);
			}
			if ((Object)(object)detailsTitleObject != (Object)null && (Object)(object)detailsTitleObject.transform.parent != (Object)(object)val)
			{
				detailsTitleObject.transform.SetParent(val, false);
			}
			if ((Object)(object)detailsSubtitleObject != (Object)null && (Object)(object)detailsSubtitleObject.transform.parent != (Object)(object)val)
			{
				detailsSubtitleObject.transform.SetParent(val, false);
			}
			if ((Object)(object)detailsTitleObject != (Object)null)
			{
				detailsTitleObject.transform.SetSiblingIndex(0);
			}
			if ((Object)(object)detailsSubtitleObject != (Object)null)
			{
				detailsSubtitleObject.transform.SetSiblingIndex(((Object)(object)detailsTitleObject != (Object)null) ? 1 : 0);
			}
			int num = (((Object)(object)detailsTitleObject != (Object)null) ? 1 : 0) + (((Object)(object)detailsSubtitleObject != (Object)null) ? 1 : 0);
			int index = num;
			index = PlaceOptionPanel(optionsTransform, val, index);
			index = PlaceOptionPanel(globalOptionsTransform, val, index);
			index = PlaceOptionPanel(cartelOptionsTransform, val, index);
			PlaceOptionPanel(notificationOptionsTransform, val, index);
			CompactDetailsLabel(((Object)(object)detailsTitleObject != (Object)null) ? detailsTitleObject.transform : null, 32f);
			CompactDetailsLabel(((Object)(object)detailsSubtitleObject != (Object)null) ? detailsSubtitleObject.transform : null, 36f);
			if ((Object)(object)detailsTitleObject != (Object)null)
			{
				Utils.SetLabelAlignment(detailsTitleObject.transform, (TextAnchor)0);
			}
			if ((Object)(object)detailsSubtitleObject != (Object)null)
			{
				Utils.SetLabelAlignment(detailsSubtitleObject.transform, (TextAnchor)0);
			}
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null)
			{
				component.anchorMin = new Vector2(0f, 1f);
				component.anchorMax = new Vector2(1f, 1f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = Vector2.zero;
				component.sizeDelta = new Vector2(0f, component.sizeDelta.y);
			}
			VerticalLayoutGroup val3 = ((Component)val).GetComponent<VerticalLayoutGroup>() ?? ((Component)val).gameObject.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val3).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)val3).spacing = 4f;
			((LayoutGroup)val3).padding = new RectOffset(8, 8, 4, 8);
			((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false;
			ContentSizeFitter val4 = ((Component)val).GetComponent<ContentSizeFitter>() ?? ((Component)val).gameObject.AddComponent<ContentSizeFitter>();
			val4.horizontalFit = (FitMode)0;
			val4.verticalFit = (FitMode)2;
			for (int i = 0; i < val.childCount; i++)
			{
				Transform child = val.GetChild(i);
				if (!((Object)(object)child == (Object)null))
				{
					LayoutElement component2 = ((Component)child).GetComponent<LayoutElement>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.flexibleHeight = 0f;
					}
				}
			}
			ScrollRect componentInParent = ((Component)val).GetComponentInParent<ScrollRect>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				componentInParent.horizontal = false;
				componentInParent.content = component;
				componentInParent.verticalNormalizedPosition = 1f;
			}
			if ((Object)(object)component != (Object)null)
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(component);
			}
		}

		private static int PlaceOptionPanel(Transform panel, Transform content, int index)
		{
			if ((Object)(object)panel != (Object)null && (Object)(object)panel.parent == (Object)(object)content)
			{
				panel.SetSiblingIndex(index);
				return index + 1;
			}
			return index;
		}

		private static void CompactDetailsLabel(Transform label, float height)
		{
			if (!((Object)(object)label == (Object)null))
			{
				LayoutElement val = ((Component)label).GetComponent<LayoutElement>() ?? ((Component)label).gameObject.AddComponent<LayoutElement>();
				val.minHeight = 0f;
				val.preferredHeight = height;
				val.flexibleHeight = 0f;
				val.flexibleWidth = 1f;
				val.minWidth = 0f;
				val.ignoreLayout = false;
			}
		}

		public static bool IsTaxWash(Component component)
		{
			if ((Object)(object)component == (Object)null || (Object)(object)component.gameObject == (Object)null)
			{
				return false;
			}
			return IsTaxWashPanel(component.gameObject);
		}

		public static bool IsTaxWashPanel(GameObject panel)
		{
			if ((Object)(object)panel == (Object)null)
			{
				return false;
			}
			if ((Object)(object)MRLCore.launderingApp?._appPanel != (Object)null && (Object)(object)panel == (Object)(object)MRLCore.launderingApp._appPanel)
			{
				return true;
			}
			string name = ((Object)panel).name;
			return name == "MRL_TaxWash" || name == "TaxNWash";
		}

		public static void RestoreTaxWashChrome(GameObject mrlApp)
		{
			if ((Object)(object)mrlApp == (Object)null)
			{
				return;
			}
			Transform val = FindMainAppContainer(mrlApp.transform);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			((Component)val).gameObject.SetActive(true);
			string[] array = new string[5] { "Background", "Header", "Topbar", "Details", "Scroll View" };
			for (int i = 0; i < array.Length; i++)
			{
				Transform val2 = val.Find(array[i]) ?? ((array[i] == "Details" || array[i] == "Scroll View") ? FindDeep(val, array[i]) : null);
				if ((Object)(object)val2 != (Object)null && ((Object)val2).name != "DeactivatedScrollView")
				{
					((Component)val2).gameObject.SetActive(true);
				}
			}
			Transform val3 = val.Find("DeactivatedScrollView");
			if ((Object)(object)val3 != (Object)null)
			{
				((Component)val3).gameObject.SetActive(false);
			}
			Transform keep = val.Find("Scroll View") ?? FindDeep(val, "Scroll View");
			HideOverlappingProductUi(val, keep);
			Transform val4 = val.Find("Content");
			if ((Object)(object)val4 != (Object)null)
			{
				HideOverlappingProductUi(val4, keep);
			}
			ApplyOriginalTwoColumnLayout(val);
			MakeOpaqueChrome(val);
			MRLCore.launderingApp?.PackDetailsContent();
		}

		public static void ShowTaxWashInsteadOfProducts()
		{
			HideVanillaProductsContainer();
			GameObject val = MRLCore.launderingApp?._appPanel;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			RestoreTaxWashChrome(val);
			try
			{
				Phone.ActiveApp = val;
			}
			catch
			{
			}
		}

		public static void HideVanillaProductsContainer()
		{
			try
			{
				if (PlayerSingleton<ProductManagerApp>.InstanceExists)
				{
					ProductManagerApp instance = PlayerSingleton<ProductManagerApp>.Instance;
					if ((Object)(object)instance != (Object)null && !IsTaxWash((Component)(object)instance))
					{
						SetAppIsOpen(instance, open: false);
						Type type = ((object)instance).GetType();
						while (type != null)
						{
							FieldInfo field = type.GetField("appContainer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							if (!(field == null))
							{
								object? value = field.GetValue(instance);
								Component val = (Component)((value is Component) ? value : null);
								if ((Object)(object)val != (Object)null)
								{
									val.gameObject.SetActive(false);
								}
								break;
							}
							type = type.BaseType;
						}
						Transform val2 = ((Component)instance).transform.Find("Container");
						if ((Object)(object)val2 != (Object)null)
						{
							((Component)val2).gameObject.SetActive(false);
						}
						DeactivateAppContainers(((Component)instance).transform);
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Tax & Wash could not close vanilla Products: " + ex.Message);
			}
			GameObject appCanvasByName = Utils.GetAppCanvasByName("ProductManagerApp");
			if (!((Object)(object)appCanvasByName == (Object)null) && !IsTaxWashPanel(appCanvasByName))
			{
				Transform val3 = appCanvasByName.transform.Find("Container");
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(false);
				}
				DeactivateAppContainers(appCanvasByName.transform);
			}
		}

		public static void ApplyAppOpen(GameObject panel, bool open)
		{
			if ((Object)(object)panel == (Object)null)
			{
				return;
			}
			try
			{
				panel.SetActive(true);
				panel.transform.SetAsLastSibling();
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Tax & Wash panel.SetActive failed: " + ex);
			}
			if (open)
			{
				RestoreTaxWashChrome(panel);
				HideVanillaProductsContainer();
			}
			else
			{
				DeactivateAppContainers(panel.transform);
			}
			try
			{
				if (PlayerSingleton<Phone>.InstanceExists)
				{
					PlayerSingleton<Phone>.Instance.SetIsHorizontal(open);
					PlayerSingleton<Phone>.Instance.SetLookOffsetMultiplier(open ? 0.6f : 1f);
				}
			}
			catch (Exception ex2)
			{
				MelonLogger.Error("Tax & Wash phone orientation failed: " + ex2);
			}
			try
			{
				if (PlayerSingleton<HomeScreen>.InstanceExists)
				{
					PlayerSingleton<HomeScreen>.Instance.SetIsOpen(!open);
				}
			}
			catch (Exception ex3)
			{
				MelonLogger.Error("Tax & Wash HomeScreen.SetIsOpen failed: " + ex3);
			}
			try
			{
				if (PlayerSingleton<AppsCanvas>.InstanceExists)
				{
					PlayerSingleton<AppsCanvas>.Instance.SetIsOpen(open);
				}
			}
			catch (Exception ex4)
			{
				MelonLogger.Error("Tax & Wash AppsCanvas.SetIsOpen failed: " + ex4);
			}
			try
			{
				if (open)
				{
					Phone.ActiveApp = panel;
				}
				else if ((Object)(object)Phone.ActiveApp == (Object)(object)panel)
				{
					Phone.ActiveApp = null;
				}
			}
			catch (Exception ex5)
			{
				MelonLogger.Error("Tax & Wash ActiveApp failed: " + ex5);
			}
		}

		public static void OpenFromIcon()
		{
			MRLCore.launderingApp?.OpenTaxWash();
		}

		public void OpenTaxWash()
		{
			if (!((Object)(object)_appPanel == (Object)null) && !_openQueued && CanOpenFromHomeScreen())
			{
				OpeningTaxWash = true;
				_openQueued = true;
				_openDelayFrames = 1;
				HideVanillaProductsContainer();
			}
		}

		public static bool CanOpenFromHomeScreen()
		{
			try
			{
				if (!PlayerSingleton<HomeScreen>.InstanceExists || !PlayerSingleton<HomeScreen>.Instance.isOpen)
				{
					return false;
				}
				if ((Object)(object)Phone.ActiveApp != (Object)null)
				{
					return false;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		private void ApplyQueuedOpen()
		{
			if (!_openQueued)
			{
				return;
			}
			if (_openDelayFrames > 0)
			{
				_openDelayFrames--;
				return;
			}
			_openQueued = false;
			try
			{
				ApplyAppOpen(_appPanel, open: true);
				SetAppIsOpen(_productApp, open: true);
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Tax & Wash open failed: " + ex);
			}
		}

		public static bool IsUnderOurIcon(GameObject obj)
		{
			GameObject val = MRLCore.launderingApp?._homeIcon;
			if ((Object)(object)val == (Object)null || (Object)(object)obj == (Object)null)
			{
				return false;
			}
			Transform val2 = obj.transform;
			while ((Object)(object)val2 != (Object)null)
			{
				if ((Object)(object)((Component)val2).gameObject == (Object)(object)val)
				{
					return true;
				}
				val2 = val2.parent;
			}
			return false;
		}

		public static bool IsPointerOverOurIcon()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (!CanOpenFromHomeScreen())
			{
				return false;
			}
			GameObject val = MRLCore.launderin